[Bug]: Provider switches omit visible history from cancelled runs#34009
Before submitting
- I searched existing issues and did not find a duplicate.
- I included enough detail to reproduce or investigate the problem.
Area
apps/server
Steps to reproduce
- Start a provider turn and let it produce a substantive assistant response.
- Cancel that started run before T3 records it as completed. Its user prompt and assistant response remain visible in the thread.
- Switch the thread to another provider and send a follow-up.
- Inspect the provider handoff or the history received by the new provider.
This was observed during a Claude-to-Codex switch. It also reproduces without live provider calls in the existing ProviderSwitch integration harness, using an adapter that emits a response and a cancelled terminal event.
Expected behavior
A provider switch retains visible history from a started run, with its cancelled status recorded. Queued requests cancelled before they start and rolled-back history should remain excluded.
Actual behavior
The started cancelled run is excluded before the handoff budget is applied. The new provider receives neither its prompt nor its response. The handoff can report zero omitted items because the lost run never enters history selection.
At main commit 1fed70cd19998cee7907f6fde3b4d4290ba99cfc, isHandoffSourceRun in apps/server/src/orchestration-v2/Orchestrator.ts accepts completed, failed and interrupted runs, but excludes cancelled runs. The same predicate controls immediate provider switching and queued promotion.
Impact
Major degradation. A provider change silently loses visible investigation results and instructions, forcing rediscovery and potentially changing the answer.
Version or commit
Observed on 0.1.1-nightly.20261019.3360. Confirmed in upstream main at 1fed70cd19998cee7907f6fde3b4d4290ba99cfc.
Environment
Linux x64, T3 Code through the Codex harness. Regression tests use temporary SQLite databases and test adapters; no live provider or production state is required.
Regression evidence
Extending the existing "hands off" integration table with cancelled source runs produced two failures on main, for immediate switching to a new provider and queued switching to a returning provider. Both failed because the handoff was undefined.
Including cancelled runs only when startedAt is non-null makes those cases pass. The extended table also cancels a separate queued request before it starts and verifies that its prompt is absent from delivered history.
Workaround
Recover the earlier messages with t3_thread_read and reintroduce the missing context manually.
Created with gpt-6.1-sol in the Codex harness through T3 Code.