Skip to content

feat(sessions): report history catch-up progress counters in status - #4382

Open
devin-ai-integration[bot] wants to merge 10 commits into
masterfrom
devin/1792524754-history-catch-up-progress
Open

devin-ai-integration[bot] wants to merge 10 commits into
masterfrom
devin/1792524754-history-catch-up-progress

Conversation

@devin-ai-integration

@devin-ai-integration devin-ai-integration Bot commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #4329

Summary

  • tracedecay_status → session_history_catch_up.progress now reports the daemon's own catch-up pass history. That covers per-provider units_projected / units_refused / units_parked / messages_upserted, the total passes, consecutive passes_without_progress, last_progress_at_unix_micros, and a typed state (awaiting_first_pass | advancing | stalled).
  • A backlog reads as stalled after SESSION_HISTORY_STALLED_PASSES (3) consecutive passes that leave work behind and commit nothing. A pass that commits work or completes the backlog resets the count, so a slow backlog stays advancing.

Motivation

#4279 (requested follow-up): status showed pending transcripts/bytes but nothing about progress over time, so an operator could not tell a slow backlog from a stalled one. The issue's acceptance asks for the values to come from the daemon-owned authority, not private DB reads. These counters are folded by the project's session refresh worker, which is the process that runs the historical passes. Status reads them through the same SessionProjectionServingStatus it already uses for session_projection.

Changes

  • tracedecay-sessions
    • ProviderRunFold::record(provider, outcome) and the new park(provider) keep a ProviderPassUnits tally for each provider. A unit is one provider run in a pass. A run that finishes within its grant with no failure counts as projected. A run with a failure counts as refused. A run deferred at its byte grant counts as parked, and so does an admitted provider that the pass byte budget never reached.
    • Both the project and profile catch-up passes now carry provider_units through IngestPassOutcome and TranscriptIngestOutcome.
    • serving.rs: new SessionHistoryCatchUpProgress (with record_pass and state()), SessionHistoryProgressState and SESSION_HISTORY_STALLED_PASSES, plus a history field on SessionProjectionServingStatus.
  • tracedecay-session-runtime
    • SessionHistoricalIngestor::run_pass now returns SessionHistoricalPass { outcome, provider_units }. From<SessionHistoricalIngestOutcome> keeps the test fakes one .into() away.
    • The worker folds only passes the ingestor actually ran into its telemetry (record_history_pass). Admission-saturated passes, missing-ingestor passes and cancelled passes are not counted.
  • tracedecay-mcp status.rs: historical_session_catch_up attaches progress, including when the backlog measurement fails. session_history_catch_up is an untyped Value in ProjectStatusV1, so the generated contracts are unchanged.

Test plan

Red → green: I removed the worker's record_history_pass call and ran the new worker test through Bazel. It failed with the worker must record both history passes, saw SessionHistoryCatchUpProgress { passes: 0, ... }. With the call restored, the test passes.

  • bazel test //crates/tracedecay-session-runtime:unit_test --test_arg=session_temporal_refresh_scheduler::worker_tests::the_worker_reports_provider_units_summed_over_its_history_passes --test_arg=--exact → PASSED, 1 passed. This test drives the real run_session_temporal_refresh_scheduler over a registered global-db harness. Under plain cargo, worker tests that use this harness fail on master with "requires an Asupersync runtime", so Bazel is the acceptance here.
  • scripts/require-exact-test.sh cargo test -p tracedecay-sessions --lib orchestration::tests::fold_tallies_each_provider_disposition_separately -- --exact → 1 passed
  • scripts/require-exact-test.sh cargo test -p tracedecay-mcp --features test-helpers,test-transport,tracedecay-daemon-service/test-helpers --lib handlers::info::status::tests::historical_progress_separates_a_slow_backlog_from_a_stalled_one -- --exact → 1 passed
  • crates/tracedecay/tests/transcript_ingest_suite/session_ingest.rs::bounded_project_catch_up_pass_persists_the_rotation_frontier now also asserts that a real bounded project pass reports codex: units_projected=1, messages_upserted=2.
  • cargo fmt --all -- --check → clean
  • cargo clippy -p tracedecay-sessions -p tracedecay-session-runtime --all-targets -- -D warnings → clean
  • cargo clippy -p tracedecay-mcp --all-targets --features test-helpers,test-transport,tracedecay-daemon-service/test-helpers -- -D warnings → clean
  • cargo clippy -p tracedecay --features test-helpers --test session_suite --test transcript_ingest_suite -- -D warnings → clean
  • No Cargo.toml changes, so the BUILD files are not regenerated.

Checklist

  • CHANGELOG.md updated: release-please generates it from the feat commit
  • No secrets, credentials, or .env files included
  • Breaking changes documented: none on the wire. progress is additive inside an untyped status section.

Link to Devin session: https://app.devin.ai/sessions/53e64e1b1cd949588eb16fe916500914
Open in Devin Desktop: https://app.devin.ai/desktop/session/53e64e1b1cd949588eb16fe916500914?variant=devin
Requested by: @ScriptedAlchemy


Devin Review

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

I'll fix CI failures and address comments from users with write access. I'll skip comments containing "(aside)".

  • Disable automatic comment, CI, and merge conflict monitoring

@changeset-bot

changeset-bot Bot commented Oct 20, 2026 •

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 9b90542

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

devin-ai-integration[bot]

This comment was marked as resolved.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
devin-ai-integration[bot]

This comment was marked as resolved.

@ScriptedAlchemy ScriptedAlchemy left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Cross-referenced #4329 and pushed ba4a485 to preserve progress from the final successful historical-ingest pass.

The scheduling classification collapses a completed pass to Complete, whose made_progress() is false. Consequently, an import that committed all messages in one pass could report messages ingested but no last-progress timestamp; the final successful pass of a larger import also failed to advance that timestamp.

The fix captures actual ingest progress before classification and carries it in the existing pass result into worker telemetry. Recording at that boundary also removes the redundant optional provider-map tuple. A new regression covers a nonempty completed pass followed by an idle completed pass, asserting that only real progress sets/advances the timestamp; the existing worker aggregation fixture now supplies the explicit progress field.

Validation:

  • Pinned nightly rustfmt and git diff --check passed on all four changed files.
  • All pass literals and telemetry call sites were checked.
  • The published tree matches the locally reviewed tree.
  • Native execution is not complete. The focused Bazel target failed while compiling the 4,982-file asupersync dependency (process_wrapper / Rustc exit 1), before executing any tests. The 8 GiB environment was under memory pressure and its cgroup reported an OOM kill; the compiler output did not identify the underlying termination. Bazel reported Executed 0 out of 1 test: 1 fails to build.

The new completed_history_records_committed_progress_but_idle_passes_do_not regression and existing worker aggregation test still need execution in CI. No passing native test result is claimed.

@ScriptedAlchemy ScriptedAlchemy left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

The current-head Linux fleet job was interrupted while building test binaries: the runner reported a shutdown signal, a connection reset, and cancellation. Its test-execution step was skipped. The Linux aggregator then failed because that job did not succeed.

Repository gates, Dashboard, benchmark self-tests, feature gates, and the shipped CLI build passed. Clippy is still running. I attempted to retry only the interrupted fleet job; GitHub rejected the request with The workflow run containing this job is already running. Once that active run finishes, the interrupted job needs a retry. This run does not provide a failing behavioral assertion against the progress-counter change.

This branch has not been deployed

No deployments
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.

Report session-history catch-up progress counters in status

1 participant