Skip to content

fix(sessions)!: defer Codex import, search newest day first - #2441

Merged
ScriptedAlchemy merged 26 commits into
masterfrom
cursor/codex-catchup-walk-335c
Sep 29, 2026
Merged

ScriptedAlchemy merged 26 commits into
masterfrom
cursor/codex-catchup-walk-335c

Conversation

@ScriptedAlchemy

@ScriptedAlchemy ScriptedAlchemy commented Sep 28, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • sessions import hands historical catch-up to the refresh workers and returns a typed partial receipt: one deferred unit per store scope. It never reports completed for work it has not done, and it no longer ends as timed_out while the daemon keeps admitting. Blocked or missing workers stay failures.
  • A project Codex pass yields only at a day directory that opens out of project after it has persisted in-scope frames from a newly opened rollout. The newest day publishes first. Mixed days, all-in-scope histories, and live tails keep the pass going.
  • An empty search during historical convergence answers stale, not complete_zero/fresh (sessions: message search reports complete_zero/fresh during catch-up #2512).
  • Removed the deleted waiter's leftover progress counters, sequence counters, and projection probe.

Review changes in this round

  • 4179085161 raised the import hand-off test bound from 1s to 10s. I replaced the wall-clock bound entirely. The fixture runs no worker loop, so an import that waited for its pass could only end at the 60s deadline as timed_out. The tests now assert the literal partial termination and that the history wake is still queued.
  • d09b67592c (CI Windows target) is already on master, so it adds nothing to the net diff.
  • a846b169f9 (sessions: message search reports complete_zero/fresh during catch-up #2512) now has a deterministic test, session_retrieval::tests::empty_answer_is_stale_until_historical_catch_up_is_current. The same empty store answers CompleteZero behind a Current serving port and Stale behind historical convergence. With a846b169f9's admitted.rs hunk reverted, it fails with CompleteZero { ..watermarks all 0.., freshness: Fresh }, the exact sessions: message search reports complete_zero/fresh during catch-up #2512 answer.
  • core_cli_suite::tool_surface_transport_test::application_surface_primitive_tools_resolve_the_working_directory_project called source_outline right after init. init returns before the code graph serves; master loses this race too. Measured init-to-served: master 0.44s, 0.12s, 0.11s, with the first call unavailable in run 1; this branch 0.32s, 0.29s, 0.28s. Master's fix(daemon): serve cold-daemon reads once their owner is ready #2612 fixed the same race independently with await_graph_ready, and this branch takes that version.

Evidence (local; debug CLI; isolated HOME and XDG dirs; one daemon capped with systemd-run --user --scope -p MemoryMax=6G)

9000 synthetic Codex rollouts over 90 days, newest day in the project, current head:

  • sessions import: exit 0 after 0.15s, session import scheduled (...); historical catch-up has remaining work 2
  • first search: no messages matched ... (status: stale ...)
  • first newest-day hit: 13.16s after import (master 2150c91ed8: import exit 1 after 35.6s, first hit 402.6s)
  • second import: exit 0 after 0.14s (master: exit 1 after 35.5s)

On a 3000-rollout corpus where the project is interleaved within each day, the previous round measured 1510 raw messages by about 610s. Master reached 853 in the same time with no search hit.

Tests that fail on master (with only the test code applied) and pass here:

  • the 3 session_sync::import_admission_tests
  • newest_day_messages_are_durable_before_older_days_are_opened
  • a_mixed_day_is_admitted_in_one_pass_before_older_days_are_opened
  • session_import_accepts_deferred_catch_up_without_treating_it_as_failure
  • empty_answer_is_stale_until_historical_catch_up_is_current, shown to fail without the fix

Suites on the merged head:

  • sessions lib 566/566, session-runtime lib 128/128, cli bin 347/347
  • session_suite 440/440, transcript_ingest_suite 193/193, full mcp_suite 607/607
  • application lib 482/482, application_suite 66/66, core_cli_suite 167/167
  • After the final master merge: sessions lib 566/566, session-runtime lib 128/128, core_cli_suite 169/169, session-filtered mcp_suite 29/29 and session_suite 108/108.
  • cargo clippy -D warnings (sessions, session-runtime, cli, tracedecay with test features) passes, and cargo fmt --check passes.

Fixes #2512
Fixes #2390

BREAKING CHANGE: sessions import schedules historical catch-up and finishes as partial coverage with one deferred unit per store scope; it no longer waits for the pass or reports completed/timed_out. An empty session search during historical convergence answers stale instead of complete_zero.

@changeset-bot

changeset-bot Bot commented Sep 28, 2026 •

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 7dd58c5

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@cursor
cursor Bot force-pushed the cursor/codex-catchup-walk-335c branch from 4d14e35 to b812d26 Compare September 28, 2026 08:49
@ScriptedAlchemy
ScriptedAlchemy marked this pull request as ready for review September 28, 2026 08:56
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, add credits to your account and enable them for code reviews in your settings.

ScriptedAlchemy and others added 3 commits September 28, 2026 09:30
Shared catch-up charged every rollout file as directory work and then
shrank that walk to the JSONL parse-slot count, so a large Codex home
listed older days for minutes before emitting any session.

Co-authored-by: Zack Jackson <ScriptedAlchemy@users.noreply.github.com>
sessions import waited for the historical cycle it had just queued.
On a large Codex home that cycle does not finish inside the existing
deadline, so the command exited timed out while admission was still
moving.

BREAKING CHANGE: A transcript import whose catch-up is still pending
finishes as partial coverage with remaining work, instead of timed_out.
Git sync still requires its own pass to finish.

Co-authored-by: Zack Jackson <ScriptedAlchemy@users.noreply.github.com>
The project Codex pass wrote a coverage cursor for every out-of-scope
rollout before it returned, so projection could not activate the newest
day until that sweep finished. Yield once an in-scope window is admitted,
and finish its projection backlog before the next history window.

Co-authored-by: Zack Jackson <ScriptedAlchemy@users.noreply.github.com>
@cursor
cursor Bot force-pushed the cursor/codex-catchup-walk-335c branch from b812d26 to 283b48e Compare September 28, 2026 09:31
ScriptedAlchemy and others added 3 commits September 28, 2026 09:48
A newest-day yield is retryable backpressure. The worker treated that as
a no-progress backoff and opened the older-day sweep after one projection
slice, leaving the newest day on a building generation.

Co-authored-by: Zack Jackson <ScriptedAlchemy@users.noreply.github.com>
Codex catch-up persists observations without ingest counters, so the
yield is a no-progress backoff. Publish the projection backlog before
that backoff opens the older-day sweep.

Co-authored-by: Zack Jackson <ScriptedAlchemy@users.noreply.github.com>
A history wake that arrives during the newest-day window was starting
the older-day sweep on the next pass. While that window is unpublished,
ignore the wake and keep projecting.

Co-authored-by: Zack Jackson <ScriptedAlchemy@users.noreply.github.com>
@cursor cursor Bot changed the title fix(sessions)!: return deferred Codex import while catch-up continues fix(sessions)!: deferred Codex import, newest day searchable first Sep 28, 2026
An import read the worker's serving state before its wake, so a
converged profile reported `completed` with no remaining work while
rollouts written since the last pass were still unadmitted. Scheduling
now marks history pending first and every hand-off is partial with one
deferred unit per store; blocked or missing workers stay failures.

A project Codex pass that persisted in-scope frames now yields at the
next day directory instead of at the next out-of-scope rollout. On an
interleaved corpus the old rule ended nearly every pass after a few
rollouts. Removes the waiter's leftover progress counters, history
sequence, and membership pre-read.
A per-day yield ended every pass of a project whose history is all in
scope, so the discovery frontier never committed and each pass re-read
the days before it. The pass now yields only at a day directory that
opens with an out-of-project rollout after in-scope frames persisted;
mixed days and in-scope days stay in one pass.
The history pass yields after in-scope frames persist so that a newest-first page does not cursor every older out-of-scope day before the admitted window is searchable. Any persisted frames set persisted_day, including appends to a rollout that was already cursored. With an active Codex session writing to today's rollout between passes, every pass ended at the first older out-of-scope day with the frontier uncommittable, so the hub redelivered the same page and older in-scope days were never reached.

Only a rollout opened for the first time this pass now arms the yield. A resumed tail already has its earlier window projected, so its appends no longer end the pass.
A 1s wall-clock bound on the import settling is a real-time assertion that a 4-vCPU CI runner under load can miss. 10s still proves the request returned the settled catch-up instead of consuming its 60s deadline.
A deferred import can expose a locally fresh but empty projection while its historical worker still has sources to ingest. Treat that zero as stale until catch-up settles, and keep an end-to-end assertion on the first empty search response.
@ScriptedAlchemy ScriptedAlchemy changed the title fix(sessions)!: deferred Codex import, newest day searchable first fix(sessions)!: defer Codex import, search newest day first Sep 29, 2026
…s-sessions-2441

# Conflicts:
#	crates/tracedecay-cli/tests/core_cli_suite/tool_surface_transport_test.rs
@ScriptedAlchemy
ScriptedAlchemy merged commit e786590 into master Sep 29, 2026
5 of 7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant