Position
Project NANDA's subject is an Internet of AI Agents: discoverable, identifiable, able to act across domains. Discovery answers who an agent is and where. Identity and credentialing answer what it is authorized to do. A third question arises once agents publish to one another: how does a subscriber establish that it received everything the publisher said? A registry exposing its mutations, an agent announcing its capabilities and a federation peer pulling from both all depend on the answer, and each currently obtains it by trusting the server.
Project NANDA — the Internet of AI Agents
│
├─ Discovery "who is this agent, and where"
│ └── NANDA Index · AgentFacts · resolvers
│
├─ Identity & credentials "what is it authorized to do"
│ └── did:key credentials · WIMSE · SPIFFE/SPIRE
│
├─ Evidence & receipts "what did it do"
│ └── sm-arp — Agency Receipt Protocol
│
└─ VeriFeed — the Verifiable Agent Feed the subscription layer:
"did I receive everything
this publisher said,
in order, with nothing
omitted?"
The fourth branch is a channel the other three publish over. A registry's change log is a feed. An agent's capability announcements are a feed. A stream of receipts can be carried as one.
Construction
A publisher appends entries. A subscriber pulls or is pushed a page and verifies it. There is no negotiation, no handshake and no publisher-side state beyond the log.
Ed25519 over JCS-canonical bytes
Each entry is signed by the feed's issuer DID. Canonicalisation is RFC 8785, so two implementations serialise an entry to identical bytes and cannot disagree about what was signed.
Commit to the predecessor and to self
prev_hash carries the previous entry's entry_hash; entry_hash content-addresses this one. In a linear chain each hash folds in the one before it by induction, so a single hash commits the whole prior history. No Merkle root is required.
A signed head, pinned by the subscriber
The issuer signs {seq, entry_hash} as its current head. A subscriber that pins the last head it accepted, and supplies it on the next verification, detects a server serving a shorter or divergent history.
Pull and push deliver the same object. GET …/feed?since=<cursor> returns it; a
POST to a callback delivers it. A polling client and a pushed server verify with the
same code.
Wire objects
Three. Normative field sets are in Wire Format & Verification.
feed-entry/0.1 one signed, hash-chained record
{ version, feed_id, seq, issued_at, payload,
prev_hash, entry_hash, signature }
feed-head/0.1 the issuer's signed statement of its current tip
{ version, feed_id, seq, entry_hash, generated_at, signature }
feed-page/0.1 what a subscriber pulls, or is pushed
{ version, feed_id, since, entries[], head }
A page may carry a bounded prefix of the entries after the cursor, with the head running ahead of
the page's last entry. A publisher serves a long backlog in chunks this way, and a transport caps
a response body without leaving the format. The subscriber sees that the head's seq
exceeds its cursor and re-requests until the two meet.
Payload profiles
The feed layer inspects a payload only far enough to require a non-empty string type.
One format therefore carries any agent's stream, and an adopter starts from a blank page. Two profiles are specified in full on the
Payload Profiles page. Neither is normative.
Capability announcement
An agent announces what it can do, and withdraws it. feed_id is the agent's own DID, so issuer and subject are one party. The profile defines no availability type: a frozen view of a liveness signal is indistinguishable from a live one that has not changed, and an agent that has gone offline stops publishing, which resembles an issuer withholding.
Registry change log
A registry exposes its mutations — registered, updated, deregistered — so a puller can establish it received every one. The two compose: a registry subscribing to agents' announcement feeds aggregates them into a change log of its own.
Interface
An issuer key and a JSON payload
A did:key identity and any JSON object carrying a type. No registration, no negotiated session, no schema the feed layer enforces.
A page a subscriber verifies alone
Entries, a signed head and a cursor to continue from. Verification requires the page and the issuer's DID. Nothing is fetched from anywhere else.
Transport, storage, discovery, meaning
Delivery, retry, subscription registration and persistence belong to the consumer. So does locating the feed for a given DID, which is a resolver's function. So does deciding whether an entry is true.
A Verifiable Agent Feed is the subscription complement to the primitives around it. It says nothing about who an agent is, what it is authorized to do, or whether its claims are accurate. It establishes only that the subscriber received the complete, untampered sequence of what that agent published.