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..0ef41c9 --- /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" +--- + +# zone-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/tests/test_layer_v08_convergence.py b/tests/test_layer_v08_convergence.py new file mode 100644 index 0000000..3c218fd --- /dev/null +++ b/tests/test_layer_v08_convergence.py @@ -0,0 +1,37 @@ +"""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 / "tools/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.declaration_versions(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 diff --git a/tools/check_layer_conformance.py b/tools/check_layer_conformance.py index dc60052..c718d42 100644 --- a/tools/check_layer_conformance.py +++ b/tools/check_layer_conformance.py @@ -21,8 +21,9 @@ re-spelled; neither form carries a standard version. Per GH-DEC-2026-020 (A12 r2), "carries a standard version" is a property of the content, not of a key name. The declaration is every key and value of the INTENT.md frontmatter and of layer.yaml; a version-bearing `standard:` or -`companion:` path, a `companion_version`, or any `*_version` key other than -`schema_version` is a pin and fails. Comments and `schema_version` are not +`companion:` path or a key naming a standard/companion version is a pin +and fails. A12 r3 excludes unrelated keys such as intent_version and bare prose +provenance. Comments and `schema_version` are not reached. Stance, claims, and evidence-classification maps are not declarations and are never read here. The version belongs to the run: every run prints VALIDATED_AGAINST and the scope it ranged over. @@ -57,7 +58,10 @@ INTENT = ROOT / "INTENT.md" # The standard text this checker was built and validated against. A # declaration carries no version (A12 r2); the run states it instead # (GH-DEC-2026-020 §4). Bump when re-validated against a newer accepted text. -VALIDATED_AGAINST = "net-kingdom/canon/standards/security-layer-model_v0.7.md" +VALIDATED_AGAINST = ( + "net-kingdom/canon/standards/security-layer-model_v0.8.md " + "(accepted-1 sha256:3d8298560069ef471fba28d2b1245fb2309328f231dad1a667cdf0ce5a5a7c8b)" +) # What a run ranges over. Nothing else in the tree is read; in particular no # stance, claims, or evidence-classification map (GH-DEC-2026-020 §3). @@ -65,12 +69,12 @@ SCOPE = "INTENT.md frontmatter, layer.yaml (A12 across all keys and values), too # A12 r2: keys that are version pins. schema_version is the file format's own # version and is not reached. -VERSION_KEY = re.compile(r"(^|_)version$", re.IGNORECASE) +VERSION_KEY = re.compile(r"(standard|companion).*version|version.*(standard|companion)", re.I) NOT_REACHED_KEYS = {"schema_version"} # A version in a path (`..._v0.7.md`, `...-v1.md`) anywhere in a value. -VERSIONED_PATH = re.compile(r"[_-]v\d+(\.\d+)*(\.[A-Za-z]+)?\b", re.IGNORECASE) +VERSIONED_PATH = re.compile(r"[_\-.]v\d+(\.\d+)*(\.md)?\b|@v?\d+\.\d+", re.I) # A bare version token (`v0.2`, `0.7`) in the value of a standard/companion pin. -PIN_KEYS = {"standard", "companion", "framework"} +PIN_KEYS = {"standard", "companion"} VERSION_TOKEN = re.compile(r"\bv?\d+\.\d+(\.\d+)*\b", re.IGNORECASE) TOOLING_IMPORTS = { @@ -160,32 +164,24 @@ def load_intent(path: Path = INTENT) -> dict[str, Any]: return front -def declaration_versions(data: Any, where: str = "") -> list[str]: - """Every standard/companion version pin in a declaration (A12 r2). - - Walks all keys and values. Comments never reach here (YAML drops them); - schema_version is skipped by name. - """ +def declaration_versions(data: Any, where: str = "", identity: bool = False) -> list[str]: + """A12 r3 pins; prose provenance and unrelated schema versions are excluded.""" found: list[str] = [] if isinstance(data, Mapping): for key, value in data.items(): name = str(key) here = f"{where}.{name}" if where else name - if name.lower() in NOT_REACHED_KEYS: + if name in NOT_REACHED_KEYS: continue if VERSION_KEY.search(name): found.append(f"key '{here}' is a version pin") continue - if name.lower() in PIN_KEYS and isinstance(value, (str, int, float)): - if VERSION_TOKEN.search(str(value)) or VERSIONED_PATH.search(str(value)): - found.append(f"'{here}: {value}' carries a version") - continue - found.extend(declaration_versions(value, here)) + found.extend(declaration_versions(value, here, name.lower() in PIN_KEYS)) elif isinstance(data, list): for index, item in enumerate(data): - found.extend(declaration_versions(item, f"{where}[{index}]")) - elif isinstance(data, str) and VERSIONED_PATH.search(data): - found.append(f"'{where}: {data}' is a version-bearing path") + found.extend(declaration_versions(item, f"{where}[{index}]", identity)) + elif isinstance(data, str) and (VERSIONED_PATH.search(data) or identity and VERSION_TOKEN.search(data)): + found.append(f"'{where}: {data}' carries a standard/companion version") return found