Repository navigation
Description
Report
An existing Copilot-backed T3 thread reportedly becomes unable to continue even though its saved native session remains intact. A separate investigating agent reports that native session reopening succeeded, after which T3 selected handoff_budget_exhausted and attempted a fresh-session fallback that the Copilot integration could not perform.
This issue records that agent's findings; the exact trace and independent reproduction are still pending. Do not yet assume which adapter capability or orchestration decision is responsible, or that every resume is affected. Native CLI resume was offered as a workaround; its success has not been independently confirmed here.
Reported sequence
- Create a Copilot conversation in T3 and accumulate conversation history.
- Later continue/reopen the same thread.
- Native reopening reportedly succeeds.
- T3 reportedly determines that the earlier-conversation handoff exceeds its budget (
handoff_budget_exhausted). - A fresh-session fallback fails, leaving the existing T3 thread unable to continue.
The precise history threshold and triggering conditions need evidence; these are not yet deterministic reproduction steps.
Scope
Investigate existing-thread continuation/resume, history-handoff admission and the Copilot fresh-session fallback. Keep this separate from #38 (standalone extension initialization at session creation) and #33 (importing external sessions).
Copilot CLI experimental flags being persisted to its own profile are outside this issue. The reporting agent states experimental mode was already disabled during this later failure. No change to native CLI settings or profile isolation is requested here.
Evidence requested from the investigating agent
Please comment with:
- Installed T3 source/version, Copilot SDK/runtime versions and whether this is a packaged build.
- Sanitized chronological trace showing successful native reopen, the budget decision, attempted fallback and exact terminal error.
- Why the handoff was required after native reopening: whether native resume was actually reusable, or a context transfer/new session was intentionally necessary.
- The relevant fallback capability/error and smallest harmless reproduction, including approximate history size and configured budget.
- Whether repeated continuation fails, whether direct native CLI resume actually works, and whether the same behavior occurs with experimental mode disabled.
Do not post raw conversations, screenshots, credentials, machine names/addresses, personal filesystem paths, or full native session identifiers. Short consistent aliases are sufficient for correlation.
Expected behavior
A supported existing thread should remain continuable when its native session can be safely resumed. If history must be transferred and exceeds the budget, provide an explicit supported recovery path rather than repeatedly selecting an unsupported fallback. Preserve original history/session identity and expose context-loss/ownership boundaries; do not silently truncate history, reset credentials, or replace the conversation.
No source fix or live-state modification is included in this report.
Activity
jdbencardinop commentedon Nov 5, 2026
Case evidence from the affected installation
The thread was created inside T3, completed six runs, then failed when the user sent another message. It was not an imported CLI conversation. A later continuation successfully reopened the native session but still failed before starting the provider turn. The user intentionally settled the thread after these failures; settling did not trigger them.
I rechecked retained provider logs, T3 trace spans, read-only persisted projections, and the installed runtime's embedded source. The terminal failure and fallback sequence are confirmed locally. A clean-room reproduction and a source fix are not included.
Environment
t3 v0.1.4-preview.20261103.1.sha256-6ddb2660d5339b0cc6f17c53d92774f1496e0d68df676d3ccbdee495a63707f4.@github/copilot-sdkand@github/copilot-sdk-linux-x64:1.0.28.1.0.105; the currently installed CLI also reports1.0.105.model: auto,autoTier: hydrafusion-max(UI: Fusion / Max). There was no recorded selection change between the successful and failed runs.Use aliases
thread-A/native-Afor this case. No raw conversations, screenshots, filesystem paths, or native identifiers are attached.What happened
All timestamps are UTC.
2026-11-04 19:52:54–22:20:22: runs 1–6 completed in the same T3-created conversation. Work included developing/testing an OMC plugin. This establishes chronology, not causation by OMC.
22:58:52–22:58:59: run 7 failed before provider-turn start. Its recovery reason was
resume_failed. This is the earlier failure; it is not evidence that the later attempt failed to reopen.2026-11-05 01:13:16.154: user submitted run 8 to the existing thread.
01:13:17.116–17.341: provider log recorded
session.resume, followed by initialization events including tools/settings/skills updates. The corresponding initialCopilotAdapter.ensureThreadspan completed successfully.01:13:17.357:
orchestrationV2.deliverContextHandoffsfailed with:01:13:17.406: the subsequent handoff check using fresh-session context succeeded.
01:13:17.417: T3 logged:
It called
ensureThreadwithforceNewNativeThread: true. The Copilot adapter explicitly rejects that request:The same budget/fallback failure occurred across five internal attempts for run 8, ending at 01:13:19.213. The UI showed “Provider turn failed to start” and the replacement error. These were retries of one user submission, not five independently reproduced continuations.
Why a handoff after successful reopen?
The installed orchestration code prepares a
delta_since_target_last_seenretry handoff for prior failed/interrupted inputs that were never accepted natively. Run 7 fits that condition: its attempt has no provider turn or native-thread assignment. Its user message was 345 UTF-8 bytes.This makes recovery of the previous undelivered input the likely reason for the handoff, rather than a need to replay the entire successful conversation. The generated handoff was not persisted, so its exact contents are not independently captured. Run 8's current user message was 2,815 UTF-8 bytes with no attachments.
Strong candidate: cumulative usage treated as native occupancy
The persisted values disagree in a way that explains the budget failure:
In the installed Copilot adapter,
session.usage_infoupdates session occupancy, whileassistant.usageaccumulates input/output usage across requests within a turn.However,
latestNativeContextUsagereads the latterproviderTurn.tokenUsage.usedTokens. Run 6 satisfies its native-session/root-node matching conditions.handoffContextForThreadmerges that value over the thread's occupancy telemetry.handoffBudgetthen subtracts it from the available context window, clamping the result to zero. This uses cumulative request accounting as though it were current context occupancy.The packaged default handoff cap is 16,000 (
T3CODE_CONTEXT_HANDOFF_TOKEN_CAP); I have not independently established a process-level override. The much larger cumulative usage would exhaust the budget regardless of that cap.This is a source-and-state explanation consistent with the observed trace, not an instrumented capture of the budget arguments at failure time.
Remaining boundaries
resume_failedpath and this laterhandoff_budget_exhaustedpath converge on the same unsupported fallback. Identical UI text does not establish an identical initial cause.Suggested narrow regression: resume an unchanged native session with valid occupancy below its context limit, cumulative per-turn request usage above that limit, and one prior failed input requiring retry handoff. Verify that admission uses occupancy rather than cumulative usage, and that recovery never selects an unsupported replacement operation.
jdbencardinop commentedon Nov 5, 2026
Independent verification and isolated continuation reproduction
Investigation only; no source fix, integration, or deployment. The preceding report remains credible, with two independently checked but distinct paths.
1. Accounting/budget explanation verified at helper level
On candidate
df3383e475c3d052bcac52259384cec319dc6901, the source confirms:session.usage_info.assistant.usageaccumulates request accounting within a turn.latestNativeContextUsagereads that cumulativeproviderTurn.tokenUsage.usedTokens.handoffContextForThreadmerges it over session occupancy before budgeting.forceNewNativeThread: true, which the Copilot adapter explicitly rejects.A private harness imported the actual exported budget helpers, using synthetic metadata containing the preceding report's sanitized numbers and a 2,815-byte placeholder request, with no attachments:
This independently reproduces the numeric accounting error. It is not a new long-conversation reproduction or an instrumented capture of the original production call.
2. Requested experimental-on/off application sequence
Used a newly created Copilot profile, separate disposable T3 state, an empty fixture Git project, SDK 1.0.28 / native runtime 1.0.105, and the same T3-created thread throughout. Selection remained Auto +
hydrafusion-max. Only harmless one-line messages were sent; no real user profile, thread, or installation was modified. Commands followed the application's typed WebSocket orchestration path, and completion was observed through terminal run events.experimental: false; create thread and sendexperimental: false; restart and continueImportant distinction: both failed continuations initially failed native
session.resumewith:Both then reached T3's
resume_failedrecovery path and the same terminal error:Thus the proposed sequence reproduces two failed application continuations, including one after config restoration, but does not reproduce the successful-native-resume →
handoff_budget_exhaustedpath described in the preceding comment. The latest completed turn's usage was only 24,037 tokens, with native occupancy 28,968 / 272,000; this was not the reported >1M cumulative-usage case.A separate headless CLI session with
--experimentaldid not persist the flag in this runtime. The application experiment therefore deliberately toggled the fresh test profile's configuration and restored it exactly. This is a configuration-state reproduction, not evidence about the CLI's flag-persistence semantics, which remain outside this issue's scope.3. Native controls and scope
experimental: false, native resume withrequestExtensionsomitted still failed on extension initialization.requestExtensions: falsereopened that same saved native session successfully, without sending a prompt. This is a diagnostic control, not a shipped application fix or proof that application continuation works.requestExtensionsomitted and with explicit false.The persistence mechanism behind the affected session/profile's extension requirement has not been localized. Do not infer that every cold resume fails, that the saved conversation was lost, or that the budget bug is Fusion-specific.
The extension-startup evidence also belongs to #38. Keep #39's accounting/admission and unsupported-recovery findings in the backlog; a future regression should exercise the original budget path separately from this extension-triggered path.
All evidence here is sanitized text. No private transcript, screenshot, token, native identifier, machine name, or local filesystem path is attached.
jdbencardinop commentedon Nov 5, 2026
Implemented on
fix/copilot-context-occupancy(branch head). Copilot declares that per-turn usage is cumulative billing, so handoff admission retains native occupancy rather than replacing it with billed totals, including saved historical turns. It also explicitly declines native replacement: resume/budget failures retain their original error instead of invoking the known-unsupported operation. The original conversation is not truncated/replaced. Persisted orchestration fixtures verify the reported 120615/200000 occupancy with 1169410 cumulative usage, unchanged native identity and billing counters; genuine budget failure and failed resume retain identity without a replacement prompt. 96 focused tests and all 113 adjacent changed-file tests pass; affected typechecks/format/lint pass. Known baseline knip and historical tpatch parent-replay blockers remain. This is validated source plus an isolated orchestration reproduction, not a replay of the private long conversation or a deployment.