feat(codex): share native threads across Codex clients#99821
Conversation
|
Codex review: needs real behavior proof before merge. Reviewed July 4, 2026, 2:38 AM ET / 06:38 UTC. Summary PR surface: Source +462, Tests +623, Docs +54. Total +1139 across 27 files. Reproducibility: yes. for the review findings: source inspection shows sparse fork attachments can be cleared by lifecycle fingerprint checks, and sandboxed sessions still block the tool's Review metrics: 2 noteworthy metrics.
Stored data model 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 findings
Review detailsBest possible solution: Fix the attach metadata and sandboxed fork blockers, refresh current-head live proof, keep isolated per-agent homes as the default, and then have maintainers explicitly accept or reject the native-home auth/session boundary. Do we have a high-confidence way to reproduce the issue? Yes for the review findings: source inspection shows sparse fork attachments can be cleared by lifecycle fingerprint checks, and sandboxed sessions still block the tool's Is this the best way to solve the issue? No as submitted: the default-off bundled-plugin direction is plausible, but the PR needs lifecycle-compatible binding, sandbox-safe fork handling, current-head proof, and maintainer acceptance of the native-home boundary. Full review comments:
Overall correctness: patch is incorrect AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against cafbd745c1b1. Label changesLabel changes:
Label justifications:
Evidence reviewedPR surface: Source +462, Tests +623, Docs +54. Total +1139 across 27 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
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5258a980c8
ℹ️ 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".
| await writeCodexAppServerBinding(sessionFile, { | ||
| threadId: forkThreadId, |
There was a problem hiding this comment.
Persist fork attachments with resume metadata
When codex_threads forks with attach=true, this writes only the thread id/cwd/model fields into the session binding. On the next Codex harness turn, startOrResumeThread compares binding metadata such as webSearchThreadConfigFingerprint and clears bindings whose fingerprint is missing or different before it ever calls thread/resume, so the advertised attach path silently starts a new thread instead of continuing the fork. Populate the same compatibility fingerprints/metadata used by normal lifecycle writes, or add a lifecycle path that treats this attach as an intentional resume.
Useful? React with 👍 / 👎.
| modelProvider?: string; | ||
| modelId?: string; | ||
| requesterSenderId?: string | null; | ||
| senderIsOwner?: boolean; |
There was a problem hiding this comment.
Forward owner state into plugin-only tool builds
This new owner bit does not reach all plugin tool factory calls: when a run has a narrow allowlist containing only plugin tools, createOpenClawCodingTools takes the pluginToolsOnly branch and passes requesterSenderId but not senderIsOwner into resolveOpenClawPluginToolsForOptions. In that context owner-gated factories like the new codex_threads factory see no owner and return null, so owners lose the tool whenever it is explicitly allowlisted without core OpenClaw tools. Pass options.senderIsOwner through that branch as well.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 404e1590b5
ℹ️ 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".
| } | ||
| const response = await request( | ||
| pluginConfig, | ||
| CODEX_CONTROL_METHODS.forkThread, |
There was a problem hiding this comment.
Allow codex_threads fork in sandboxed sessions
When this tool runs from a sandboxed OpenClaw session, the fork goes through codexControlRequest and requestOptions() includes the active sessionKey/sessionId; extensions/codex/src/app-server/sandbox-guard.ts:62 still classifies thread/fork as blocked-native-bypass, so resolveCodexNativeSandboxBlock throws before Codex is contacted. That makes the documented safe path—fork a native thread and attach it to the current OpenClaw session—fail for owners whose agent uses OpenClaw sandboxing; add a safe control-plane fork path or pass sandbox-aware parameters that the guard can allow.
Useful? React with 👍 / 👎.
|
Exact-head proof for
Intentional safety boundary: shared native |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f50b5191c6
ℹ️ 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".
| if (!sessionId) { | ||
| return undefined; | ||
| } | ||
| const storePath = runtime.agent.session.resolveStorePath(undefined, { |
There was a problem hiding this comment.
Resolve attachments from configured session store
When an installation uses a non-default session.store, this resolves the current session against the default per-agent store instead of context.config.session.store (the existing session readers, e.g. extensions/codex/src/conversation-binding.ts:883, pass the configured store). In that configuration codex_threads either cannot find the entry or writes the fork binding beside the wrong default transcript path, so attach=true appears to succeed but the next Codex harness turn reads the real session file and starts/resumes without the fork.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 3060c19d01
ℹ️ 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".
| if (params.authProfileId === null) { | ||
| return isolatedStartOptions; | ||
| return scopedStartOptions; |
There was a problem hiding this comment.
Keep user-home Codex auth from inherited API keys
When appServer.homeScope is "user", resolveCodexAppServerClientStartContext passes authProfileId: null, so this branch returns before the existing withClearedEnvironmentVariables(...CODEX_API_KEY, OPENAI_API_KEY...) protection runs. In a Gateway process that already has OPENAI_API_KEY or CODEX_API_KEY for other OpenClaw/OpenAI usage, a shared-user-home app-server spawned against a ChatGPT-authenticated native ~/.codex can still inherit those API-key env vars and run under API-key auth instead of the user's native Codex account, which contradicts the new shared-home/native-auth mode and can bill or route through the wrong account. Clear inherited API-key env vars for user-home native auth unless the key is explicitly configured for this app-server launch.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b9e5670f69
ℹ️ 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".
| const requestedStartOptions = | ||
| options?.startOptions ?? resolveCodexAppServerRuntimeOptions().start; | ||
| const usesNativeAuth = | ||
| options?.authProfileId === null || requestedStartOptions.homeScope === "user"; |
There was a problem hiding this comment.
Preserve native auth for user-home OpenAI turns
When homeScope: "user" is used with an agent routed through provider openai, this marks the app-server startup as native-auth but then returns authProfileId: undefined; the thread lifecycle only suppresses modelProvider: "openai" when isCodexAppServerNativeAuthProfile(...) sees a real native auth profile (extensions/codex/src/app-server/thread-lifecycle.ts:1792). Since the Codex harness explicitly supports openai as well as codex (extensions/codex/harness.ts:16), those user-home turns still send the public OpenAI provider override instead of letting Codex use the native user account/config promised by the new mode. Carry a native-auth/home-scope marker into model-provider selection, or otherwise omit the override for user-home native auth.
Useful? React with 👍 / 👎.
|
Land-ready verification for the resynced exact head
The existing isolated per-agent Codex home remains the default. Shared user-home mode is explicit, local-stdio-only, owner-only for thread management, and documented with its native credential/state and cross-process writer boundaries. |
|
Merged via squash.
|
* feat(codex): share native threads across clients * test(codex): track coexistence temp dirs * fix(codex): preserve native source on thread forks * test(codex): use public temp fixtures * fix(codex): preserve owner context for deferred tools * fix(codex): forward owner identity to dynamic tools * fix(codex): forward owner status to harness attempts * docs(security): document shared Codex home * docs(security): document shared Codex home * docs(security): document shared Codex home
Closes #99781
What Problem This Solves
OpenClaw's Codex harness isolates each agent in a private Codex home, so threads created in Codex Desktop or the CLI are invisible to OpenClaw, and OpenClaw-created threads are invisible to native Codex clients.
Why This Change Was Made
Adds an opt-in
appServer.homeScope: "user"mode that connects the stdio app-server to the native user Codex home and authentication. An owner-onlycodex_threadstool lists, reads, forks, renames, archives, and restores native threads; continuation is fork-first so two clients never write the same thread concurrently.The existing per-agent isolated home remains the default. Shared-user-home mode is intentionally rejected for remote WebSocket transports.
User Impact
Operators can opt a Codex-backed OpenClaw agent into the same thread store used by Codex Desktop and the CLI, inspect and manage those native threads from OpenClaw, and attach a safe native fork to the current OpenClaw session.
Evidence
OPENCLAW_LIVE_TEST=1 OPENCLAW_LIVE_CODEX_THREAD_COEXISTENCE=1 node scripts/test-live.mjs -- extensions/codex/src/native-thread-coexistence.live.test.ts).corepack pnpm build).