## Why
Unarchiving a thread previously read rollout metadata across both active and archived history, including unrelated threads.
## What changed
Use `RolloutReferenceIndex::scan_archived_threads` to restrict discovery to archived files whose canonical filenames match the requested thread. Continue validating ownership through session metadata and include compressed and reverted rollouts.
## Testing
Add coverage for compressed and replacement archived rollouts, metadata ownership mismatches, unrelated filenames, and exclusion of active rollouts.
GitOrigin-RevId: 8784f3502b839dcb4a3839744010e350d0196545
## Why
Thread stores need a way to reuse history and writer state loaded while preparing a resume, rather than loading them again during session startup.
## What changed
- Add an opaque, single-use `ThreadStoreResumePreparation` and an optional preparation in `StartThreadOptions`.
- Pass preparation through session startup to `ThreadStore::resume_thread_with_preparation`, which defaults to an unsupported-operation error.
- Reject preparation for ephemeral threads or threads without resumed history. Continue using `resume_thread` when no preparation is supplied.
## Testing
Add a regression test verifying that supplied preparation selects the prepared store path and propagates its unsupported-operation error instead of falling back to ordinary resume.
GitOrigin-RevId: 26537d9b83443bd56341d6afc713f32b999dc67c
## Why
Compression replaces `.jsonl` rollout files with `.jsonl.zst` files, so checking only the original path can skip existing sessions. Compression can also replace a file between path lookup and canonicalization.
## What changed
- Resolve compressed rollout alternatives when selecting the latest local session.
- Retry rollout path resolution when files disappear during lookup or canonicalization.
## Testing
Extend coverage to verify latest-session filtering after startup compression and resuming a compressed rollout through its original relative `.jsonl` path with preserved turns.
GitOrigin-RevId: a4d5c399567ab4c7cd8aaa8b5f38821ee8b8d802
## Why
Blocking rollout reads can continue decompressing and scanning history after the calling async task is dropped.
## What changed
Propagate caller cancellation through rollout readers, prefix validation, model-context scans, history materialization, and working-directory lookup. Check cancellation during compressed input and output, bounded reads, seeks, and between history records. Return an error on cancellation so partial history cannot be mistaken for a complete read.
## Testing
Add regression coverage for dropping a caller during decompression, cancelling compressed input and output (including skippable frames), cancelling reads and seeks on plain and decoded snapshots, and cancelling history materialization between records.
GitOrigin-RevId: e3dac952789b53402f2a5f17c2a2232506feb9d6
## Why
Cancelling an async migration caller can leave its blocking compression or decompression worker running. Releasing migration locks before that worker finishes allows other writers or migrations to access files still being processed.
## What changed
Share maintenance, cross-process writer, and local writer locks with blocking workers during migration and recovery. Keep those locks held until file work completes, releasing cross-process locks before allowing local writers to proceed.
## Testing
Add a regression test for cancelled compression and decompression callers that verifies locks remain held until the worker finishes and the output is complete. Preserve the Unix check that decompression temporaries have owner-only permissions.
GitOrigin-RevId: 74855250d89ecab81eaadc2956e328d37b65e72e
## What changed
- Add the disabled-by-default `output_token_replay` feature to request `output.encrypted_content` from OpenAI providers.
- Preserve encrypted message and tool-call output, message and function-call status, and output-text `annotations` and `logprobs` through history and replay. Update the generated protocol schemas and SDK types.
- Strip output ciphertext from requests to other providers while retaining it in stored history, including after replay is disabled. Remove encrypted content from memory extraction inputs.
## Testing
Add integration coverage for the feature/provider combinations, metadata replay across follow-up requests, and history preservation when resuming with replay disabled.
GitOrigin-RevId: 77729a021b6771933402aebe74ece8eb39c057e2
## What changed
Add `thread/items/read` to retrieve persisted items by `threadId`, `turnId`, and 1–100 `itemIds`. Return matching items in canonical stored order, omitting missing IDs and items outside the requested turn.
Add item ID filtering to the thread store while preserving inherited history and fork cutoffs. Require the experimental API capability for the new endpoint.
## Testing
Add coverage for stored ordering, turn scoping, missing IDs, request size limits, experimental capability gating, and inherited items across fork cutoffs.
GitOrigin-RevId: 9b243dd87577bd4fe36900c388a386b2e26ff2e0
## Why
DB-only listing and pagination failures must not look like exhausted history. This hardens the DB-only listing added in https://github.com/openai/codex/pull/18502 and page refilling added in https://github.com/openai/codex/pull/7509.
## What changed
- Return JSON-RPC error `-32603` when `useStateDbOnly: true` cannot query the local state database, including requests with an empty `cwd` array.
- Track all cursors encountered while filling a page and return `-32603` for repeated cursors, including on full pages.
- Document that callers can retry these errors; a successful response with `nextCursor: null` still indicates exhaustion. Default scan-and-repair requests retain their filesystem fallback.
## Testing
Add regression tests for missing or mismatched state databases versus healthy empty history, with active and archived listings and null or empty `cwd` filters. Cover repeated cursors during page refilling and on full pages using the in-memory thread store.
GitOrigin-RevId: 09653a84fc65f47316d8bbae9e4cf3dd8ce9948a
## What changed
Remove `workspace_roots`, `current_date`, `timezone`, `network`, `personality`, and `multi_agent_mode` from `TurnContextItem` and stop recording them in rollouts. Update the precomputed protocol schema accordingly.
Make `summary` optional when reading turn context and write `"none"` as a compatibility placeholder for older readers, rather than persisting the active reasoning-summary setting.
## Testing
Update protocol tests to cover omitted `summary` fields and compatibility-placeholder serialization. Extend compaction tests to verify that model requests retain the updated reasoning-summary setting after compaction while the rollout checkpoint records the placeholder.
GitOrigin-RevId: d49eabaa1b340be1d79f7f09115281a307ea8a64
## What changed
Add `model` and `reasoningEffort` to `subAgentActivity` items for multi-agent v2 spawns. Capture startup settings before the child begins its turn and resolve the reported effort against model metadata, including model defaults, while preserving the child's configured effort.
Carry these fields through live notifications, persisted activity, thread history, and legacy rollout migration. Update the JSON schemas and generated TypeScript and Python types. Older records and other activity kinds retain null values.
## Testing
Add coverage for resolved spawn settings matching the child's request across legacy and paginated history, preserving configured effort, forwarding metadata through events and history, and reading and migrating older records without the new fields.
GitOrigin-RevId: a9e4241ae21bb8db1ead293f78ffba8257cca0ae
## Why
Clients starting delegated work need to attribute descendant turns to the original turn and retain that attribution through completion and history reads.
## What changed
- Accept optional `parentTurnId` and `rootTurnId` in `turn/start`, and expose `rootTurnId` on returned turns and lifecycle notifications.
- Default new turns to their own root when none is supplied. Preserve the active turn's root when steering, ignoring incoming lineage fields.
- Carry root IDs through completion, interruption, recovery, and fork boundaries, and persist them for paginated history reads. Leave unknown roots null in older history.
- Update protocol schemas and generated TypeScript and Python bindings.
## Testing
Extend coverage for default and explicit roots, steering without changing lineage, interrupted and recovered turns, history reads after restart in both history modes, nested fork pagination, and compatibility with older database writers.
GitOrigin-RevId: f1a570a12bd11742929fd2e8b017e5d35aa07dcb
## Why
Recovering an interrupted turn replaced its original trigger with `retry` and restored only its root lineage from model context. Turns suspended before that context was written could lose their attribution entirely.
## What changed
- Persist regular-turn attribution in `TurnStartedEvent` and compaction resume metadata, including the trigger, parent and root turn IDs, and initiating agent path.
- Restore matching attribution during recovery, keep unknown triggers absent, and retain the model-context root fallback for older records.
- Reconstruct attribution from surviving turns across rollback and late completion or abort events, and clear inherited attribution when spawning a forked agent.
## Testing
Add coverage for repeated cold recovery, suspension before context persistence, legacy rollouts, fresh attribution on subsequent turns, compaction checkpoints, rollback, and late terminal events.
GitOrigin-RevId: 85b5763e8fbd48a1ea2c07cfda8196e63c2cd33a
## Why
Messages with the `partial_answer` phase contain answer text without declaring a terminal answer. They should remain searchable and speakable without being treated as final messages.
## What changed
- Preserve explicit `partial_answer` phases in streamed and completed realtime handoffs, bypassing legacy channel-prefix parsing and routing them to the `speakable` channel.
- Treat partial answers as nonterminal in V1 handoffs and omit the final-message prefix.
- Include partial answers in thread occurrence searches and normalize them to the final conversation channel in rollout traces.
## Testing
Extend coverage for realtime phase routing, streamed and completed handoffs, partial-answer search results, and rollout normalization. Verify that turn summaries still exclude nonterminal messages.
GitOrigin-RevId: aa183da783f6e7e0b78ddd51073cba533297e121
## Why
Assistant answer text may be followed by more output or tools. A distinct `partial_answer` phase lets callers represent this separately from commentary and a terminal `final_answer`.
## What changed
- Add `MessagePhase::PartialAnswer` and expose `partial_answer` in the app-server schemas and generated TypeScript and Python types.
- Keep the TUI working indicator visible after partial answers and exclude them from the thread history's final-answer summary field.
- Route partial answers to the speakable channel in realtime V3 BEM-tag mode.
## Testing
Add coverage for phase preservation through serialization, input-message conversion, and SSE item start/completion events. Extend TUI snapshot coverage to verify that partial answers keep the working indicator visible while final answers hide it.
GitOrigin-RevId: 1ae3ad9264b6e36ae1cbe6b93df3d345ab4460e6
## Why
Session activity can move unread threads ahead of a pagination cursor, and timestamp-only cursors can skip threads with equal creation times. Either can prevent a session label lookup from detecting duplicate labels. Database failures must also remain distinguishable from an exhausted listing.
## What changed
- Resolve session labels using database-only listings ordered by `CreatedAt`, with thread IDs breaking timestamp ties. Accept unique matches across pages with valid timestamp-and-ID cursors, while retaining ambiguity errors for older cursors that cannot establish uniqueness.
- Preserve timestamp index ranges for database continuation queries and timestamp-only cursors for listings that may fall back to the filesystem.
- Propagate database-only listing and name-resolution failures. Keep best-effort name enrichment for ordinary listings and retry latest-session lookup with scan-and-repair after a database-only error.
- Keep loaded sessions selectable in the resume and fork pickers when a later page fails, stop further pagination, and display `Could not load more sessions`.
## Testing
Add regression coverage for creation-time continuation after session activity, cursor query plans, filesystem fallback, database and name-query errors, cross-page label uniqueness, older server cursors, and selection after picker pagination failures.
GitOrigin-RevId: 264ab2e69b8ad12d9edaa31fd253cb9805a46a90
## Why
Delegated turns can begin without a user message, leaving threads without a task preview. Populate the preview from delegated input so these threads are discoverable before a user follow-up.
## What changed
- Extract previews from completed `create_thread` and `send_message_to_thread` outputs in the `codex_app` and `codex_tui` namespaces.
- Unwrap recognized `<codex_delegation>` inputs and decode their escaped task text for display, preserving model content. Keep plain or unrecognized wrappers as text and ignore blank inputs.
- Fill missing previews in state metadata extraction and live thread metadata updates without replacing existing previews or setting the title or `first_user_message`.
## Testing
Add tests for delegation decoding and tool filtering, preview-only metadata updates, preservation of later user-message metadata, and database listing before a user follow-up in both legacy and paginated history modes.
GitOrigin-RevId: f7b3c60ef75e08c76b4084d043e3967bf2bade22
## Why
Paginated thread history can persist large MCP results in completed tool-call items. Bound these stored results to avoid retaining multi-megabyte payloads.
## What changed
Apply a 64 KiB preview budget when persisting oversized MCP results in paginated history. Replace the result with a truncated text preview of its serialized JSON, preserving `is_error` and clearing `structuredContent` and `_meta`. Leave small results unchanged.
Share the truncation helper with the existing MCP tool-call event path.
## Testing
Add helper tests for unchanged small results and oversized results with structured content and metadata. Add a thread-history test verifying that persisted MCP results contain a bounded preview with the beginning, end, and truncation marker while preserving tool arguments.
GitOrigin-RevId: 09dce73c70bfd357c9b9630f456e9e5c1d8492cf
## Why
Paginated history previously persisted completed commands' full `aggregated_output`, allowing large command outputs to inflate stored history.
## What changed
- Limit persisted command `aggregated_output` to 64 KiB, including a truncation marker. Preserve the beginning and end of the output without splitting UTF-8 characters.
- Apply the shared persistence policy to rollout recording, thread-store appends, and legacy-to-paginated history migration.
- Measure persisted payload bytes after truncation so persistence metrics reflect the stored representation.
## Testing
Add coverage for the byte limit, UTF-8 boundaries, unchanged inputs that fit, and markers that exceed the budget. Verify capped output in paginated thread history and migrated legacy history, and verify persistence metrics use the truncated payload size.
GitOrigin-RevId: 01d420d396ad34b42dc5dc208c0bf88d890639ee
## What changed
- Remove `stdout`, `stderr`, and `formatted_output` from `CommandExecutionItem` and `ExecCommandEndEvent`, retaining `aggregated_output` as the output field.
- Update command event producers, legacy conversion, rollout traces, and the precomputed schema. Use aggregated output for terminal trace results.
- Clear `interaction_input` in emitted and migrated command completion items.
## Testing
Update command execution and trace tests to use aggregated output, and assert that legacy rollout migration preserves `aggregatedOutput`.
GitOrigin-RevId: ed59827d4a5ec9a767084ee4feac72c2042440f2
## Why
`thread/attachment/list` lists attachments for a known thread. Clients also need to find the threads associated with a given attachment identity.
## What changed
Add `thread/attachmentOwner/list` to return owning thread IDs and archive status for an exact `attachmentType` and `identityKey`. Support cursor pagination and an optional `archived` filter, including both archived and non-archived threads by default.
Wire the request through the thread store and update documentation, protocol schemas, and generated TypeScript and Python types. The lookup is limited to the configured thread store and reports current membership, not an atomic resource-cleanup check.
## Testing
Extend app-server integration tests to cover exact type-and-key matching, multiple owners, archive filtering, and invalid cursor rejection.
GitOrigin-RevId: 30f4a20e00243d0023246d465a9b95213b3adeb6
## What changed
Expose `ThreadManager::request_agent_tree_shutdown` and an `AgentTreeShutdown::wait` handle. Requests reject new starts in the shared runtime, cancel pending startup, and signal every session in that tree, including delegates outside the thread registry. Waiting covers admitted operations and session teardown, and reports cleanup or persistence writer failures. Other root trees remain unaffected; registry removal and persistence handoff remain caller responsibilities.
Retain tree membership through startup, cancelled spawn cleanup, residency eviction, and completion watchers. Release persistence resources before returning startup failures, and stop completion watchers during tree shutdown without reporting shutdown as a child result.
## Testing
Add coverage for tree isolation, children removed from the registry, delegate teardown, cancellation during required MCP initialization, aborted teardown, persistence writer failures, and successful retry after a failed resume releases its writer.
GitOrigin-RevId: a109e25adf23d20baf7595891099947050c6b6b5
## Why
Naming a paginated thread before its first turn must make it durable so it can be resumed immediately and after an app-server restart.
## What changed
Persist the live rollout before updating name metadata in SQLite. Propagate persistence failures before saving the name.
## Testing
Add thread-store tests for empty-thread persistence and failure handling, plus an app-server regression test that resumes a named empty thread before and after a restart and completes its first turn.
GitOrigin-RevId: 2f7556c7de65f6a86177130c39e1a17951496931
## What changed
Run rollout file opening, metadata lookup, seeking, reading, and record
projection together in a single `tokio::task::spawn_blocking` call. Use
synchronous file I/O in `read_projection_steps_sync` and carry the current
tracing span into the blocking task.
GitOrigin-RevId: a231a8b9a328f6d2e2095a29cde1718ccb6b3901
## Why
Resuming a thread rereads persisted history even when a preloaded snapshot is unchanged. Reusing that snapshot must still account for writes committed before writer ownership is acquired.
## What changed
- Carry optional, non-serialized revisions from stored history and model context through thread and agent resume paths.
- Validate the revision under writer ownership and reuse the shared snapshot when it matches. Reload stored history when the revision is missing or changed, while preserving explicit history overrides.
- Resolve the selected rollout before loading context, validate compressed snapshots before materialization, and enforce archived-thread restrictions on canonical paths.
## Testing
Extend coverage for snapshot reuse and late-write refresh in legacy and paginated histories, compressed rollout reuse, archived rollout symlinks, and cold child restoration that includes edits made after preloading history.
GitOrigin-RevId: e1fd7aee6ef2b30f41951e6b7e6b01c3e1420cab
## Why
A stored history snapshot can become stale before a resumed thread acquires writer ownership. Resume must include writes committed before that acquisition.
## What changed
Make `ThreadStore::resume_thread` return the replay context and use it for session restoration and metadata initialization. The local store refreshes stored snapshots while holding writer ownership, reads through the installed writer to honor explicit rollout paths, and releases the writer if loading context fails. Explicit histories without a canonical session header retain their override semantics.
## Testing
Extend resume tests to cover edits made after the initial snapshot in both legacy and paginated history modes, stale SQLite rollout paths, and preservation of explicitly supplied history.
GitOrigin-RevId: 2361f524d324c859f5dfcf2863320e2045736c2e
## Why
Thread name resolution performs a separate SQLite metadata lookup for each thread. Batch these reads to reduce database queries for large result sets.
## What changed
Add `StateRuntime::get_threads` and use it in `resolve_thread_names`. Fetch metadata in batches of at most 999 IDs to stay within SQLite's bind limit, skipping missing or invalid records independently so valid metadata remains available.
## Testing
Add regression coverage for reads spanning multiple batches, invalid and missing records, duplicate IDs, and empty input.
GitOrigin-RevId: a403416f1da5adea56705c70839850760d3eb550
## Why
Updates that only change `updated_at` should not rewrite unrelated thread metadata or its indexes.
## What changed
Use `touch_thread_updated_at` for timestamp-only patches when the SQLite row exists and the rollout path is unchanged. Preserve the full update path for missing rows, changed rollout paths, and patches containing other metadata, including staged changes.
## Testing
Add regression coverage for legacy and paginated histories that verifies missing-row reconstruction, timestamp-only writes using SQLite triggers, preservation of other metadata, and application and removal of staged metadata.
GitOrigin-RevId: d5bc70d57e591e3eb8e9521f0c31a7ef75f244d3
## Why
Guardian needs the assistant's delivered question to interpret a user's reply. Messages sent through nested Code Mode tools must remain available as review context, and approvals based on earlier context must become stale when a new delivery is confirmed. Assistant messages do not themselves grant authorization.
## What changed
- Capture successful hosted User Messaging sends after input rewriting and before result callbacks or post-tool hooks.
- Retain bounded delivery text in acceptance order, persist it through cancellation and shutdown, and preserve it across compaction and resume with an older-client-compatible rollout encoding.
- Track assistant review context separately from user authorization, invalidating pending and cached approvals for both local and worker reviews when that context changes.
- Associate retained deliveries with the correct instruction or communication boundary during rollback.
## Testing
Add coverage for nested messaging review context, fast replies and communication ordering, shutdown persistence, stale local and worker approvals, rollout compatibility, and rollback retention.
GitOrigin-RevId: 1bc1ec9e8947560b99f4b39a42ddb9f2099f519b
## Why
Archived threads without previews were filtered out of thread listings, even though they had valid session metadata.
## What changed
- Include archived threads with empty previews in both SQLite and rollout-file listings.
- Add archive-specific indexes for creation, update, and recency ordering so these listings can use indexed pagination.
## Testing
Add regression coverage for paginated archive listings with and without SQLite, archive query plans that avoid temporary sorting, and metadata reads that preserve source and file timestamps for empty archived threads.
GitOrigin-RevId: e29d0257b2e029bea5fdf94eed6dab1006d2a8f2
## What changed
Allow `cursor` to accept an item anchor such as `{"type":"item","itemId":"item-123"}` with a non-empty `turnId`. Ascending pagination returns items after the anchor; descending pagination returns items before it. The anchor itself is excluded, and subsequent pages use the returned opaque string cursor.
Resolve anchors within the requested turn's visible history, including inherited fork history. Reject missing turn IDs and empty, unknown, or out-of-scope item IDs with invalid params (`-32602`). Preserve existing string and null cursor behavior, and update the protocol schemas, TypeScript and Python types, and API documentation.
## Testing
Add protocol round-trip and invalid-shape tests, app-server coverage for anchored pagination and errors, and thread-store coverage for growing turns, reverse pagination, page boundaries, fork visibility, and anchor scope validation.
GitOrigin-RevId: a74cea190d3ff1b44865429f8b0650b793eb688d
## What changed
- Make `LocalThreadStore` default to paginated history while retaining explicit legacy mode.
- Explicitly use paginated history for Guardian review sessions and allow in-memory stores to create paginated threads.
- Rename full-history resume, fork, and subagent helpers to identify them as legacy APIs, and document the paginated alternatives.
- Reject `thread/revert` for ephemeral threads and prevent the TUI from replaying or attaching to ephemeral agent threads.
## Testing
Add coverage for preserving the default and explicitly selected history modes and conversation context across restart, and for retaining context after rejected ephemeral reverts. Extend Guardian checkpoint coverage across both history modes and verify that saved reviews use paginated history.
GitOrigin-RevId: 870239eb3757018159ee4f230a009c97d38ac5b7
## Why
Ordinary user replies can depend on preceding assistant messages. Losing those messages during compaction can leave Guardian without the context needed to interpret a reply's scope.
## What changed
- Retain original assistant messages, including commentary, with their recorded order across checkpoints and resume. Exclude compaction output from this evidence.
- Include assistant context in local and delegated reviews as untrusted context, with separate storage limits and lower budget priority than user instructions.
- Prefer assistant context preceding ordinary replies when selecting bounded root evidence, and report unavailable context without inferring what a reply refers to.
- Preserve inherited context scope and remove assistant evidence beyond rollback boundaries, including during rollout migration.
## Testing
Extend coverage for compaction and resume, checkpoint migration, queued-input ordering and rollback, role labeling, and evidence budgets that preserve user restrictions while dropping assistant context.
GitOrigin-RevId: 886189b0be29ffc3d324b56f5d0b673d6b8d84da
## Why
Command execution analytics lack the observed sandbox backend. Older execution servers may omit this information, so an unknown backend must remain distinguishable from an explicitly unsandboxed process.
## What changed
- Carry optional `sandbox_type` metadata through command execution items and emit its metric tag as `sandbox_backend` in analytics.
- Propagate the observed backend through unified execution completion and failure events, including asynchronous exits.
- Preserve missing backend information as `None` and mark executed user shell commands as `Some(SandboxType::None)`.
- Exclude the metadata from serialized command items and generated schemas and TypeScript types.
## Testing
Extend tests for missing and explicit executor backends, backend propagation on failed execution, and analytics payloads, including platform-specific backend tags in app-server integration coverage.
GitOrigin-RevId: 178fe46824a6194910802ec02168ed40ee0b2019
## Why
Resuming a compacted thread should use the compaction and its newer records without depending on older turn contexts or restoring stale state from before the compaction.
## What changed
- Stop paginated model-context scans at the newest compaction with `replacement_history` and `window_number`. Fall back to full replay if the newest compaction lacks either field.
- Align reconstruction with that boundary and restore `last_started_turn_id`, previous turn settings, and the multi-agent version from compaction resume metadata. Allow newer completed turns to override the saved settings.
- Keep canonical session metadata alongside the bounded replay and use the same scan boundary for subagent rollout migration.
## Testing
Add coverage for cold resume after mid-turn compaction, bounded/full replay equivalence, missing companion state, settings precedence, and incomplete-compaction fallback.
GitOrigin-RevId: f836464bb5cadd9be4a4e05b5d1679223713fc87
## Why
Forked subagent startup serializes history persistence and spawn-edge writes. Cancellation during startup can also leave a provisional child behind.
## What changed
- Defer copied-history durability so it can run alongside spawn-edge persistence, while still awaiting both before submitting the child's initial input.
- Commit agent and residency reservations and notify clients only after initial input is accepted.
- Guard provisional children so cancellation or startup failure removes and shuts them down, discards their stored state, and closes their spawn edge after any pending edge write finishes.
## Testing
Add coverage for cancellation at the child-history durability barrier, checking child termination, removal, and edge closure. Extend fork-context tests in legacy and paginated history modes to verify inherited context can be read from storage after spawn acknowledgment without flushing the live child first.
GitOrigin-RevId: e02dda57efc32b7237bb7af0ce5e5844922890c3
## Why
Compaction companion records do not represent all resume state, including the last started turn and previous turn settings. The selected multi-agent runtime also needs a persisted value when no companion turn context is present.
## What changed
- Add optional `resume_metadata` to `CompactedItem`, recording the multi-agent version, last started turn ID, and previous turn settings. Preserve the distinction between absent metadata and explicitly empty values while retaining compatibility with older records.
- Capture this metadata under the settings persistence lock alongside the compaction checkpoint.
- Rewrite inherited metadata to use the child agent's runtime, and clear previous turn settings when the child must rebuild context.
- Clear pending continuation state before delivering acceptance of standalone settings updates, while holding the persistence lock.
## Testing
Add coverage for metadata round trips with empty values, legacy reader compatibility, checkpoint companion records, inherited fork metadata, and continuation invalidation while settings event delivery is blocked.
GitOrigin-RevId: f30b7feaa7e2fdb5b65fc3c53b37fd7a7fe27903
## Why
Guardian review threads use synthetic approval prompts as user messages. Deriving thread titles and previews from those prompts exposes large, unhelpful summaries in thread listings.
## What changed
- Default Guardian threads to the title "Guardian review" and preview "Approval review" across metadata creation, rollout reads, and resume.
- Skip synthetic user messages and goal updates when deriving Guardian display metadata, leaving `first_user_message` unset for new threads.
- Preserve custom names, including legacy indexed names, when listing, reading, resuming, and migrating threads to paginated history.
## Testing
Add regression coverage for compact metadata, resume without session metadata, custom names before and after migration, and app-server persistence, listing, and rename/resume behavior.
GitOrigin-RevId: 42aa707db20c3e57ffa5fd4c91ee313710be10d7
## Why
Injecting context before the first turn currently forces a full flush. Stores need a preparation checkpoint that can leave disposable context in memory, while local storage must keep prepared context durable before the first user input.
## What changed
- Add `PersistContext::ThreadPreparation` and `CodexThread::checkpoint_preparation()`, and use the checkpoint in `inject_response_items()`.
- Allow stores to defer rollout-derived metadata writes through `record_thread_metadata()`, including during preparation and execution checkpoints. Keep standard metadata updates synchronous.
- Flush local storage at preparation checkpoints so injected context survives restart.
## Testing
Add tests showing that preparation and first sampling can proceed without waiting for durable metadata. Cover prepared context in first and follow-up requests, plus durability before first input and restoration after restart, in both legacy and paginated history modes.
GitOrigin-RevId: 74f6bb1a5f8d47192364b8bba6afd703a3b7d688
## What changed
- Persist producer-recorded item start and completion times in thread history, preserving existing non-null values on updates.
- Return nullable `startedAtMs` and `completedAtMs` Unix millisecond timestamps from `thread/items/list`, and update the generated schemas and TypeScript and Python types.
- Leave timestamps unknown for existing rows and older writers.
## Testing
Add coverage for exact timestamp persistence, protocol round trips with present and missing timestamps, paginated item responses, and compatibility with older database writers.
GitOrigin-RevId: 894853481085782ff54db1704799e41446d15e51
## What changed
- Capture optional `creator_user_id` and `creator_account_id` from authentication when creating a thread, including forks.
- Carry these fields through thread storage, rollout metadata, and a SQLite migration. Leave them absent when unavailable or when reading older threads.
- Preserve recorded creator values across resume and metadata updates. On revert, recover missing rollout values from SQLite before writing replacement metadata.
## Testing
Add coverage for ChatGPT and API-key sessions, resume under another account, forks using current authentication, metadata extraction and upserts, and repeated reverts after creator fields are removed from a rollout.
GitOrigin-RevId: 9839fa42f9392f12226002e2c27d05d5656f5695
## Why
Row derives and migration embedding do not need query macros or a host SQLite driver.
## What changed
- Remove the `macros` feature from `sqlx` and depend directly on `sqlx-macros` with only `derive` and `migrate` enabled.
- Update state and thread-store derives and migration embedding to use `sqlx_macros`.
- Enable `sqlx-sqlite`'s `offline` feature directly to preserve query-description support in the target driver.
- Pin `sqlx`, `sqlx-macros`, and `sqlx-sqlite` to `=0.9.0` to keep their versions aligned.
GitOrigin-RevId: 8a8ef691ff2862a7dad978a578c5206b52dfc0b6
## Why
Permanent thread deletion needs to remove persisted agent message board data even when the message board feature has been disabled.
## What changed
- Add a cleanup hook for single and batch thread deletion, invoked after reference and writer checks but before rollout removal so cleanup failures remain retryable.
- Remove the deleted roots' channels, posts, and subscriptions regardless of the current feature setting.
- Record board tombstones and check them within write transactions to prevent delayed writes from recreating deleted data.
## Testing
Add an app-server regression test that creates a board, archives its root thread, restarts with the feature disabled, and verifies that permanent deletion removes the persisted channels, posts, and subscriptions.
GitOrigin-RevId: 4ea71559a8df0814dffda23a056a9bbaf6e0a0cb
## Why
Compression metrics do not distinguish startup runs from runs requested through
`rollout/compress`, making their outcomes indistinguishable by entry point.
## What changed
Pass `RolloutCompressionTrigger` from startup and RPC callers through the
compression worker. Add a `trigger` tag with `startup` or `rpc` to run, file,
scan-error, and temporary-file cleanup metrics, including durations, byte counts,
and compression ratios.
GitOrigin-RevId: f23d9da791b666a7311f2323f6bead6570067798
## Why
Clients need widget presentation details to render MCP Apps without waiting for the full MCP catalog, including when replaying saved history.
## What changed
- Add `mcpToolCall.mcpAppUi` with the invoked descriptor's `resourceUri` and `preferredModelDisplayMode`, and carry it through tool-call events and saved history.
- Support `fullscreen` and default to `inline` when the display preference is missing or unsupported.
- Keep existing resource URI fields for compatibility. Leave `mcpAppUi` null for older history and tools that declare widgets only in result metadata, where clients still use catalog discovery.
- Update protocol schemas, TypeScript and Python types, and app-server documentation.
## Testing
Add parameterized integration coverage for fullscreen, missing and unsupported preferences, legacy URI metadata, and result-only widgets, verifying consistent tool events and preservation across session resume.
GitOrigin-RevId: 2a9bed804dcea8c2b4903b8406fa6710681f7f5e
## What changed
- Accept `fileId` alongside the existing `url` form for app-server image inputs, and forward file references to the Responses API as `file_id`. Update generated schemas and client types.
- Preserve file references, image detail hints, and mixed inline/file image ordering through user-message events, thread history, and rollout migration. Retain file images when truncating tool output.
- Pass file references through image preparation without resolving them, while keeping resize-notice numbering correct. Omit them from unsupported TUI display and Guardian image context.
- Reject image-edit requests whose recent-image window includes a file reference, preventing selection of an older inline image instead.
## Testing
Add coverage for serialization, request and rollout preservation, mixed-image history ordering, incomplete ordering metadata, tool-output truncation, and rejection of unsupported image-edit selections.
GitOrigin-RevId: 6ca20a8577155cc934b720803c3b7b3bffdf972a
## What changed
Copy the source thread's current attachments when creating a non-ephemeral fork, including forks at an earlier turn. Copies receive new attachment IDs and creation timestamps while preserving resource identities and payloads. Attachment membership can then change independently on either thread; referenced resources are not copied.
Await the atomic copy before publishing the fork. If copying fails, log the error and allow the conversation fork to succeed without attachments. Resuming a fork does not copy attachments again.
Document that clients should use `forkedFromId` on `thread/started` and fetch the fork's attachments with `thread/attachment/list`; copying does not emit per-attachment updates.
## Testing
Add coverage for atomic rollback, independent attachment membership, inheritance across history cutoffs, successful conversation forks after copy failures, and resuming without restoring removed attachments.
GitOrigin-RevId: 939d2c6a3073ccfcd922380c6beda45d3deac606
## What changed
Represent images in `ContentItem` and `FunctionCallOutputContentItem` with `ImageReference::Inline`, flattened to preserve the existing `image_url` wire format. Update image producers and consumers and regenerate app-server schemas and SDK artifacts.
Preserve the Python SDK's `InputImageContentItem` and `InputImageFunctionCallOutputContentItem` class names during generation.
## Testing
Add a regression test for stable Python image class names and adapt existing image tests to the shared representation.
GitOrigin-RevId: c38a780ac3314c2ac2deb3afc1b93b94b6f93fec
## What changed
Add experimental `thread/start.daybreakEnabled` so clients can set the initial preference for persistent threads. Omitted or null values leave it unset; explicit values are rejected for ephemeral threads.
Return the choice in the start response, `thread/started`, and reads before persistence. Stage it with the initial thread metadata and save it when the thread is persisted. Later changes still use `thread/metadata/update`. The preference does not select `turn/start.cyberAccessProgram` or grant access.
## Testing
Add coverage for true, false, and unset values in responses, notifications, reads, and reads after persistence and restart, plus rejection for ephemeral threads. Update existing metadata and access-program tests to exercise threads with an initial preference.
GitOrigin-RevId: 3bff3dc55a18436067bc2a3f156f5abf52d7321b
## Why
Persisting user input received during an active turn currently blocks the next model request. Stores that support background persistence can overlap this checkpoint with inference.
## What changed
- Add `PersistContext::SteeredUserInput` and `allows_background_persistence()` so stores may enqueue these checkpoints, with durability and error reporting enforced by later flush or shutdown operations.
- Use the new context for accepted steered user input and apply the same metadata handling as turn-start persistence.
- Keep tool outputs synchronous, including in mixed input batches, and allow stores to retain synchronous persistence for all contexts.
## Testing
Add gated-store integration tests covering background user-input persistence, synchronous stores, and synchronous tool-output checkpoints. Verify that the next request includes the steered input and waits for persistence when required.
GitOrigin-RevId: c60b7b6c9b483245fd3169306bcf0de248ccdf35
## Why
Session initialization can be cancelled after a persistence writer is installed but before acquisition returns. Cleanup must wait for acquisition to finish so it can discard the writer.
## What changed
Extend `LiveThreadInitGuard` to own in-flight acquisition and finish it before discarding persistence, including when the guard is dropped. Use the guard for thread creation, resume, and inherited model context initialization.
## Testing
Add a regression test that cancels acquisition after writer installation, verifies cleanup waits for handoff, and confirms the writer is removed afterward.
GitOrigin-RevId: 09041fa5cd675d082a86a4cc8a719c572afe11a8