Apply GH-DEC-2026-020: the checker states its version and scope, and reads content
scripts/check_layer_conformance.py now prints, on every run (success and failure), the standard text it checks against (VALIDATED_AGAINST: security-layer-model_v0.8.md @ net-kingdom f9e1611 with gate-house A9, A11, A12 r2 @ 104f3fc) and its scope. A12 detection widens from the key name standard_version to any *_version key (companion_version included), a versioned standard/companion path, or a bare vN.N token in any key or value of INTENT.md frontmatter or layer.yaml. schema_version and comments are not reached; pep-stance.yaml and pip-claims.yaml are not read for A12 and keep their version fields (GH-DEC-2026-020 §3). The widened check found one value the key-name check could not: the state-hub-work-records note in layer.yaml cited "the v0.7 scope rule". It is reworded to "the standard's scope rule"; no layer or role value changes. Tests fail if a versioned standard: path, a companion_version or a bare version token returns, and if a run stops stating its version and scope. 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
00e203c447
commit
8322f0587e
3 changed files with 155 additions and 12 deletions
|
|
@ -58,10 +58,82 @@ def test_intent_frontmatter_agrees_with_layer_yaml():
|
|||
assert _fold(intent["layer"]) in {"taxonomy", "tooling", "engine", "staff"}
|
||||
|
||||
|
||||
def _checker():
|
||||
spec = importlib.util.spec_from_file_location("check_layer_conformance", SCRIPT)
|
||||
module = importlib.util.module_from_spec(spec)
|
||||
assert spec.loader is not None
|
||||
spec.loader.exec_module(module)
|
||||
return module
|
||||
|
||||
|
||||
def test_no_declaration_carries_a_standard_version():
|
||||
"""GH-DEC-2026-017 / A12: neither form carries a standard version."""
|
||||
"""A12 r2 / GH-DEC-2026-020: no version in any key or value of either form."""
|
||||
checker = _checker()
|
||||
assert "standard_version" not in yaml.safe_load((ROOT / "layer.yaml").read_text())
|
||||
assert "standard_version" not in _intent()
|
||||
assert checker.version_findings(yaml.safe_load((ROOT / "layer.yaml").read_text()),
|
||||
"layer.yaml") == []
|
||||
assert checker.version_findings(_intent(), "INTENT.md") == []
|
||||
|
||||
|
||||
def test_versioned_standard_path_or_companion_version_fails():
|
||||
"""GH-DEC-2026-020 §1-§2: the pin is caught under any name, not only standard_version."""
|
||||
checker = _checker()
|
||||
base = {"layer": "Engine", "role": "PIP"}
|
||||
bad = [
|
||||
{**base, "standard": "net-kingdom/canon/standards/security-layer-model_v0.7.md"},
|
||||
{**base, "companion_version": "0.2"},
|
||||
{**base, "companion": "net-kingdom/SECURITY-COMPANION.md v0.2"},
|
||||
{**base, "standard_version": "0.8"},
|
||||
{**base, "notes": [{"note": "Outside §5 by the v0.7 scope rule."}]},
|
||||
]
|
||||
for data in bad:
|
||||
assert checker.version_findings(data, "x"), data
|
||||
|
||||
|
||||
def test_schema_version_comments_and_section_numbers_are_not_reached():
|
||||
checker = _checker()
|
||||
data = yaml.safe_load(
|
||||
"# Framework: net-kingdom/canon/standards/security-layer-model_v0.7.md\n"
|
||||
"schema_version: '0.1'\nstandard: netkingdom-security-layer-model\n"
|
||||
"declared_shapes: {'5.1': [], '5.2': []}\ndeclared_at: '2026-08-29'\n"
|
||||
"ref: net-kingdom/canon/standards/tenant-engine-boundary-contract_v0.1.md\n")
|
||||
assert checker.version_findings(data, "x") == []
|
||||
|
||||
|
||||
def test_checker_does_not_apply_a12_to_stance_or_claims_maps():
|
||||
"""A12 r2 / GH-DEC-2026-020 §3: those files keep their version and are not read for it."""
|
||||
for name in ("pep-stance.yaml", "pip-claims.yaml"):
|
||||
assert "standard_version" in yaml.safe_load((ROOT / name).read_text())
|
||||
assert _run().returncode == 0
|
||||
|
||||
|
||||
def test_every_run_states_version_and_scope(tmp_path):
|
||||
"""GH-DEC-2026-020 §4: the version lives in the run, on success and on failure."""
|
||||
checker = _checker()
|
||||
ok = _run()
|
||||
assert ok.stdout.count(checker.VALIDATED_AGAINST) >= 2 # header and OK line
|
||||
assert "scope:" in ok.stdout
|
||||
report = _run("--report")
|
||||
assert checker.VALIDATED_AGAINST in report.stdout and "scope:" in report.stdout
|
||||
|
||||
|
||||
def test_a_failing_run_still_states_version_and_scope(tmp_path, monkeypatch, capsys):
|
||||
checker = _checker()
|
||||
fake = tmp_path / "INTENT.md"
|
||||
fake.write_text("---\nlayer: Engine\nrole: PIP\n"
|
||||
"standard: net-kingdom/canon/standards/security-layer-model_v0.7.md\n---\n")
|
||||
monkeypatch.setattr(checker, "INTENT", fake)
|
||||
monkeypatch.setattr(sys, "argv", ["check_layer_conformance.py"])
|
||||
try:
|
||||
checker.main()
|
||||
except SystemExit as exc:
|
||||
assert exc.code == 2
|
||||
else: # pragma: no cover
|
||||
raise AssertionError("a versioned standard: path must fail")
|
||||
out = capsys.readouterr()
|
||||
assert checker.VALIDATED_AGAINST in out.out and "scope:" in out.out
|
||||
assert "carries a version" in out.err
|
||||
|
||||
|
||||
def test_checker_rejects_a_divergence_that_survives_the_fold(tmp_path, monkeypatch):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue