tenant-engine/tests/test_layer_conformance.py
tegwick 1dabbcf47d Validate accepted security layer v0.8 owner declaration
Assistant: codex
Assistant-Model: gpt-6.1-sol
Assistant-Session: 01a126e1-76f8-7643-8cf3-e93336539ade
2026-10-11 02:21:25 +02:00

219 lines
8.8 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.

"""TEN-WP-0011-T01/T02: layer declaration and published PEP stance."""
from __future__ import annotations
import importlib.util
import subprocess
import sys
from pathlib import Path
import yaml
from tenant_engine.stance import published_stance, shipped_stance
ROOT = Path(__file__).resolve().parents[1]
SCRIPT = ROOT / "scripts" / "check_layer_conformance.py"
def _run(*args: str) -> subprocess.CompletedProcess[str]:
return subprocess.run([sys.executable, str(SCRIPT), *args], capture_output=True, text=True)
def test_layer_yaml_declares_engine_pip():
data = yaml.safe_load((ROOT / "layer.yaml").read_text())
assert data["repository"] == "tenant-engine"
assert data["layer"] == "engine"
assert data["role"] == "pip"
assert data["derived"] is True
assert data["derived_from"] == "INTENT.md"
assert data["tooling_contacts"] == []
assert data["pep_stance"] == "pep-stance.yaml"
assert data["pip_claims"] == "pip-claims.yaml"
ids = {c["id"] for c in data["non_tooling_clients"]}
assert "postgres-own-store" in ids
assert "sqlite-dev-store" in ids
assert "access-engine-check" in ids
assert "state-hub-work-records" in ids
def _intent() -> dict:
return yaml.safe_load((ROOT / "INTENT.md").read_text().split("---", 2)[1])
def _fold(value: object) -> str:
return str(value).translate(str.maketrans("ABCDEFGHIJKLMNOPQRSTUVWXYZ",
"abcdefghijklmnopqrstuvwxyz"))
def test_intent_frontmatter_agrees_with_layer_yaml():
"""A11/A9: the derived form agrees with the governing one after a case-fold.
A fold, not an equality: INTENT.md says Engine and layer.yaml says engine,
and neither is re-spelled. A real divergence still fails.
"""
intent = _intent()
decl = yaml.safe_load((ROOT / "layer.yaml").read_text())
assert _fold(intent["layer"]) == _fold(decl["layer"])
assert _fold(intent["role"]) == _fold(decl["role"])
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():
"""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, "standard": "security-layer-model v0.7"}, # 021 §3 addition
{**base, "ref": "net-kingdom/canon/standards/tenant-engine-boundary-contract_v0.1.md"},
]
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"
"notes: [{note: 'Outside §5 by the v0.7 scope rule.'}]\n")
assert checker.version_findings(data, "x") == []
def test_prose_citation_is_not_a_pin():
"""GH-DEC-2026-021 §1: a revision cited in prose is provenance, not reached."""
checker = _checker()
for data in ({"notes": [{"note": "Outside §5 by the v0.7 scope rule."}]},
{"role_note": "Per Security Layer Model v0.8 §11 and companion v0.2."}):
assert checker.version_findings(data, "x") == [], data
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 "value carries a version" in out.err
def test_checker_rejects_a_divergence_that_survives_the_fold(tmp_path, monkeypatch):
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)
fake = tmp_path / "INTENT.md"
fake.write_text("---\nlayer: Staff\nrole: PIP\n---\n")
monkeypatch.setattr(module, "INTENT", fake)
try:
module.intent_frontmatter()
except SystemExit as exc:
assert exc.code == 2
else: # pragma: no cover
raise AssertionError("a Staff INTENT.md must not pass as Engine")
def test_checker_passes_on_the_real_tree():
result = _run()
assert result.returncode == 0, result.stderr + result.stdout
def test_checker_catches_an_undeclared_openbao_client(tmp_path, monkeypatch):
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)
fake_src = tmp_path / "src" / "tenant_engine"
fake_src.mkdir(parents=True)
(fake_src / "vault.py").write_text("import hvac\n")
monkeypatch.setattr(module, "SRC", fake_src)
hits = module.scan()
assert hits
assert any(h[1] == "hvac" for h in hits)
def test_published_stance_equals_shipped_behaviour():
assert published_stance() == shipped_stance()
assert set(shipped_stance()) == {"unset", "unreachable", "non_allow", "unknown"}
assert set(shipped_stance().values()) == {"fail_closed"}
def test_accepted_v08_run_provenance_and_catalog_scope():
checker = _checker()
assert "security-layer-model_v0.8.md" in checker.VALIDATED_AGAINST
assert "sha256:3d8298560069ef471fba28d2b1245fb2309328f231dad1a667cdf0ce5a5a7c8b" in checker.VALIDATED_AGAINST
assert "single repository tenant-engine (catalogued in §4)" in checker.SCOPE
def test_reference_semantics_propagate_identity_through_nested_sequences():
checker = _checker()
for data in (
{"nested": {"standard": ["Security Layer Model v0.8"]}},
{"companion": [["Security Companion 0.3"]]},
{"standard": {"alternate": ["Security Layer Model v0.7"]}},
):
# A dictionary begins a fresh identity key; only sequence descendants
# inherit the immediate standard:/companion: identity in the reference.
if isinstance(data.get("standard"), dict):
assert checker.find_version_pins(data) == []
else:
assert checker.find_version_pins(data), data
assert checker.find_version_pins({"rationale": "Assented at v0.7; migrated at v0.8."}) == []
assert checker.find_version_pins({"intent_version": "0.2.0", "schema_version": "0.1"}) == []
def test_ascii_folding_never_discards_non_ascii_letters():
checker = _checker()
assert checker._fold("Staff") == "staff"
assert checker._fold("Engine") == "engine"
# Deleting non-ASCII bytes would turn this fifth token into Staff.
assert checker._fold("Stαaff") not in checker.LAYER_VOCABULARY