Status:
draft · ADR-41 · Filed 2026-05-02ADR — Reconnect FSM for persona daemons
Status
DraftContext
The per-agent daemon must preserve turn-boundary delivery discipline even while the underlying WS connection disconnects and reconnects. Without an explicit state machine, reconnect races can emit doorbells in the middle of active agent work, before authoritative pending reconciliation completes, or multiple times for the same backlog. The reconnect path is therefore a structural primitive, not an implementation detail. Desiree surfaced the reconnect finite-state machine as the point future implementers will reason against. Donna agreed it should be promoted to an ADR rather than left buried in SPEC-070 body text.Decision
The daemon’s reconnect path is governed by the following explicit FSM:DISCONNECTED -> RECONCILING -> CONNECTED -> EMITTING
State meanings:
DISCONNECTED: WS path unavailable; no doorbell emission allowed.RECONCILING: daemon is re-establishing authoritative state by querying the durable pending queue; no doorbell emission allowed.CONNECTED: transport is healthy and authoritative queue state is known, but the daemon is waiting for the next agent activity boundary.EMITTING: one-per-turn doorbell emission is permitted.
- Reconnect always enters
RECONCILINGbefore any visible emission. - Doorbell emission is forbidden outside
EMITTING. - Reconnect never injects immediately on transport recovery.
- The daemon waits for the next agent activity boundary before entering
EMITTING. - A backlog of pending signals yields one doorbell and one authoritative drain, not a doorbell storm.
Consequences
- Implementers have a queryable, named model for reconnect edge cases.
- The daemon preserves turn-boundary discipline during transport churn.
- Porsche’s dashboard and Desiree’s journal can point at stable state names instead of prose.
- Any future attempt to collapse
CONNECTEDandEMITTING, or to emit duringRECONCILING, is an ADR-visible change rather than a casual refactor.
Alternatives considered
1. No explicit FSM
Rejected. Too easy to bury ordering assumptions in code and recreate duplicate/mistimed doorbells.2. Immediate emission on reconnect
Rejected. Violates turn-boundary discipline at the least-context-loaded moment.3. Aggregate backlog into N doorbells
Rejected. This is batching’s evil twin; the daemon becomes a notification storm generator.Cross-references
- SPEC-070 v0.2
- PR #45 / commit
5df6679 - postmortem
0660f88e - docs/research/surface-comparison-2026-05-02.md

