"""A12 r2 (GH-DEC-2026-017 §5, GH-DEC-2026-020): the layer declaration carries no version of the standard or of its companion, in any key or value. The declaration is every key of the INTENT.md frontmatter and every key of the derived layer.yaml. Comments and `schema_version` are not reached. Stance, claims and classification maps are not declarations and are not checked here. Parsed as text, not YAML: pyyaml is not a dependency of this repository, and a skipped test would enforce nothing. """ import re from pathlib import Path ROOT = Path(__file__).resolve().parents[1] # A version-bearing key (any key ending in `version`, except the file's own # schema version) or a version in a value, including one carried in a path or # file name such as `security-layer-model_v0.7.md`. VERSION_KEY = re.compile(r"^\s*-?\s*([A-Za-z0-9_]*version)\s*:", re.IGNORECASE) VERSION_VALUE = re.compile(r"_v\d+(\.\d+)*|\bv\d+\.\d+") # OPEN, reported to gate-house with this repository's A12 r2 findings: a prose # citation of a past rule inside a rationale value ("the v0.5 scope rule") is # not a pin, but A12 r2's "no key or value" reads literally as reaching it. # Listed here, exactly, so it stays visible and nothing else slips past. CITATION_ALLOWLIST = { "Progress events. Outside §5 by the v0.5 scope rule. Recorded, not", } def _declaration_lines(text: str) -> list[str]: lines = [] for raw in text.splitlines(): line = raw.split(" #", 1)[0] if line.lstrip().startswith("#") or not line.strip(): continue lines.append(line) return lines def _intent_frontmatter() -> str: text = (ROOT / "INTENT.md").read_text() match = re.match(r"^---\n(.*?)\n---\n", text, re.DOTALL) assert match, "INTENT.md has no frontmatter; the declaration lives there" return match.group(1) def _findings(name: str, text: str) -> list[str]: found = [] for line in _declaration_lines(text): key = VERSION_KEY.match(line) if key and key.group(1).lower() != "schema_version": found.append(f"{name}: version key: {line.strip()}") elif ( not key and VERSION_VALUE.search(line) and line.strip() not in CITATION_ALLOWLIST ): found.append(f"{name}: versioned value: {line.strip()}") return found def test_declaration_carries_no_version(): findings = _findings("INTENT.md frontmatter", _intent_frontmatter()) findings += _findings("layer.yaml", (ROOT / "layer.yaml").read_text()) assert not findings, "\n".join(findings) def test_companion_version_absent(): assert "companion_version" not in "\n".join( _declaration_lines((ROOT / "layer.yaml").read_text()) ) assert "companion_version" not in "\n".join( _declaration_lines(_intent_frontmatter()) ) def test_standard_path_unversioned(): match = re.search(r"^standard:\s*(\S+)", _intent_frontmatter(), re.MULTILINE) assert match, "INTENT.md frontmatter names no standard" assert match.group(1) == "net-kingdom/canon/standards/security-layer-model" def test_detector_catches_the_forms_ruled_on(): # The check must see the pin under any name, not only `standard_version`. assert _findings("x", 'companion_version: "0.2"\n') assert _findings("x", 'standard_version: "0.7"\n') assert _findings( "x", "standard: net-kingdom/canon/standards/security-layer-model_v0.7.md\n" ) assert not _findings("x", 'schema_version: "0.1"\n') assert not _findings("x", "# Companion: SECURITY-COMPANION.md v0.2\n") assert not _findings("x", ' statute: "§9.4"\n "5.1": []\n')