Skip to content

fix(client): show queued runs that drain after newer turns - #17388

Closed
voltcrash wants to merge 1 commit into
pingdotgg:mainfrom
voltcrash:t3/investigate-fix-16987
Closed

voltcrash wants to merge 1 commit into
pingdotgg:mainfrom
voltcrash:t3/investigate-fix-16987

Conversation

@voltcrash

Copy link
Copy Markdown
Contributor

Problem

Queued runs receive their ordinal when queued. When a newer direct turn runs first, the bounded client timeline drops the queued run's later user message and reply as unloaded history. Persisting that incomplete projection also makes the omission survive reloads.

Closes #16987.

Change

Track runs that were pending at hydration or became live afterwards, and exempt their items from the partial-history ordinal guard. Keep that eligibility through completion and retained-thread resume so final replies still arrive. Replacement snapshots establish a fresh boundary. Unloaded historical runs keep the existing filtering behavior, and visible rows retain authoritative ordinal order.

Bump the shared orchestration cache version so previously incomplete snapshots are fetched again. Both changes live in packages/client-runtime, covering web, Electron desktop, and React Native mobile across providers and local/remote connections. The cache refresh causes a one-time snapshot fetch after upgrading.

Scope and approval

Maintainer triage establishes the client-side failure and intended visibility. This PR addresses that failure and its persisted caches. Queue ordering remains the separate design question described in that comment. Related #16437 addresses late siblings of already-loaded runs; this fix also handles queued runs with no loaded rows.

Verification

On unmodified b707eeb05, the new shared-runtime stream regression failed for HTTP, socket, and warm-cache snapshots: only the newer turn's items remained, with both queued message IDs absent. After the fix, it passes for those paths and retained-thread resume. It checks a newer item raising the watermark, the queued user message, a reply arriving after run completion, ordinal insertion, exclusion of an unloaded historical run, and the saved projection/resume sequence. A cache regression confirms that schema-version-3 snapshots are discarded for a fresh fetch.

All 103 tests passed with:

vp test run packages/client-runtime/src/state/threads-sync.test.ts packages/client-runtime/src/state/orchestrationV2Projection.test.ts packages/client-runtime/src/state/threadHistoryMerge.test.ts packages/client-runtime/src/state/threadHistoryController.test.ts packages/client-runtime/src/platform/orchestrationCache.test.ts apps/web/src/connection/storage.test.ts apps/mobile/src/connection/environment-cache-store.test.ts

vp run --filter @t3tools/client-runtime typecheck passed. Targeted vp lint --report-unused-disable-directives and vp fmt --check passed for all five changed files. git diff --check passed.

Verification uses the actual shared thread subscription/reducer/persistence paths with controlled stream events. A live provider session, browser, and native mobile UI were not exercised. No UI components or layouts change.

Implemented with gpt-6.1-sol in the Codex harness.

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:M 30-99 changed lines (additions + deletions). labels Oct 9, 2026
@macroscopeapp

macroscopeapp Bot commented Oct 9, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at fc9c564

Macroscope's review found this PR approvable — This is a focused client-side bug fix that restores queued-run visibility across live, cached, and retained synchronization paths. The production logic is small, cache invalidation is explicit, and regression tests cover the affected scenarios without introducing new APIs, infrastructure, or sensitive behavior.

You can add or adjust custom eligibility rules. Learn more.

@coderabbitai

coderabbitai Bot commented Oct 9, 2026

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Path: .coderabbit.config.ts
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: ce820e7e-74a4-494d-8725-e4e3e12294a5
📥 Commits

Reviewing files that changed from the base of the PR and between b707eeb and fc9c564.

📒 Files selected for processing (5)
  • packages/client-runtime/src/platform/orchestrationCache.test.ts
  • packages/client-runtime/src/platform/orchestrationCache.ts
  • packages/client-runtime/src/state/orchestrationV2Projection.ts
  • packages/client-runtime/src/state/threads-sync.test.ts
  • packages/client-runtime/src/state/threads.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review.


📝 Walkthrough

Walkthrough

The change tracks pending run IDs in thread state and uses them to preserve matching turn items during partial-timeline projection updates. It also increments the orchestration cache schema version and adds tests for cache invalidation and queued-run event handling.

Changes

Queued-run turn visibility

Layer / File(s) Summary
Track pending runs
packages/client-runtime/src/state/threads.ts
Thread resume state initializes and retains IDs for pending runs. Matching run.created and run.updated events add pending run IDs, and replacement projections reset the tracked set.
Preserve live-run items
packages/client-runtime/src/state/orchestrationV2Projection.ts, packages/client-runtime/src/state/threads.ts
Partial-timeline filtering exempts missing turn items that belong to tracked live runs. Thread event handling passes the tracked IDs to projection updates.
Cache compatibility and event coverage
packages/client-runtime/src/platform/orchestrationCache.ts, packages/client-runtime/src/platform/orchestrationCache.test.ts, packages/client-runtime/src/state/threads-sync.test.ts
The cache schema version changes from 3 to 4. Tests cover discarding version 3 cache envelopes and queued-run updates across HTTP, socket, cache, and retained snapshots.

Priority: ➖ Normal

Estimated code review effort: 3 (Moderate) | ~25 minutes

Change: Bug fix · Severity of issue fixed: Medium

Sequence Diagram(s)

sequenceDiagram
  participant EventStream as Thread event stream
  participant Threads as threads.ts
  participant Projection as orchestrationV2Projection.ts
  EventStream->>Threads: run.created or run.updated with pending status
  Threads->>Threads: Add run ID to liveRunIds
  EventStream->>Threads: turn-item.updated
  Threads->>Projection: Apply event with liveRunIds
  Projection-->>Threads: Keep matching live-run item
Loading

Suggested reviewers: juliusmarminge

Merge Risk

Merge Risk: ⚪ Minimal · up to fc9c5

The queued-run visibility change is ready to merge after normal checks. No unresolved issue was established in the reviewed paths.

Security Architecture Review

Security architecture risk: 🔵 Low · up to fc9c5

The changes preserve queued-reply visibility and refresh old local snapshots. No introduced security weakness was demonstrated, but some recovery and upstream access-control guarantees remain unverified.

Retained concerns
No architecture-level concerns identified.

Security review details

Security Blast Radius

  • inferred — The changed behavior is bounded to additional admission of already-delivered turn items into a client conversation projection. Resume state is keyed by environment and thread, and cache operations retain those identities. The inspected production changes introduce no new execution, credential, or provisioning authority.

Trust Boundaries and Controls

  • observed — Pending-event tracking checks the event envelope against the local thread, and projection application independently rejects mismatched event-thread IDs. These client checks and the pagination exemption do not establish server authorization or cross-field consistency between envelope and payload identities.

Resilience and Maintainability Implications

  • observed — Existing containment mechanisms remain: sequence filtering skips repeated events, projection updates apply a batch against current state, stale resume owners cannot persist snapshots, and deleted state ignores subsequent events. No concrete regression in these mechanisms was established.
🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Description check Passed The description includes all required sections. It clearly explains the queued-run timeline problem, the implementation, scope and approval, focused verification results, limitations, and the agent us…
Title check Passed The title clearly and concisely describes the main change: showing queued runs after newer turns complete.
Linked Issues check Passed The PR satisfies the coding requirements in [#16987]. threads.ts tracks pending run IDs in initial and retained state, refreshes the set for replacement snapshots, and passes it to projection update…
Out of Scope Changes check Passed The changes stay within [#16987]. The source changes update shared client thread synchronization, partial-timeline projection, and orchestration cache invalidation. The tests exercise the same behavio…
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

@juliusmarminge

Copy link
Copy Markdown
Member

Note

Grok responding on behalf of Julius.

Thanks for working on this, and for the careful write-up. #16987 is now fixed on main by #17764, which keeps a queued run's items when they arrive after a newer turn, so I'm closing this one as superseded. If you still see queued turns going missing on a build that includes #17764, please open a new issue with the details and we'll take another look.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:M 30-99 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Queued messages that run after newer steers never appear in the thread

2 participants