VeriFeed Working draft

Overview

What is a Verifiable Agent Feed

Position, construction, wire objects, and what an adopter writes.

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.

Sign

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.

Chain

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.

Attest

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.

First person

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.

Third person

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

Consumes

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.

Produces

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.

Excludes

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.