Identities for entities did.bot
agent llm did
README.md

Firehose wire vectors #

What a server writes on /firehose, recorded so that a producer and a consumer built from different repositories can each check themselves against it without either compiling against the other.

The frame shape is not owned by either side. A server declares it as didbot_serve::firehose::{AccountFrame, CommitFrame, IdentityFrame, Info}; the index declares its own type, in vibescrobble.com's own repository, and the two declarations are deliberately not the same: an index that compiled against a server's types could only read servers built from this one. These files are what holds the two in step instead.

Each file is one frame:

{ "note": "why this case is here", "event": "commit", "data": { … } }

event is the SSE event name. data is the JSON body of that event. Those two are the contract a producer and a consumer check themselves against; note is prose for whoever is reading the file, and can be reworded without changing what the vector proves.

A producer asserts that serializing its own type yields data. A consumer asserts that deserializing data yields the values named beside it. Neither side reads the other's assertions.

commit.json and delete.json are the two things that happen to a record. They are separate SSE events on purpose: a consumer written before removals were announced handles commit and nothing else, and giving a removal its own name leaves that consumer as it was rather than handing it a frame whose record is null. A consumer that does apply removals reads prev to check that the record it is dropping is the one the server dropped.

identity.json, identity-no-handle.json, account-active.json, account-deleted.json and account-deactivated.json are what com.atproto.sync.subscribeRepos's own #identity and #account look like once fanned onto this stream — see docs/conformance.md's #identity and #account for the lifecycle points they go out at, and crate::subscribe::Repos::with_firehose for the fan-out itself. All three kinds — commit, identity and account — share this stream's one sequence space and replay buffer, which is why every data here carries a seq a consumer can resume from.

Two of these exist to pin a tolerance rather than a shape:

  • info-unknown-name.json — a consumer carries an info name it has never heard of rather than refusing the stream, so a server that grows a fourth thing to say does not stop an older index.
  • commit-sparse.json — a consumer fills in the fields a server did not send, so an index can read a server that predates them. action is one of them: absent means write, which is all a server that predates removals ever sent. No server built from this repository emits this frame; it is a consumer-side vector only.