fix(pi): fork completed turns while the next turn is running#23052
Problem
Forking a completed Pi turn while the next turn is still running fails with “Pi turn 2 has no captured session-tree entry and none was found in the session tree.” The running turn has a synthetic weak reference and no completion timestamp, although Pi has already persisted its prompt.
Change
Allow the existing session-tree recovery window to remain open at its upper end for a running boundary turn. Keep the retained turn’s lower bound, ancestry validation, and earliest-user-entry selection, so the fork cuts before the running turn’s prompt rather than a later steer. Completed boundary turns keep their finite upper bound.
Add one adapter regression for the running weak-reference boundary. This is a server-only Pi adapter change; no client, wire contract, or other provider changes.
Scope and approval
Fixes #23050
Triaged bug via the automated issue flow. Focused repair of the existing fork behavior, following #20521; no authentication, credential, permission, approval, mode, sandbox, or MCP changes.
Verification
- Test-first: the running-boundary regression fails on main with the exact reported protocol error; the existing three native-fork tests pass. Independent proof audit reruns red and green.
./node_modules/.bin/vp test run packages/provider-pi/src/server/adapter.test.ts: 84/84 pass on the final head, including the existing completed-uncaptured-boundary cases.- Scoped Pi typecheck, changed-file lint, formatting, whitespace checks, and
knip --workspace packages/provider-pi --no-config-hintspass. Lint reports one existing unusedlayerwarning outside this change. - Temporary fake-Pi runtime driver: before fails with the exact protocol error; after returns
/fake/forked.jsonland sends native fork atu2, excluding turn 2 and its later steer. Evidence is from the adapter’s fake Pi protocol harness, not native session persistence. - Codex GPT-6.1 Sol and Claude Opus 5.5 independent reviews: MERGE, no confirmed bugs. Removed their nonblocking fixture-only ancestry assertion.
- UI evidence matrix is empty. No visual changes; no screenshots or recordings required.
23050-runtime-proof.txt 23050-proof-matrix.txt
Pi 1.3.0 installed without model credentials. Attempted the isolated worktree web flow, but repeated dev watcher restarts on source/test-cache changes and reconnect failures prevented completing the live two-turn sequence. Live Pi, authenticated model behavior, Windows, Electron desktop, and mobile remain unverified. No live T3 state was written. Main was fetched and merged locally; it was already up to date.
Implementation and regression test: Claude Opus 5.5. Triage, integrated verification, proof audit, and review: Codex GPT-6.1 Sol and Claude Opus 5.5 through T3 Code (Codex and Claude Agent harnesses).
Checks
- SuccessfulCodeRabbitGitHub
Review completed
- Successful
Skipped - Not affected
- SkippedBuild preview JS bundleGitHub
- Skipped
- SkippedBuild preview JS bundleGitHub
- Skipped
- Skipped
- SkippedEAS PreviewGitHub
- Skipped
- SkippedRemove preview downloadGitHub
- SkippedDeploy web previewGitHub
- SkippedDeploy web previewGitHub
- SkippedEAS PreviewGitHub
- Skipped
- Skipped
- SkippedRemove preview downloadGitHub
- Skipped
- Skipped
- SkippedBuild preview JS bundleGitHub
- SkippedEAS PreviewGitHub
- SkippedDeploy web previewGitHub
- Skipped
- SkippedRemove preview downloadGitHub
- Skipped
- Skipped
- Skipped
- SuccessfulRemove preview downloadGitHub
- SkippedRemove preview downloadGitHub
- SkippedEAS PreviewGitHub
- SkippedDeploy web previewGitHub
- SkippedBuild preview JS bundleGitHub
- Skipped
- Skipped
- Skipped
- SuccessfulCheckGitHub
- SkippedDeploy web previewGitHub
- SkippedEAS PreviewGitHub
- SkippedBuild preview JS bundleGitHub
- SkippedDeploy web previewGitHub
- SkippedBuild preview JS bundleGitHub
- SkippedEAS PreviewGitHub
- SuccessfulNative fingerprint diffGitHub
- Skipped
- Successful
- Successful
- Successful
- Successful
- SkippedRelease SmokeGitHub
- Skipped
- SkippedRustGitHub
- SuccessfulTestGitHub
- SuccessfulTest WebGitHub
- SuccessfulBuild and TypecheckGitHub
- SuccessfulLabel PR 23052GitHub
- Skipped
- SuccessfulLabel PR sizeGitHub
- SuccessfulTest Server 7GitHub
- SuccessfulTest Server 6GitHub
- SuccessfulTest Server 8GitHub
- SuccessfulTest Server 2GitHub
- SuccessfulTest Server 3GitHub
- SuccessfulTest Server 4GitHub
- SuccessfulLintGitHub
- SuccessfulTest Server 5GitHub
- SuccessfulTest Server 1GitHub
- SuccessfulChangesGitHub
- SuccessfulPrepare PR size configGitHub
- SuccessfulCollect PR targetsGitHub
- SkippedEAS PreviewGitHub
- SuccessfulNative fingerprint diffGitHub
Added 3 commits
Approvability
Verdict: Approved at 1372a7a
Macroscope's review found this PR approvable — This is a narrowly scoped Pi adapter bug fix that keeps completed-turn behavior unchanged while allowing forks to recover a prompt from a currently running boundary turn. The accompanying regression test covers the previously failing case, with no schema, defaults, infrastructure, or static-analysis override changes.
You can add or adjust custom eligibility rules. Learn more.
Thread transfer impact
✅ Thread transfer remains within every enforced ceiling.
| Provider | Metric | Main baseline | This PR | Impact | PR ceiling | |
|---|---|---|---|---|---|---|
| Codex | Total thread wire | 5.0 KiB | 5.0 KiB | 0 B (0.0%) | 6.8 KiB | ✅ |
| Codex | Thread snapshot wire | 3.8 KiB | 3.8 KiB | 0 B (0.0%) | 4.9 KiB | ✅ |
| Codex | Live turn WebSocket wire | 1.2 KiB | 1.2 KiB | 0 B (0.0%) | 2.0 KiB | ✅ |
| Codex | Live turn WebSocket decoded | 20.9 KiB | 20.9 KiB | 0 B (0.0%) | 29.3 KiB | ✅ |
| Codex | Live turn messages | 2 | 2 | 0 (0.0%) | 8 | ✅ |
| Claude | Total thread wire | 5.0 KiB | 5.0 KiB | 0 B (0.0%) | 6.8 KiB | ✅ |
| Claude | Thread snapshot wire | 3.8 KiB | 3.8 KiB | 0 B (0.0%) | 4.9 KiB | ✅ |
| Claude | Live turn WebSocket wire | 1.2 KiB | 1.2 KiB | 0 B (0.0%) | 2.0 KiB | ✅ |
| Claude | Live turn WebSocket decoded | 21.2 KiB | 21.2 KiB | 0 B (0.0%) | 29.3 KiB | ✅ |
| Claude | Live turn messages | 2 | 2 | 0 (0.0%) | 8 | ✅ |
Baseline: d27c606 · PR result: 1372a7a · Source CI: success
Scenario and decoded snapshot size
10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.
- Codex decoded thread snapshot: 108.5 KiB
- Claude decoded thread snapshot: 108.8 KiB
Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed.
No actionable comments were generated in the recent review. 🎉
ℹ️ Recent review info
⚙️ Run configuration
- Configuration used: Path: .coderabbit.config.ts
- Review profile: CHILL
- Plan: Team
- Run ID:
06674b94-6ba1-4034-bb54-17fe610201db
📥 Commits
Reviewing files that changed from the base of the PR and between d27c6067a9162150f654e38f455a7a936ef79178 and 1372a7af05a99986ff154c41ec3d6c83b21f51c3.
📒 Files selected for processing: 2
packages/provider-pi/src/server/adapter.test.tspackages/provider-pi/src/server/adapter.ts
Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 6 remain after this review.
📝 Walkthrough
The uncaptured fork-entry search now supports a boundary turn that has started but is still running. A regression test verifies that forking succeeds and includes the running turn’s root entry, but not its steer entry.
Changes: Running-turn fork boundary
Layer / File(s) Summary Handle running fork boundaries
packages/provider-pi/src/server/adapter.ts,packages/provider-pi/src/server/adapter.test.tspiUncapturedForkEntryuses an open-ended search window whencompletedAtis absent, while still requiringstartedAt. The regression test checks the fork identity and confirms that only the running turn’s root entry is included.Priority: ⬇️ Low
Estimated code review effort: 2 (Simple) | ~10 minutes
Change: Bug fix
Possibly related issues
- Issue 23050 reports the Pi fork failure when the next turn is still running. This change addresses that case by extending the uncaptured search window and adding a regression test.
Suggested reviewers:
henrychu04
Merge Risk: ⚪ Minimal · up to 1372a
The running-turn fork change appears mergeable after normal checks; the available evidence establishes no remaining issue.
Pre-merge checks: Passed 4
Check name Status Explanation Title check Passed The title clearly and concisely describes the main fix: Pi can fork a completed turn while the next turn is running. Description check Passed The description includes the required Problem, Change, Scope and approval, and Verification sections. It explains the failure, implementation, regression test, verification results, and unverified env… Linked Issues check Passed Check skipped because no linked issues were found for this pull request. Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request. Full details: Description check
Explanation
The description includes the required Problem, Change, Scope and approval, and Verification sections. It explains the failure, implementation, regression test, verification results, and unverified environments.
✨ Finishing Touches
📝 Generate docstrings
- Commit to this branch
- Create a new PR
🧪 Generate unit tests (beta)
- Commit to this branch
- Create a new PR
- Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Comment @coderabbitai help to get the list of available commands.