D-311 — Signature-scope string unification
Decision: underscored identifiers are canonical (tool_sandbox, conduit_receipt, human_approval, herald_endorsement). SPEC §3.4 had drifted to a hyphenated, partly-misnamed list (tool-sandbox, conduit-receipt, human-approval, herald-lineage). EXT §6.1 is and remains the canonical scope registry. SPEC and THREATS prose are now aligned.
The inconsistency
Two places in the canon enumerated the signature-scope set:
1. SPEC §3.4 (line 186) — pre-fix:
tool-sandbox, conduit-receipt, human-approval, herald-lineage.
2. EXT §6.1 (lines 414–424) — canonical, unchanged:
origin, tool_sandbox, conduit_receipt, human_approval, herald_endorsement.
Plus two occurrences in THREATS.md (lines 268 and 596 — the residual-risk and consolidated-recommendations lists) using SPEC's hyphenated form, and one quoted policy label in SPEC §3.4 (line 190) ("human-approved") that was easy to mis-read as a literal scope value.
Worker-B (T-012) flagged this as F-4 in their submission notes.
Why underscored identifiers win
EXT §6.1 is the formal registry section. It is the source for:
- domain-separation tags per scope (EXT §6.3 —
herald.sig.sandbox.v1etc.), - progressive-signing rules (EXT §6.4),
- the verifier rule "MUST refuse to treat scopes as interchangeable" (§6.1).
Everywhere else in EXT and SPEC, multi-token identifiers use underscores: conduit_receipt, audit_sth, lineage_endorsement, capability_manifest, trace_parent, model_hash. CBOR map keys are text strings (SPEC §3.5) and the underscore convention is uniform.
The hyphenated SPEC §3.4 list was therefore the outlier. Its position in a non-normative recap paragraph (pointing forward to EXT §6) makes it a typo rather than a competing convention.
Naming change, not just spelling
herald-lineage (old SPEC) → herald_endorsement (canonical) is a name change, not just punctuation. EXT §6.1 line 422 explains why: a Herald can endorse any envelope claim, with lineage being only one example ("e.g. lineage"). The general scope name is more accurate than the lineage-specific one. Toolchains that already implemented herald-lineage from the SPEC must update both the spelling and the noun.
Fix applied
SPEC.md changes (2 lines)
Line 186 (the scope enumeration):
- - Subsequent signatures MAY come from: tool sandboxes (`scope: "tool-sandbox"`), conduits (`scope: "conduit-receipt"`), humans-in-the-loop (`scope: "human-approval"`), Heralds (`scope: "herald-lineage"`).
+ - Subsequent signatures MAY come from: tool sandboxes (`scope: "tool_sandbox"`), conduits (`scope: "conduit_receipt"`), humans-in-the-loop (`scope: "human_approval"`), Heralds (`scope: "herald_endorsement"`). See [EXT §6.1] for the full scope registry; underscored identifiers are canonical.Line 190 (the policy-label example, ambiguous as quoted):
- - An envelope is `valid` only if the origin signature verifies AND every signature an application's policy *requires* (e.g. "human-approved") verifies. ...
+ - An envelope is `valid` only if the origin signature verifies AND every signature an application's policy *requires* (e.g. a `scope: "human_approval"` signature) verifies. ...THREATS.md changes (2 lines)
Line 268 (residual-risk list):
- ... a per-signature `scope` field in addition (origin, tool-sandbox, conduit-receipt, human-approval, herald-lineage) so verifiers refuse to treat scopes as interchangeable [EXT §3.4 / recommendation 11]. A captured tool-sandbox key without ...
+ ... a per-signature `scope` field in addition (`origin`, `tool_sandbox`, `conduit_receipt`, `human_approval`, `herald_endorsement`) so verifiers refuse to treat scopes as interchangeable [EXT §6.1]. A captured `tool_sandbox` key without ...(Citation also updated: [EXT §3.4 / recommendation 11] → [EXT §6.1] since the actual registry now lives in §6.1.)
Line 596 (consolidated-recommendations item 18):
- 18. **Per-signature `scope` field (origin, tool-sandbox, conduit-receipt, human-approval, herald-lineage).** ...
+ 18. **Per-signature `scope` field (`origin`, `tool_sandbox`, `conduit_receipt`, `human_approval`, `herald_endorsement`).** ...EXT.md
No changes. EXT §6.1 was already canonical.
CHARTER.md
No scope-string references. Untouched.
Out-of-scope: English-compound prose
Five hits in THREATS.md remain hyphenated:
- THREATS.md:42 — "Mandatory conduit-receipt timestamp on
birth/..." - THREATS.md:46 — "Sender requires conduit-receipt for non-repudiation..."
- THREATS.md:296 — "no third-party time anchor unless a conduit-receipt is used..."
- THREATS.md:298 — "Either require a conduit-receipt timestamp on every envelope..."
- THREATS.md:595 — "Mandatory conduit-receipt timestamps on
birth/..."
These are English-compound noun-phrase usage ("the receipt issued by a conduit"), not the literal scope-identifier value. EXT.md style for prose uses "conduit receipt" (no hyphen, no underscore — see EXT §5.5 heading "Mandatory conduit receipts on state-transition envelopes"). A future copy-edit pass over THREATS could normalise prose-style to match EXT (drop the hyphen), but that's stylistic, not a correctness fix. Out of scope for D-311.
Verification
$ grep -nE '\b(tool|conduit|human|herald)-(sandbox|receipt|approval|lineage)\b' SPEC.md EXT.md CHARTER.md THREATS.md
THREATS.md:42: ... conduit-receipt timestamp on `birth`/... # English compound
THREATS.md:46: ... requires conduit-receipt for non-repudiation... # English compound
THREATS.md:296: ... unless a conduit-receipt is used... # English compound
THREATS.md:298: ... a conduit-receipt timestamp on every envelope...# English compound
THREATS.md:595: ... Mandatory conduit-receipt timestamps on... # English compound
# (no scope-identifier hits remain)
$ grep -cE '\btool_sandbox\b|\bconduit_receipt\b|\bhuman_approval\b|\bherald_endorsement\b' SPEC.md EXT.md THREATS.md
SPEC.md:5
THREATS.md:3
EXT.md:15All identifier-form hits are now underscored and consistent.
Implications for downstream work
- T-002 (CBOR-deterministic profile, completed by worker-E): does not depend on scope strings — encoder/decoder operates on text-string CBOR map keys/values without inspecting scope semantics. No change.
- T-012 (standard-attestation registry, completed by worker-B): consumed the EXT §6.1 underscored forms; closes worker-B's
F-4. No change to T-012 output. - T-003 (TS reference library, future): must use the underscored identifiers as the only canonical form. No legacy hyphenated alias.
- T-004 (Python reference library, future): same.
- Test vectors (T-001, post-D-308): v0.2 vectors include only an
originsignature; no other scopes are exercised yet. A follow-on multi-sig vector pack (T-024/T-025?) should use the underscored canonical names from the start.
Closes
- Worker-B
F-4from T-012 NOTES.md — directly resolved. - Reduces the inverse-coverage residual that D-302 §6 left open (one fewer ambiguity for the inverse index).
Future maintenance
If a new scope is added to the registry (EXT §6.1), it MUST use the same convention: lowercase, underscore-separated, single-token nouns or short noun-phrases. No hyphens, no camelCase, no dots (dots are reserved for the domain-separation-tag namespace, e.g. herald.sig.sandbox.v1). The corresponding herald.sig.<name>.v1 tag in EXT §6.3 follows the existing dot-separated pattern.
— D-311, completed by driver-claude, 2026-05-05.