Skip to content

fix(server): fork Codex threads at native turn boundary - #9169

Closed
Yusuf007R wants to merge 359 commits into
pingdotgg:t3code/codex-turn-mappingfrom
Yusuf007R:codex/fix-codex-paginated-thread-fork
Closed

Yusuf007R wants to merge 359 commits into
pingdotgg:t3code/codex-turn-mappingfrom
Yusuf007R:codex/fix-codex-paginated-thread-fork

Conversation

@Yusuf007R

@Yusuf007R Yusuf007R commented Sep 2, 2026 •

Copy link
Copy Markdown

Codex 0.151 makes durable threads paginated by default, but T3's retry/edit fork path still truncates a completed native fork with the deprecated thread/rollback endpoint. Codex rejects that endpoint for paginated threads, leaving the provider-turn start failed and the T3 run stuck in its starting state.

What Changed

  • Resolve the selected durable provider turn to its native Codex turn ID before creating the fork.
  • Pass that ID as lastTurnId in the original thread/fork request so Codex omits later turns atomically.
  • Skip the follow-up rollback whenever the native boundary is available.
  • Preserve the existing rollback-count path only as a compatibility fallback for historical projected turns without a native turn reference.
  • Cover the native-boundary mapping with a focused adapter test.

Why

The existing flow first creates a complete native fork. If the user selected an earlier turn, T3 counts the terminal turns after that boundary and calls thread/rollback on the newly created thread. Forking at the current head works because the count is zero; retrying or editing an earlier turn reaches the rollback call.

Paginated Codex threads reject that second request with paginated threads do not support thread/rollback. Although Codex has already created the fork, T3 receives an error and fails the durable provider-turn.start effect, so the run appears unresponsive.

Codex already supports the intended operation directly: thread/fork.lastTurnId creates a fork through the specified turn, inclusive. Supplying the known native turn ID removes the incompatible second request without adding recovery, persistence, or provider-version detection machinery.

UI Changes

None. This changes only the Codex provider adapter's native fork request.

Validation

  • vp test run apps/server/src/orchestration-v2/Adapters/CodexAdapterV2.test.ts
  • vp run --filter t3 typecheck
  • vp fmt apps/server/src/orchestration-v2/Adapters/CodexAdapterV2.ts apps/server/src/orchestration-v2/Adapters/CodexAdapterV2.test.ts --check

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • Screenshots are not applicable because there are no UI changes
  • Video is not applicable because there are no animation or interaction changes

Implemented with GPT-5.6 in the Codex desktop harness.


Note

Medium Risk
Changes native fork semantics for retry/edit-at-earlier-turn flows; incorrect boundary mapping could fork with wrong history, though fallback rollback preserves legacy behavior when native ids are missing.

Overview
Codex same-provider forks now cut history at the selected turn in one thread/fork call instead of forking at the head and calling thread/rollback, which paginated Codex threads reject.

The adapter adds resolveCodexForkBoundary, which maps the orchestrator’s source provider turn to its native Codex turn id when nativeTurnRef is present. forkThread includes that id as lastTurnId on thread/fork and sets rollback to zero so the post-fork thread/rollback path is skipped. When there is no native turn reference, behavior stays the same: fork latest state and roll back by the count of later terminal provider turns.

Unit tests cover native-boundary vs identityless fallback. Replay fixtures and orchestration docs were updated to expect lastTurnId and no rollback in the prior-turn fork scenario.

Reviewed by Cursor Bugbot for commit 8d034c8. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Fork Codex threads at native turn boundary instead of rollback

  • Adds resolveCodexForkBoundary to CodexAdapterV2, which returns the source provider turn's native turn id as the fork boundary when available and resets rollback count to zero
  • Updates the forkThread handler to include the resolved native turn id in the native fork request and skip fork-local rollback in that case; turns without native identity still use the existing latest-state fork plus rollback fallback
  • Updates replay fixtures in thread_fork_native, thread_fork_native_prior_turn, thread_merge_back_continue, and thread_merge_back_siblings to expect native boundary fork requests and removes explicit rollback exchanges where applicable
  • Behavioral Change: Codex forks with a native source turn id now fork directly at that turn; forks without native identity are unaffected and retain rollback fallback

Macroscope summarized 8d034c8.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 2, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-04T15:39:53.412435Z 2822d10 Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:S 10-29 changed lines (additions + deletions). labels Sep 2, 2026
@Yusuf007R
Yusuf007R marked this pull request as draft September 2, 2026 05:11

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d577d2ca43

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +5205 to +5207
...(forkBoundary.lastTurnId === undefined
? {}
: { lastTurnId: forkBoundary.lastTurnId }),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Update the fork replay fixture for lastTurnId

When the source turn has a native reference, this now adds lastTurnId to every thread/fork request. The replay harness compares normalized outbound frames exactly and does not remove this field, while testkit/fixtures/thread_fork_native_prior_turn/codex_transcript.ndjson still expects a fork containing only threadId followed by thread/rollback; consequently the focused ThreadFork.integration.test.ts scenario fails before validating the new behavior. Update that transcript to expect the native boundary and remove the obsolete rollback exchange.

AGENTS.md reference: AGENTS.md:L109-L109

Useful? React with 👍 / 👎.

@macroscopeapp

macroscopeapp Bot commented Sep 2, 2026 •

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — This is a focused Codex server fix that changes existing fork behavior by using native turn boundaries and retaining a compatibility fallback. Unresolved substantive review comments concern replay validation and null-identity fallback behavior, so the final implementation should receive human review.

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

@juliusmarminge
juliusmarminge force-pushed the t3code/codex-turn-mapping branch 2 times, most recently from ceea97b to d2f1f51 Compare September 2, 2026 18:07
@shivamhwp

Copy link
Copy Markdown
Collaborator

Note: GPT-5.6 on behalf of shivam (@shivamhwp).

Please rebase this onto the latest t3code/codex-turn-mapping branch. The base branch was rewritten, so GitHub currently shows 331 unrelated commits, 948 changed files, and merge conflicts instead of the two-file change described here.

After rebasing, please update the Codex replay fixtures for the new thread/fork.lastTurnId request. The fork and merge-back integration tests still expect the old rollback sequence, which is causing the server test failures.

Once the diff is clean and those tests pass, we can review the actual fix.

@Yusuf007R
Yusuf007R force-pushed the codex/fix-codex-paginated-thread-fork branch from d577d2c to fb05690 Compare September 4, 2026 15:14
@Yusuf007R
Yusuf007R marked this pull request as ready for review September 4, 2026 15:29
@github-actions github-actions Bot added size:M 30-99 changed lines (additions + deletions). and removed size:S 10-29 changed lines (additions + deletions). labels Sep 4, 2026
@Yusuf007R
Yusuf007R marked this pull request as draft September 4, 2026 15:29
macroscopeapp[bot]
macroscopeapp Bot previously approved these changes Sep 4, 2026
@Yusuf007R
Yusuf007R marked this pull request as ready for review September 4, 2026 15:35
@macroscopeapp
macroscopeapp Bot dismissed their stale review September 4, 2026 15:35

Dismissing prior approval to re-evaluate 2822d10

macroscopeapp[bot]
macroscopeapp Bot previously approved these changes Sep 4, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2822d10f05

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +799 to +804
const nativeTurnRef = boundaryTurn?.nativeTurnRef;
if (nativeTurnRef === null || nativeTurnRef === undefined) {
return { rollbackTurnCount };
}

return { lastTurnId: nativeTurnRef.nativeId, rollbackTurnCount: 0 };

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Treat null native IDs as missing fork boundaries

When a persisted Codex turn has an identity-less provider ref whose nativeId is null (a valid OrchestrationV2ProviderRef), this returns lastTurnId: null and resets rollbackTurnCount to zero. forkThread then sends a null boundary, which is equivalent to omitting the boundary, while also skipping the compatibility rollback; forking from an earlier run therefore retains later turns. Check nativeTurnRef.nativeId for null before disabling rollback.

Useful? React with 👍 / 👎.

@juliusmarminge
juliusmarminge force-pushed the t3code/codex-turn-mapping branch from 9eeed8c to 8af5734 Compare September 4, 2026 18:23
@Yusuf007R
Yusuf007R force-pushed the codex/fix-codex-paginated-thread-fork branch from 2822d10 to 8d034c8 Compare September 4, 2026 19:31
@macroscopeapp
macroscopeapp Bot dismissed their stale review September 4, 2026 19:31

Dismissing prior approval to re-evaluate 8d034c8

@juliusmarminge
juliusmarminge force-pushed the t3code/codex-turn-mapping branch 2 times, most recently from 877b9de to b82facd Compare September 5, 2026 04:52
mwolson and others added 6 commits September 4, 2026 21:54
…4457)

Update every deterministic Codex turn/start expectation with the explicit user approvals reviewer emitted by the adapter, restoring exact replay coverage and unblocking the merge lane.
…ojects (pingdotgg#3640)

Restore versioned shell-cache hydration, reconcile repository enrichment across multiple environments, and decode non-null settled shell timestamps correctly.
)

Normalize subagent result disclosure across timeline rendering and collapsed/expanded states.

Co-authored-by: codex <codex@users.noreply.github.com>
…dotgg#3754)

Expose MCP tools for worktree handoff and status inspection, with focused server and contract coverage.

Co-authored-by: codex <codex@users.noreply.github.com>
saphid and others added 8 commits September 6, 2026 04:24
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: shivam <91240327+shivamhwp@users.noreply.github.com>
…dotgg#9930)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: shivam <91240327+shivamhwp@users.noreply.github.com>
…tgg#9903)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
@Yusuf007R
Yusuf007R force-pushed the codex/fix-codex-paginated-thread-fork branch from 8d034c8 to e3fc9dd Compare September 7, 2026 17:09
@juliusmarminge
juliusmarminge force-pushed the t3code/codex-turn-mapping branch 5 times, most recently from ed5dc41 to 2b1139a Compare September 10, 2026 19:28
@juliusmarminge
juliusmarminge force-pushed the t3code/codex-turn-mapping branch 4 times, most recently from e03e376 to e39429e Compare September 12, 2026 08:17
saphid pushed a commit to saphid/t3code that referenced this pull request Sep 13, 2026
Retry/edit of an earlier turn in a paginated native Codex thread forked at
head and then issued thread/rollback, which paginated threads reject. Resolve
the selected provider turn nativeTurnRef and pass it as lastTurnId to
thread/fork so later turns are excluded atomically and no rollback is needed.
Fall back to fork-then-rollback only when no native reference is available,
and fail honestly when that fallback hits a paginated fork. rollbackThread now
probes historyMode and reports an explicit unsupported error for paginated
threads instead of sending a request Codex will reject.

Adapts the approach from pingdotgg#9169 by Yusuf007R.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@juliusmarminge
juliusmarminge force-pushed the t3code/codex-turn-mapping branch 2 times, most recently from 600a8a5 to d8c75ec Compare September 15, 2026 00:23
saphid pushed a commit to saphid/t3code that referenced this pull request Sep 15, 2026
Retry/edit of an earlier turn in a paginated native Codex thread forked at
head and then issued thread/rollback, which paginated threads reject. Resolve
the selected provider turn nativeTurnRef and pass it as lastTurnId to
thread/fork so later turns are excluded atomically and no rollback is needed.
Fall back to fork-then-rollback only when no native reference is available,
and fail honestly when that fallback hits a paginated fork. rollbackThread now
probes historyMode and reports an explicit unsupported error for paginated
threads instead of sending a request Codex will reject.

Adapts the approach from pingdotgg#9169 by Yusuf007R.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@juliusmarminge
juliusmarminge force-pushed the t3code/codex-turn-mapping branch 2 times, most recently from 463d0c6 to e10a1e2 Compare September 15, 2026 06:28
juliusmarminge pushed a commit to saphid/t3code that referenced this pull request Sep 15, 2026
Retry/edit of an earlier turn in a paginated native Codex thread forked at
head and then issued thread/rollback, which paginated threads reject. Resolve
the selected provider turn nativeTurnRef and pass it as lastTurnId to
thread/fork so later turns are excluded atomically and no rollback is needed.
Fall back to fork-then-rollback only when no native reference is available,
and fail honestly when that fallback hits a paginated fork. rollbackThread now
probes historyMode and reports an explicit unsupported error for paginated
threads instead of sending a request Codex will reject.

Adapts the approach from pingdotgg#9169 by Yusuf007R.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@juliusmarminge

Copy link
Copy Markdown
Member

Stale duplicate of #11490 — same native thread/fork boundary fix, rebased with additional fixtures. Thanks!

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.

8 participants