D-306 — Substitution Report
Substitutions applied to THREATS.md. Run python3 patch.py to regenerate.
| # | Description | Hits | Pattern | Replacement |
|---|---|---|---|---|
| 1 | Drop ', post-amendment]' suffix | 8 | , post-amendment\] | ] |
| 2 | EXT §2.4-amended → EXT §1 (Molt) | 3 | \[EXT §2\.4-amended\] | [EXT §1] |
| 3 | EXT §2.4 / §8.3-hardened (compound) → EXT §1, §4 | 1 | \[EXT §2\.4 / §8\.3-hardened\] | [EXT §1, §4] |
| 4 | EXT §5.3a → EXT §2.5 | 4 | \[EXT §5\.3a\] | [EXT §2.5] |
| 5 | EXT §4.2-hardened → EXT §7.3 | 2 | \[EXT §4\.2-hardened\] | [EXT §7.3] |
| 6 | EXT §4.2-amended → EXT §7.3 | 1 | \[EXT §4\.2-amended\] | [EXT §7.3] |
| 7 | EXT §4.2 (whisper) → EXT §7.3 | 1 | \[EXT §4\.2\] | [EXT §7.3] |
| 8 | EXT §8.3-hardened → EXT §4 | 3 | \[EXT §8\.3-hardened\] | [EXT §4] |
| 9 | EXT §8.3-amended → EXT §4 | 2 | \[EXT §8\.3-amended\] | [EXT §4] |
| 10 | EXT §5.2-hardened → EXT §5.4 | 3 | \[EXT §5\.2-hardened\] | [EXT §5.4] |
| 11 | EXT §5.2-amended → EXT §5.5 (mandatory conduit receipts) | 1 | \[EXT §5\.2-amended\] | [EXT §5.5] |
| 12 | EXT §9.1-hardened → CHARTER §6.6, EXT §9.4 | 3 | \[EXT §9\.1-hardened\] | [CHARTER §6.6, EXT §9.4] |
| 13 | EXT §9.6-hardened → EXT §9 | 2 | \[EXT §9\.6-hardened\] | [EXT §9] |
| 14 | EXT §9.7-hardened → EXT §7.4 | 2 | \[EXT §9\.7-hardened\] | [EXT §7.4] |
| 15 | EXT §9.5-hardened → EXT §8 | 5 | \[EXT §9\.5-hardened\] | [EXT §8] |
| 16 | EXT §9.2-hardened → CHARTER (graded recordability not built) | 2 | \[EXT §9\.2-hardened\] | [CHARTER, gap: graded recordability not yet specified] |
| 17 | EXT §8.2-hardened → EXT §3 | 5 | \[EXT §8\.2-hardened\] | [EXT §3] |
| 18 | EXT §8.2-extended → EXT §3.6 (Herald revocation) | 1 | \[EXT §8\.2-extended\] | [EXT §3.6] |
| 19 | EXT §8.2 (handle binding) → EXT §11 (DNS) + EXT §3.2 (Herald handle) | 1 | \[EXT §8\.2\] | [EXT §11, §3.2] |
| 20 | EXT §3-extended → EXT §3.3 | 4 | \[EXT §3-extended\] | [EXT §3.3] |
| 21 | EXT §3.5-extended → EXT §6.6 | 1 | \[EXT §3\.5-extended\] | [EXT §6.6] |
| 22 | EXT §5.3-hardened → EXT §2.6, §2.7 (LOTS, minimal metadata) | 2 | \[EXT §5\.3-hardened\] | [EXT §2.6, §2.7] |
| 23 | EXT §5.3-extended (provenance proof) → EXT §2.8 (ZK promotion) | 1 | \[EXT §5\.3-extended, §11\.2\] | [EXT §2.8] |
| 24 | EXT §2.3-hardened → SPEC §2.3, gap (rendering rule not specified) | 1 | \[EXT §2\.3-hardened\] | [SPEC §2.3, gap: distinct rendering rule unspecified — see T-021] |
| 25 | EXT §3.7 → SPEC §3.7 (nonce belongs to core SPEC) | 1 | \[EXT §3\.7\] | [SPEC §3.7] |
| 26 | SPEC §9.1, §9.6, §9.7 (compound) → CHARTER + EXT split | 1 | \[SPEC §9\.1, §9\.6, §9\.7\] | [CHARTER §6.6, EXT §9, §7.4] |
| 27 | SPEC §9.1 (patina) → CHARTER §6.6 | 2 | \[SPEC §9\.1\] | [CHARTER §6.6] |
| 28 | SPEC §9.2 (ghost mode) → CHARTER | 2 | \[SPEC §9\.2\] | [CHARTER] |
| 29 | SPEC §9.5 (Bestiary) → EXT §8 (protocol shape) / CHARTER §6.6 (taxonomy) | 4 | \[SPEC §9\.5\] | [EXT §8] |
| 30 | SPEC §9.6 (inheritance) → EXT §9 | 4 | \[SPEC §9\.6\] | [EXT §9] |
| 31 | SPEC §9.7 (quorum) → EXT §7.4 (protocol shape) / CHARTER (cultural) | 1 | \[SPEC §9\.7\] | [EXT §7.4] |
| 32 | SPEC §9.8 (stigmergy) → CHARTER | 1 | \[SPEC §9\.8\] | [CHARTER] |
| 33 | SPEC §9.11 (whisper-only conduit) → CHARTER §5.9 (The Dovecote) | 2 | \[SPEC §9\.11\] | [CHARTER §5.9] |
| 34 | SPEC §9.12 (Naming Office) → CHARTER | 1 | \[SPEC §9\.12\] | [CHARTER] |
| 35 | SPEC §4.2 whisper → SPEC §4.2 (kept) — note moved to EXT §7.3 for shape | 1 | \[SPEC §4\.2 whisper\] | [SPEC §4.2 whisper (shape: EXT §7.3)] |
| 36 | Drop ', post-amendment' qualifier inside citations | 0 | , post-amendment\b | `` |
| 37 | SPEC §3.5/§3.6 → SPEC §3.5, §3.6 | 1 | \[SPEC §3\.5/§3\.6\] | [SPEC §3.5, §3.6] |
Total substitutions: 80
Source size: 68656 bytes; patched size: 68285 bytes; delta: -371 bytes.
Second pass — compound citations (2026-05-05)
The first pass (patch.py) handled only bare-form citations ([EXT §X-amended]). It missed compound forms with semicolon-suffixed metadata ([EXT §X-amended; CS#], [EXT §Y-hardened; recommendation N]). A second pass with a generic lookup-table perl substitution closed the gap.
Rules applied (lookup table):
| Old (drift) prefix | New |
|---|---|
EXT §2.1 (collision/squatting belongs to SPEC) | SPEC §2.1 |
EXT §2.3 (lineage cycle / consent graph) | EXT §3.1 |
EXT §2.4 (molt) | EXT §1 |
EXT §3.3 (trace-parent invariant — actually in SPEC v0.2) | SPEC §3.3a |
EXT §3.4 (multi-sig) | EXT §6 |
EXT §3.5 (signature suite registry) | EXT §6.6 |
EXT §4.2 (whisper) | EXT §7.3 |
EXT §5.2 (refusal transparency) | EXT §5.4 |
EXT §5.3 (audit log) | EXT §2 |
EXT §8.2 (Heralds) | EXT §3 |
EXT §8.3 (capability manifests) | EXT §4 |
EXT §9.1 (patina) | CHARTER §6.6, EXT §9.4 |
EXT §9.2 (ghost mode) | CHARTER |
EXT §9.5 (Bestiary) | EXT §8 |
EXT §9.6 (inheritance) | EXT §9 |
EXT §9.7 (quorum) | EXT §7.4 |
The substitution preserves the trailing ; CS# / ; recommendation N annotations verbatim, so cross-references to numbered review items (CS1-CS13 from 01-security, recommendations 1-20 from 02-redteam) remain intact.
Verification: grep -cE '\[(EXT\|SPEC) §[0-9.]+(-amended|-hardened|-extended)' THREATS.md → 0.
The compound-citation pattern is now part of the generic patch rule; tools/threats-citation-patch.py covers the bare form, and the lookup-table perl pass covers compounds. Future re-runs need both.