Assistant: codex Assistant-Model: gpt-6.1-sol Assistant-Session: 01a126e1-76f8-7643-8cf3-e93336539ade
219 lines
8.8 KiB
Python
219 lines
8.8 KiB
Python
"""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
|