kings-guard/tests/test_layer_conformance.py
tegwick 7b678e5d73 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
2026-09-21 09:38:27 +02:00

290 lines
11 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""kings-guard's layer declaration is checkable, not merely asserted (§11).
The claim under test is the one our whole position rests on: no direct
Tooling-layer client. A test that only ran the checker against a clean tree
would prove nothing — it would pass just as happily if the checker were broken.
So the negative case is exercised too, on a synthetic tree.
"""
from __future__ import annotations
import subprocess
import sys
from pathlib import Path
import pytest
yaml = pytest.importorskip("yaml")
ROOT = Path(__file__).resolve().parents[1]
SCRIPT = ROOT / "scripts" / "check_layer_conformance.py"
DECL = ROOT / "layer.yaml"
def _run(*args: str) -> subprocess.CompletedProcess[str]:
return subprocess.run(
[sys.executable, str(SCRIPT), *args],
capture_output=True,
text=True,
)
def test_declaration_exists_and_declares_staff():
"""§11: an estate-authored repository declares its layer machine-readably."""
assert DECL.exists(), "no layer.yaml — §11 requires a machine-readable declaration"
data = yaml.safe_load(DECL.read_text())
assert data["repository"] == "kings-guard"
# Folded, not equal: §3's vocabulary is case-insensitive (GH-DEC-2026-017 §2).
# An equality assertion here would perform the re-spelling the ruling declined.
assert data["layer"].lower() == "staff"
assert data["framework"] == "netkingdom-security-layer-model"
def _load_checker():
import importlib.util
spec = importlib.util.spec_from_file_location("check_layer_conformance", SCRIPT)
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
return module
def _intent_frontmatter() -> dict:
lines = (ROOT / "INTENT.md").read_text().splitlines()
assert lines[0].strip() == "---"
end = lines[1:].index("---") + 1
return yaml.safe_load("\n".join(lines[1:end]))
def test_intent_governs_and_the_sidecar_is_marked_derived():
"""GH-DEC-2026-017 §1 / A11: INTENT.md governs; layer.yaml is derived from it."""
front = _intent_frontmatter()
assert front["layer"].lower() == "staff"
data = yaml.safe_load(DECL.read_text())
assert data["derived"] is True
assert data["derived_from"] == "INTENT.md"
def test_no_standard_version_in_either_form():
"""GH-DEC-2026-017 §5 / A12: a layer declaration carries no standard version."""
assert "standard_version" not in _intent_frontmatter()
assert "standard_version" not in yaml.safe_load(DECL.read_text())
# The validated-against version moved to the conformance record, not away.
assert _load_checker().VALIDATED_AGAINST.startswith(
"net-kingdom/canon/standards/security-layer-model"
)
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()
front = _intent_frontmatter()
data = yaml.safe_load(DECL.read_text())
assert not module.forms_disagree(front["layer"], data["layer"])
assert not module.forms_disagree("Staff", "STAFF")
def test_a_real_layer_disagreement_survives_the_fold():
"""The fold must not blind the check: Staff vs Engine is still a finding."""
module = _load_checker()
assert module.forms_disagree("Staff", "engine")
def test_vocabulary_is_the_four_tokens_including_taxonomy():
"""A9: closed at four tokens; a three-token validator carries the defect."""
assert _load_checker().LAYER_VOCABULARY == {"taxonomy", "tooling", "engine", "staff"}
def test_checker_rejects_a_declaration_carrying_a_standard_version(tmp_path, monkeypatch):
module = _load_checker()
decl = tmp_path / "layer.yaml"
decl.write_text(DECL.read_text() + '\nstandard_version: "0.7"\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_checker_rejects_an_unmarked_sidecar(tmp_path, monkeypatch):
module = _load_checker()
data = yaml.safe_load(DECL.read_text())
data.pop("derived")
decl = tmp_path / "layer.yaml"
decl.write_text(yaml.safe_dump(data))
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_no_tooling_contacts_declared():
"""The blocked-clean position: nothing to declare, because nothing is touched."""
data = yaml.safe_load(DECL.read_text())
assert data["tooling_contacts"] == [], (
"a Tooling contact appeared in the declaration; kings-guard's blocked-clean "
"position under §11 no longer holds and KG-DEC-2026-001 needs revisiting"
)
for shape, entries in data["declared_shapes"].items():
assert entries == [], f"§5.{shape} shape declared; see comment above"
def test_unowned_capabilities_carry_the_gap_record_fields():
"""§5.3 field shape, reused for §13 unowned-capability rows (§17 gap-record)."""
data = yaml.safe_load(DECL.read_text())
caps = data["unowned_capabilities"]
assert caps, "the three known gaps should be declared"
for cap in caps:
for field in ("capability", "intended_owner", "blocked_on", "review", "state"):
assert cap.get(field), f"{cap.get('id')} missing '{field}'"
assert cap["state"] == "unowned-capability"
def test_checker_passes_on_the_real_tree():
result = _run()
assert result.returncode == 0, result.stderr
def test_agent_principal_rule_checks_are_honest():
"""§3.4 claims that are tests, and claims that remain assertions, are named."""
data = yaml.safe_load(DECL.read_text())
checks = data["agent_principal_rule_checks"]
assert checks["no_standing_credential"]["form"] == "test"
assert checks["memory_is_not_a_state_plane"]["form"] == "test"
assert checks["tool_use_shapes"]["form"] == "assertion"
assert checks["reconstructable_as_caller"]["form"] == "mixed"
assert data["agent_principal_rules"]["no_standing_credential"] is True
def test_checker_catches_a_standing_credential(tmp_path, monkeypatch):
import importlib.util
spec = importlib.util.spec_from_file_location("check_layer_conformance", SCRIPT)
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
fake_src = tmp_path / "src" / "kings_guard"
fake_src.mkdir(parents=True)
(fake_src / "secrets.py").write_text('VAULT_TOKEN = "s.standing-secret"\n')
(tmp_path / ".env").write_text("OPENBAO_TOKEN=s.also-standing\n")
monkeypatch.setattr(module, "SRC", fake_src)
monkeypatch.setattr(module, "ROOT", tmp_path)
hits = module.scan_standing_credentials()
assert hits, "a standing credential was not detected — the checker is blind"
kinds = " ".join(reason for _, reason in hits)
assert "credential-shaped file" in kinds or "standing-credential" in kinds
def test_checker_catches_an_undeclared_tooling_client(tmp_path, monkeypatch):
"""The negative case: a direct OpenBao client must fail the check.
This is the convenience §6 warns about — it would arrive as one import.
"""
import importlib.util
spec = importlib.util.spec_from_file_location("check_layer_conformance", SCRIPT)
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
fake_src = tmp_path / "src" / "kings_guard"
fake_src.mkdir(parents=True)
(fake_src / "effector.py").write_text(
"import hvac\n\n\ndef contain(actor):\n hvac.Client().revoke(actor)\n"
)
monkeypatch.setattr(module, "SRC", fake_src)
monkeypatch.setattr(module, "ROOT", tmp_path)
hits = module.scan()
assert hits, "a direct OpenBao client was not detected — the checker is blind"
assert hits[0][1] == "hvac"