Apply GH-DEC-2026-020: print scope on every run, widen A12 detection.

The checker now prints the standard version and the run's scope first on
every run, pass or fail, and enforces A12 r2 over every key and value of
the INTENT.md frontmatter and layer.yaml, not only a key named
standard_version. Tests fail if a versioned standard: path or a
companion_version comes back. Neither declaration form changed.

KG-DEC-2026-005 records assent to A9, A10, A11 and A13 and returns A12 r2
revised, with one finding: "any value" reaches prose revision citations.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 63291@bnt-lap001
Assistant-Session: 8bd77868-ca68-4f49-bb1e-d539ecc0d703
This commit is contained in:
tegwick 2026-09-21 09:38:27 +02:00
parent 358f759c72
commit 7b678e5d73
3 changed files with 291 additions and 17 deletions

View file

@ -75,6 +75,95 @@ def test_no_standard_version_in_either_form():
)
def test_no_version_anywhere_in_either_form():
"""A12 r2 / GH-DEC-2026-020 §1§2: content, not a key name.
Fails if a versioned `standard:` path or a `companion_version` comes back, or
any other version pin in any key or value of either declaration form.
"""
module = _load_checker()
front = _intent_frontmatter()
assert "companion_version" not in front
assert "companion_version" not in yaml.safe_load(DECL.read_text())
assert "_v0" not in str(front.get("standard", ""))
assert module.a12_findings(front, "INTENT.md")[0] == []
assert module.a12_findings(yaml.safe_load(DECL.read_text()), "layer.yaml")[0] == []
@pytest.mark.parametrize(
"front_extra",
[
"standard: net-kingdom/canon/standards/security-layer-model_v0.7.md",
"standard: security-layer-model 0.8",
"companion: net-kingdom/SECURITY-COMPANION_v0.2.md",
'companion_version: "0.2"',
'standard_version: "0.7"',
'spec_version: "0.7"',
],
)
def test_checker_rejects_a_version_pin_in_intent_frontmatter(tmp_path, monkeypatch, front_extra):
module = _load_checker()
front = {k: v for k, v in _intent_frontmatter().items() if k != "standard"}
intent = tmp_path / "INTENT.md"
intent.write_text("---\n" + yaml.safe_dump(front) + front_extra + "\n---\n\n# INTENT\n")
monkeypatch.setattr(module, "INTENT", intent)
with pytest.raises(SystemExit) as exc:
module.load_governing_layer()
assert exc.value.code == 2
def test_checker_rejects_companion_version_in_the_sidecar(tmp_path, monkeypatch):
module = _load_checker()
decl = tmp_path / "layer.yaml"
decl.write_text(DECL.read_text() + '\ncompanion_version: "0.2"\n')
monkeypatch.setattr(module, "DECL", decl)
monkeypatch.setattr(module, "ROOT", tmp_path)
with pytest.raises(SystemExit) as exc:
module.load_declaration()
assert exc.value.code == 2
def test_schema_version_and_comments_are_not_reached():
"""GH-DEC-2026-020 §1: the sidecar's own schema version is not the standard's."""
module = _load_checker()
pins, _ = module.a12_findings(
yaml.safe_load('# Framework: security-layer-model_v0.7.md\nschema_version: "0.1"\n'),
"x",
)
assert pins == []
def test_a_prose_citation_is_reported_not_failed():
"""A revision citation in a gap record is provenance; its reach is unruled."""
module = _load_checker()
pins, citations = module.a12_findings({"owner_status": "declined (v0.6 §13)"}, "x")
assert pins == [] and citations
def test_every_run_prints_version_and_scope_even_when_it_fails(tmp_path):
"""GH-DEC-2026-020 §4: the version belongs to the run, and so does the scope."""
module = _load_checker()
ok = _run()
assert module.VALIDATED_AGAINST in ok.stdout and module.SCOPE in ok.stdout
ok_line = [line for line in ok.stdout.splitlines() if line.startswith("OK:")][0]
assert module.VALIDATED_AGAINST in ok_line and module.SCOPE in ok_line
report = _run("--report")
assert module.VALIDATED_AGAINST in report.stdout and module.SCOPE in report.stdout
# A failing run: copy the checker beside a declaration carrying a pin.
(tmp_path / "scripts").mkdir()
(tmp_path / "scripts" / SCRIPT.name).write_text(SCRIPT.read_text())
(tmp_path / "INTENT.md").write_text(
"---\nlayer: Staff\nstandard: security-layer-model_v0.7.md\n---\n"
)
failed = subprocess.run(
[sys.executable, str(tmp_path / "scripts" / SCRIPT.name)],
capture_output=True,
text=True,
)
assert failed.returncode == 2
assert module.VALIDATED_AGAINST in failed.stdout and module.SCOPE in failed.stdout
def test_the_two_forms_agree_after_folding_case():
"""`Staff` in INTENT.md and `staff` in layer.yaml are one value, not a finding."""
module = _load_checker()