Skip to content

feat(overseer): operator turn supersedes session inbox (#108) - #109

Open
heavygee wants to merge 1 commit into
feat/overseer-converse-contextfrom
feat/overseer-inbox-turn-supersede
Open

feat(overseer): operator turn supersedes session inbox (#108)#109
heavygee wants to merge 1 commit into
feat/overseer-converse-contextfrom
feat/overseer-inbox-turn-supersede

Conversation

@heavygee

@heavygee heavygee commented Aug 2, 2026

Copy link
Copy Markdown
Owner

Summary

  • Operator turn (web/Telegram/CLI user message, including ping_session) dismisses active inbox items for that session (superseded_by_operator_turn).
  • Resume alone does not clear.
  • query_open_loops / "what am I forgetting?" = whole sessions still needing attention that the operator has not turned on since that need — not within-session memory.
  • Canon: Overseer is cross-session tip-of-surface only (Overseer: operator turn supersedes session inbox items (cross-session only) #108).

Test plan

  • hub/src/store/inboxItems.test.ts supersede + re-promote
  • query_open_loops excludes operator-touched sessions
  • Dogfood on tip soup after Meta remat: continue a session with a live inbox card; card should leave active set

Made with Cursor

Cross-session altitude: an operator turn on S dismisses tip-of-surface
inbox cards for S (not resume-alone). query_open_loops only returns whole
sessions still needing attention that the operator has not turned on since.

Co-authored-by: Cursor <cursoragent@cursor.com>
@heavygee

heavygee commented Aug 2, 2026

Copy link
Copy Markdown
Owner Author

Closes #108. New tip layer above #106 — Meta remat needed before dogfood of this rule on :3006.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2beca81e3a

ℹ️ 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".

Comment on lines 116 to +119
if (shouldRecordSessionActivity(content)) {
onSessionActivity?.(sid, msg.createdAt)
// Local CLI operator turn — tip-of-surface inbox dies (#108).
store.inbox.supersedeForOperatorTurn(sid)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Restrict supersession to human-authored messages

shouldRecordSessionActivity also returns true for an agent ready event, and every launcher emits that event when a session starts or reopens. Consequently, resume/reopen alone enters this branch and obsoletes the session's active inbox items; sessionHasOperatorTurnSince reuses the same predicate and also removes the session from query_open_loops. Use a human-user-message predicate rather than the broader activity predicate.

Useful? React with 👍 / 👎.

Comment on lines 475 to +477
this.onSessionActivity?.(sessionId, msg.createdAt)
// Operator turn (web / telegram / ping_session) — tip-of-surface inbox dies (#108).
this.store.inbox.supersedeForOperatorTurn(sessionId)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Defer supersession until a scheduled message is delivered

When payload.scheduledAt is in the future, the message is stored now but, as the following branch documents, is not delivered to the CLI until it matures. This unconditional call therefore clears the session's attention cards up to seven days before the operator actually turns on the session; canceling the scheduled message does not restore those cards. Skip future-scheduled rows here and supersede them from the maturity path instead.

Useful? React with 👍 / 👎.

Comment on lines +778 to +780
const recent = this.messages.getMessages(sessionId, 80)
return recent.some(
(message) => message.createdAt > sinceTs && shouldRecordSessionActivity(message.content)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Search the complete message history for operator turns

This checks only the latest 80 transcript rows. If an operator continues a session and that turn is followed by more than 80 agent/output chunks without a newer status-bearing event, the turn falls outside this window and the old need is incorrectly returned by query_open_loops as forgotten. Use a database existence query over all messages since sinceTs, or persist the last operator-turn timestamp per session.

Useful? React with 👍 / 👎.

Comment on lines +344 to +347
let count = 0
for (const item of items) {
const updated = recordInboxOperatorAction(db, item.id, 'dismiss', feedback, null)
if (updated) count += 1

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep implicit supersession out of disposition labels

Each ordinary session turn routes the automatic transition through recordInboxOperatorAction, which inserts action='dismiss' into inbox_operator_actions. That table is explicitly consumed by query_dispositions and clustering as operator decision/training history, so routine continuations will be reported and learned as explicit dismissal preferences. Update the inbox item's status without creating a disposition row, or exclude superseded_by_operator_turn rows from disposition queries and discovery.

Useful? React with 👍 / 👎.

Comment on lines 475 to +477
this.onSessionActivity?.(sessionId, msg.createdAt)
// Operator turn (web / telegram / ping_session) — tip-of-surface inbox dies (#108).
this.store.inbox.supersedeForOperatorTurn(sessionId)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Skip supersession for idempotent message replays

addMessage returns the previously stored row when a web request repeats an existing localId, but this side effect still runs as if a new operator turn landed. If that retry is delayed until after the worker has emitted a newer attention event, replaying the old request incorrectly obsoletes the new card even though the operator sent nothing new. Only supersede when the message insert actually created a row.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant