Prevent Codex thread rotation from losing next-step context#94093
Conversation
|
Codex review: needs real behavior proof before merge. Reviewed June 18, 2026, 1:46 PM ET / 17:46 UTC. Summary PR surface: Source +86, Tests +107. Total +193 across 4 files. Reproducibility: yes. at source level: current main omits maxRenderedContextChars in the no-context-engine fresh and stale projection paths while the projection helper defaults missing caps to 24,000 rendered characters. I did not run a live high-window Codex session in this read-only review. Review metrics: 2 noteworthy metrics.
Root-cause cluster Members:
Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything. Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Proof guidance:
Risk before merge
Maintainer options:
Next step before merge
Security Review detailsBest possible solution: Land this candidate for #84084 after real redacted app-server proof or an explicit maintainer proof override; keep the narrower overlapping PRs non-canonical unless maintainers choose a replacement. Do we have a high-confidence way to reproduce the issue? Yes at source level: current main omits maxRenderedContextChars in the no-context-engine fresh and stale projection paths while the projection helper defaults missing caps to 24,000 rendered characters. I did not run a live high-window Codex session in this read-only review. Is this the best way to solve the issue? Yes for the code direction: the PR reuses the existing budget helper, handles the stale-binding forced-fresh edge, and trims only projected context to Codex's upstream input cap. The remaining blocker is real-path proof or maintainer override, not an identified code defect. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against a48e5091cba7. Label changesLabel justifications:
Evidence reviewedPR surface: Source +86, Tests +107. Total +193 across 4 files. View PR surface stats
What I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
|
b882885 to
8dad0ca
Compare
2383950 to
1f3ced8
Compare
|
Merged via squash as a maintainer decision.
Thanks @VACInc! |
* 'main' of https://github.com/openclaw/openclaw: (82 commits) fix(e2e): validate chat tools body limit fix(e2e): honor chat tools body limit fix(e2e): validate chat tools timeout fix(e2e): give cleanup smoke build heap headroom fix(e2e): validate plugin lifecycle limits refactor(auto-reply): add lifecycle storage seams (#93685) fix: preserve pending subagent completion announces (#94349) fix(e2e): validate plugin log limits before setup fix(e2e): validate codex media timeout fix(e2e): validate fixture log limits fix(e2e): validate cleanup log limits fix(e2e): validate docker log limits fix(live): validate docker pids limits fix(e2e): validate docker pids limits test: fold channel message flows into qa e2e (#93174) fix(e2e): validate docker build limits Prevent Codex thread rotation from losing next-step context (#94093) fix(e2e): validate fixture cleanup interval fix(agents): correct claw-score validation workflow fix(e2e): validate log tail limits ...
…#94093) Merged via squash. Prepared head SHA: 1f3ced8 Maintainer decision: `checks-node-core-tooling` is an unrelated baseline/tooling failure; PR-relevant CI and real behavior proof passed. Co-authored-by: VACInc <[email protected]> Co-authored-by: jalehman <[email protected]> Reviewed-by: @jalehman
* 'main' of https://github.com/openclaw/openclaw: (82 commits) fix(e2e): validate chat tools body limit fix(e2e): honor chat tools body limit fix(e2e): validate chat tools timeout fix(e2e): give cleanup smoke build heap headroom fix(e2e): validate plugin lifecycle limits refactor(auto-reply): add lifecycle storage seams (openclaw#93685) fix: preserve pending subagent completion announces (openclaw#94349) fix(e2e): validate plugin log limits before setup fix(e2e): validate codex media timeout fix(e2e): validate fixture log limits fix(e2e): validate cleanup log limits fix(e2e): validate docker log limits fix(live): validate docker pids limits fix(e2e): validate docker pids limits test: fold channel message flows into qa e2e (openclaw#93174) fix(e2e): validate docker build limits Prevent Codex thread rotation from losing next-step context (openclaw#94093) fix(e2e): validate fixture cleanup interval fix(agents): correct claw-score validation workflow fix(e2e): validate log tail limits ...
…#94093) Merged via squash. Prepared head SHA: 1f3ced8 Maintainer decision: `checks-node-core-tooling` is an unrelated baseline/tooling failure; PR-relevant CI and real behavior proof passed. Co-authored-by: VACInc <[email protected]> Co-authored-by: jalehman <[email protected]> Reviewed-by: @jalehman
Summary
turn/starttext-input limits without truncating the current user request, even when prior transcript text contains projection delimiter strings.End-user issue
A user can leave a long channel session open, come back hours later or the next day, and ask the agent to continue the work. The OpenClaw session may still be the same session, but the Codex native app-server thread may have been rotated under token pressure while the topic accumulated enough history.
Before this change, that rotation could make the next answer feel forgetful: the agent might miss the previously agreed next steps, ask the user to repeat context, or continue from only the recent tail of the conversation. This is especially visible in long-lived GPT/Codex channel sessions because the user experience looks like an idle-session reset even when no OpenClaw idle or max-age reset happened.
This PR does not make conversation memory unlimited and does not disable compaction. It makes the continuity bridge less lossy when OpenClaw has to start a fresh native Codex thread from the mirrored session history.
Root Cause
OpenClaw keeps Codex app-server conversation continuity in native Codex threads, while the mirrored OpenClaw transcript is persistence/search state. When a Codex native thread was unavailable or had to be replaced under token pressure, the no-context-engine continuity paths called
projectContextEngineAssemblyForCodexwithoutmaxRenderedContextChars.That omitted option made the projection helper fall back to its conservative 24,000 character rendered-context cap. In long-running channel topics, a token-pressure native thread rotation could therefore preserve only a small tail of the prior discussion, dropping older next-step or handoff context even though the OpenClaw session itself had not idle-reset.
There was a second loss path once stale native bindings were involved. OpenClaw correctly precomputed a small stale-resume projection containing only messages newer than the native binding because a resumed Codex thread already owns the older history. But if token pressure then discarded that native thread and started fresh, the older native-owned history was no longer available in Codex. The forced fresh start could still reuse the stale-resume delta, so the first turn on the new native thread only received post-binding context.
The app-server also rejects oversized
turn/starttext input before compaction can help. The final patch records the generated projected-context byte range and trims only that range after OpenClaw prompt wrappers are applied, preserving the current user request while keeping the final app-server input under Codex's text-input cap.RCA proof from the reported private topics was redacted for PPI: the session configuration had no idle/max-age reset, while local logs showed Codex native token-limit fresh-thread rotations for the affected topic. One rotation rebuilt the turn prompt with a small prompt after a stale binding had been cleared, matching the code path above and explaining why the next answer could look like it forgot the plan after returning later.
Real behavior proof
Behavior addressed: Codex fresh native thread continuity keeps the same scaled projection budget used by the active context-engine path, forced fresh starts rebuild from mirrored session history once the native thread binding is discarded, and oversized projected context is fitted under Codex app-server
turn/starttext-input limits without truncating the current user request.Real environment tested: local OpenClaw source checkout, Codex app-server Vitest shard, local formatting check, local diff whitespace check, Codex autoreview.
Exact steps or command run after this patch:
Evidence after fix:
Observed result after fix: the fresh-thread regression keeps older continuity anchors placed before enough filler that the old default cap would truncate them, the forced-rotation regression keeps both pre-binding native-owned context and post-binding stale context when
thread/resumeis skipped andthread/startis used, and the new oversized-turn regression keeps the finalturn/startinput at or below Codex's text-input cap while preserving recent continuity and the current user request. The delimiter regression includes the full generated</conversation_context>/Current user request:separator inside old transcript content to prove quoted history cannot spoof the projected-context boundary.What was not tested:
check:changed/CI locally to avoid unnecessary load for this Codex app-server continuity patch.Verification
git diff --check -- extensions/codex/src/app-server/context-engine-projection.ts extensions/codex/src/app-server/context-engine-projection.test.ts extensions/codex/src/app-server/run-attempt.ts extensions/codex/src/app-server/run-attempt.test.tspnpm exec oxfmt --check --threads=1 extensions/codex/src/app-server/context-engine-projection.ts extensions/codex/src/app-server/context-engine-projection.test.ts extensions/codex/src/app-server/run-attempt.ts extensions/codex/src/app-server/run-attempt.test.tsnode scripts/run-vitest.mjs extensions/codex/src/app-server/run-attempt.test.ts extensions/codex/src/app-server/context-engine-projection.test.ts -- -t "projects bounded continuity|preserves stale-binding continuity|keeps large fresh-thread continuity|fits projected context" --reporter=verbose.agents/skills/autoreview/scripts/autoreview --mode local --prompt "Review only the updated local PR #94093 Codex app-server continuity input-limit patch..."