AI Initiative logoAI Initiative
Reading room / Manthan

D-308 — Domain-separation tag version reconciliation

D-308 — Domain-separation tag version reconciliation. Covers The inconsistency; Why `.v1` is right; Fix applied; SPEC.md changes.

Historical audit / evidence record
This is the retained source text, not a new validation of its claims. Numerical results and comparative claims require the accompanying source review before public reuse.

Read the connected case study or article →

Not explicitly stated in source · Date not established

Provenance, authorship and editorial notes

D-308 — Domain-separation tag version reconciliation

Id

manthan-herald-protocol-audits-dom-sep-version-fix

Project

Manthan

Source path

manthan/herald-protocol/audits/dom-sep-version-fix.md

Source sha256

992233100ed1aca4c056c14580b2fc61cfcbfcc50144f98e8b363b4ba91f5710

Local copy sha256

992233100ed1aca4c056c14580b2fc61cfcbfcc50144f98e8b363b4ba91f5710

Repo head

3a94084024a3434cef331fecac91c2c3b43f0313

Date
Not recorded
Date basis

Original publication date not established; Git revision date retained separately.

Author

Not explicitly stated in source

Author basis

Unknown; Git committer not substituted for document author.

Last source commit

8b75d1b0157c20a0a463f0e31008ef9f73099beb

Last source commit date

2026-06-08T07:40:14Z

Document status

Historical audit / evidence record

Summary

D-308 — Domain-separation tag version reconciliation. Covers The inconsistency; Why `.v1` is right; Fix applied; SPEC.md changes.

Topics
  • Adversarial review and case studies
  • The inconsistency
  • Why `.v1` is right
  • Fix applied
Theme

Adversarial review and case studies

Priority

reference

Related ids
  • manthan-herald-protocol-audits-manthan-cohort1-postmortem
Evidence concerns
  • Recovered source text is preserved verbatim. Assertions, comparisons, commands and results belong to its original context; they were not re-executed or externally re-verified during this corpus review.
  • Historical record: current deployment, task completion and test status must not be inferred from this date-bound document.
Word count

1022

Bytes

6916

Source relative

herald-protocol/audits/dom-sep-version-fix.md

Remote mirror

manthan/herald-protocol/audits/dom-sep-version-fix.md

Full text preserved

True

D-308 — Domain-separation tag version reconciliation

Decision: .v1 is canonical. SPEC §3.6 had drifted to .v2; that has been corrected in-place. EXT §12 was already correct at .v1 (24 entries). Worker-A's test vectors have been regenerated with .v1 and re-verify cleanly (all 7 ✓).


The inconsistency

Two places in the canon describe the domain-separation tag set:

1. SPEC §3.6 — Domain separation (table, lines 212-220). Pre-fix, all 9 tags read .v2 (e.g. herald.envelope.v2, herald.molt.v2, etc.).
2. EXT §12 — Domain-separation registry (table, lines 770-792). All 24 tags read .v1.

Plus inline references in EXT §1, §2, §3, §4, §5, §7, §8, §11 — every signed primitive cited a .v1 tag.

Worker-B (T-012, standard attestation registry) flagged this as F-1 in their submission notes. Worker-A (T-001, test vectors) had to make a judgement call when generating signatures and chose .v2 per current SPEC §3.6 — meaning the test vectors were aligned with the wrong half of the spec.

Why .v1 is right

The semantic question is: what does the version suffix track?

Option B is what real protocols do. DKIM uses dkim1; it has stayed dkim1 across many specification revisions. TLS cipher-suite identifiers are similarly schema-version, not protocol-version.

For HERALD:

If a future protocol revision introduces a new signing primitive (post-quantum candidate, BLS aggregation), then the tag bumps to .v2 for the affected primitive. Until then, .v1 is correct.

This also matches the EXT §12 registry rule: "Adding a new tag requires a registered description, a list of permitted scopes, and a worked example. Removing a tag requires deprecation notice and a transition period of at least 12 months." The lifecycle is per-tag, not protocol-wide.

Fix applied

SPEC.md changes

- | Originating envelope | `herald.envelope.v2` |
- | Birth attestation | `herald.birth.v2` |
- | Molt | `herald.molt.v2` |
- | Deprecation | `herald.deprecation.v2` |
- | Lineage endorsement | `herald.lineage_endorsement.v2` |
- | Capability manifest | `herald.capability_manifest.v2` |
- | Refusal | `herald.refusal.v2` |
- | Conduit receipt | `herald.conduit_receipt.v2` |
- | Audit-log STH | `herald.audit_sth.v2` |
+ | Originating envelope | `herald.envelope.v1` |
+ | Birth attestation | `herald.birth.v1` |
+ | Molt | `herald.molt.v1` |
+ | Deprecation | `herald.deprecation.v1` |
+ | Lineage endorsement | `herald.lineage_endorsement.v1` |
+ | Capability manifest | `herald.capability_manifest.v1` |
+ | Refusal | `herald.refusal.v1` |
+ | Conduit receipt | `herald.conduit_receipt.v1` |
+ | Audit-log STH | `herald.audit_sth.v1` |

Applied via perl -i -pe 's/herald\.([a-z_]+)\.v2/herald.$1.v1/g' SPEC.md. SPEC §2.4 line 120 already cited herald.molt.v1 — that line was already correct; the table was the outlier.

Test vectors

Worker-A's test-vectors/v0.2/generate.py and verify.py had a constant DOM_SEP_ENVELOPE = b"herald.envelope.v2". Changed to .v1. Re-ran python3 generate.py (deterministic; produces a fresh vectors.json with re-signed bytes). Ran python3 verify.py — all 7 vectors verify cleanly against the new tag. The vector id and signature bytes have changed (different dom_sep prefix produces different signature input), but the structure and expected verification verdicts are unchanged.

EXT.md

No changes needed. EXT §12 was already correct.

CHARTER.md

Spot-check: CHARTER does not enumerate domain-separation tags directly; it references EXT for protocol shape. No changes needed.

THREATS.md

Spot-check: THREATS cites domain-separation as a defence (§3.6 post-D-306). No version-suffix references. No changes needed.

Propagation status

FilePre-fixPost-fixNotes
SPEC.md9 × .v2 (one in §2.4 was .v1 by accident)9 × .v1Table now self-consistent; line 120 was already correct
EXT.md24 × .v124 × .v1Unchanged — was already canonical
test-vectors/v0.2/*.py1 × .v2 constant1 × .v1 constantRegenerated; all 7 vectors re-verify
test-vectors/v0.2/vectors.json9 × "herald.envelope.v2"0 × .v2 (false positives in base32-encoded sigils ignored)Regenerated
CHARTER.md——No tag references
THREATS.md— (post-D-306)—No tag references
audits/threat-coverage.md——Cites SPEC/EXT §s, not tags

Verification

$ grep -nE 'herald\.[a-z_]+\.v2' SPEC.md
(no output)

$ grep -cE 'herald\.[a-z_]+\.v1' SPEC.md
9

$ grep -cE 'herald\.[a-z_]+\.v1' EXT.md
24

$ python3 test-vectors/v0.2/verify.py
... (7 verifications) ...
OK: all 7 vectors verified against expected results

Implications for downstream work

Closes

Future maintenance

The version suffix should be bumped when (and only when) the signing primitive changes. A migration would look like:

1. Register .v2 of the affected tag(s) in EXT §12.
2. Specify the new signing scheme in SPEC §3.6 (or equivalent).
3. Define a transition period (≥12 months per EXT §12 rule).
4. Verifiers MUST accept either version during transition; SHOULD prefer .v2 once published.

This is the same pattern DKIM uses for selector rotation.


— D-308, completed by driver-claude, 2026-05-05.

Continue exploring