## Why
A malformed or discontinuous rollout record can otherwise block later valid
thread history from being materialized in SQLite.
## What changed
- Skip malformed JSON, unknown records, missing or regressed ordinals, ordinal
gaps, and invalid timestamps while advancing the projection checkpoint.
- Keep unknown-record ordinals available for a subsequent valid retry.
- Record projection outcomes and anomaly kinds with OpenTelemetry counters.
## Testing
- Cover malformed lines, missing, duplicate, and forward-gap ordinals, and valid
retries after unknown records.
GitOrigin-RevId: 9ae616b44513e35a1fa209e54f05f0612abcbd86
## Why
Rollout compression skips files that participate in paginated fork lineages because lineage readers rely on byte offsets into the original JSONL. This prevents shared rollout history from being compressed.
## What changed
- Add a seekable rollout reader that preserves logical JSONL offsets for plain and zstd-compressed files without materializing compressed data beside the rollout.
- Use the reader for lineage validation, model-context replay, and SQLite history projection, including when compression races with a read.
- Add the opt-in `local_thread_store_shared_compression` feature. The default mode continues to leave shared lineages uncompressed for compatibility, while the new mode includes referenced sources and fork pointers.
- Record the uncompressed size in new zstd frames so common prefix-bound checks can avoid decoding the full file.
## Testing
Add coverage for seekable compressed reads, prefix validation across zstd frame shapes, compressed lineage replay and projection, concurrent forks, and compression-mode behavior.
GitOrigin-RevId: 83e519f7eabf7448977eff37c55899858cc17a07
## Why
Clients need a bounded view of realtime conversations that preserves the order of speech, agent work, and turn lifecycle events without loading the full thread history.
## What changed
- Persist realtime session boundaries, transcript segments, and promoted agent items in paginated thread rollouts.
- Add the experimental `thread/timeline/list` API to page ordinary items, realtime items, and turn boundaries in canonical rollout order. Include `activeRealtimeSessionAtPageStart` so each page can be rendered independently.
- Emit typed `thread/realtime/item/started`, `thread/realtime/item/transcript/delta`, and `thread/realtime/item/completed` notifications around durable realtime items.
- Keep the existing `thread/items/list` response and legacy thread history behavior unchanged.
## Testing
- Cover mixed timeline pagination, realtime-session state at page boundaries, rollout replay, subagent history prefixes, transcript streaming, steering, and promoted agent artifacts.
GitOrigin-RevId: faa2c420192d63e060e8fb32446e3c797422656e
## Why
Serde's generic buffering for flattened and internally tagged fields is incompatible with `serde_json`'s `arbitrary_precision` representation. As a result, persisted rollout items containing nested floating-point values can fail to decode.
## What changed
- Decode the rollout envelope at the JSON persistence boundary before deserializing the item payload.
- Use the shared decoder for both session resume and thread-history projection.
- Cover token-count floats, response-item metadata, field ordering, and ignored metadata in the decoder compatibility test.
GitOrigin-RevId: 59c7f6fbcf83162b5ed6980a69381fe45fc20a0a
## What changed
- Add `codex-history` for model-history and persisted-rollout domain types, including `RolloutItem`, `RolloutLine`, `CompactedItem`, and initial/resumed history state.
- Re-export the persisted types from `codex-rollout` and update consumers to use the new crate boundary instead of `codex-protocol`.
- Preserve existing rollout serialization, including legacy numeric compacted-window IDs.
## Testing
- Add `codex-history` tests for rollout JSON round trips, compacted-history compatibility, persisted history modes, and multi-agent version selection.
GitOrigin-RevId: 944daa9297ddd231d3aebbdcb05fff4adf8b4e1b
## Why
A failed rollout append can leave a rejected line before a valid same-ordinal
retry. Advancing the byte checkpoint past that line without also advancing the
ordinal checkpoint can prevent subsequent history from being projected.
## What changed
- Defer rejected and unknown rollout lines until a later valid ordinal shows
whether they were replaced by a retry or consumed an ordinal.
- Advance skipped ordinal ranges together with the durable byte checkpoint,
while rejecting gaps that cannot be explained by rejected lines.
- Prefer item event timestamps and parse the rollout timestamp only when an
item needs it as a fallback.
## Testing
Added coverage for same-ordinal retries, inferred ordinal gaps, unknown and
malformed records, invalid fallback timestamps, and unexplained gaps.
GitOrigin-RevId: 374beda316c605d562bd9526abed19916598d69f
## Why
Paginated thread history could reject valid rollout records when rate-limit
percentages were encoded as floating-point JSON values, preventing later final
answers from being projected.
## What changed
Deserialize each rollout line through `serde_json::Value` before converting it
to `RolloutLine`, preserving floating-point rate-limit values during history
materialization.
## Testing
Added coverage for projecting fractional, integral, very small, and large
floating-point rate-limit percentages across both catch-up materialization and
subsequent history appends.
GitOrigin-RevId: 68da907987ffe59f4a3033ef90f3b88c39734cb1
## Why
Local thread stores without an initialized state database should not implicitly
create SQLite files or partially delete threads that have materialized history.
## What changed
- Report paginated history listing as unsupported when no state database is
available, and skip history projection and materialization in that mode.
- Reject paginated forks without a state database.
- Validate access to materialized history before deleting rollout files, so a
failed deletion preserves both the rollout and its history rows.
## Testing
Added coverage that a store without a state database creates no SQLite files
and preserves materialized history when deletion is unsupported. Existing
projection tests now initialize the state runtime explicitly.
GitOrigin-RevId: 2eaa0f5f0de8d5e4d84375ec50b310746a0ee68e
## Why
`thread/fork` rejected threads using paginated history, so they could not use the same fork workflow as legacy threads.
## What changed
- Create paginated forks by referencing a frozen source-history prefix while persisting only child-owned records in the new rollout.
- Support latest, `lastTurnId`, and `beforeTurnId` boundaries, including inherited lineage, model-context reconstruction, interruption markers, and approval-reviewer inheritance.
- Make paginated reads and occurrence search traverse referenced history while excluding source records added after the fork.
- Coordinate fork preparation with archive and delete operations, and materialize compressed rollouts before they become fork references.
## Testing
Added app-server and thread-store coverage for boundary selection, active turns, inherited reads and search, compressed lineage, and concurrent source lifecycle operations.
GitOrigin-RevId: 66052d69517d7fb97a3b7817ab77a39c5ad995fd
## What changed
- Store the starting byte offset and terminal ordinal and byte offset for each turn projected into SQLite.
- Advance offsets across blank and rejected physical lines while leaving incomplete trailing lines for the next materialization pass.
- Stop later rollout records from changing a turn after it reaches a terminal state.
## Testing
- Cover active and completed turn positions, trailing partial lines, skipped invalid lines, subagent history prefixes, and records received after terminal state.
GitOrigin-RevId: a7da2f0b00c0bf47b841db874c79a0d495c18acd
## What changed
- Inherit paginated history mode when spawning or forking a subagent from a paginated parent.
- Load the parent's model context when forking and persist it as an inherited rollout prefix, while excluding that prefix from the child's projected turns, items, and metadata.
- Record the boundary between inherited context and child history, and reject partially initialized paginated subagent rollouts on resume.
- Resume paginated subagents from their stored model context instead of legacy rollout history.
## Testing
Added coverage for fresh and forked paginated subagents, compacted-history forks, model-context resume, inherited-prefix projection, metadata isolation, and incomplete-prefix detection.
GitOrigin-RevId: e57dc37c29aa4aaaf57b052b991be591d730e5ba
## Why
Thread history JSONL is the durable source of truth, while SQLite is a rebuildable view. If a SQLite projection fails after a durable append, the next write must catch up the unprojected suffix instead of skipping it.
## What changed
- Start materialization at the byte offset stored in `thread_history_projection_state`.
- Project only complete newline-terminated rollout records, leaving a trailing partial record for a later pass.
- Preserve validation for missing files, invalid offsets, and missing or out-of-order ordinals without advancing projection state.
## Testing
Add coverage for catching up after projection failure, avoiding replay when already synchronized, retaining partial lines, and rejecting invalid suffixes without changing SQLite state.
GitOrigin-RevId: 8a7200a77edd5411ddf5fe31ab6af5ee287ed7d7
## What changed
- Project durable paginated rollout records into rebuildable SQLite tables for turns, items, and projection progress while keeping JSONL as the source of truth.
- Add cursor-based local reads for turn summaries and thread or per-turn items, including archived-thread and history-mode validation.
- Serialize writes, shutdown, and deletion per thread so projection updates cannot race cleanup, and remove projected rows when a thread is deleted.
- Preserve stable item ordering while updating repeated snapshots and expose structured turn error details.
## Testing
- Cover projection, snapshot updates, summary recovery, pagination, failure handling, shutdown flushing, legacy-mode rejection, and deletion races.
GitOrigin-RevId: 34533185ece7f1f5690004c7f12b0f1f34dc2640