Skip to content

[codex] Add threadCatalog metadata subscriptions - #26009

Closed
btraut-openai wants to merge 7 commits into
mainfrom
btraut/thread-catalog-subscription
Closed

btraut-openai wants to merge 7 commits into
mainfrom
btraut/thread-catalog-subscription

Conversation

@btraut-openai

@btraut-openai btraut-openai commented Jun 3, 2026 •

Copy link
Copy Markdown
Contributor

Why

Sidebar clients have an awkward choice today: fetch one page with thread/list and miss activity in threads outside that page, or resume every thread and pay for detailed runtime subscriptions they do not need.

This adds a metadata-only catalog subscription so clients can keep a small paginated sidebar view while still hearing about future persisted thread changes. thread/list remains the way to fetch existing catalog data; threadCatalog/subscribe is only for future metadata mutations.

What changed

The app-server v2 protocol now exposes threadCatalog/subscribe, threadCatalog/unsubscribe, and threadCatalog/changed. Catalog change notifications carry a complete ThreadSummary with sidebar row metadata, including ids, preview/name, cwd, created/updated/recency timestamps in seconds and milliseconds, archive state, git info, source, and parent thread id when known. They intentionally exclude turns, items, messages, deltas, tool state, status, and loaded runtime state.

The implementation publishes summaries from persisted thread creation and metadata update paths. Listing, reading, and resuming threads do not make them recent; meaningful thread activity and metadata mutations do. Ephemeral in-memory threads stay out of this catalog subscription rather than adding a second app-server-owned shadow catalog.

How it works

Think of thread/list as asking, “What are the first N persisted rows in my sidebar right now?”

threadCatalog/subscribe asks, “From now on, tell me when any persisted thread row changes, even if I did not load that row yet.”

Clients should start buffering threadCatalog/changed notifications before sending the subscribe request, wait for the subscribe response, call thread/list, then apply the buffered summaries idempotently. Reconnecting clients should resubscribe and refetch their visible page because catalog subscriptions do not replay offline changes.

codex-apps follow-up should subscribe before the initial sidebar list, apply its existing filters when summaries arrive, upsert/reorder/remove rows on threadCatalog/changed, unsubscribe when the view is disposed, and refetch on reconnect.

Verification

Regenerated app-server schema fixtures and ran the focused protocol tests, app-server catalog subscription tests, and thread resume regression locally. Also ran scoped Rust fix/clippy for touched crates, Rust formatting, and whitespace checks.

@btraut-openai btraut-openai changed the title [codex] Add thread catalog subscriptions [codex] Add metadata-only thread catalog subscriptions Jun 3, 2026
@btraut-openai
btraut-openai force-pushed the btraut/thread-catalog-subscription branch from 300f2d6 to 6880449 Compare June 3, 2026 02:19
@btraut-openai
btraut-openai force-pushed the btraut/thread-catalog-subscription branch from 6880449 to bbb721b Compare June 3, 2026 08:14
btraut-openai added a commit that referenced this pull request Jun 3, 2026
@btraut-openai
btraut-openai force-pushed the btraut/thread-catalog-subscription branch from bbb721b to 7d62042 Compare June 3, 2026 16:13
@btraut-openai
btraut-openai marked this pull request as ready for review June 3, 2026 21:37

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

Copy link
Copy Markdown
Contributor

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: 7d620423f2

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread codex-rs/app-server/src/request_processors/thread_processor.rs
Comment thread codex-rs/app-server/src/request_processors/thread_catalog_subscription.rs Outdated
btraut-openai added a commit that referenced this pull request Jun 4, 2026
btraut-openai added a commit that referenced this pull request Jun 4, 2026
@btraut-openai
btraut-openai force-pushed the btraut/thread-catalog-subscription branch from 7d62042 to e031dc6 Compare June 4, 2026 16:46
btraut-openai added a commit that referenced this pull request Jun 12, 2026
# Conflicts:
#	codex-rs/tui/src/app/app_server_event_targets.rs
@btraut-openai
btraut-openai force-pushed the btraut/thread-catalog-subscription branch from e031dc6 to 6806826 Compare June 12, 2026 01:26
Comment thread codex-rs/app-server/src/request_processors/thread_lifecycle.rs Outdated
Comment thread codex-rs/app-server-protocol/src/protocol/v2/thread_data.rs
Comment thread codex-rs/app-server-protocol/src/protocol/common.rs Outdated
@btraut-openai
btraut-openai requested a review from a team as a code owner June 12, 2026 21:51
btraut-openai added a commit that referenced this pull request Jun 12, 2026
# Conflicts:
#	codex-rs/tui/src/app/app_server_event_targets.rs
@btraut-openai
btraut-openai force-pushed the btraut/thread-catalog-subscription branch from 3d970d4 to 7954ae9 Compare June 12, 2026 22:04
btraut-openai added a commit that referenced this pull request Jun 16, 2026
# Conflicts:
#	codex-rs/tui/src/app/app_server_event_targets.rs
@btraut-openai
btraut-openai force-pushed the btraut/thread-catalog-subscription branch from 7954ae9 to f100d8f Compare June 16, 2026 18:04
@btraut-openai btraut-openai changed the title [codex] Add metadata-only thread catalog subscriptions [codex] Add threadCatalog metadata subscriptions Jun 19, 2026
btraut-openai added a commit that referenced this pull request Jun 19, 2026
# Conflicts:
#	codex-rs/tui/src/app/app_server_event_targets.rs
@btraut-openai
btraut-openai force-pushed the btraut/thread-catalog-subscription branch from f100d8f to 7baa30b Compare June 19, 2026 19:28
Comment thread codex-rs/app-server-protocol/src/protocol/v2/thread_data.rs
Comment thread codex-rs/app-server/src/request_processors/thread_lifecycle.rs Outdated
Comment thread codex-rs/app-server/src/request_processors/thread_catalog_subscription.rs Outdated
Comment thread codex-rs/app-server/src/request_processors/thread_catalog_subscription.rs Outdated
Comment thread codex-rs/app-server/src/request_processors/thread_catalog_subscription.rs Outdated
btraut-openai added a commit that referenced this pull request Jun 22, 2026
# Conflicts:
#	codex-rs/tui/src/app/app_server_event_targets.rs
@btraut-openai
btraut-openai force-pushed the btraut/thread-catalog-subscription branch from dc0c72d to 07dff7c Compare June 22, 2026 19:16

@jif-oai jif-oai left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This is getting large because catalog publication is spread across LiveThread, core, listener tasks, and individual request handlers. That makes the invariant difficult to make complete and ordered. We already miss direct store mutations and have multiple mapping/delivery paths.

Can we first introduce one store-owned catalog change stream (upsert/delete/...) or any equivalent. Then make app-server only handle subscriber fanout? wdyt?

Comment thread codex-rs/app-server/src/request_processors/thread_summary.rs
Comment thread codex-rs/thread-store/src/live_thread.rs
Comment thread codex-rs/app-server-protocol/src/protocol/v2/thread_data.rs
Comment thread codex-rs/app-server/src/request_processors/thread_catalog_subscription.rs Outdated
@btraut-openai
btraut-openai force-pushed the btraut/thread-catalog-subscription branch from 07dff7c to 5c7d2ca Compare June 24, 2026 17:26
@btraut-openai
btraut-openai force-pushed the btraut/thread-catalog-subscription branch from 5815824 to 68ac705 Compare June 24, 2026 18:06
@btraut-openai

Copy link
Copy Markdown
Contributor Author

Codex: > Can we first introduce one store-owned catalog change stream (upsert/delete/...) or any equivalent?

I kept this PR surgical instead. A store-owned stream would require changing every store implementation and defining delete/tombstone semantics alongside the existing thread/deleted notification. Runtime mutations publish from LiveThread; app-server-owned mutations publish at their existing request boundaries through the shared stored-row mapper and ordered fanout. I audited those direct paths and added the missing external-session import publication with integration coverage. I do not think the broader persistence refactor belongs in this PR.

# Conflicts:
#	codex-rs/tui/src/app/app_server_event_targets.rs
Add revision-based bootstrap ordering, refresh spawned threads after listener attachment, preserve catalog notifications under in-process backpressure, and correct the generated recency timestamp type.
Carry root session identity through StoredThread summaries and make catalog unsubscribe wait for in-flight notification delivery.
@btraut-openai
btraut-openai force-pushed the btraut/thread-catalog-subscription branch from 68ac705 to c1b099d Compare June 24, 2026 18:31
@btraut-openai

Copy link
Copy Markdown
Contributor Author

Codex: Closing this. Jif is right: the store should own one ordered catalog change stream, and app-server should only fan it out. This PR spread that invariant across too many mutation paths and stopped being reviewable. I’m going to split it into a store-owned change stream first, then a thin app-server subscription on top.

@btraut-openai

Copy link
Copy Markdown
Contributor Author

Codex: First replacement is #29894. It is store-only and adds no app-server or schema surface. I’m leaving the fanout/API PR until this ownership boundary is reviewed.

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.

2 participants