The plugin re-resolved its own enable state with supervision.enabled as
enabledByDefault, so an operator who only declared plugins.entries.codex.config
(auto-enabled by core) silently lost every codex setting, including
appServer.homeScope=user, whenever supervision was absent or off.
Use a live plugin config block as the plugin-side default, matching core's
plugin-tool-configured auto-enable and the onepassword convention. Supervision
stays gated in its own tool surface.
* feat(codex): fork upstream-linked sessions at a message via thread/fork
* fix(gateway): fail closed for rewind and branch switch on upstream-linked sessions
* fix(codex): fail closed on first-message forks, image-only prompts, and orphan archival
* fix(codex): baseline retained history and reject paginated threads on upstream fork
* fix(codex): validate the full fork prefix and fail closed across crash windows
* fix(codex): treat all non-text inputs as unverifiable in fork drift checks
* fix(codex): support first-message forks as empty-history upstream cuts
* fix(codex): reject source-id reuse and unverifiable hidden inputs in fork boundaries
* refactor(codex): materialize upstream forks from verified thread read-back
* fix(codex): satisfy strict type lanes and knip for upstream fork
The live codex text provider was a redundant projection of the openai
catalog (exclusive provider ownership; the openai plugin's ChatGPT OAuth
discovery already serves gpt-5.6-* route-aware). Folding it:
- extensions/codex no longer registers a text provider, catalog entry, or
synthetic text auth; provider.ts/provider-catalog.ts/provider-discovery.ts
and the route-blind model-name heuristics are deleted; the narrow
post-harness reasoning fallback moves to an app-server-owned module
- openai thinking policy keys on explicit selected-route provenance
(api === openai-chatgpt-responses) instead of value-shape inference
- models.list gains an optional additive agentRuntime field (configured
intent); session agentHarnessId remains the execution proof
- doctor --fix migrates the shipped codex/* config shape end to end:
every model slot, provider-config merge with blocker-aware conflict
handling, sessions, cron payloads (two-phase: runtime policy persists
before cron refs rewrite), transcripts; migrated refs carry model-scoped
agentRuntime.id=codex preserving the shipped wizard semantics; auto
runtime policies normalize to codex with sibling fields preserved;
blocked provider conflicts retain the whole legacy namespace fail-closed
with an actionable warning
- the stale openai:default profile cleanup (#91352) was deliberately
deferred to a follow-up after review showed it needs per-agent identity
proofs; doctor keeps warning about unusable profiles
Fixes#105561Fixes#84637Fixes#90420
* fix(codex): settle plugin activation, align plugin/list with codex 0.144, bound discovery per turn
- plugin/list curated queries omit cwds and marketplaceKinds (0.144 semantics:
explicit kinds disable the automatic global remote catalog; cwds:[] never
suppressed it), and the missing-marketplace check recognizes the current
openai-curated-remote wire name via the shared predicate (#107305)
- curated plugin/list snapshots settle in a process-local metadata cache
(coalesced, invalidated on install/identity change/restart, 1h freshness
window matching the app-inventory cache) so a missing marketplace or plugin
no longer re-runs blocking discovery RPCs on every embedded-Codex turn;
fail-open local-only responses (upstream warns without a load error when the
remote catalog fetch fails) are never cached, and workspace-directory
queries stay live because external activation has no invalidation signal
- the whole plugin-config build shares one bounded startup deadline with
remaining-budget propagation per RPC and a deny-all apps fallback, so a hung
plugin/list cannot consume the turn (#107305)
- guarded thread requests (start/resume/fork under the native-config fence)
must carry a finite timeout or abort signal, closing the unbounded-fence-hold
window for raw callers (#106719 hardening)
* chore(codex): keep plugin metadata types and deadline builder module-local
Deadline behavior tests exercise the production provider composition instead
of a test-only export.
- session_end with a provably different nextSessionKey (dashboard "New Chat",
fork child) no longer permanently retires the still-live parent Codex
binding; same-key rollovers, unknown-key ends, and terminal ends retire as
before (#106778)
- mirrored session-history reads treat well-formed non-Codex transcripts as an
empty mirror instead of a read failure, so codex harness hooks stop warning
on every non-Codex model run; corrupted session headers stay on the warn
path (#106556)
Adds Codex as a selectable hosted web-search provider, routes native Codex search safely across model overrides, and isolates bounded hosted-search workers from configured tools.\n\nVerification: focused post-merge regression suite passed 202/202 tests on exact head 23824af49a.
Harden the Codex app-server native execution bridge for OpenClaw sandboxed runs. The change keeps core sandbox policy in OpenClaw while exposing the process, filesystem, and HTTP relay behavior Codex needs inside a scoped exec server.
The large exec-server/test files were split into focused modules before landing, and the PR was rebased onto current main with focused tests, Testbox changed checks, CI, and Codex autoreview green.
Co-authored-by: joshavant <830519+joshavant@users.noreply.github.com>