zone-engine/tests/test_canon_lineage.py
tegwick be29c28100 feat: harden zone reference contracts
Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a0291a-1e87-7151-9934-fcbfe3f65eb1
2026-08-23 12:27:13 +02:00

63 lines
2.2 KiB
Python

from pathlib import Path
from tempfile import TemporaryDirectory
import unittest
from tools.check_canon_lineage import check_lineage
CANON = b"""---
id: netkingdom-security-zones-v0.1
status: proposed
---
# Fixture canon
"""
class CanonLineageTest(unittest.TestCase):
def test_matching_artifact_passes_and_mutation_fails(self):
import hashlib
with TemporaryDirectory() as directory:
root = Path(directory)
path = root / "canon" / "standards" / "security-zones_v0.1.md"
path.parent.mkdir(parents=True)
path.write_bytes(CANON)
manifest = {
"standard": "canon-lineage_v0.1",
"artifact": "security-zones_v0.1",
"publication_owner": "net-kingdom",
"canonical_path": "canon/standards/security-zones_v0.1.md",
"canonical_revision": "fixture",
"canonical_status": "proposed",
"canonical_sha256": hashlib.sha256(CANON).hexdigest(),
}
result = check_lineage(manifest, root, verify_revision=False)
self.assertTrue(result["ok"])
path.write_bytes(CANON + b"changed\n")
result = check_lineage(manifest, root, verify_revision=False)
self.assertFalse(result["ok"])
self.assertIn("content hash changed", result["errors"][0])
def test_lifecycle_change_is_detected_separately(self):
import hashlib
accepted = CANON.replace(b"proposed", b"accepted")
with TemporaryDirectory() as directory:
root = Path(directory)
path = root / "standard.md"
path.write_bytes(accepted)
manifest = {
"standard": "canon-lineage_v0.1",
"canonical_path": "standard.md",
"canonical_revision": "fixture",
"canonical_status": "proposed",
"canonical_sha256": hashlib.sha256(accepted).hexdigest(),
}
result = check_lineage(manifest, root, verify_revision=False)
self.assertFalse(result["ok"])
self.assertIn("lifecycle changed", result["errors"][0])
if __name__ == "__main__":
unittest.main()