From ff0712b2604b2e388b7517890f156ec4d1f89927 Mon Sep 17 00:00:00 2001 From: tegwick Date: Mon, 21 Sep 2026 13:05:05 +0200 Subject: [PATCH] Apply GH-DEC-2026-021: name the text in force, converge on the reference detector MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit VALIDATED_AGAINST now names the accepted security-layer-model v0.7 (net-kingdom@66dc491) as amended by GH-DEC-2026-017, -020, -021 (gate-house@39d9287), not the held v0.8 (021 §2). The A12 detector converges on ops-warden's playbook reference plus the 021 §3 addition (a version in a standard:/companion: value is a pin). A prose citation such as 'the v0.7 scope rule' is no longer failed (021 §1); tests updated. The layer.yaml note rewording stays. Co-Authored-By: Claude Opus 5 Assistant: claude-code Assistant-Model: opus Assistant-Process: 63291@bnt-lap001 Assistant-Session: 8bd77868-ca68-4f49-bb1e-d539ecc0d703 --- scripts/check_layer_conformance.py | 60 ++++++++++++++++-------------- tests/test_layer_conformance.py | 13 ++++++- 2 files changed, 43 insertions(+), 30 deletions(-) diff --git a/scripts/check_layer_conformance.py b/scripts/check_layer_conformance.py index d833448..8fa96bc 100644 --- a/scripts/check_layer_conformance.py +++ b/scripts/check_layer_conformance.py @@ -7,8 +7,8 @@ Read-only. Makes two mechanical checks: derived artifact (derived: true, derived_from: INTENT.md) that must agree with it after ASCII case-folding. The layer is one of §3's closed four tokens (Taxonomy, Tooling, Engine, Staff). Neither form carries a - version of the standard or its companion in any key or value - (GH-DEC-2026-017 §1-§5, GH-DEC-2026-020, amendments A9, A11, A12 r2). + version of the standard or its companion as a pin (GH-DEC-2026-017 + §1-§5, GH-DEC-2026-020, GH-DEC-2026-021 §1, amendments A9, A11, A12 r2). 2. No catalogued Tooling client (OpenBao, key-cape) appears in src/ unless it maps to a declared §5.1 / §5.2 / §5.3 entry. @@ -16,10 +16,13 @@ PostgreSQL / SQLite / httpx-to-flex-auth / httpx-to-audit-core are not Tooling contacts. They are listed in layer.yaml non_tooling_clients so the inventory is total. -A12 r2 reaches content, not a key name: a `*_version` key (standard_version, -companion_version, ...), a versioned `security-layer-model_v0.7.md` or -companion path, and a bare `v0.7` token all count. `schema_version` and YAML -comments are not reached. Stance, claims and classification maps +A12 reaches a pin, not a citation (GH-DEC-2026-021 §1). The detector is +ops-warden's estate reference (wiki/playbooks/netkingdom-layer-declaration.md, +021 §3): a key naming a standard or companion version, a version in a path or +file-name token (`_v0.7`, `-v0.8.md`, `@0.7`), and, the one addition, any +version token in the value of a `standard:` or `companion:` key. A revision +cited in prose (a space-preceded `v0.7`) is provenance and is not reached. +`schema_version` and YAML comments are not reached. Stance, claims and classification maps (pep-stance.yaml, pip-claims.yaml) are not declarations; this check does not read them for A12 and must not (A12 r2, GH-DEC-2026-020 §3). @@ -41,34 +44,33 @@ try: import yaml except ImportError: # pragma: no cover - dev extra print("FAIL: PyYAML is required (pip install pyyaml)", file=sys.stderr) - raise SystemExit(2) + raise SystemExit(2) from None ROOT = Path(__file__).resolve().parents[1] SRC = ROOT / "src" / "tenant_engine" DECL = ROOT / "layer.yaml" INTENT = ROOT / "INTENT.md" -# The standard text this checker was built and validated against -# (GH-DEC-2026-020 §4, A12 r2: the version belongs to the run). Bump it when -# the checker is re-validated against a newer accepted text. -VALIDATED_AGAINST = ("net-kingdom/canon/standards/security-layer-model_v0.8.md " - "@ net-kingdom f9e1611, with gate-house " - "docs/amendments/v0.8-section-11-declaration-amendments.md " - "A9, A11, A12 r2 @ gate-house 104f3fc") +# The text in force this checker enforces (GH-DEC-2026-020 §4, GH-DEC-2026-021 +# §2): the ACCEPTED v0.7 plus the gate-house decisions enforced beyond it. v0.8 +# is held under GH-DEC-2026-019 and does not govern, so it is not named here. +# Re-point after the flip (GH-WP-0004-T11). +VALIDATED_AGAINST = ("net-kingdom/canon/standards/security-layer-model_v0.7.md " + "(net-kingdom@66dc491) as amended by GH-DEC-2026-017, " + "GH-DEC-2026-020, GH-DEC-2026-021 (gate-house@39d9287)") SCOPE = ("declaration = INTENT.md frontmatter + layer.yaml (every key and value); " "tooling scan = src/tenant_engine/**/*.py; " "not reached: pep-stance.yaml, pip-claims.yaml, comments, schema_version") -# A12 r2: what reads as a version of this standard or its companion. -_VERSION_KEY = re.compile(r"(?:^|_)version$", re.IGNORECASE) +# A12 pin detector, converged on ops-warden's estate reference (GH-DEC-2026-021 +# §3). The path pattern deliberately flags a versioned path of any document. +_VERSION_KEY = re.compile(r"(standard|companion).*version|version.*(standard|companion)", + re.IGNORECASE) +_VERSION_IN_VALUE = re.compile(r"[_\-.]v\d+(\.\d+)*(\.md)?\b|@v?\d+\.\d+", re.IGNORECASE) _EXEMPT_KEYS = {"schema_version"} # the declaration file's own schema, not reached -_VERSIONED_PATH = re.compile( - r"(?:security-layer-model|security[-_]companion|companion)[^\s]*?[_-]v?\d+(?:\.\d+)+", - re.IGNORECASE) -# A bare version token (v0.7). A declaration names no other versioned text, so -# a bare token reads as this standard's. File-name suffixes of other -# standards (…_v0.1.md) are preceded by '_' and are not matched here. -_BARE_VERSION = re.compile(r"(? str: def version_findings(data: object, where: str) -> list[str]: - """Every key or value of a parsed declaration that carries a version (A12 r2).""" + """Every pin in a parsed declaration (A12, GH-DEC-2026-021 §1, §3).""" found: list[str] = [] def walk(node: object, path: str) -> None: @@ -106,14 +108,16 @@ def version_findings(data: object, where: str) -> list[str]: if _VERSION_KEY.search(str(key)): found.append(f"{where}: key '{sub}' is a version key") continue - if isinstance(key, str): - walk(key, sub + " (key)") + if (_fold(key) in _IDENTITY_KEYS and isinstance(value, str) + and _ANY_VERSION.search(value)): + found.append(f"{where}: '{sub}' carries a version: {value.strip()[:80]!r}") + continue walk(value, sub) elif isinstance(node, list): for i, item in enumerate(node): walk(item, f"{path}[{i}]") elif isinstance(node, str): - if _VERSIONED_PATH.search(node) or _BARE_VERSION.search(node): + if _VERSION_IN_VALUE.search(node): found.append(f"{where}: '{path}' carries a version: {node.strip()[:80]!r}") walk(data, "") @@ -124,7 +128,7 @@ def _reject_versions(data: object, where: str) -> None: findings = version_findings(data, where) if findings: print("FAIL: a layer declaration must not carry a version of the standard " - "or its companion, in any key or value (A12 r2, GH-DEC-2026-020)", + "or its companion, as a pin (A12, GH-DEC-2026-020, GH-DEC-2026-021 §1)", file=sys.stderr) for line in findings: print(f" {line}", file=sys.stderr) diff --git a/tests/test_layer_conformance.py b/tests/test_layer_conformance.py index f44de77..ff7648b 100644 --- a/tests/test_layer_conformance.py +++ b/tests/test_layer_conformance.py @@ -85,7 +85,8 @@ def test_versioned_standard_path_or_companion_version_fails(): {**base, "companion_version": "0.2"}, {**base, "companion": "net-kingdom/SECURITY-COMPANION.md v0.2"}, {**base, "standard_version": "0.8"}, - {**base, "notes": [{"note": "Outside §5 by the v0.7 scope rule."}]}, + {**base, "standard": "security-layer-model v0.7"}, # 021 §3 addition + {**base, "ref": "net-kingdom/canon/standards/tenant-engine-boundary-contract_v0.1.md"}, ] for data in bad: assert checker.version_findings(data, "x"), data @@ -97,10 +98,18 @@ def test_schema_version_comments_and_section_numbers_are_not_reached(): "# Framework: net-kingdom/canon/standards/security-layer-model_v0.7.md\n" "schema_version: '0.1'\nstandard: netkingdom-security-layer-model\n" "declared_shapes: {'5.1': [], '5.2': []}\ndeclared_at: '2026-08-29'\n" - "ref: net-kingdom/canon/standards/tenant-engine-boundary-contract_v0.1.md\n") + "notes: [{note: 'Outside §5 by the v0.7 scope rule.'}]\n") assert checker.version_findings(data, "x") == [] +def test_prose_citation_is_not_a_pin(): + """GH-DEC-2026-021 §1: a revision cited in prose is provenance, not reached.""" + checker = _checker() + for data in ({"notes": [{"note": "Outside §5 by the v0.7 scope rule."}]}, + {"role_note": "Per Security Layer Model v0.8 §11 and companion v0.2."}): + assert checker.version_findings(data, "x") == [], data + + def test_checker_does_not_apply_a12_to_stance_or_claims_maps(): """A12 r2 / GH-DEC-2026-020 §3: those files keep their version and are not read for it.""" for name in ("pep-stance.yaml", "pip-claims.yaml"):