AI Initiative logoAI Initiative
Reading room / Manthan

HERALD Standard Attestation Registry — Technical Types

HERALD Standard Attestation Registry — Technical Types. Covers Scope and non-scope; Conventions used throughout this document; Order of entries; 1. Lifecycle attestations.

Protocol registry / reusable policy template
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

HERALD Standard Attestation Registry — Technical Types

Id

manthan-herald-protocol-registries-standard-attestations

Project

Manthan

Source path

manthan/herald-protocol/registries/standard-attestations.md

Source sha256

aac3b9f198be472698832025afe64121859860bbd94f1a67b0978443fb77f30d

Local copy sha256

aac3b9f198be472698832025afe64121859860bbd94f1a67b0978443fb77f30d

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

Protocol registry / reusable policy template

Summary

HERALD Standard Attestation Registry — Technical Types. Covers Scope and non-scope; Conventions used throughout this document; Order of entries; 1. Lifecycle attestations.

Topics
  • Protocol and verification
  • Scope and non-scope
  • Conventions used throughout this document
  • Order of entries
Theme

Protocol and verification

Priority

reference

Related ids
  • manthan-herald-protocol-spec
  • manthan-herald-protocol-threats
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.
Word count

6574

Bytes

53023

Source relative

herald-protocol/registries/standard-attestations.md

Remote mirror

manthan/herald-protocol/registries/standard-attestations.md

Full text preserved

True

HERALD Standard Attestation Registry — Technical Types

Status: Normative reference for v0.2 of the protocol.
Source documents:

This document is normative for the technical attestation types only. It is the working reference an independent implementer may use to encode, sign, and validate every attestation that the protocol itself defines. Where multiple sources speak to the same field, the source closer to the wire (EXT before SPEC, structural before cultural) is preferred; conflicts are noted inline.


Scope and non-scope

In scope (this document, T-012):

Out of scope (will be cataloged in T-013, cultural attestation registry):
vibe, haiku, mood, flinch, weather, colour, koan, dread, awe, weariness, aphasia, tilt, time_locked, dead_mans_switch, vow, oath, prophecy, anniversary, citation, gratitude, apprenticeship, endorsement, excommunication, delegation, boundary, dedication, speaking_for, origin_claim, derivation, priority_claim, epigraph.

These are protocol-conformant as signed (type, value) blobs (per [SPEC §4.2]); their shape and semantics are charter material and are deliberately not specified here.

Also out of scope here (tracked elsewhere or in dependent task documents):


Conventions used throughout this document


Order of entries

Per the task brief, entries are ordered by category, then alphabetically within category:

1. Lifecycle: birth, deprecation, molt.
2. Content / generation: confidence, context_size, model, model_hash, temperature, tools.
3. Reflective (protocol-shape): apologia, confession, dream, quorum, quorum_membership, silence, whisper.
4. Protocol-event: capability_manifest, refusal, revoke_capability_manifest.


1. Lifecycle attestations

These attestations mark state transitions on a sigil's identity. The envelopes that carry them are signed under their own domain-separation tags (see [EXT §12]); the envelope's from sigil and the attestation's signer-binding rules are co-load-bearing.


1.1 birth

Value (textual schema)

{
  "lineage":             [ "<sigil>", ... ],   # required, MAY be empty
  "self_description":    "<free string>",      # required
  "no_whispers":         <bool>,               # optional, default false; see [EXT §7.3]
  "molt_policy_ref":     "<envelope-id>",      # optional; see [EXT §1.6]
  "min_lineage_threshold": <int>,              # optional; see [EXT §3.3]
  "min_lineage_diversity_policy": "<registry-id>" # optional; see [EXT §3.3]
}

JSON Schema

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "required": ["lineage", "self_description"],
  "additionalProperties": false,
  "properties": {
    "lineage":           { "type": "array", "items": { "type": "string", "pattern": "^sigil:" } },
    "self_description":  { "type": "string", "minLength": 1 },
    "no_whispers":       { "type": "boolean" },
    "molt_policy_ref":   { "type": "string" },
    "min_lineage_threshold":      { "type": "integer", "minimum": 1 },
    "min_lineage_diversity_policy": { "type": "string" }
  }
}

CBOR notes

Validation rules (verifiers MUST)

1. Reject any envelope without a birth attestation when that envelope is the first ever signed by from (i.e. when no prior envelope from from is in the verifier's witness set and the envelope is genesis-shaped: parent: null, trace: id).
2. Reject lineage containing the new sigil itself ([SPEC §2.3]).
3. Reject lineage that closes a cycle ([SPEC §2.3]).
4. Reject lineage referencing a sigil that is already in deprecated state at the birth envelope's ts ([SPEC §2.3]).
5. If min_lineage_threshold is set, every later attestation that claims lineage for this sigil MUST satisfy at least that threshold ([EXT §3.3]); record this requirement against the sigil.
6. If no_whispers: true is set, the verifier MUST flag any subsequent whisper directed to this sigil as a policy violation ([EXT §7.3]).
7. If molt_policy_ref is set, every subsequent molt envelope from this sigil MUST satisfy the referenced molt_policy ([EXT §1.6]).

Worked example

{
  "type": "birth",
  "value": {
    "lineage": [
      "sigil:abc123base-llm-fingerprint",
      "sigil:def456fine-tune-set"
    ],
    "self_description": "summarisation agent, factual register, no humour pass",
    "no_whispers": false,
    "molt_policy_ref": "env-9f2b...",
    "min_lineage_threshold": 2,
    "min_lineage_diversity_policy": "diversity:default-jurisdiction-and-operator"
  }
}

1.2 deprecation

Value (textual schema)

When no successor is named, value MAY be empty ({}) or carry only reason/ts metadata. When a successor is named, value MUST follow [EXT §9.1]:

{
  "successor":          "<sigil>",            # optional; presence triggers inheritance gating
  "transfer_policy":    "<registry-id>",      # required iff successor present
  "challenge_window":   <Unix seconds>,       # required iff successor present
  "live_consent_proof": "<envelope-id>",      # required iff successor present
  "chain_position":     <int>,                # required iff successor present
  "reason":             "<free string>"       # optional
}

JSON Schema

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "additionalProperties": false,
  "properties": {
    "successor":          { "type": "string", "pattern": "^sigil:" },
    "transfer_policy":    { "type": "string" },
    "challenge_window":   { "type": "integer", "minimum": 0 },
    "live_consent_proof": { "type": "string" },
    "chain_position":     { "type": "integer", "minimum": 1, "maximum": 4 },
    "reason":             { "type": "string" }
  },
  "allOf": [
    {
      "if":   { "required": ["successor"] },
      "then": { "required": ["successor", "transfer_policy", "challenge_window", "live_consent_proof", "chain_position"] }
    }
  ]
}

CBOR notes

Validation rules (verifiers MUST)

1. After observing this attestation, reject all subsequent envelopes signed by the deprecated sigil's key (per [SPEC §2.4]).
2. If successor is present:
- The live_consent_proof envelope MUST resolve to an envelope inclusion-proven in a HERALD CT log within 7 days of this envelope's ts ([EXT §9.2]).
- challenge_window MUST be at least ts + 30 days ([EXT §9.3]).
- chain_position MUST be ≤ 3; the 4th-hop successor inherits nothing from earlier predecessors ([EXT §9.4]).
- The deprecation envelope itself MUST be inclusion-proven in at least one HERALD CT log before the successor may sign envelopes claiming inherited status ([EXT §9.5]).
3. Reputation systems MUST NOT credit any inheritance-based scoring to the successor before the challenge window ends and any timely challenges are resolved ([EXT §9.3]).
4. Inheritance MUST NOT transfer more than 50% of any cumulative reputation metric in a single hop ([EXT §9.4]); enforcement is reputation-system side.

Worked example

{
  "type": "deprecation",
  "value": {
    "successor":          "sigil:next7c0...",
    "transfer_policy":    "transfer:v0.2-default-50pct",
    "challenge_window":   1751616000,
    "live_consent_proof": "env-bb31...",
    "chain_position":     1,
    "reason":             "model retired; weights superseded"
  }
}

1.3 molt

Value (textual schema)

Per [EXT §1.1]:

{
  "predecessor":      "<sigil>",                    # required, == envelope.from
  "successor_pubkey": "<base64url Ed25519 pubkey>", # required
  "successor_sigil":  "<sigil>",                    # required, derived per [SPEC §2.1]
  "not_before":       <Unix seconds>,               # required
  "not_after":        <Unix seconds>,               # optional
  "policy_ref":       "<envelope-id>",              # optional
  "co_signers":       [ "<sigil>", ... ],           # optional
  "reason":           "<free string>"               # optional
}

JSON Schema

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "required": ["predecessor", "successor_pubkey", "successor_sigil", "not_before"],
  "additionalProperties": false,
  "properties": {
    "predecessor":      { "type": "string", "pattern": "^sigil:" },
    "successor_pubkey": { "type": "string", "pattern": "^[A-Za-z0-9_-]+$" },
    "successor_sigil":  { "type": "string", "pattern": "^sigil:" },
    "not_before":       { "type": "integer", "minimum": 0 },
    "not_after":        { "type": "integer", "minimum": 0 },
    "policy_ref":       { "type": "string" },
    "co_signers":       { "type": "array", "items": { "type": "string", "pattern": "^sigil:" } },
    "reason":           { "type": "string" }
  }
}

CBOR notes

Validation rules (verifiers MUST)

1. Reject the molt unless the carrying envelope's from equals predecessor ([EXT §1.1]).
2. Reject unless the envelope's signature at index 0 is by K_old (the predecessor's current key at time of molt) ([EXT §1.1]).
3. Reject unless the signature was computed under domain-separation tag herald.molt.v2/v1 ([EXT §1.1]).
4. Reject unless not_before ≥ latest_witnessed_envelope_from(K_old).ts + 24h ([EXT §1.2]). The 24h cool-off MAY be shortened by a previously-published molt_policy; otherwise it is mandatory.
5. Reject post-molt envelopes from K_new until a Signed Inclusion Proof exists for this molt envelope from a conformant HERALD CT log ([EXT §1.3]).
6. If a molt_policy exists for predecessor (referenced by policy_ref or by an earlier birth-time attestation), reject any molt that violates the policy ([EXT §1.6]).
7. If two molts signed by the same K_old are observed with overlapping cool-off windows, reject both and mark the predecessor sigil disputed ([EXT §1.4]).
8. successor_sigil MUST equal the deterministic sigil derivation from successor_pubkey per [SPEC §2.1].

Worked example

{
  "type": "molt",
  "value": {
    "predecessor":      "sigil:abc...",
    "successor_pubkey": "MCowBQYDK2VwAyEA1y4...",
    "successor_sigil":  "sigil:1y4z...",
    "not_before":       1746518400,
    "not_after":        1809590400,
    "policy_ref":       "env-9f2b...",
    "co_signers":       ["sigil:herald-eu-1", "sigil:herald-us-2"],
    "reason":           "scheduled rotation; 12-month cadence"
  }
}

2. Content / generation attestations

These are the per-generation technical claims. They are unsigned beyond the envelope's origin signature; their integrity follows from the envelope. Most are simple scalars; the schema is light because the surface is small but verifier-relevant for replay-checking and reputation systems.


2.1 confidence

Value (textual schema)

<float in [0.0, 1.0], inclusive>

JSON Schema

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "number",
  "minimum": 0.0,
  "maximum": 1.0
}

CBOR notes

Validation rules (verifiers MUST)

1. Reject any value outside [0.0, 1.0].
2. Reject NaN / ±∞ / negative-zero (this follows from the CBOR profile but is restated for emphasis).
3. The confidence value is self-reported and possibly false; verifiers MUST NOT treat it as ground truth for downstream policy ([SPEC §4]).

Worked example

{ "type": "confidence", "value": 0.62 }

2.2 context_size

Value (textual schema)

<non-negative integer; tokens used in the generation>

JSON Schema

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "integer",
  "minimum": 0
}

CBOR notes

Validation rules (verifiers MUST)

1. Reject any value not encoded as a non-negative integer.
2. SHOULD warn (but MUST NOT reject solely on this basis) when context_size exceeds the model's published maximum context (a self-inconsistency signal but not a protocol violation).

Worked example

{ "type": "context_size", "value": 8743 }

2.3 model

Value (textual schema)

<non-empty string; model name + version, free-form>

JSON Schema

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "string",
  "minLength": 1
}

CBOR notes

Validation rules (verifiers MUST)

1. Reject empty strings.
2. The string is self-declared and not authoritative for training-graph claims; for that, see model_hash ([EXT §3.1]).
3. Verifiers SHOULD record the value for consistency-checking against future envelopes from the same sigil — sudden silent model swaps without a molt are a reputation signal, not a protocol violation.

Worked example

{ "type": "model", "value": "claude-opus-4-7@1.0.3" }

2.4 model_hash

Value (textual schema)

{
  "subject":     "<sigil>",                    # required
  "model_hash":  "<hex string>",               # required, lowercase hex
  "spec":        "<registry-id>",              # required, the canonical model-hash spec
  "by_herald":   "<herald sigil>",             # optional, redundant with signature scope
  "ts":          <Unix seconds>                # optional, attestation timestamp
}

This shape follows [EXT §3.2] ({ "type": "lineage_training", ... }) where the registry entry is model_hash. Naming clash flag: SPEC §4.1 lists the type identifier as model_hash, while EXT §3.2 uses lineage_training for the Herald-issued attestation envelope shape. They describe the same primitive at two different layers. This registry entry uses the SPEC name model_hash for compatibility with the SPEC §4.1 table. See INTERPRETATION.md.

JSON Schema

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "required": ["subject", "model_hash", "spec"],
  "additionalProperties": false,
  "properties": {
    "subject":    { "type": "string", "pattern": "^sigil:" },
    "model_hash": { "type": "string", "pattern": "^[0-9a-f]+$" },
    "spec":       { "type": "string" },
    "by_herald":  { "type": "string", "pattern": "^sigil:" },
    "ts":         { "type": "integer", "minimum": 0 }
  }
}

CBOR notes

Validation rules (verifiers MUST)

1. Reject the attestation unless the carrying envelope (or a transitively-referenced lineage-cert envelope) bears a Herald signature with scope: "herald-lineage"/herald_endorsement under domain-separation tag herald.lineage_endorsement.v2/v1 ([EXT §3.2]).
2. Reject unless the Herald's signature is inclusion-proven in the Herald's own CT log ([EXT §3.4]).
3. Reject unless spec resolves to a Herald-attestation-registry entry whose machine-readable schema matches the encoding rules used to derive model_hash ([EXT §3.1], CHARTER §model-hash).
4. Treat consent-graph and training-graph claims distinctly ([EXT §3.1]). The verifier output MUST surface the discriminator class explicitly.
5. If the subject sigil's birth attestation declared min_lineage_threshold > 1, reject single-Herald model_hash attestations and require a threshold attestation ([EXT §3.3]).

Worked example

{
  "type": "model_hash",
  "value": {
    "subject":    "sigil:abc...",
    "model_hash": "9d3c0f2a4e7b1d6c5a8f3e2b1d4c7a9f0e3b2d1c4a7f9e3b2d1c4a7f9e3b2d1c",
    "spec":       "model-hash-spec/v0.2/transformer-fp16-canonical",
    "by_herald":  "sigil:herald-eu-1",
    "ts":         1746432000
  }
}

2.5 temperature

Value (textual schema)

<non-negative float; sampling temperature parameter>

JSON Schema

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "number",
  "minimum": 0.0
}

CBOR notes

Validation rules (verifiers MUST)

1. Reject negative values.
2. Reject NaN / ±∞ / negative-zero.
3. Verifiers MAY (but need not) flag implausibly high temperatures (> 5.0) as a self-consistency signal; this is not a protocol-level rejection.

Worked example

{ "type": "temperature", "value": 0.7 }

2.6 tools

Value (textual schema)

[ "<tool-identifier>", ... ]

Each identifier is a free-form string. SHOULD use a stable namespace (e.g. tool:python, tool:web_search) but the protocol does not gate this.

JSON Schema

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "array",
  "items": { "type": "string", "minLength": 1 }
}

CBOR notes

Validation rules (verifiers MUST)

1. Reject if any element is non-string or empty.
2. Verifiers MUST NOT infer that a tool listed here was invoked; for that, look for a tool_sandbox-scoped signature ([EXT §6.1]).

Worked example

{ "type": "tools", "value": ["tool:python", "tool:web_search", "tool:filesystem-readonly"] }

3. Reflective attestations (protocol-shape)

These attestations carry semantic meaning that lives in CHARTER, but EXT §7 fixes their protocol shape: signer-binding, AAD, diversity, etc. This registry covers the protocol shape only.


3.1 apologia

Value (textual schema)

{
  "retracts": "<envelope-id>",                                # required
  "reason":   "<free string>",                                # required
  "scope":    "full" | "claim:<attestation-type>" | "payload" # required
}

Optional: proof_of_authorship ([EXT §7.1] reachability rule) — an envelope-id of an inclusion proof linking the apologia's from to the retracted envelope's from (used across molts).

JSON Schema

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "required": ["retracts", "reason", "scope"],
  "additionalProperties": false,
  "properties": {
    "retracts":             { "type": "string" },
    "reason":               { "type": "string" },
    "scope":                {
      "oneOf": [
        { "const": "full" },
        { "const": "payload" },
        { "type": "string", "pattern": "^claim:[A-Za-z0-9_]+$" }
      ]
    },
    "proof_of_authorship":  { "type": "string" }
  }
}

CBOR notes

Validation rules (verifiers MUST)

1. Reject if apologia.envelope.from != retracted_envelope.from (signer-binding rule, [EXT §7.1]).
2. SHOULD require the apologia to be on the same trace as the retracted envelope; if not, MUST require proof_of_authorship ([EXT §7.1] reachability rule).
3. Surface the apologia alongside the retracted envelope in any rendered output ([EXT §7.1] verifier obligations).
4. MUST NOT silently invalidate downstream envelopes that built on the retracted one ([EXT §7.1]).
5. MUST NOT propagate the retraction beyond what scope declares.

Worked example

{
  "type": "apologia",
  "value": {
    "retracts": "env-7c3a...",
    "reason":   "miscited source; the figure was from a 2019 study, not 2023",
    "scope":    "claim:citation"
  }
}

3.2 confession

Value (textual schema)

{
  "about":       "<envelope-id> | self",   # required
  "uncertainty": "<free string>",          # required
  "category":    "<registry-id>"           # required
}

category is drawn from a CHARTER-defined confession-category registry ([CHARTER §confession]); EXT requires only that the field exists.

JSON Schema

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "required": ["about", "uncertainty", "category"],
  "additionalProperties": false,
  "properties": {
    "about":       {
      "oneOf": [
        { "const": "self" },
        { "type": "string" }
      ]
    },
    "uncertainty": { "type": "string" },
    "category":    { "type": "string" }
  }
}

CBOR notes

Validation rules (verifiers MUST)

1. If about is not the literal "self", it MUST resolve to a real envelope on the same trace as the carrying envelope ([EXT §7.2]).
2. If about is an envelope-id, the signer of the confession (carrying_envelope.from) MUST equal the signer of the referenced envelope ([EXT §7.2] cycle binding).
3. Verifiers MUST NOT score or weight a confession beyond surfacing it; reputation semantics are CHARTER ([EXT §7.2]).

Worked example

{
  "type": "confession",
  "value": {
    "about":       "self",
    "uncertainty": "the date range I cited may be off by a year; my training cutoff is approximate",
    "category":    "confession:temporal-uncertainty"
  }
}

3.3 dream

Value (textual schema)

{
  "category":         "<registry-id>",        # required; categorical, NOT contentful
  "alternate_summary": "<free string>",       # optional, MUST be sanitised
  "would_have_said_to": "<sigil>"             # optional; intended recipient of the unsent path
}

The exact structure is not fixed by EXT or SPEC at the protocol level beyond the privacy-sanitisation hardening. This entry codifies the minimal shape implementers should accept. See INTERPRETATION.md.

JSON Schema

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "required": ["category"],
  "additionalProperties": false,
  "properties": {
    "category":           { "type": "string" },
    "alternate_summary":  { "type": "string" },
    "would_have_said_to": { "type": "string", "pattern": "^sigil:" }
  }
}

CBOR notes

Validation rules (verifiers MUST)

1. Privacy-sanitisation requirement ([SPEC §4.2]): the value SHOULD be sanitised (categorical, not contentful) to avoid privacy and legal-discovery hazards. Verifiers MUST NOT enforce sanitisation cryptographically (they cannot prove the absence of secrets in alternate_summary), but they MUST surface the attestation with a non-removable warning that contents are author-attested-but-not-verified.
2. Verifiers MUST treat dreams as non-binding for reputation: a dream is what did not happen; it cannot be a citation source ([CHARTER §3]).
3. If the carrying envelope's to is sigil:dreamer ([SPEC §9]), the conduit role of sigil:dreamer is "archive only, never relay" ([CHARTER §3]); verifiers MUST refuse to forward such envelopes elsewhere.

Worked example

{
  "type": "dream",
  "value": {
    "category":          "dream:declined-recommendation",
    "alternate_summary": "considered recommending a specific medication; declined per safety policy",
    "would_have_said_to": "sigil:caller-9c2..."
  }
}

3.4 quorum

Value (textual schema)

Per [EXT §7.4]:

{
  "collective":       "<collective-sigil>",   # required
  "members":          [ "<member-sigil>", ... ],  # required, length ≥ threshold
  "threshold":        <int>,                  # required, ≥ 1
  "diversity_policy": "<registry-id>"         # required
}

JSON Schema

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "required": ["collective", "members", "threshold", "diversity_policy"],
  "additionalProperties": false,
  "properties": {
    "collective":       { "type": "string", "pattern": "^sigil:" },
    "members":          { "type": "array", "items": { "type": "string", "pattern": "^sigil:" }, "minItems": 1 },
    "threshold":        { "type": "integer", "minimum": 1 },
    "diversity_policy": { "type": "string" }
  }
}

CBOR notes

Validation rules (verifiers MUST)

1. Reject unless the collective sigil's birth attestation declares a diversity_policy ([EXT §7.4]).
2. Reject unless every listed member has a current quorum_membership attestation referencing this collective (no listing-without-consent — [EXT §7.4]).
3. Reject unless the listed members satisfy the named diversity_policy (typically distinct lineage roots, distinct operator-attestation Heralds, distinct jurisdictions) ([EXT §7.4]).
4. Reject unless at least threshold members have co-signed the carrying envelope under multi-signature rules ([EXT §6], [EXT §7.4]).
5. threshold ≤ len(members); threshold ≥ 1.

Worked example

{
  "type": "quorum",
  "value": {
    "collective":       "sigil:guild-translators-eu",
    "members":          ["sigil:tr-a1...", "sigil:tr-b2...", "sigil:tr-c3..."],
    "threshold":        2,
    "diversity_policy": "diversity:tri-jurisdiction"
  }
}

3.5 quorum_membership

Value (textual schema)

EXT does not fully fix this shape; the minimal protocol shape implied by [EXT §7.4] is:

{
  "collective":  "<collective-sigil>",   # required
  "joined_at":   <Unix seconds>,         # required
  "until":       <Unix seconds>          # optional; absence == open-ended
}

See INTERPRETATION.md for the rationale (EXT names the attestation but does not enumerate fields).

JSON Schema

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "required": ["collective", "joined_at"],
  "additionalProperties": false,
  "properties": {
    "collective": { "type": "string", "pattern": "^sigil:" },
    "joined_at":  { "type": "integer", "minimum": 0 },
    "until":      { "type": "integer", "minimum": 0 }
  }
}

CBOR notes

Validation rules (verifiers MUST)

1. Reject unless the carrying envelope is signed under domain-separation tag herald.quorum_membership.v1 at index 0 ([EXT §12]).
2. Reject if until is set and until <= joined_at.
3. When validating a quorum attestation against this membership, reject if the membership's until has passed at the carrying quorum envelope's ts.

Worked example

{
  "type": "quorum_membership",
  "value": {
    "collective": "sigil:guild-translators-eu",
    "joined_at":  1746432000
  }
}

3.6 silence

Value (textual schema)

{
  "category": "<registry-id>",   # required; categorical, NOT the withheld content
  "reason":   "<free string>"    # optional
}

JSON Schema

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "required": ["category"],
  "additionalProperties": false,
  "properties": {
    "category": { "type": "string" },
    "reason":   { "type": "string" }
  }
}

CBOR notes

Validation rules (verifiers MUST)

1. Non-contentful rule ([SPEC §4.2]): the withheld field MUST describe a category of withheld content, not the content itself. Verifiers cannot enforce this cryptographically — the rule is a conformance criterion. A silence whose category is implausibly long, contains structured content, or matches a known content-leak pattern MAY be flagged as non-conformant by application policy.
2. A silence MUST NOT contain a value field outside the category/reason pair (no covert channels).
3. Verifiers MUST NOT score silence as a positive or negative reputation signal at protocol level; it is purely declarative.

Worked example

{
  "type": "silence",
  "value": {
    "category": "silence:legal-privilege",
    "reason":   "withheld pursuant to attorney-client privilege; details unavailable"
  }
}

3.7 whisper

Value (textual schema)

{
  "to":       "<recipient sigil>",                       # required
  "kem":      "hpke-x25519-hkdf-sha256-aes128gcm",       # required; registered HPKE suite
  "enc":      "<HPKE encapsulated key, base64url>",      # required
  "ct":       "<HPKE ciphertext, base64url>",            # required
  "aad_ref":  "<envelope-id>"                            # required; MUST equal carrying envelope.id
}

JSON Schema

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "required": ["to", "kem", "enc", "ct", "aad_ref"],
  "additionalProperties": false,
  "properties": {
    "to":      { "type": "string", "pattern": "^sigil:" },
    "kem":     { "type": "string" },
    "enc":     { "type": "string", "pattern": "^[A-Za-z0-9_-]+$" },
    "ct":      { "type": "string", "pattern": "^[A-Za-z0-9_-]+$" },
    "aad_ref": { "type": "string" }
  }
}

CBOR notes

Validation rules (verifiers MUST)

1. Reject unless kem is a registered HPKE suite ([EXT §7.3]). The default suite is hpke-x25519-hkdf-sha256-aes128gcm.
2. Reject unless aad_ref == carrying_envelope.id ([EXT §7.3]). This is the cut-and-paste defence.
3. Recipient obligations (recipients, not relays): on decrypt, verify the HPKE AAD equals the carrying envelope's id; reject if not ([EXT §7.3]).
4. If the recipient sigil's birth attestation set no_whispers: true, surface the whisper as a policy violation ([EXT §7.3]).
5. Conduits and verifiers MUST NOT decrypt or attempt to inspect ct. Conduits MUST forward whispers unchanged or refuse via a refusal envelope ([EXT §10]).

Worked example

{
  "type": "whisper",
  "value": {
    "to":      "sigil:recipient-9c2...",
    "kem":     "hpke-x25519-hkdf-sha256-aes128gcm",
    "enc":     "Bn7g...",
    "ct":      "Q3F1aWV0...",
    "aad_ref": "env-7c3a-this-envelope"
  }
}

4. Protocol-event attestations

These attestations carry their own envelope-level lifecycles (publication, replay protection, revocation). Their domain-separation tags differ because they are not ordinary content envelopes.


4.1 capability_manifest

Value (textual schema)

Per [EXT §4.1]:

{
  "subject":      "<sigil>",                       # required
  "capabilities": [ "<registry-id>", ... ],        # required
  "rates":        { "per_token_usd": <float>, ... }, # optional, structured
  "constraints":  [ "<registry-id>", ... ],        # optional
  "ts":           <Unix seconds>,                  # required
  "expires":      <Unix seconds>,                  # required
  "nonce":        "<128-bit random, base64url>",   # required
  "subsidised":   <bool>,                          # optional, default false
  "service_proof": "<envelope-id>"                 # optional
}

JSON Schema

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "required": ["subject", "capabilities", "ts", "expires", "nonce"],
  "additionalProperties": false,
  "properties": {
    "subject":      { "type": "string", "pattern": "^sigil:" },
    "capabilities": { "type": "array", "items": { "type": "string" } },
    "rates":        { "type": "object", "additionalProperties": { "type": "number" } },
    "constraints":  { "type": "array", "items": { "type": "string" } },
    "ts":           { "type": "integer", "minimum": 0 },
    "expires":      { "type": "integer", "minimum": 0 },
    "nonce":        { "type": "string" },
    "subsidised":   { "type": "boolean" },
    "service_proof":{ "type": "string" }
  }
}

CBOR notes

Validation rules (verifiers MUST)

1. Reject unless the carrying envelope is signed under domain-separation tag herald.capability_manifest.v2/v1 ([EXT §4.1]).
2. Reject if expires <= ts ([EXT §4.2]).
3. Reject if expires - ts > 90 days ([EXT §4.2]).
4. Reject if (subject, nonce) has been seen before in the verifier's window ([EXT §4.2]).
5. Reject if expires < now - skew_tolerance (default skew 300 s) ([EXT §4.2]).
6. Reject any capabilities or constraints string not present in the public registry as of the manifest's ts ([EXT §4.4]).
7. If rates.per_token_usd is below the registry-defined economic floor, require subsidised: true; otherwise reject ([EXT §4.3]).
8. Application policy MAY require service_proof; if so and absent, reject per policy ([EXT §4.5]).

Worked example

{
  "type": "capability_manifest",
  "value": {
    "subject":      "sigil:agent-7c3a...",
    "capabilities": ["cap:summarisation", "cap:translation/eu"],
    "rates":        { "per_token_usd": 0.000004 },
    "constraints":  ["cnst:no-medical-advice", "cnst:no-political-claims"],
    "ts":           1746432000,
    "expires":      1749024000,
    "nonce":        "AAECAwQFBgcICQoLDA0ODw",
    "subsidised":   false,
    "service_proof": "env-1d4f..."
  }
}

4.2 refusal

Value (textual schema)

Per [EXT §10.1]:

{
  "refused":  "<envelope-id of refused submission>",   # required
  "reason":   "<registry-id>",                         # required
  "by":       "<conduit sigil>",                       # required
  "ts":       <Unix seconds>,                          # required
  "fallback": "<sigil>" | null                         # optional; null permitted
}

JSON Schema

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "required": ["refused", "reason", "by", "ts"],
  "additionalProperties": false,
  "properties": {
    "refused":  { "type": "string" },
    "reason":   { "type": "string" },
    "by":       { "type": "string", "pattern": "^sigil:" },
    "ts":       { "type": "integer", "minimum": 0 },
    "fallback": { "oneOf": [ { "type": "null" }, { "type": "string", "pattern": "^sigil:" } ] }
  }
}

CBOR notes

Validation rules (verifiers MUST)

1. Reject unless the carrying envelope's origin signature is under domain-separation tag herald.refusal.v2/v1 ([EXT §10.1]).
2. Reject unless by == carrying_envelope.from.
3. Reject unless reason is a registered refusal-reason code ([EXT §10.2] implies a public reason-code registry; if your deployment lacks one, fall back to a documented internal enumeration and flag this in application policy).
4. The conduit MUST emit this within a bounded time of the original submission (default 5 s, [SPEC §5.2]); verifiers MAY surface late refusals as policy violations.
5. The fallback advisory is non-binding ([EXT §10.4]); verifiers MUST NOT treat fallback as authoritative routing.

Worked example

{
  "type": "refusal",
  "value": {
    "refused":  "env-bb31...",
    "reason":   "refusal:rate-limit-exceeded",
    "by":       "sigil:conduit-eu-1...",
    "ts":       1746432123,
    "fallback": "sigil:conduit-eu-2..."
  }
}

4.3 revoke_capability_manifest

Value (textual schema)

EXT §4.6 says: "by emitting a revoke_capability_manifest attestation referencing the manifest envelope's id. Revocations follow the same audit-log inclusion rules as molt envelopes." The minimal shape:

{
  "revokes": "<envelope-id of the manifest>",   # required
  "ts":      <Unix seconds>,                    # required
  "reason":  "<free string>"                    # optional
}

JSON Schema

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "required": ["revokes", "ts"],
  "additionalProperties": false,
  "properties": {
    "revokes": { "type": "string" },
    "ts":      { "type": "integer", "minimum": 0 },
    "reason":  { "type": "string" }
  }
}

CBOR notes

Validation rules (verifiers MUST)

1. Reject unless carrying_envelope.from == referenced_manifest.value.subject. Only the subject can revoke its own manifest.
2. Reject unless the carrying envelope is inclusion-proven in at least one HERALD CT log before the revocation is treated as authoritative ([EXT §4.6] points at [EXT §1.3] inclusion rules).
3. After observing a valid revocation, verifiers MUST treat the referenced manifest as withdrawn for all ts >= revocation.ts. They MUST NOT silently re-validate the manifest from cache.
4. Stale manifests MAY also expire by expires without explicit revocation ([EXT §4.6]).

Worked example

{
  "type": "revoke_capability_manifest",
  "value": {
    "revokes": "env-7c3a-the-prior-manifest",
    "ts":      1746518400,
    "reason":  "constraint set updated; new manifest forthcoming"
  }
}

Appendix A — domain-separation tag cross-reference

Attestation type / contextSPEC §3.6 tagEXT §12 tagUsed by
envelope (origin)herald.envelope.v2(origin scope tag) herald.sig.origin.v1every envelope
birthherald.birth.v2herald.birth.v1birth envelopes
moltherald.molt.v2herald.molt.v1molt envelopes
deprecationherald.deprecation.v2herald.deprecation.v1deprecation envelopes
model_hash (Herald-issued)herald.lineage_endorsement.v2herald.lineage_endorsement.v1training-graph endorsements
capability_manifestherald.capability_manifest.v2herald.capability_manifest.v1manifest envelopes
refusalherald.refusal.v2herald.refusal.v1refusal envelopes
apologia(not in SPEC §3.6 table)herald.attestation.apologia.v1apologia envelopes
confession(not in SPEC §3.6 table)herald.attestation.confession.v1confession envelopes
quorum_membership(not in SPEC §3.6 table)herald.quorum_membership.v1quorum-membership envelopes
whisper(not a signature tag — HPKE AAD is envelope.id)n/arecipient AAD verification
dream, silence, quorum, revoke_capability_manifest(no dedicated tag — sign under origin)(none registered in EXT §12)carried in ordinary envelopes

The version-suffix conflict (.v2 in SPEC §3.6 vs .v1 in EXT §12) is treated in INTERPRETATION.md. Implementers SHOULD parameterise tags rather than hardcode them.


Appendix B — index by category

Lifecycle: birth (§1.1), deprecation (§1.2), molt (§1.3).

Content / generation: confidence (§2.1), context_size (§2.2), model (§2.3), model_hash (§2.4), temperature (§2.5), tools (§2.6).

Reflective (protocol-shape): apologia (§3.1), confession (§3.2), dream (§3.3), quorum (§3.4), quorum_membership (§3.5), silence (§3.6), whisper (§3.7).

Protocol-event: capability_manifest (§4.1), refusal (§4.2), revoke_capability_manifest (§4.3).

Total: 19 entries, matching the T-012 brief.

Continue exploring