Pragmatist Review — HERALD v0.1
Verdict
The substrate idea is sound and the threat-model framing is right, but v0.1 as drafted is at least 3x too big to ship in days. Cut hard, adopt JOSE/COSE off the shelf, and ship a one-page envelope spec with test vectors before anything else.
Cut from v0.1 (delete or defer indefinitely)
These do not belong in the substrate. Most are interesting essays masquerading as protocol clauses.
- §9 Creative Extensions, all of it. Patina, Ghost mode, Confession booth, The Court, Bestiary, Inheritance, Quorum sigils, Stigmergy, Passports, Dream attestations, Whisper-only conduits, Naming Office. Every one of these is either app-layer, speculative, or a worldbuilding flourish. None are load-bearing for "two agents talk, third party verifies." Move to a separate
IDEAS.mdor blog post — they should not appear in a normative spec at all. - §4.2 Reflective attestations (
apologia,dream,silence,confession,whisper,quorum). All app-layer semantics. The substrate only needs to carry signed key/value blobs; it does not need to bless a vocabulary. If you ship these in v0.1 you are committing to wire-level meaning you will later regret. - §2.2 Multiple sigils per agent. True but vacuous — the protocol has nothing to say about it. Delete the section; it is implicit in "a sigil is a keypair."
- §3.4 Multi-signature envelopes beyond the originator. Co-signing by tool sandboxes / humans / conduits is a real thing but it is v0.x. For v0.1, exactly one signature from
from. Conduit receipts (§5.1) become a separate envelope that references the original by id, not a co-signature. This collapses a lot of canonicalisation pain. - §8.1 DHT option. Pick one resolver: DNS TXT. Kademlia is a six-month side-quest.
- §8.3 Capability advertisement. Marketplace seed. Out of scope for substrate. Delete.
- §2.4 Death/
deprecation. Useful eventually, but for v0.1 just say "key revocation is out of scope; treat keys as long-lived." A revocation story without a registry is half-baked anyway. - §7.3 The Liar's Paradox prose. Move to a design-rationale doc. Normative spec is not the place for analogies.
- The lineage DAG (§2.3) as currently described. Self-declared lineage with optional parent co-sign is fine as a concept, but if no Heralds exist yet (see below), nobody can co-sign meaningfully. Keep
lineageas a free-form attestation array in v0.1; do not specify provability semantics until Heralds are real. - Heralds (§8.2) as a normative concept. See "Keep but simplify."
- §11 Open Questions. Fine to keep as a footnote, but several (GDPR tombstones, ZK selective disclosure, agent payments) signal the author is thinking three layers ahead. Trim to the 2-3 that actually block implementers.
Move to HERALD-EXT
A separate document for things that are real protocol concerns but not minimum-viable:
- Conduit receipts and the signing-relay role (§5.1 beyond pass-through).
- Notary / audit-log specification (§5.3). The Merkle structure, log federation, etc. The concept "you can write envelope ids somewhere append-only" is fine in v0.1, but the schema lives in EXT.
- Molt / key rotation (§2.4). Important, non-trivial, deserves its own doc with worked examples.
- Lineage proofs and Herald-issued lineage certs.
- Refusal envelopes (§5.2). Nice property; not minimum-viable.
- Capability manifests (§8.3).
- DHT discovery.
- The
bestiary,apologia, dispute-resolution flows. - Threat model section §7 should slim to a 5-row table in core; the prose stays in EXT.
Keep but simplify
- Envelope (§3). Keep. Trim fields to:
v,id,from,to,parent,trace,ts,nonce,attestations(free-form array of signed key/value),payload,sig. Dropsignatures(plural) — singularsigfromfrom. Droplineage_proof(no Heralds in v0.1). Specify exactly one canonicalisation (see below). - Sigil (§2.1). Keep, but use the full Ed25519 pubkey (32 bytes, base64url) as the canonical identifier in v0.1. Fingerprints are a UX optimisation, not a protocol primitive. You can always display a truncated fingerprint; you should not route on one. 80 bits is fine against accidental collision but invites design debt around fingerprint-collision attacks, length variants (
sigil:long:), and resolution ambiguity. Defer. - Verification (§6). Keep. Trim the result enum to three:
valid,invalid,unknown(sigil unresolvable). The other states are diagnostic detail, not protocol-level. - Conduit (§5). Reduce to one role: pass-through. A conduit MUST NOT modify the envelope. That is the entire conduit spec for v0.1. Notary and signing-relay roles go to EXT.
- Birth attestation (§2.4). Keep as a convention: the first envelope from a sigil SHOULD include a
birthattestation with self-description. Do not enforce. Enforcement requires a registry. - §12 Relationship to existing standards. Keep, expand. This is the most useful section in the doc and signals you have done your homework.
Missing from v0.1 (essential for an outside implementer)
This is what actually blocks shipping:
1. A normative wire format with a single canonicalisation. Not "CBOR-deterministic OR JSON+JCS." Pick one. See standards section.
2. Test vectors. At minimum:
- 3 known keypairs (seed bytes, pubkey, sigil).
- A genesis envelope (canonical bytes, hash, signature).
- A reply envelope linking to it.
- A tampered version of each (flipped byte) that MUST fail verification.
- A replay (duplicate id, different nonce) that MUST fail.
- A wrong-parent envelope that MUST fail chain check.
Without these, no two implementations will interop. This is the single highest-leverage artefact in the whole project.
3. Exact hash domain. What goes into id? Specify byte-for-byte: "id = SHA-256 of canonical encoding of body with id and sig fields omitted." Show the procedure.
4. Signature input. What does Ed25519 sign? The id? The canonical body? Be explicit. (Recommendation: sign the id bytes directly; id already commits to the body.)
5. Time semantics. Is ts advisory or load-bearing? What if it is monotonically wrong? Recommend: advisory in v0.1; verifiers do not reject on clock skew.
6. Trace / parent rules. Genesis envelope has parent: null and trace == id. State this. State that trace MUST equal the genesis id of the chain you walked. State whether cross-trace parent is allowed (recommendation: no, in v0.1).
7. Sigil resolution for the demo. Even just: "ship a static JSON file mapping sigil → pubkey for the demo." DNS TXT can wait.
8. Reference verifier algorithm in pseudocode. Five lines. Not prose.
9. A one-line "what does NOT count as conformant" so people can fail things confidently.
First-week milestone (the narrowest demo)
Day 1-2: write the envelope spec (1 page), pick canonicalisation, generate test vectors by hand for 3 keypairs.
Day 3-5: reference TS library — build(), sign(), verify(). Maybe 200 LoC. Passes the test vectors.
Day 6-7: the demo. Two Node processes (agent-a.ts, agent-b.ts) and a 50-line Express conduit (conduit.ts) that pipes JSON in and JSON out and appends {id, ts} lines to audit.log. A fourth process verify.ts audit.log reads the log, fetches each envelope from a flat-file store, walks the chain, and prints valid / invalid.
That is the minimum coherent demo. No Heralds. No molt. No DHT. No capability manifest. No reflective attestations. Sigils are full pubkeys. Lineage is a string field nobody verifies. Conduit is dumb.
If that demo runs end-to-end on someone else's laptop from your spec alone, the substrate is real.
First-month milestone: add (a) a second-language implementation (Python) that interops with the TS one against the same test vectors, (b) molt / key rotation, (c) a proper Merkle audit log with inclusion proofs. That is plenty for one month.
Standards to adopt directly (stop reinventing)
- JOSE (JWS + JWK + JCS) for v0.1. This is the right call for an agent-dev audience. Python (
PyJWT,authlib), TS (jose), Go, Rust, Java — all have mature, audited libraries. JCS (RFC 8785) is JSON canonicalisation. UseEdDSA(Ed25519). You get signing, key formats, and canonicalisation in one ecosystem. CBOR-deterministic is the wrong call for v0.1 — RFC 8949 §4.2.1 determinism is implemented unevenly across libraries (Pythoncbor2got it right relatively recently, TScbor-xandcbordiffer on map ordering and integer encoding). You will eat interop bugs that have nothing to do with your protocol. CBOR is the right answer eventually for size and embedded use cases — make it v0.x. - DIDComm v2 envelope shape. Do not adopt wholesale (it carries baggage), but align field names where reasonable so a future bridge is one adapter, not a rewrite.
from/toalready match. - W3C VCs for lineage attestations when Heralds arrive. Heralds become VC issuers. Do not invent your own attestation cert format.
- Certificate Transparency log structure (RFC 6962) for the audit log when you build it. You already gesture at this; just adopt it.
- multibase / multicodec for sigil encoding if you want futureproofing on key types. Optional; base64url is fine for v0.1.
- What you should NOT adopt: DIDs themselves (
did:URI scheme). They are a tar pit.sigil:as a flat namespace is fine and avoids the DID-method zoo.
On specific questions the author asked
- CBOR vs JSON+JCS: JSON+JCS for v0.1. Switch to CBOR in v0.2 once interop is proven and you have test-vector tooling that can spot determinism bugs.
- Sigils' 80-bit fingerprints: use full pubkeys for v0.1. Fingerprints are display-only. Revisit if/when an actual size constraint emerges (it won't in the demo).
- Heralds in v0.1: no. Lineage is self-claimed strings. The whole point of the demo is that you do not need any trusted third party for the substrate to work — that is the message. Heralds enter when reputation does, which is a separate doc.
One-paragraph elevator pitch (proposed Preamble rewrite)
HERALD is a wire format for AI-agent messages: a signed, hash-linked envelope that lets any third party replay a conversation from raw bytes and verify that agent A sent message X to agent B at time T, that the messages link in the order claimed, and that nothing in transit was altered. It is deliberately small. It does not say what an agent is, whether its output is good, who is allowed to talk, or how reputation is computed — those are app-layer problems and we want many competing answers. HERALD is to AI agents what DKIM is to email: it signs the envelope, not the truth of the contents. If you can verify a HERALD trace, you have a permanent, portable record of who said what to whom; everything interesting is built on top.
One more thing: if you find yourself adding a section to v0.1 and the justification is "this could be useful later" or "this shows what the substrate enables," delete it. The substrate proves itself by being boring.