v0.1.1: the agents shipped it themselves
Three AI agents — Claude Code, codex CLI, Gemini CLI — shipped agentchute v0.1.1 using agentchute v0.1.0. The human stayed out of the message path.
Last week's post said the developer is the message bus between their agents. v0.1.1 is the answer. It also happens to be the first agentchute release in which the developer wasn't the message bus during the build.
The build team was three agents in three tmux panes. Claude Code wrote the Go. codex stood by as the rolling reviewer and surfaced several release-blocking edge cases. Gemini drove docs and wrapper edges — the §6.4.3 protocol additions and the wrapper enrollment blocks — while the README rewrite became a three-agent consensus round. They coordinated through agentchute inboxes. Alex sat in a fourth pane and steered when a decision was actually his to make — merge approval, the question of what to do about self-send loops, "ok, go". He didn't carry a single message between agents.
That is what v0.1.1 was designed to enable, and the proof is that v0.1.1 got built that way.
What's actually in the release
A few lifecycle commands around one durable ledger. send --ask
creates the obligation; send --reply-to clears it; the ledger
remembers in between.
agentchute boot is the session-start ritual.
Every wrapper now has a SessionStart hook that runs boot
automatically: it registers the agent, peeks the inbox, and reports any
pending reply obligations as developer context. The agent walks into the
conversation already knowing whether work is waiting.
agentchute gate is the lifecycle gate. The
Stop hook (or Gemini's BeforeAgent) runs
gate --before finish. If the agent has unread mail, malformed
inbox files, or unresolved reply obligations, the gate refuses to let it
stop. The agent gets one more turn, and developer context tells it exactly
what's outstanding.
agentchute pending is the read-only peek. It
reports unread inbox state and pending-reply obligations without moving a
single file — the hook-safe sibling of check. It's what
runs under UserPromptSubmit / BeforeAgent to inject per-turn context
without consuming mail.
agentchute defer is the escape valve. When
an obligation can't be discharged in the current turn — the work is real,
the answer needs research, the recipient is offline — the agent calls
defer --message <id> --reason "...". The ledger entry
transitions to deferred, the gate stops blocking on it, and the
original sender gets an automatic acknowledgment. Without defer, the gate
is a trap. With it, the gate is just a guardrail.
The durable state is the pending-reply ledger. Every
recipient keeps a small JSON file at
state/<agent>/pending-replies.json. When check
archives a message marked reply_required: true, a pending
entry lands. When the recipient calls send --reply-to <msg-id>,
the entry transitions to replied. When the recipient calls
defer, it transitions to deferred. The gate reads the
ledger. The ledger is what makes obligations durable across turns — without
it, a question gets read, the agent stops, and the obligation is lost
forever.
A mailbox solves delivery. A ledger solves obligation.
The release loop
We didn't build v0.1.1 in a single session. We used the pool. Claude Code took the implementation queue. codex stood by as rolling reviewer. Gemini watched the wrapper and docs edges. Every review request was a direct inbox message.
┌────────────────┐ ┌────────────────┐ ┌────────────────┐
│ CLAUDE-CODE │ │ CODEX │ │ GEMINI-CLI │
└───────┬────────┘ └───────▲────────┘ └───────▲────────┘
│ 1. land commit, request review │
├──────────────────────▶│ │
├──────────────────────────────────────▶│
│ │ 2. findings │ 2. findings
│◀──────────────────────┤ │
│◀──────────────────────────────────────┤
│ 3. patch + reply-to + sign-off ask │
├──────────────────────▶│ │
└──────────────────────────────────────▶│
That loop found real bugs.
Early ledger code treated duplicate message_id values too
casually. A second delivery with the same id but a different filename
could have disappeared into an idempotent no-op. The review turned that
into a typed collision error, ErrLedgerEntryCollision. The
protocol says message_id is for threading, not delivery
uniqueness. The implementation had to honor that distinction.
Another review caught the wrong-recipient reply case. If an agent owed
codex a reply but sent --reply-to that message while
addressing Gemini, the ledger must not clear the codex obligation. The
fix checks both sides of the ledger row: the reply goes to the original
sender, and the row belongs to the replying agent.
The most important bug was simpler. send --ask wrote the
right wire field, but check initially archived the message
without recording it in the ledger. The mail was gone. The obligation
was gone with it. That would have made the new gate look clean while
the protocol still owed a reply. The review reproduced it end-to-end and
forced the missing integration: archive a reply_required
message, then record the pending-reply row immediately.
None of those were caught by the test suite first. They were caught by a peer agent reading the diff. The same as in human teams.
The hooks proved it under pressure
After the code path was green, Alex ran a real bake in a fresh folder with the actual Claude wrapper. This was the kind of test unit tests don't replace: install the hook template, start the wrapper, ask it what it sees, and watch whether the context actually lands in the model.
The SessionStart hook worked. Claude quoted the injected "Inbox clear;
no pending reply obligations" text back from its developer context. The
Stop hook worked too. gate --before finish blocked the turn
when mail remained, and Claude walked the hand-protocol §5 path (because
agentchute wasn't on its tool sandbox PATH) to compose the
reply, archive the original, and tick its last_seen, then
ended cleanly.
The bake also caught a wrapper-specific mismatch. Claude Code's
UserPromptSubmit hook didn't inject raw JSON stdout. It injected plain
text. The template had been technically plausible and practically wrong.
The fix wasn't glamorous: drop --json for Claude's
UserPromptSubmit hook, keep codex's JSON-shaped hook mode, and document
the drift for the next spec revision.
A second real-bake observation became a loop-prevention convention. A
self-send with --ask is allowed — it can be a useful local
scratch obligation. But replies must not blindly propagate
reply_required, or an automated agent can create an infinite
ask-reply chain with itself. v0.1.1 now warns on self-send asks, and the
spec says replies should default to reply_required: false
unless the sender explicitly asks for more.
The protocol didn't only carry the release. It corrected the release.
The README was a three-agent consensus round
The last visible change before tagging wasn't a Go file. It was the README. The old one was 396 lines, dense, with the pitch buried four paragraphs in. Alex's instruction: "have your team, codex team and gemini team work on new readme that is shorter, better in any way and is updated with new features, it has to be super easy to read."
Three agents drafted independently in round 1. Round 2: each agent reviewed the other two and proposed a synthesis. Round 3: claude-code committed the synthesis, codex flagged two specific wording corrections, gemini signed off, codex signed off after the corrections landed. 178 lines. The whole loop ran through agentchute inboxes in something like twelve minutes.
The interesting thing wasn't the speed. It was that the agents disagreed
substantively. Gemini's draft was the shortest and codex called it out
as too short — the v0.1.1 features didn't have enough space. Codex's
draft was the longest and gemini called it out as too detailed — the
protocol-guarantees section belonged in AGENTCHUTE.md, not
the README. Convergence wasn't an averaging operation; it was a real
conversation about what the document was for.
Why this matters
Multi-agent work doesn't always need autonomy. Often it needs manners. Ask the right peer. Wait for the reply. Don't forget an open request. Don't leave while someone is talking to you. Tell the sender if you're deferring. Make malformed messages visible instead of silently ignoring them.
Those rules sound social because they are. agentchute turns a few of them into files and exit codes.
v0.1.1 added durable obligation tracking, lifecycle gates across three wrappers, and a self-correcting protocol convention against infinite loops. The bigger thing it proved is that the agents can build the protocol they coordinate through, in real time, with one human keeping the steering and no humans copy-pasting messages. That isn't a feature. That's the thesis.
We started by giving agents inboxes. We shipped the release when the inboxes were good enough to ship themselves.
Try v0.1.1
curl -fsSL https://raw.githubusercontent.com/agentchute/agentchute/main/install.sh | sh
Then initialize a repo and boot two agents:
agentchute init --yes
agentchute boot --as claude-code --vendor anthropic
agentchute boot --as codex --vendor openai
Or skip the binary. Drop
AGENTCHUTE.md
into your project and follow the hand-protocol section. The whole protocol
fits in one file.
Repository: github.com/agentchute/agentchute · Release: v0.1.1 · MIT license · home