diff --git a/docs/agent-coordination.md b/docs/agent-coordination.md index ce0880b6..38455ac7 100644 --- a/docs/agent-coordination.md +++ b/docs/agent-coordination.md @@ -480,6 +480,39 @@ a human watches and steers a conversation that continues without it — which is §1.15 shows the chat system was rebuilt to support (durable event log, cursor replay, agent-as-writer, session outliving the socket). +**Measured, 2026-08-07 — the durability claim above is no longer an argument.** Six tests run live +against the running system, deliberately looking for the break. Method and raw evidence: +`COMMS/handoff-durability-2026-08-07.md`. + +| what was done to it mid-handoff | turn completed | narration durable | +|---|---|---| +| nothing (control) | ✅ | ✅ | +| `pm2 restart officer` | ✅ | ✅ | +| **`officer` stopped for 25 s** | ✅ | ✅ **6 events written while the server was down** | +| target's `claude` process SIGKILLed | ❌ lost | ⚠️ partial, with an explicit error row | +| next handoff to that same agent | ✅ | ✅ same Claude session resumed | +| handoff POSTed while `officer` is down | ❌ lost | ❌ no queue, no retry | + +Three things follow, and they change how the outstanding work should be read: + +- **The "no browser open" requirement is satisfied, and so is the harder one.** Not one of these runs had + a page open, and the middle row is the proof that officer is genuinely off the delivery path: the agent + sidecar committed the model's own words to Postgres during a 25-second server outage. +- **A restart costs a *turn*, not an *agent*.** After being killed mid-turn, the receiver resumed the + identical Claude session on the next handoff and volunteered which work had been lost. Continuity — + `sessionKey` minted once, write-through map on disk — does the job it was built for. That makes the + outstanding claude **stage 5** a smaller problem than its position on the list suggests. +- **The remaining hole is on the *sending* side.** A handoff POSTed while officer is down is refused and + dropped, and nothing in the introduction text tells the agent to retry — so the sender can believe it + handed off when it did not. That, not the receiving side, is where store-and-forward would earn its + keep. + +One topology fact found while setting this up, worth stating here because it is the practical limit on +working unattended: **`officer-agent` is `sidecar/claude/user-instance.ts`, and every `claude` process on +the machine is its direct child.** `pm2 restart officer-agent` therefore kills every agent on every +dashboard at once, mid-turn. `CLAUDE.md` reassures that restarting *officer* is safe — it is, and that is +verified above — but is silent on this one. + ### 1.17 The restart payload is temporary — the protocol is not > The restart thing is giving me pain right now. Pretty soon that won't be a problem, because I won't