Repository navigation
Conversation
ApprovabilityVerdict: Approved at Macroscope's review found this PR approvable — Portable side-chat handoffs now point history recovery at the parent thread while remaining owned by the side chat. Regular forks and existing handoffs are unchanged, keeping the change narrowly scoped. You can add or adjust custom eligibility rules. Learn more. |
|
No actionable comments were generated in the recent review.
|
| Layer / File(s) | Summary |
|---|---|
Separate history coverage from handoff ownership apps/server/src/orchestration-v2/ContextHandoffService.ts |
prepareProviderHandoff accepts an optional historyThreadId. Coverage uses it when supplied, but the handoff remains owned by threadId. |
Side-chat wiring and fork recovery test apps/server/src/orchestration-v2/Orchestrator.ts, apps/server/src/orchestration-v2/ThreadFork.execution.test.ts |
Side-chat dispatch passes the source thread as historyThreadId. Tests check recovery handoffs for side chats and regular forks, including ownership and history coverage. |
Estimated code review effort: 2 (Simple) | ~10 minutes
Change: Bug fix
Possibly related issues
pingdotgg/t3code#28809— Reports side-chat recovery using the child thread when the history belongs to the parent. This change passes the source thread for side-chat handoff history coverage.
Suggested labels: bugfix, size:S
Suggested reviewers: t3dotgg, macroscopeapp
Merge Risk: 
Minimal · up to 633a0
-
New side-chat handoffs point recovery to the parent in normal delivery. The existing compact fallback remains unchanged.
Pre-merge checks: 
4
-
Full details: Title check
-
Explanation
The title "fix(server): recover side-chat fork history from its parent" matches the main change. The PR makes newly prepared portable side-chat handoffs name the parent thread in their history coverage and recovery hint, and the objectives describe the same change. It uses a conventional commit format and is specific to the server component, so it passes.
Full details: Description check
-
Explanation
The description follows the template's main sections: Problem, Change, Scope and approval, and Verification. The Problem and Change sections clearly explain the bug and the fix. Scope and approval gives a focused-fix rationale and references issue
#28809, but it does not include a triaged issue link or maintainer approval comment, and it relies on the CONTRIBUTING exception for obvious bugs. Verification is detailed: it lists the focused test files and results, the revert-based failing-test check, lint and typecheck results, and a live Codex run before and after. It also states what was not checked (Windows and UI rendering). The template's agent-model footer is present. The description is mostly complete, so it passes.
-
Finishing Touches
-
Generate unit tests (beta)
-
- Create a new PR
-
- Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Problem
When a side chat starts through portable context, its handoff tells the agent to recover omitted history with
t3_thread_readon the side chat itself. A side chat excludes parent timeline rows, so a recovery hint that names the side chat cannot reach the parent history it lists.Change
Newly prepared portable side-chat handoffs now name the parent thread in their history coverage and recovery hint. The side chat still owns the handoff and its target run. Regular portable forks keep naming the fork, because a fork shows the rows it inherits.
Scope and approval
Refs #28809. This is a small, focused fix for an obvious bug under CONTRIBUTING's exception for fixes without prior triage. The cause does not depend on the operating system.
The change covers recovery instructions only. The same-model label, transfer-limit wording, #27072 cursor cost, compact overflow fallback and already-persisted handoffs are unchanged.
Verification
Server-only change. The client renders the handoff data the server stores.
vp test runonapps/server/src/orchestration-v2/ContextHandoffService.test.ts,Orchestrator.control-reads.test.ts,Orchestrator.migration.test.tsandThreadFork.execution.test.ts: 34 of 34 pass.ContextHandoffService.tsandOrchestrator.tsreverted to57d764ea1a, one test fails with an assertion error: "portable fork recovery uses the readable history thread (sideChat=true)". ThesideChat=falsecase passes before and after.vp fmt --checkandvp lintreport no errors and no new warnings on the 3 changed files.vp run --filter t3 typecheckpasses.Live run on Linux with real Codex: the parent finished one turn and was running a second, so the side chat took the portable path on its own. On main
57d764ea1a, the stored recovery hint names the side chat. All 3 listed history items exist in the parent and none exist in the side chat. On633a0b6ed7, the hint names the parent, which holds all 3 items, and the side chat still owns the handoff. Both runs omitted zero items, so this shows where recovery points, not a full omitted-item recovery.Live Codex run, before and after
Environment: Linux, Codex GPT-6.1-Sol, real signed-in Codex 0.166.0. Isolated T3 servers, no forced provider capabilities. No Windows/UI rendering claim. Thread and item identifiers below use role aliases for readability.
Setup on both builds
node scripts/dev-runner.ts dev:server --home-dir <isolated-home> --no-seed.PARENT_HISTORY_28809and wait for its first run to complete.sleep 120.latest_stablewithsideChat: trueand send the first child message. This naturally selects portable context.Before: main 57d764e
Parent runs at observation: first completed; second running. Child first run completed.
Stored recovery instruction (thread id replaced with alias):
After: 633a0b6
Fresh isolated state and new real Codex parent/child; same setup. Parent first run completed and second running.
Stored recovery instruction (thread id replaced with alias):
The regular portable-fork scope control is covered by the focused execution test. Same-model labels, transfer limits, overflow fallback, pagination cost and existing handoffs were not changed.
Model: GPT-6.1-Sol, Claude Opus 5.5 (review), GPT-6-Astra (review). Harness: Codex, Claude Code.