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()