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:
parent
358f759c72
commit
7b678e5d73
3 changed files with 291 additions and 17 deletions
|
|
@ -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()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue