From 79ea443d9cba8fc31c134fc86250f6b97211c064 Mon Sep 17 00:00:00 2001 From: tegwick Date: Sun, 11 Oct 2026 02:21:25 +0200 Subject: [PATCH] Bind checker to accepted v0.8 and preserve provenance distinctions Assistant: codex Assistant-Model: gpt-6.1-sol Assistant-Session: 01a126e1-76f8-7643-8cf3-e93336539ade Assistant-Process: 8340@bnt-lap001 --- .../2026-10-11-layer-v08-migration.md | 31 ++++++++++ scripts/check_layer_conformance.py | 58 ++++++++----------- tests/test_layer_conformance.py | 2 +- tests/test_layer_v08_convergence.py | 42 ++++++++++++++ 4 files changed, 98 insertions(+), 35 deletions(-) create mode 100644 docs/conformance/2026-10-11-layer-v08-migration.md create mode 100644 tests/test_layer_v08_convergence.py diff --git a/docs/conformance/2026-10-11-layer-v08-migration.md b/docs/conformance/2026-10-11-layer-v08-migration.md new file mode 100644 index 0000000..db7f361 --- /dev/null +++ b/docs/conformance/2026-10-11-layer-v08-migration.md @@ -0,0 +1,31 @@ +--- +type: conformance-record +derived: true +derived_from: net-kingdom/canon/standards/security-layer-model_v0.8.md +derived_source_sha256: "3d8298560069ef471fba28d2b1245fb2309328f231dad1a667cdf0ce5a5a7c8b" +updated: "2026-10-11" +--- + +# maturity-engine accepted v0.8 checker migration + +This owner applies GH-WP-0004-T11's post-flip migration to the confirmed +accepted NetKingdom v0.8 cut, immutable accepted-1 artifact SHA256 +3d8298560069ef471fba28d2b1245fb2309328f231dad1a667cdf0ce5a5a7c8b. +The checker names that artifact and its local scope in every run. INTENT +frontmatter remains authoritative and the sidecar remains derived; a +contradiction is a finding, never hidden by choosing one form. No declaration +acquires a standard version. + +The pin detector follows OpsWarden's A12 r3 reference semantics: standard and +companion identity values (including nested lists), version-bearing paths and +standard/companion version keys are pins; unrelated intent/schema/spec versions +and bare prose provenance are not. Existing local Tooling/contact and capability +detectors remain in place. Historical version strings in negative fixtures are +retained. This source migration grants no native capability or runtime authority. + +Validation includes the existing local declaration/contact suite and the same +12-case pin/provenance corpus across all four assigned owners, with exact +accepted-artifact and scope assertions. The local test counts and staged source +digests are retained in the coordinating Custodian evidence receipt. Standalone +checker runs continue to inspect only this repository; no estate-wide compliance +claim or novel declaration is produced. diff --git a/scripts/check_layer_conformance.py b/scripts/check_layer_conformance.py index e12b674..8a0bdbd 100644 --- a/scripts/check_layer_conformance.py +++ b/scripts/check_layer_conformance.py @@ -37,8 +37,8 @@ import yaml # carry this (A12); the run does. Bump it when re-validated against a newer # accepted text. VALIDATED_AGAINST = ( - "net-kingdom/canon/standards/security-layer-model_v0.7.md" - " (+ GH-DEC-2026-017, GH-DEC-2026-020 / A12 r2)" + "net-kingdom/canon/standards/security-layer-model_v0.8.md " + "(accepted-1 sha256:3d8298560069ef471fba28d2b1245fb2309328f231dad1a667cdf0ce5a5a7c8b)" ) # §3 as amended (A9): closed, four tokens, compared after an ASCII case fold. @@ -47,7 +47,7 @@ LAYER_VOCABULARY = {"taxonomy", "tooling", "engine", "staff"} def _fold(value: object) -> str: """ASCII case-fold: two spellings of a token are one token.""" - return str(value).strip().encode("ascii", "ignore").decode().lower() + return str(value).strip().translate(str.maketrans("ABCDEFGHIJKLMNOPQRSTUVWXYZ", "abcdefghijklmnopqrstuvwxyz")) ROOT = Path(__file__).resolve().parents[1] @@ -63,40 +63,30 @@ SCOPE = "INTENT.md frontmatter, layer.yaml, imports under src/maturity_engine" # `standard_version`. `schema_version` is the file format's own version, not a # standard version, and is not reached (GH-DEC-2026-020 §1). EXEMPT_VERSION_KEYS = {"schema_version"} -# A version-bearing path or file name, e.g. `security-layer-model_v0.7.md`, -# `.../v0.2/companion.md`. Matched only against whitespace-free values, so prose -# notes citing a rule's history are not mistaken for a pin. -VERSIONED_PATH = re.compile(r"(?i)(?:^|[_\-/.])v\d+(?:\.\d+)*(?:$|[_\-/.])") -# Keys that name a standard or companion: any version-like token in their value counts. -STANDARD_KEYS = {"standard", "companion", "framework"} -BARE_VERSION = re.compile(r"\d+\.\d+") +VERSION_KEY = re.compile(r"(standard|companion).*version|version.*(standard|companion)", re.I) +VERSIONED_PATH = re.compile(r"[_\-.]v\d+(\.\d+)*(\.md)?\b|@v?\d+\.\d+", re.I) +STANDARD_KEYS = {"standard", "companion"} +BARE_VERSION = re.compile(r"\bv?\d+\.\d+", re.I) -def version_findings(data: object, where: str) -> list[str]: - """Every place a standard or companion version appears in a declaration.""" +def version_findings(data: object, where: str, identity: bool = False) -> list[str]: + """A12 r3 pins; bare prose provenance and unrelated versions are not pins.""" found: list[str] = [] - - def walk(node: object, path: str, key: str | None) -> None: - if isinstance(node, dict): - for k, v in node.items(): - ks = str(k) - if ks in EXEMPT_VERSION_KEYS: - continue - if "version" in ks.lower(): - found.append(f"{where}: key '{path}{ks}' carries a version") - walk(v, f"{path}{ks}.", ks) - elif isinstance(node, list): - for i, v in enumerate(node): - walk(v, f"{path}{i}.", key) - elif isinstance(node, str): - value = node.strip() - label = path.rstrip(".") - if key and key.lower() in STANDARD_KEYS and BARE_VERSION.search(value): - found.append(f"{where}: '{label}' value {value!r} carries a version") - elif value and not any(c.isspace() for c in value) and VERSIONED_PATH.search(value): - found.append(f"{where}: '{label}' value {value!r} is a version-bearing path") - - walk(data, "", None) + if isinstance(data, dict): + for key, value in data.items(): + name = str(key) + here = f"{where}.{name}" if where else name + if name in EXEMPT_VERSION_KEYS: + continue + if VERSION_KEY.search(name): + found.append(f"{here} names a standard/companion version") + continue + found.extend(version_findings(value, here, name.lower() in STANDARD_KEYS)) + elif isinstance(data, list): + for index, item in enumerate(data): + found.extend(version_findings(item, f"{where}[{index}]", identity)) + elif isinstance(data, str) and (VERSIONED_PATH.search(data) or identity and BARE_VERSION.search(data)): + found.append(f"{where} = {data!r} carries a standard/companion version") return found diff --git a/tests/test_layer_conformance.py b/tests/test_layer_conformance.py index 0346b36..ea05938 100644 --- a/tests/test_layer_conformance.py +++ b/tests/test_layer_conformance.py @@ -148,7 +148,7 @@ def test_no_version_anywhere_in_either_declaration(): {"companion": "net-kingdom/v0.2/SECURITY-COMPANION.md"}, {"companion_version": "0.2"}, {"standard_version": "0.7"}, - {"framework": "netkingdom-security-layer-model 0.8"}, + {"standard": ["netkingdom-security-layer-model 0.8"]}, ], ) def test_checker_catches_a_version_beyond_the_key_name(declaration): diff --git a/tests/test_layer_v08_convergence.py b/tests/test_layer_v08_convergence.py new file mode 100644 index 0000000..116c6a6 --- /dev/null +++ b/tests/test_layer_v08_convergence.py @@ -0,0 +1,42 @@ +"""Accepted A12 r3 semantics, retaining local contact scanners and scope.""" +import importlib.util +from pathlib import Path +import pytest + +ROOT = Path(__file__).resolve().parents[1] +SCRIPT = ROOT / "scripts/check_layer_conformance.py" + +def checker(): + spec = importlib.util.spec_from_file_location("v08_checker", SCRIPT) + module = importlib.util.module_from_spec(spec) + spec.loader.exec_module(module) + return module + +@pytest.mark.parametrize("value,pinned", [ + ({"intent_version": "0.3"}, False), + ({"spec_version": "0.7"}, False), + ({"note": "per v0.6 section 13"}, False), + ({"note": "revised 0.7 wording"}, False), + ({"schema_version": "0.1"}, False), + ({"standard": "security-layer-model 0.8"}, True), + ({"STANDARD": ["security-layer-model v0.8"]}, True), + ({"companion": [["SECURITY-COMPANION v0.3"]]}, True), + ({"nested": {"standard_version": "0.8"}}, True), + ({"nested": {"companion_version": "0.3"}}, True), + ({"references": ["security-layer-model@0.8"]}, True), + ({"references": ["security-layer-model_v0.7.md"]}, True), +]) +def test_reference_pin_provenance_semantics(value, pinned): + module = checker() + assert bool(module.version_findings(value, "test")) is pinned + +def test_run_names_exact_accepted_standard_and_scope(): + module = checker() + assert "security-layer-model_v0.8.md" in module.VALIDATED_AGAINST + assert "3d8298560069ef471fba28d2b1245fb2309328f231dad1a667cdf0ce5a5a7c8b" in module.VALIDATED_AGAINST + assert "INTENT.md" in module.SCOPE + +def test_ascii_fold_never_discards_non_ascii_characters(): + module = checker() + assert module._fold("Enginée") not in module.LAYER_VOCABULARY + assert module._fold("ENGINE") == "engine"