Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

ADR 0011 · A restarted daemon does not replay what it missed

  • Status: accepted
  • Date: 2026-09-15
  • Source: issue #19 ("decide restart behaviour"); ADR 0003, ADR 0007

Context

Prospero's per-agent stream replays an agent's whole history when a client connects, and from is the only cursor. A daemon that reconnects from 0 after a restart would re-post every event it had already delivered.

Ariel keeps no state of its own (ADR 0003), and gonzalo's access-control record kinds (gonzalo ADR 0022) have nothing to hold a stream position. The options were:

  • Persist a cursor. Add a record kind for the last delivered seq per agent, or per daemon. It would let Ariel resume exactly, at the cost of a new record kind in gonzalo, a write on every notification, and a cursor that is wrong whenever two daemons run at once.
  • Notify only what happens after startup. No new state anywhere, at the cost of a gap: an agent that ended while the daemon was down is never announced.

ADR 0007 already narrows the blast radius. Message refs are not persisted, so a restart cannot edit the live messages the previous process posted, and the FleetWatcher skips agents already terminal on its first poll.

Decision

A restarted arield starts from the fleet as it is, and replays nothing.

  • Agents already terminal at the first fleet poll are history: no message.
  • Each agent still running gets a fresh live message. The message the previous process posted is left as it was, showing the last state it saw.
  • Agents that started and ended entirely during the downtime are never notified. This is the accepted gap.
  • No cursor is stored, in gonzalo or anywhere else.

Consequences

  • Positive: No new record kind, no write per notification, and no cursor to be wrong when two daemons overlap during a rolling restart. Restart behaviour is a consequence of ADR 0003 rather than a mechanism of its own, and a restart costs at most one fresh message per running agent.
  • Negative: A downtime that spans an agent's whole life hides it from chat entirely; the fleet dashboard and prospero's own history remain the record. A running agent's old live message is never finalized, so a channel can hold a stale message that stops updating. An operator watching one channel cannot tell a restart gap from a quiet fleet.
  • Revisit if: restarts become frequent enough that missed terminal states matter (a rolling deployment on every chart change, say), or gonzalo gains a cursor-shaped record kind for another consumer, in which case resuming becomes cheap enough to reconsider.