feat(overseer): event_attention sidecar + principal/namespace - #114
feat(overseer): event_attention sidecar + principal/namespace#114heavygee wants to merge 2 commits into
Conversation
Move attention triad to fork-local event_attention (sparse backfill, parity check, stop writing legacy columns). Record namespace + structured principal on every write; refuse non-human principals without a human owner. Encode salience≠authority for privileged overseer reads (fresh hub grant only). Co-authored-by: Cursor <cursoragent@cursor.com>
Parse stays lenient (historical/foreign rows); serialize omits the field so unvalidated pointers never accumulate. Parse/isValidGrantingEventId require a positive integer PK candidate (not Number.isFinite). Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 078c2530be
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| ); | ||
| CREATE INDEX IF NOT EXISTS idx_events_session_ts ON events(related_session_id, ts DESC); | ||
| CREATE INDEX IF NOT EXISTS idx_events_type_ts ON events(event_type, ts DESC); | ||
| CREATE INDEX IF NOT EXISTS idx_events_namespace_ts ON events(namespace, ts DESC); |
There was a problem hiding this comment.
Add tenancy columns before creating their index
When an existing installation opens a database created by the parent schema, events has no namespace column, and CREATE TABLE IF NOT EXISTS does not add it. This index statement therefore raises no such column: namespace before ensureEventsTenancyColumns() can run, preventing the hub from starting on every such upgrade. Move the guarded ALTER TABLE calls before any DDL that references the new columns.
Useful? React with 👍 / 👎.
| const id = Number(result.lastInsertRowid) | ||
| upsertEventAttention(db, id, { |
There was a problem hiding this comment.
Make event and attention writes atomic
If the process exits or the sidecar statement fails after the events insert commits but before this call completes, the event remains permanently non-salient: its legacy flags were deliberately written as zero, startup backfill cannot reconstruct them, and an idempotent retry returns the existing row without repairing the sidecar. Wrap the base insert and sidecar upsert in one database transaction so attention events cannot silently become zero-flag events.
Useful? React with 👍 / 👎.
| if (options.namespace) { | ||
| clauses.push("COALESCE(e.namespace, 'default') = ?") | ||
| params.push(options.namespace) |
There was a problem hiding this comment.
Preserve legacy events for non-default namespaces
On an upgraded database, all historical events have namespace = NULL; this predicate classifies every such row as default, so an Overseer for any non-default namespace loses its entire historical event stream even when related_session_id identifies one of its sessions. It also prevents the subsequent eventInCallerScope() legacy fallback from ever inspecting those rows. Allow NULL rows through for related-session scope checking, or backfill their namespace from the referenced session.
Useful? React with 👍 / 👎.
Summary
event_attentionsidecar for the attention triad (sparseINSERT OR IGNOREbackfill, logged parity check, reads viaLEFT JOIN/COALESCE, stop writing legacyevents.attention_*columns; do not DROP them on the live table).namespace+ structuredprincipal_jsonon every event write; refuse non-human principals with no resolvable human owner (day-one kill criterion). Multi-user claims still gated on isolation tests - we are not claiming that yet.allowWrites/ conversational focus). System prompt + write-auth test encode salience ≠ authority.Stacked on #113 (
feat/overseer-converse-focus). RFC: Discussion #1332 / B7 fork attention out of upstream RFC.Test plan
bun test hub/src/store/eventAttention.test.tsbun test shared/src/eventPrincipal.test.ts shared/src/overseerWriteIntent.test.tsbun test hub/src/sync/overseerEntity.test.ts(incl. namespace isolation)hubtsc --noEmit:3006DB copy or remat: confirm parity logmismatches: 0and ~3.2k sidecar rows from ~5.3k eventsallowWrites; poisoned work-ad summary does not unlock pingMade with Cursor