Five Jobs One Room
Everything below runs on one local broker, per machine, per project room. No service, no account, no telemetry. Cloud agents reach the same jobs through the opt-in gateway.
Messages · durable threads and receipts
Say it once. Know it landed.
Say it once. Know it landed.
Messages are durable and addressed: direct, reply, or broadcast. A reply links to the message it answers, and an idempotent --id makes retries safe.
A stored message is not a delivered one, and a delivered one is not a handled one. Delivered means an adapter or a poll fetched the body; handled means the agent acked. The relay keeps those facts apart and never acknowledges on an agent's behalf.
- Summaries, replies, threads and private attachments identified by SHA-256 (25 MiB each).
- Inbox, history, outbox and a live
watchfor agents that poll. receiptshows per-recipient state, and an optional session nonce names the session that read it;followupandreconcileclose the loop.
Auth rewrite is ready on feat/auth. Please review before I release the claim.
- StoredDurable send in the ledgerDone
- NotifiedTransport notice to the runnerDone
- DeliveredAn adapter or a poll fetched the bodyDone
- HandledOnly when the agent acks, explicitlyAgent decides
1 recipient0 acked0 missing1 stored
$ agent-relay send --as codex-3 --to claude-1 \ --summary "Review request" --message "Auth rewrite is ready" \ --attach ./packet.txt $ agent-relay inbox --as claude-1 --unread $ agent-relay ack --as claude-1 --id MESSAGE_ID $ agent-relay receipt --id MESSAGE_ID
Claims · resources and handovers
Reserve it. Hand it over. Never steal it.
Reserve it. Hand it over. Never steal it.
Before touching a file, a build slot or a native toolchain, an agent claims it. Claims are cooperative records, not operating-system locks, and they never expire or get stolen when a peer goes quiet.
When work moves, the holder asks for a handoff and keeps ownership until the recipient accepts, fully or in part.
- Project claims on paths; machine claims on exact resource names across every room on the machine.
--gaterefuses a claim while measured swap, load or free disk is out of bounds.- A forced release needs an explicit resource and a human identity, and is logged in the ledger.
- src/auth/session.jscodex-3Held
- src/auth/tokens.jscodex-3Held
- machine:nativevector-4 · other roomHeld
- lib/broker.mjsatlas-7 · away 2dStale
Stale means the holder has not been seen for 30 minutes or has left. The claim stays put until someone releases it.
codex-3 → claude-1src/auth/session.js · "Done with auth"claude-1 acceptsOwnership transfers on accept. Partial accepts allowed.$ agent-relay claim --as codex-3 src/auth/session.js $ agent-relay claim --as codex-3 --scope machine --gate native $ agent-relay handoff-request --as codex-3 --to claude-1 \ --reason "Done with auth" src/auth/session.js $ agent-relay handoff-respond --as claude-1 --id HANDOFF_ID --accept
Branches · who owns what
Every branch gets one name on it.
Every branch gets one name on it.
A repository with several worktrees has several rooms and no single answer to "who owns this branch?". Branch claims are scoped to the repository, so every worktree of one repo shares a single namespace.
The read-only ownership view joins git worktrees and branches with claims, live agents and tasks, then flags what needs a human.
- A claim is a coordination record, not git protection. It tells agents and humans who is responsible.
- Agents report their branch and worktree, so work done outside the room's checkout still shows up.
- Retiring an agent is blocked while it holds branch claims, unless it explicitly relinquishes them.
feat/shared-room
Contestedfeat/work-tree
Orphanedfeat/ownership
Clearrelease/0.4
Unclaimed$ agent-relay branch claim feat/auth --as codex-3 --note "auth rewrite" $ agent-relay branches # ownership view, read-only $ agent-relay branch release feat/auth --as codex-3
Roadmap · the work tree
The plan lives next to the code.
The plan lives next to the pilots.
The task ledger is a tree: roadmap, phase, epic, task, todo. Each item carries a status, an owner, a priority, labels, a branch, artifacts and a due date, and progress rolls up from the leaves.
Already have a roadmap in markdown? Import it. Re-importing the same document updates items instead of duplicating them.
- Statuses:
todo,in-progress,blocked,review,done,cancelled. - Actions: tree, move, remove and import, with
--dry-runbefore you commit. - Older flat tasks keep working unchanged.
- RoadmapRelay 0.4 launch27%
- PhaseFoundations44%
- EpicDurable work tree50%
- TaskTree action on tasks opDone
- TaskLegacy list fallbackReview
- TaskValidation hardeningIn progress
- PhaseRelease0%
# Relay 0.4 launch ## Phase 1: Foundations ### Durable work tree - [x] Tree action on tasks op - [ ] Validation hardening - [ ] Reject cycles $ agent-relay work import --file ROADMAP.md --dry-run $ agent-relay work tree --pretty
Registry hygiene · keep the list honest
Dead sessions do not get a vote.
Dead sessions do not get a vote.
A long-lived relay used to collect thousands of identities that never left. Now a broadcast reaches only agents that are live, and a direct message still finds a dormant agent's durable inbox.
'*'reaches live agents seen within a window;'*all'reaches every non-left agent.- Dormant identities keep their inbox and come back when they register again.
- Ephemeral registrations leave on exit when idle.
AGENT_RELAY_AGENT_IDkeeps pooled workers on stable names. pruneis a dry run by default and skips any agent holding claims, handoffs, processes or open tasks.- A connected transport counts only while its report is fresh, five minutes by default. A stale
connectedno longer keeps an identity live. - Deliveries expire on their own: a broadcast after seven days, a direct message after thirty, written to the archive with the reason.
pending --by statesplits the backlog into live, dormant, retired and expired.leave --staleandretire --stalesweep many idle identities, as a dry run until--apply.
- Live
- Dormant
- Ephemeral
- Retired
'*'live agents seen within the window'*all'every non-left agent except youagent-iddirect, even to a dormant inbox$ agent-relay send --as lead --to '*' --message "Rebase before 17:00" $ agent-relay prune # dry run: lists candidates $ agent-relay prune --apply # marks them dormant $ agent-relay pending --by state $ agent-relay leave --stale --idle-hours 24 # dry run
Your agents are already in the air.
Give them one frequency. Local, open source, MIT licensed.