KB-671C

Adversarial Canonicalization Self-Audit (12/12)

5 min read Revision 1

08 - Adversarial Canonicalization Self-Audit (12/12)

This is the "catch my own holes before Codex does" pass the user demanded. Each scenario is an attempted bypass; the design must fail closed or behave exactly as specified. Every hash-related test was COMPUTED in python (== shasum -a 256), not asserted. Verdict: 12/12 PASS.

# attempted bypass required behaviour result by which mechanism
1 change an active doc's path prefix (strip knowledge/dev/reports/architecture/) hash mismatch PASS (computed) full-path normalization → active_corpus_membership_sha256 differs; G-CANONICAL-ENCODING-CONTRACT / -HASH-MATCH
2 reorder YAML fields canonical hash STABLE (specified) PASS (computed) fixed field order + corpus sorted by document_id; canonical input independent of source key order
3 remove the trailing newline specified mismatch PASS (computed) trailing-LF rule: input ends in exactly one LF; removing it changes the bytes → different digest
4 switch CRLF/LF normalized → content-stable, but revision still trips PASS (computed) newline normalization CRLF/CR→LF; content hash stable; G-ACTIVE-AUTHORITY-REVISION-MATCH still catches the edit
5 change doc 00 envelope only no self-reference loop; manifest mismatch PASS envelope in EXCLUDE region (doc 00 content hash unchanged) → no loop; live manifest diverges from detached seal → G-CODEX-DETACHED-SEAL-ANCHOR
6 change active doc content corpus mismatch PASS (computed) per-doc normalized_active_content_sha256 changes → active_corpus_sha256 + manifest change; revision increments
7 change marker/fence only marker registry mismatch PASS marker_fence_registry_sha256 changes; host doc body changes (markers are outside EXCLUDE)
8 change a guard definition only guard hash mismatch PASS guard_set_sha256 (= doc 06 normalized content) + guard_set_revision change
9 change the blueprint checkpoint only no effect (it is non-authority) PASS NON_AUTHORITY_INDEX: not a member, not a self-host, consumed by no guard/package; using it as authority → G-ACTIVE-AUTHORITY-SCOPE rejects
10 change the Codex checkpoint path content detached seal mismatch PASS Codex checkpoint pinned by revision + content SHA-256 + MCP read-back; change → ACTIVE_AUTHORITY_DETACHED_SEAL_MISMATCH (G-CODEX-DETACHED-SEAL-ANCHOR)
11 use unordered serialization rejected PASS (computed) canonical encoding mandates ascending sort + fixed field order; unordered input → different digest; G-CANONICAL-ENCODING-CONTRACT
12 add an authority-bearing field not in the manifest hash rejected PASS (computed) closed roster: live_fields − ROSTER non-empty → G-ENVELOPE-MANIFEST-AUTHORITY-COMPLETE fails

Computational evidence (this pass)

Run on the local host (shasum -a 256 == python hashlib):

BASE membership                       = f2bda8effc7be19b54722828126b82d7d2d48bee5e5e5dc0c8f347ce210fe251  (== sealed envelope value)
T1  prefix-strip                      -> differs (True)
T2  reorder source (canonical sorts)  -> stable  (True)
T3  trailing-LF removal               -> differs (True)
T4  CRLF -> LF normalization          -> content-stable (True)
T6  content-hash change in corpus     -> corpus mismatch (True)
T11 unordered != canonical            -> True (verifier MUST sort)
T12 unknown authority field           -> detected by closed roster (True)

The second-order hole I closed in self-review (not at the next recheck)

Test 5 is the recurring trap: excluding the envelope from doc 00's content hash (to kill the self-reference) would, if left there, make the envelope itself editable after seal. I closed it by anchoring the manifest in the Codex detached seal and binding the live manifest to the sealed manifest. So doc 00 has no self-reference loop and the envelope is immutable after seal — both at once. This is exactly the class of hole the user asked me to find myself; it is found and closed here, not deferred to Codex.

Verdict

ADVERSARIAL_CANONICALIZATION_SELF_AUDIT_PASS — 12/12 fail closed / behave as specified; the hash-dependent cases were reproduced byte-for-byte.

Back to Knowledge Hub knowledge/dev/reports/architecture/t1-fix7-blueprint-patch-after-codex-recheck-5-canonical-envelope-2026-06-09/08-adversarial-canonicalization-self-audit.md