You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(gastown): implement town reconciler with event-driven state management
Replace the imperative patrol/scheduling/review-queue alarm phases with a
declarative reconciler that drains events, computes desired state, and
applies corrective actions. This is the complete implementation of the
reconciliation spec (Phases 1-5).
Core changes:
- Event table (town_events) with 8 event types, dual-write in all RPC handlers
- 6 reconciler functions: agents, beads, review queue, convoys, GUPP, GC
- applyEvent/applyAction for all event and action types
- Event-only agentDone/agentCompleted (no direct mutations)
- Lazy assignment for slingConvoy/startConvoy (#1249)
- Container status observation pre-phase (replaces witnessPatrol)
- Agent activity watermark via enriched heartbeat
- Invariant checker + reconciler metrics in getAlarmStatus
- Rework flow: gt_request_changes tool for refinery change requests
- Refinery system prompt wired in (buildRefinerySystemPrompt)
Bug fixes discovered during rollout:
- Convoy landing MR cycling (reconciler created duplicates)
- Multi-agent hook mutual exclusion (hookBead now unhooks stale agents)
- agentCompleted no longer closes beads when gt_done wasn't called
- GUPP NaN bug for agents with null last_activity_at
- Container status event flood (upsert instead of insert per tick)
- Rule 4 scoped to in_progress MR beads only
Dead code removed: ~1,578 lines from patrol.ts, scheduling.ts,
review-queue.ts, and Town.do.ts (witnessPatrol, deaconPatrol,
processReviewQueue, processConvoyLandings, pollPendingPRs, etc.)
Verify agents recover from the container restart. The reconciler handles all recovery:
79
106
80
-
-**Polecats**: idle+hooked agents should be dispatched by `schedulePendingWork`
81
-
-**Refinery**: if it was mid-review, `recoverStuckReviews` handles it after the timeout
82
-
-**Orphaned beads**: `rehookOrphanedBeads` picks up beads with stale assignees after 2 min
107
+
-**Polecats**: idle+hooked agents are re-dispatched by `reconcileBeads` Rule 2
108
+
-**Refinery**: if it was mid-review, the container status observation detects the dead container and sets the refinery to idle. `reconcileReviewQueue` Rule 6 re-dispatches it.
109
+
-**Orphaned beads**: `reconcileBeads` Rule 3 resets in-progress beads with no working agent to open after 5 min, then Rule 1 assigns a new agent.
83
110
84
111
**Red flags**:
112
+
85
113
-`Working: 0` for more than 5 min after container is active
0 commit comments