Skip to content

Thread event log (canonical state)

Every state-affecting operation produces an event. The current-state cache exists for query convenience but events are authoritative.

Details

Schema

thread_events table (see work_buddy.threads.store): - id AUTOINCREMENT PK - thread_id FK → threads(thread_id) ON DELETE CASCADE - kind (one of ALL_KINDS from work_buddy.threads.events) - actor (agent | user | sidecar | fsm_engine | conductor | inciting) - inference_tier (ReasoningTier value or NULL) - timestamp - data_json - parent_event_id (optimistic-lock target) - migration_id (cross-Thread linked events)

Event kinds (catalog)

Lifecycle, inference, confirmation, clarification, redirect, consent, execution, migration, decomposition, budget — see work_buddy.threads.events for the full list and constants. validate_kind() enforces at submit.

Optimistic locking

Each event carries the latest parent_event_id the actor saw before deciding. The store rejects an insert whose parent_event_id doesn't match the most recent landed event for that thread (raises OptimisticLockConflict). First-event submissions (parent_event_id=None) bypass the check. Two concurrent submissions race; one succeeds, one retries.

Cross-Thread migrations

When a context item moves between Threads, both Threads emit events sharing a migration_id: context_removed on the source, context_added on the destination. get_linked_events(migration_id) retrieves both.