perf(orchestration): avoid full history loads in runtime paths - #5080
perf(orchestration): avoid full history loads in runtime paths#5080tarik02 wants to merge 200 commits into
Conversation
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
ApprovabilityVerdict: Needs human review This PR changes how projection data is loaded throughout the orchestration system, switching from full history loads to bounded/targeted queries. While designed as a performance optimization, this fundamentally changes what data is available at runtime in core orchestration paths, warranting careful human review. You can customize Macroscope's approvability policy. Learn more. |
a543fd4 to
378615b
Compare
Co-authored-by: codex <codex@users.noreply.github.com>
- Initialize provider as unchecked in a pending state - Update initial probe message to reflect session-local status
- Type the runtime effect with `Scope` - Build the ACP session runtime without wrapping it in `Effect.scoped`
- Use strict TurnId and ProviderItemId parsing in Codex session routing - Decode in-memory stdio chunks in streaming mode to avoid split UTF-8 corruption
- Transfer session-owned scopes into adapter state - Ensure runtime scopes close on stop and startup failure - Add regression coverage for scoped lifecycle cleanup
- Close the managed native event logger when the adapter layer tears down - Make session runtime close idempotent with an atomic closed flag - Add coverage for flushing thread native logs on shutdown
- Use codex app-server snapshots for auth, models, and skills - Remove legacy CLI/config discovery paths and related helpers - Update tests for the new provider status flow
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
- Document the target orchestration graph, IDs, lifecycles, and capability model - Add Codex app-server probe fixtures and update the probe test harness
- Introduce orchestration v2 service interfaces and error types - Add replay runtime, fixtures, and integration coverage - Update shared contracts and probe transcripts Co-authored-by: codex <codex@users.noreply.github.com>
- Add Codex adapter and replay harness wiring - Introduce in-memory orchestration projections and provider registry - Expand orchestration contracts for turn and runtime events
Co-authored-by: codex <codex@users.noreply.github.com>
- Add context transfer IDs, schemas, and projections - Support cheap fork creation and Codex native fork rollback - Cover fork idempotency and replay behavior in tests
- Track remaining projection, context transfer, rollback, capability, and subagent work - Clarify current V2 baseline and debugger-only follow-ups
- Map fork and merge-back turns into stored handoffs and transfer resolutions - Add shell snapshot projection support plus coverage tests - Update replay fixtures and web contracts for the new turn flow
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
… compaction (#4971) Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
- Disable LegendList end-maintenance that could snap after user scrolling - Cancel stale imperative scrolls and release settled turn anchors - Stabilize handoff run data to avoid per-event timeline rerenders
…elay Live profiling of the built app (debugger pause inside the hot sqlite call) showed AgentAwarenessRelay.publishThread grinding at ~8 full shell snapshots per second after boot. Two causes: - streamDomainEvents was eventSink.stream() with no cursor, which replays every stored event from genesis before going live — so each boot fed the relay the entire event history as fresh activity, and it queued a publish per activity-relevant event for hours. It now tails from the current high-water mark; the relay's startup snapshot publish already covers initial state, and the sink subscribes before reading the cursor so no live event is lost. - publishThreadUnsafe materialized the full shell snapshot to find one thread; it now uses getThreadShell (archived/deleted map to the tombstone path exactly as the active-list lookup did). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
A renderer performance trace showed the minimap strips as a standing source of main-thread frame work: each strip transitioned background-color (paint) and width (layout), and both fire constantly — scrolling or streaming flips a band of in-view states at once, and the hover fisheye animates several widths at a time — so any interaction kept a 60fps style/layout/paint pipeline running. The strip now animates only compositor-friendly properties: width tiers are scale-x on a fixed-width box, and the in-view highlight is a bright overlay faded with opacity. The scroll handler also skips no-op data-in-view attribute writes, which previously re-dirtied style state for every strip on every scroll tick. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Follow-ups from the main merge: - Migration numbering: main's 035_ProjectionThreadTitleRegeneration is released and keeps its id; this branch's unreleased v2 migrations shift to 036-044 instead (a released migration can never be renumbered). - thread.metadata.update accepts regenerateTitle: true arms an in-flight titleRegeneration marker on the thread payload (requestId + startedAt), a landing title or explicit false clears it. The marker projects onto thread shells and through the client-runtime shell model, so the sidebar's Regenerating state works unchanged. - New ThreadTitleRegenerationService worker reacts to armed markers on the live domain-event stream (so ws, MCP, and mobile dispatches all behave the same): builds a newest-first conversation digest from the v2 projection (8k-char budget, retained attachments — ported from the v1 reactor), generates via TextGeneration, and lands the title with a follow-up metadata update. Failures clear the marker and log. - The server advertises threadTitleRegeneration again, and the client updateThreadMetadata dispatches regenerateTitle-only updates. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The turn item materialized when a queued run is promoted was emitted with inputIntent "turn_start", but the deterministic replay driver (and the recorded queued_turn fixtures) expect "queued_turn" — the mismatch stalled replay before the queued run could start, leaving run 1 waiting and run 2 queued forever in all five queued_turn fixtures. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Effect service conventions: ThreadManagementThreadNotSendableError carried an Archived/NoSteerableRun reason union and switched on reason._tag inside the message getter. Modelled as two error classes (ThreadManagementThreadArchivedError, ThreadManagementNoSteerableRunError); both still map to the MCP thread_not_sendable failure code. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Prevent the title row from shifting when output is revealed - Preserve panel and compact button sizing
…5309) Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
- Schema.UnknownFromJsonString -> Schema.fromJsonString(Schema.Unknown) - SchemaIssue.InvalidValue single-argument form in checkpointDiff - McpServerClient requires protocolVersion Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Required for follow-up requests by the 2025-06-18 MCP HTTP transport that effect beta.103 enforces. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
53f1402 to
d36446e
Compare
The thread-panel mapping change replaced the compact className on the Run and Add controls with the isPanel conditional and dropped the non-panel icon-compact classes that the responsive test asserts. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Ports the deleted v1 ProviderCommandReactor title coverage onto the v2 service: marker arming/clearing via thread.metadata.update, superseded requestId no-ops, digest-driven regeneration, the "New thread" and unchanged-title fallbacks, generation failure, and missing initial messages, plus unit tests for formatThreadTitleContext. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
82209f3 to
bc39163
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Want fixes drafted automatically? Bugbot Autofix can create code changes for findings. A team admin can enable Autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit bc39163. Configure here.
…o perf/orchestration-v2-projection-loads
25de21d to
0af2a6e
Compare

What Changed
Why
Routine server operations loaded and schema-decoded every historical turn item. Memory and CPU usage therefore grew with the full thread history, even when a call only needed current runtime state.
This reduces server-side loading without changing client behavior, thread snapshots, pagination, or visible history.
Checklist
Note
Avoid full history loads in orchestration runtime paths by introducing operational projections
getOperationalProjection(latest turn item only) andgetRecoveryProjection(pending/running/waiting items only) toProjectionStoreV2, alongside targeted fetch methodsgetRun,getCheckpointScope,getRunTurnItems,getNodeTurnItems, andgetPresentTurnItemIds.getThreadProjectioncalls across orchestration services (Orchestrator.ts, ThreadManagementService.ts, ProviderTurnStartService.ts, etc.) with the appropriate scoped fetch; full history is only loaded when explicitly required (e.g. provider resume fallback, legacy import).ProjectionMaintenanceverification now usesvalidateThreadProjectionto decode turn item payloads in batches without loading full projections.message_ordinalrows.Macroscope summarized 41fcc34.
Note
Medium Risk
Touches core orchestration dispatch and projection loading across many services; incorrect bounded reads could change runtime behavior on long threads, though full-history paths are preserved for handoffs and imports.
Overview
Orchestration V2 no longer hydrates every historical turn item on most server paths.
ProjectionStoreV2adds bounded projections (getOperationalProjectionloads only the latest turn item;getRecoveryProjectionloads pending/running/waiting items) and targeted reads (getRun,getCheckpointScope,getRunTurnItems,getNodeTurnItems,getPresentTurnItemIds).The orchestrator, thread management, provider turn control/start, checkpoint capture/rollback, runtime requests, provider session manager, and continuation/recovery services now call those APIs instead of
getThreadProjection. Full history remains for snapshots, provider handoffs, v1 import / provider-switch dispatch, and client-facinggetThreadProjection.Projection maintenance startup verification uses
validateThreadProjection, which decodes turn items in batches of 256 instead of loading full projections. Tests cover bounded loads and a larger many-items scenario (301 items).Reviewed by Cursor Bugbot for commit 41fcc34. Bugbot is set up for automated code reviews on this repo. Configure here.