-
Notifications
You must be signed in to change notification settings - Fork 7
Description
Parent: #204 | Priority: P0 — Required for real-time activity feed
Problem
The product vision requires a live activity feed on the town dashboard showing "beads created, agents spawned, mail sent, molecules advancing, merges completed." But there is no event log anywhere in the system. The Rig DO mutates state (creates beads, updates statuses, sends mail) but doesn't write an append-only event stream.
The gastown_bead_events table was described in the original proposal but was never implemented in the DO SQLite schema. Without it, the dashboard has no source of truth for "what happened" — only "what is the current state."
What This Enables
- Town-wide activity feed — SSE/polling endpoint that returns recent events across all rigs
- Bead detail timeline — "Created by Mayor at 14:32 → Assigned to Toast at 14:32 → Hooked at 14:33 → Status changed to in_progress at 14:35 → Closed at 15:12"
- Future Postgres replication — Events can be synced to Postgres for analytics
- Debugging — Trace exactly what happened to any bead
Implementation
1. Add bead_events table to Rig DO SQLite
CREATE TABLE bead_events (
id TEXT PRIMARY KEY,
bead_id TEXT NOT NULL,
agent_id TEXT,
event_type TEXT NOT NULL, -- 'created', 'assigned', 'hooked', 'unhooked', 'status_changed', 'closed', 'escalated', 'mail_sent', 'agent_spawned', 'agent_exited'
old_value TEXT,
new_value TEXT,
metadata TEXT DEFAULT '{}',
created_at TEXT NOT NULL
);
CREATE INDEX idx_bead_events_bead ON bead_events(bead_id);
CREATE INDEX idx_bead_events_created ON bead_events(created_at);2. Write events on every state mutation in Rig DO
createBead()→ writecreatedeventhookBead()→ writehookedevent (with agent_id)unhookBead()→ writeunhookedeventupdateBeadStatus()→ writestatus_changedevent (with old/new)closeBead()→ writeclosedeventsendMail()→ writemail_senteventagentDone()→ writeclosed+unhookedeventsregisterAgent()/ agent status changes → writeagent_spawned/agent_exitedevents
3. Expose events via HTTP
New handler: GET /api/rigs/:rigId/events?since=<iso-timestamp>&limit=<n>
Returns events newer than since, ordered by created_at. Default limit 100.
4. Town-wide event aggregation
New endpoint on the gastown worker: GET /api/towns/:townId/events?since=<iso-timestamp>
Fans out to all Rig DOs in the town, merges and sorts events. This drives the dashboard activity feed. For Phase 1, simple polling (every 3-5s). For Phase 3, SSE.
Acceptance Criteria
-
bead_eventstable in Rig DO SQLite schema - Events written on all state mutations (bead, agent, mail)
-
GET /api/rigs/:rigId/eventsendpoint -
GET /api/towns/:townId/eventsendpoint (fan-out across rigs) - Events include enough context for the dashboard to render meaningful descriptions
- Bead detail panel can show full event timeline