codex plugin.
For setup and routing decisions, start with
Codex harness.
Plugin config surface
All Codex harness settings live underplugins.entries.codex.config.
Supervision
Native session discovery lists non-archived Codex sessions from the Gateway computer and opted-in paired nodes by default. Disable only that catalog with:CODEX_HOME or
~/.codex) and the Codex home of every configured OpenClaw agent. Register
additional local Codex stores only when sessions live in a home OpenClaw does
not already know about, for example a store created with a custom CODEX_HOME
outside OpenClaw:
Local Codex · <label> and grouped by each session’s working
directory. String entries and objects without label use the basename of the
canonicalized home directory; an explicit label overrides that default.
Sessions in these stores support the same view, continue, and archive actions,
and the selected OpenClaw agent still owns the resulting connection; homes
only adds catalog sources.
Only existing directories are included. Equivalent paths are canonicalized and
deduplicated against the automatic homes, and automatic homes keep priority
under the 100-source catalog cap. Changes require a Gateway restart.
sessionCatalog.homes needs the default managed stdio app-server transport;
Unix and WebSocket transports reject it with a visible error because they
cannot start a source-bound app-server for each home.
supervision separately controls agent-facing tools:
Endpoint entries accept these fields:
The Codex Sessions page uses the plugin’s supervision App Server and shows
only non-archived sessions. Without explicit
appServer connection settings,
that connection is managed user-home stdio. Stored or idle local rows can create
a model-locked Chat with bounded user and assistant history through the last
terminal persisted source turn. Its private binding keeps the snapshot fork,
canonical appServer-source branch, history injection, and later turns on that
connection. The first canonical start uses the pair returned by the fork. Later
resumes omit OpenClaw model and provider overrides so Codex restores the
canonical thread’s persisted pair; a separate native change can update that
pair, but the outer model and fallback chain never replace it. Stored and idle
rows can be archived after no-other-runner confirmation, unless another active
OpenClaw binding owns the exact target or one of its non-archived spawned
descendants. OpenClaw follows Codex’s descendant pagination and fails closed on
enumeration errors, cycles, or safety-limit exhaustion. Confirmation still
covers unknown native clients and the status-to-archive race. A supervised
model-locked Chat cannot be deleted while it protects the native binding.
Active sources cannot create a branch or be archived, but an existing supervised
Chat can still be opened. Paired-node continuation requires operator.admin, a
stored or idle interactive thread, and a connected node advertising and
permitting the catalog list, transcript read, and codex.cli.session.resume
commands. It binds Chat to native CLI resume on that node, not the local branch
flow or a streaming App Server harness. Other paired-node rows remain readable,
and paired-node archive is unavailable. See
paired-node limits.
appServer.homeScope: "user" alone changes which Codex home a managed harness
process uses; it does not publish the fleet catalog. Enabling supervision does
not change the harness default. Instead, the separate supervision connection
defaults to managed user-home stdio when no explicit appServer
connection settings exist. Explicit settings are honored for that connection.
Pending and committed supervised bindings retain that connection for every turn;
disabled supervision or connection/lifecycle drift fails closed instead of
falling back to the agent-home harness. The default connection shares stored
sessions with native Codex clients, not their process-local activity state.
Legacy plugins.entries.codex-supervisor settings are retired. Run
openclaw doctor --fix to migrate the old entry, endpoint definitions, policy
flags, and plugin allow/deny references into this block. Explicit canonical
codex.config.supervision values win conflicts.
App-server transport
For ordinary harness turns, OpenClaw starts the managed Codex binary shipped with the official plugin (currently@openai/codex 0.153.4):
codex plugin instead of
whichever separate Codex CLI happens to be installed locally. OpenClaw resolves
@openai/codex/bin/codex.js from the loader-selected plugin root using Node
package resolution, including npm-hoisted and pnpm-linked dependencies. It does
not search .bin shims or global PATH for managed startup. On Windows, Node
runs the same package entrypoint without requiring a codex.cmd shim.
Set appServer.command only when you intentionally want a different executable.
Ordinary managed turns with the default isolated agent home prefer this pinned
package even when a macOS desktop bundle is installed. When
Computer Use is enabled, or when homeScope is
"user" and can load native Computer Use state, managed startup instead prefers
the desktop app binary that owns the required macOS permissions. The same
desktop-first rule applies when an isolated agent home’s effective Codex config
enables native Computer Use. If no desktop app bundle is installed, OpenClaw
falls back to the pinned package binary.
Before cutting over a staged OpenClaw package, run the opt-in managed-binary
check against the candidate installation:
appServer connection settings, it uses managed stdio with homeScope: "user";
the ordinary harness remains managed stdio with homeScope: "agent". Explicit
connection settings are honored by both paths. Set homeScope: "user"
explicitly when the ordinary harness should share $CODEX_HOME (or ~/.codex)
with native clients. A private supervised binding uses the supervision
connection regardless of the ordinary harness default. Independent App Server
processes retain separate live status and approval state.
For non-production testing against an already-running app-server, WebSocket
transport is available:
appServer fields:
appServer.args accepts an array (recommended) or a quoted argument string.
OPENCLAW_CODEX_APP_SERVER_ARGS uses the same string parsing on every platform:
single and double quotes group words, backslashes and # stay literal, and an
unfinished quote groups the remaining text. This preserves the string grammar
shipped in v2026.9.1; strings do not use shell escaping.
Use array entries for values containing embedded quotes, such as
'model="gpt-5.6-luna"'. For a directory containing a literal backslash, both
forms below pass the same path to Codex:
validate=false
validate=false
\\ in JSON5 encodes one backslash. Array entries preserve embedded quotes
and backslashes, but surrounding whitespace is trimmed and empty entries are
omitted. Strings also omit empty quoted arguments. Account for these limits
before converting existing strings to arrays.
appServer.serviceTier is used only when no shared Fast-mode run control is
supplied. On Codex harness turns, shared Fast on sends priority, Fast off
sends null to clear the OpenClaw-owned tier, and auto decides for each model
call. /codex fast off is separate: it persists flex in the bound native
conversation preference for later conversation-bound turns and does not change
the shared OpenClaw session policy. These values describe native configuration
and preference state, not observed provider routing.
appServer.networkProxy is explicit because it changes the Codex sandbox
contract. When enabled, OpenClaw also sets features.network_proxy.enabled and
default_permissions in the Codex thread config so the generated permission
profile can start Codex-managed networking. OpenClaw generates a
collision-resistant openclaw-network-<fingerprint> profile name from the
profile body by default; use profileName only when a stable local name is
required.
danger-full-access, enabling
networkProxy uses workspace-style filesystem access for the generated
permission profile instead. Codex-managed network enforcement is sandboxed
networking, so a full-access profile would not protect outbound traffic.
The plugin manages stable Codex app-server 0.153.4. Explicit custom
executables, remote app-servers, and macOS desktop binaries must report a
parseable semantic version of 0.149.0 or newer. Older, malformed, and
unversioned handshakes are rejected. Newer versions log a compatibility warning
and continue through normal runtime and capability validation.
OpenClaw treats non-loopback WebSocket app-server URLs as remote and requires
identity-bearing WebSocket auth through appServer.authToken or an
Authorization header. appServer.authToken and each appServer.headers.*
value can be a SecretInput; the secrets runtime resolves SecretRefs and env
shorthand before OpenClaw builds app-server start options, and unresolved
structured SecretRefs fail before any token or header is sent.
When native Codex plugins are configured, OpenClaw caches one
runtime-and-workspace-scoped plugin/installed snapshot. This snapshot covers
installed plugins from Codex-discovered marketplaces, including disabled ownership;
plugin/read resolves only exact configured plugin identities. Failed or
incomplete installed snapshots are never cached. /codex plugins available
queries plugin/list for the current conversation workspace, while
/codex plugins install <plugin>@<marketplace> installs only after an owner or
operator.admin explicitly authorizes that plugin. Existing explicitly
configured curated plugins retain their automatic recovery path. The model’s
plugin-discovery tool cannot install, enable, or authenticate a plugin.
app/installed reports installed app runtime state, and app/read returns
authenticated metadata for at most 100 requested app IDs per call. OpenClaw
force-refreshes the first cold installed snapshot and consolidates successful
curated installations into one app-inventory refresh. Later cached reads do
not force repeated connector refreshes.
Deny-by-default Codex app policy is evaluated per thread, so an explicitly
allowed app can be installed and authenticated before it becomes callable.
OpenClaw provisionally admits only ownership-proven, policy-approved apps,
creates the thread with _default.enabled = false and explicit app overrides,
then calls app/installed once with that thread’s ID and forceRefresh: false.
If that snapshot reports missing, disabled, or non-callable apps, OpenClaw logs
one warning and continues with the remaining tools. Codex still enforces
managed restrictions, workspace policy, and app/tool permissions; unavailable
apps gain no access.
The check completes before OpenClaw injects history, starts a turn, or
persists the native thread binding. If the snapshot request fails, OpenClaw deletes a persistent
provisional thread with thread/delete or unsubscribes an ephemeral thread
with thread/unsubscribe. If safe cleanup cannot be confirmed, it retires the
owning app-server connection. Supervised branches also clean up their temporary
probe and retain recovery state when cleanup fails.
With allow_all_plugins, an explicitly disabled configured workspace plugin
still denies its owned apps. When app/read does not expose that ownership,
OpenClaw uses its plugin/installed snapshot and reads only the exact
configured plugin’s details to reserve the denied app IDs. It does not scan
unrelated marketplaces or install, enable, or authenticate the disabled plugin;
missing ownership fails closed.
Only connect OpenClaw to a 0.149.0 or newer remote app-server trusted to accept
configured marketplace plugin installs and inventory refreshes. Missing modern
inventory methods and server, authentication, or transport failures fail closed.
Approval and sandbox modes
Local stdio app-server sessions default to YOLO mode:approvalPolicy: "never", approvalsReviewer: "user", and
sandbox: "danger-full-access". This trusted local operator posture lets
unattended OpenClaw turns and heartbeats make progress without native approval
prompts that nobody is around to answer.
If Codex’s local system requirements file disallows implicit YOLO approval,
reviewer, or sandbox values, OpenClaw treats the implicit default as guardian
instead and selects allowed guardian permissions. tools.exec.mode: "auto"
also forces guardian-reviewed Codex approvals and does not preserve unsafe
legacy approvalPolicy: "never" or sandbox: "danger-full-access" overrides;
set tools.exec.mode: "full" for an intentional no-approval posture.
Hostname-matching [[remote_sandbox_config]] entries in the same requirements
file are honored for the sandbox default decision.
Set appServer.mode: "guardian" for Codex guardian-reviewed approvals:
guardian preset expands to approvalPolicy: "on-request",
approvalsReviewer: "auto_review", and sandbox: "workspace-write" when those
values are allowed. Individual policy fields override mode. The older
guardian_subagent reviewer value is still accepted as a compatibility alias,
but new configs should use auto_review.
When an OpenClaw sandbox is active, the local Codex app-server process still
runs on the Gateway host. OpenClaw therefore disables Codex native Code Mode,
user MCP servers, and app-backed plugin execution for that turn instead of
treating Codex host-side sandboxing as equivalent to the OpenClaw sandbox
backend. Shell access is exposed through OpenClaw sandbox-backed dynamic tools
such as sandbox_exec and sandbox_process when the normal exec/process tools
are available.
On Docker-backed OpenClaw sandbox hosts (
agents.defaults.sandbox.mode set to
a Docker backend), openclaw doctor probes whether the host allows the
unprivileged user (and, when Docker sandbox network egress is disabled,
network) namespaces that nested Codex bwrap needs for workspace-write
shell execution inside the sandbox container. A failed probe usually surfaces
as bwrap: setting up uid map: Permission denied or
bwrap: loopback: Failed RTM_NEWADDR: Operation not permitted on
Ubuntu/AppArmor hosts. Fix the reported host namespace policy for the OpenClaw
service user and restart the gateway; prefer a scoped AppArmor profile for the
service process over the host-wide
kernel.apparmor_restrict_unprivileged_userns=0 fallback, and do not grant
broader Docker container privileges just to satisfy nested bwrap.Sandboxed native execution
The stable default is fail-closed: active OpenClaw sandboxing disables native Codex execution surfaces that would otherwise run from the Codex app-server host. UseappServer.experimental.sandboxExecServer: true only when you want
to try Codex’s remote environment support with OpenClaw’s sandbox backend.
This preview path uses the pinned Codex 0.153.4 app-server.
remote-exec placement on a paired device or enrolled Crabbox
cloud worker is a separate, placement-owned execution path and does not require
appServer.experimental.sandboxExecServer. The Gateway keeps Codex
app-server and provider auth local, while the authorized node runs the managed,
pinned Codex exec-server over its existing duplex connection. It requires
explicit gateway.nodes.commands.allow authorization for
codex.exec-server.stdio.v1, the approved pairing surface, and launch
authorization for each attempt. A deliberately selected session Full access
permission can replace the critical allow-once prompt only while the exact
admitted turn and placement remain current and both node-local tools.exec
and exec-approvals floors allow full/off execution. Ordinary and raw callers
still require human approval. Local deny blocks either launch; local ask and
allowlist policies cannot be bypassed with Full access. Changed local policy
during setup refuses the launch. Gateway and node must both support this
authorization path; missing node policy support fails closed. The node receives a
fresh private home and sanitized environments, never Gateway provider, cloud,
or GitHub credentials. A lost node connection terminates the attempt and
process instead of resuming it. Each node-backed attempt uses its own Gateway
app-server client because Codex can register a remote environment but cannot
remove one from a running app-server. The node exec-server does not consume an
OpenClaw worker slot. HTTP requests containing authentication, cookies, API
keys, or other credential-bearing headers are rejected before reaching the
node; use a Gateway-owned authenticated request or a credential-free endpoint
instead.
Normal Codex turns are supported, but /btw side questions are unavailable
until they can be bound to the active placement.
The managed placement workspace is not an OS sandbox: approved processes and
files have the node account’s full access. Use a separate least-privilege node
account when isolation is required.
See Run Codex on a paired device
and Run Codex on a cloud worker.
Auth and environment isolation
In the default per-agent home, stdio launches use Codex’s ephemeral credential store, including custom commands selected byappServer.command or
OPENCLAW_CODEX_APP_SERVER_BIN. Command wrappers must forward Codex’s -c
configuration arguments. For stdio launches with an explicit app-server
subcommand, OpenClaw groups -c / --config overrides before that subcommand,
preserving their order and leaving wrapper prefixes and other arguments in place.
This prevents Codex from dropping earlier overrides when flags appear on both
sides of app-server. OpenClaw’s ephemeral credential-store override remains
last when OpenClaw owns auth; native user-home auth is unchanged.
Workspace-write turns also preserve explicit sandbox_workspace_write temporary
root exclusions from these arguments, including attached -ckey=value flags
and TOML comments after boolean values. The last explicit value wins.
Explicit turn sandbox policies and network-proxy permission profiles keep their
existing precedence.
OpenClaw supplies auth in this order:
- An explicit or ordered OpenClaw auth profile for the agent.
- For an API-key route only, a prepared key or local stdio fallback from
CODEX_API_KEY, thenOPENAI_API_KEY.
codex-home/auth.json in
this mode. Import that file explicitly as described below. Set
appServer.homeScope: "user" only when the app-server should instead own and
use the operator’s native Codex account.
No credential file is written in this mode, in either home. A subscription
profile is handed over as an account/login/start request of type
chatgptAuthTokens, which Codex installs as in-memory external auth rather
than persisting; the ephemeral credential store covers the API-key login,
which would otherwise write CODEX_HOME/auth.json.
Token refresh is inverted so the long-lived secret never leaves OpenClaw. Codex
holds only a short-lived access token, and on an unauthorized response it sends
an account/chatgptAuthTokens/refresh request back to OpenClaw over the same
connection. OpenClaw refreshes against its own auth profile store and returns a
fresh access token, so the refresh token stays in SQLite. A refresh that does
not answer within the app-server’s timeout fails that turn rather than falling
back to another credential. A failed refresh retires the shared client from
reuse; existing leases drain, and the next request starts a fresh client. If the
workspace changed, retry the request. If credentials cannot refresh, sign in
again with openclaw models auth login --provider openai and select that profile.
Shared clients recheck the selected profile before reuse so changing accounts
under the same profile ID also selects a new client.
When OpenClaw sees a ChatGPT subscription-style Codex auth profile (OAuth or
token credential type), it removes CODEX_API_KEY and OPENAI_API_KEY from
the spawned Codex child process. That keeps Gateway-level API keys available
for embeddings or direct OpenAI models without making native Codex app-server
turns bill through the API by accident.
Explicit Codex API-key profiles and local stdio env-key fallback use
app-server login instead of inherited child-process env. WebSocket app-server
connections do not receive Gateway env API-key fallback; use an explicit auth
profile or the remote app-server’s own account.
Stdio app-server launches inherit OpenClaw’s process environment by default.
OpenClaw owns the Codex app-server account bridge and sets CODEX_HOME to a
per-agent directory under that agent’s OpenClaw state. That keeps Codex
config, accounts, plugin cache/data, and thread state scoped to the OpenClaw
agent instead of leaking in from the operator’s personal ~/.codex home.
Set appServer.homeScope: "user" to share native Codex state with Codex
Desktop and the CLI. This local user-home mode supports managed stdio and
explicit Unix transport. It uses $CODEX_HOME when set and ~/.codex
otherwise, including native auth, config, plugins, and threads.
OpenClaw skips its auth-profile bridge for the app-server. Verified owner
turns can use codex_threads to list (with an optional search filter),
read, fork, rename, archive, and unarchive those threads. Fork a thread before
continuing it in OpenClaw; independent Codex processes do not coordinate
concurrent writers for the same thread.
That homeScope opt-in applies to ordinary harness sessions. Hosted web search
and settled-turn finalization use private temporary homes and OpenClaw auth
even when ordinary sessions share the user home. A Chat created
through Codex Sessions uses its private supervision connection instead, which
preserves the native connection’s auth and provider configuration for the
canonical branch and future resumes. If that supervised turn finishes tool work
without a final answer, OpenClaw does not borrow host credentials to generate
one. It delivers the settled-tool fallback
without repeating completed actions.
In a model-locked supervised Chat, codex_threads cannot attach a different
fork or archive the Chat’s bound native thread. List and metadata-only read
remain available. Raw transcript reads require allowRawTranscripts; when it
is disabled, list search is also rejected because native search can match
transcript previews. Rename, unarchive, detached fork, and archive of an
unrelated thread not owned by another OpenClaw Chat require
allowWriteControls. Neither option bypasses a locked binding.
OpenClaw does not rewrite HOME for normal local app-server launches.
Codex-run subprocesses such as openclaw, gh, git, cloud CLIs, and shell
commands see the normal process home and can find user-home config and
tokens. Codex may also discover $HOME/.agents/skills and
$HOME/.agents/plugins/marketplace.json; that .agents discovery is
intentionally shared with the operator home and is separate from isolated
~/.codex state.
In the default agent scope, OpenClaw plugins and OpenClaw skill snapshots
still flow through OpenClaw’s own plugin registry and skill loader; personal
Codex ~/.codex assets do not. If you have useful Codex CLI skills or
plugins from a Codex home that should become part of an isolated OpenClaw
agent, inventory them explicitly:
codex-home/auth.json directly. Replace
<agent-id> with the configured agent that owns this Codex home:
appServer.clearEnv:
appServer.clearEnv only affects the spawned Codex app-server child process.
OpenClaw removes CODEX_HOME and HOME from this list during local launch
normalization: CODEX_HOME stays pointed at the selected agent or user scope,
and HOME stays inherited so subprocesses can use normal user-home state.
Dynamic tools
Codex dynamic tools default tosearchable loading, exposed under the
openclaw namespace with deferLoading: true. OpenClaw normally does not
expose dynamic tools that duplicate Codex-native workspace operations or
Codex’s own tool-search surface:
readwriteeditapply_patchexecprocesstool_calltool_describetool_searchtool_search_code
progress_card is not filtered with those native workspace tools. It remains
available through the OpenClaw dynamic-tool bridge as the durable session status
surface.
When a finite runtime allowlist disables native Code Mode, OpenClaw sends an
empty execution-environment selection. In that direct, unsandboxed case,
OpenClaw keeps its policy-filtered exec and process tools as the shell
fallback. Runtime allowlists and codexDynamicToolsExclude still apply.
Most remaining OpenClaw integration tools, such as messaging, media, cron,
browser, nodes, gateway, heartbeat_respond, and web_search, are available
through Codex tool search under that namespace. This keeps the initial model
context smaller. A small set of tools stay directly callable regardless of
codexDynamicToolsLoading, because Codex tool search can be unavailable or
resolve a connector-only universe: agents_list, sessions_spawn, and
sessions_yield. Developer instructions still steer normal Codex subagents
toward native spawn_agent for Codex-native subagent work, while
sessions_spawn remains available for explicit OpenClaw or ACP delegation.
Message-tool-only source replies also stay direct, since that is a
turn-control contract.
Codex Code Mode projects generic OpenClaw dynamic-tool results as text. Parse a
JSON result before reading fields. Nested dynamic calls are serialized by the
Codex runtime, so Promise.all does not submit them concurrently; use a
bounded sequential launch loop when starting collector children.
Tools marked catalogMode: "direct-only", including the OpenClaw computer
tool and regular-agent openclaw delegation, are grouped under openclaw_direct.
OpenClaw adds that namespace to Codex’s
features.code_mode.direct_only_tool_namespaces list without replacing
operator-supplied entries. Codex therefore exposes those tools as
DirectModelOnly in normal and code-mode-only threads instead of routing them
through nested Code Mode tools.* calls. This preserves image-bearing results,
which nested Code Mode otherwise flattens to text. It also keeps delegated human
approval on the direct model call: a yielded script cell must not let the model
finish its turn while that approval is still waiting.
Set codexDynamicToolsLoading: "direct" only when connecting to a custom
Codex app-server that cannot search deferred dynamic tools or when debugging
the full tool payload.
Timeouts
OpenClaw-owned dynamic tool calls are bounded independently fromappServer.requestTimeoutMs. Ordinary Codex item/tool/call requests use the
first available timeout in this order:
- A positive per-call
timeoutMsargument. - For
image_generate,agents.defaults.mediaModels.image.timeoutMs. - For
image_generatewithout a configured timeout, the 120 second image-generation default. - For the media-understanding
view_imagetool, the selected image-capabletools.media.models[]entry’stimeoutSecondsconverted to milliseconds, or the 60 second media default. For image understanding, this applies to the request itself and is not reduced by earlier preparation work. - For the
messagetool, a fixed 600 second outer budget that covers Gateway delivery and bounded same-key reconciliation. - The 90 second dynamic-tool default.
item/tool/call budget. Provider-specific
request timeouts run inside that call and keep their own timeout semantics.
Ordinary dynamic tool budgets are capped at 600000 ms. agents_wait adds 30000 ms
of outer completion grace. Human-interaction tools use the validated question
wait plus 30000 ms: ask_user and secrets credential requests honor their question
timeout, while delegated openclaw calls use the fixed 930000 ms default. That
budget covers the ten-minute approval window plus staging and application;
model-authored arguments cannot override it. The app-server request watchdog
leaves another 30000 ms beyond the applicable tool budget for the result to reach
Codex.
On timeout, OpenClaw aborts the tool signal where supported and returns a failed
dynamic-tool response to Codex so the turn can continue instead of leaving the
session in processing. These wait budgets never preserve approval authority
after the requesting run or tool closes.
Turn execution and settlement
Native Codex owns provider-stream liveness, network recovery, and native turn completion. For ordinary turns, OpenClaw waits forturn/completed with the
exact thread and turn identity, or an authoritative failure or cancellation.
Silence, completed tool output, and a completed-looking assistant message do
not prove that the turn has finished. Partial output remains available on
failure, but OpenClaw does not upgrade a timeout or lost client into success.
The existing agents.defaults.timeoutSeconds setting supplies one elapsed
execution budget per attempt, defaulting to 48 hours. Progress does not reset
that budget, including during long tool execution. Set it to 0, or use a
per-run timeout of 0, for unlimited execution. Native connection recovery
can keep retrying, so a provider-stream timeout is not a whole-turn deadline.
An unlimited native wait ends only on a native terminal outcome, an
authoritative failure, or explicit Stop. Startup, app-server control requests,
approvals, dynamic tools, and cancellation retain their independent deadlines.
/btw side questions retain their separate ten-minute completion budget.
On receipt of the exact native terminal event, OpenClaw starts an absolute
two-minute local-settlement budget before asynchronous transcript and media
projection. Later notifications do not reset it. Presentation callbacks start
in order and join at settlement without blocking native notification processing.
If the native turn completed successfully with a complete final answer, expiry
preserves that answer as a degraded success. OpenClaw retires unfinished
projection and stale writes, then persists the answer through the existing
transcript owner, preserving write ordering and hooks.
Recovered replies retain native network-result provenance even when the
corresponding tool projection did not settle or a message-write hook replaces
the message.
The turn.settlement_warning trajectory event records the pending presentation
callback, transcript/checkpoint write, or media projection stage, together with
the elapsed time and budget. Newly persisted recovered replies also carry the
settlement warning. Final persistence retains its best-effort policy and the
existing five-second drain grace; if the writer remains unavailable, OpenClaw
records turn.settlement_persistence_unavailable and delivers the completed
text without leaving a stale write behind. Expiry without a native completed answer remains a timeout.
After separately bounded abort cleanup, queued projection gets a five-second
drain grace. These local bounds also apply to unlimited runs.
Stop and execution-budget expiry interrupt the affected native attempt and
bound cleanup before releasing its lane. A quiet turn or a local settlement
failure does not establish that a shared app-server client is dead; unrelated
thread leases on a healthy client remain isolated. Generic stale-run recovery
also respects the exact active native owner, without exempting expired
OpenClaw requests, tools, cancellation, terminal cleanup, or ownerless state.
Replay-safe stdio app-server failures may be retried once on a fresh attempt.
Assistant, tool, active-item, or side-effect evidence can make replay unsafe;
OpenClaw then reports the failure rather than automatically rerunning the work.
Verify current state before retrying an unsafe failed turn.
The former appServer.turnCompletionIdleTimeoutMs,
appServer.turnAssistantCompletionIdleTimeoutMs, and
appServer.postToolRawAssistantCompletionIdleTimeoutMs settings are retired.
Run openclaw doctor --fix to remove them. Doctor preserves unrelated settings
and does not translate idle windows into an elapsed run budget.
Model discovery
By default, the Codex plugin asks the app-server for available models. Model availability is owned by Codex app-server, so the list can change when OpenClaw upgrades the bundled@openai/codex version or when a deployment
points appServer.command at a different Codex binary. Availability can also
be account-scoped. Use /codex models on a running gateway to see the live
catalog for that harness and account.
Automatic discovery and hosted-search model selection use visible picker entries.
Bounded turns with an explicit model selection, including image understanding,
structured extraction, isolated completion, and settled-turn finalization, also
look up hidden entries returned by model/list. The model must still be listed
and support the required input modalities. Listing does not prove account
entitlement.
Native discovery reads model/list and account/read from the same scoped
app-server client. An API-key account remains API-key authentication; model
listing does not imply a ChatGPT transport or endpoint. Picker readiness is
valid only while that native owner and its account/config observation remain
current. A missing account, failed refresh, account/config mutation, or retired
client leaves native models unavailable until discovery succeeds again.
Use the Models page Refresh action (models.list with view: "all" and
refresh: true) to publish the full catalog for the selected agent. Prepared-only
reads do not start discovery. Native configuration changes outside OpenClaw
require the native owner’s supported reload/restart and a catalog refresh;
OpenClaw does not poll native home files for readiness. Authored host routes and
explicit profile selections retain their existing auth and compatibility checks.
Native catalog identifiers are runtime identifiers, not privacy labels. A
deployment using a broker-owned alias must supply an alias-safe native catalog
before starting app-server: both id and model in model/list must be the
alias, with the desired displayName. Different native runtime identifiers are
preserved in OpenClaw model parameters. Renaming the picker label does not hide
those identifiers from requests or session state.
Codex’s startup model_catalog_json setting can supply a native catalog; a
per-thread override does not reload it. Preserve the complete model capability,
instruction, compaction, and reviewer metadata. Catalog membership does not
reject arbitrary model overrides, so the broker must enforce allowed selectors
on every request. Disable native session discovery with
sessionCatalog.enabled: false when no native history should be imported.
A custom endpoint is not automatically a supported Codex route. Explicit
agentRuntime.id: "codex" does not bypass prepared-route compatibility or the
trusted-endpoint requirement for model-backed approval review. A workload API
key also does not provide ChatGPT account identity or subscription refresh.
Verify those contracts before using a broker with the native harness; do not
substitute a custom provider, remove safety metadata, or weaken review to make
an inference smoke test pass.
If discovery is temporarily unavailable or times out, the subscription route
uses offline hints derived from the bundled OpenAI model manifest, with Codex
plugin fallbacks for gpt-5.5 and gpt-5.5-pro reasoning efforts:
Offline hints never prove account entitlement. An authenticated discovery
response remains authoritative even if it contains no visible models; HTTP
401 and 403 return an empty catalog rather than exposing fallback models.
The current bundled harness is
@openai/codex 0.153.4. A live model/list
probe against the official 0.153.4 app-server, using an isolated,
unauthenticated Codex home and includeHidden: true, returned this public
subset of catalog metadata:The probe marked
gpt-5.4 and gpt-5.4-mini as hidden. This snapshot does not
prove account entitlement. Available model IDs, input modalities, and reasoning
efforts remain account-scoped. Run /codex models after starting or upgrading
the gateway to inspect the actual public picker for your account.OpenClaw reasoning controls preserve supported native levels, including ultra.
Codex owns Ultra’s proactive delegation and model-specific inference effort;
Platform API effort metadata does not downgrade the selected runtime mode.
Hidden models can also appear in the app-server catalog for internal or
specialized flows without being normal model-picker choices.plugins.entries.codex.config.discovery:
Restricted turns
The Codex harness evaluates the effective tool policy for every turn. It marks the turn policy-restricted when any explicit policy would otherwise leave a Codex-native capability outside the OpenClaw policy boundary. Restriction sources include global, provider, agent, group, sender, sandbox, subagent, inherited, scheduled/runtime, and per-run tool policies. A finite allowlist always restricts the native surface. A deny list restricts it when an expanded entry is unknown or absent from the audited safe-deny set; this includes wildcards and tool groups containing any unsafe entry.disableTools becomes an
empty per-run allowlist and therefore also restricts the native surface. Default
tool-profile narrowing is not an explicit restriction and does not activate this
mode.
The current audited safe-deny names are:
tools.deny: ["nodes"]
restricts the native surface because nodes is not in the audited set.
Policy-restricted turns have no Codex environment selection or native Code Mode.
OpenClaw disables inherited and configured MCP servers, attests that they remain
disabled, disables native hook relays, and applies the effective policy to its
dynamic tools. A temporary restriction on an existing session uses a transient
Codex thread and preserves the unrestricted binding for later resume.
Ring zero is not a configurable policy profile. It is the host-scoped system
agent path used by OpenClaw setup and repair flows. The host must activate the
system-agent authority and provide the exact single-tool allowlist
["openclaw"]. Ring zero applies the restricted tool surface plus host-authored
base instructions and zero project-document budget. It also suppresses
OpenClaw’s AGENTS.md developer-instruction carrier, so ambient workspace
instructions cannot enter the setup/repair turn.
Message-only source replies also use the restricted tool surface. Lightweight
bootstrap turns and tool-disabled internal turns additionally set the project-
document budget to zero. These modes are separate inputs even when their final
thread configuration overlaps.
Workspace bootstrap files
The full generic developer policy, including abefore_prompt_build.systemPrompt
replacement, remains native session configuration for compaction and native-child
inheritance. Ordinary persistent cold or changed-configuration resumes require an
uninterrupted managed local stdio process owner and observed native unload before OpenClaw injects the full
current policy. Merely sending developerInstructions on thread/resume does not
refresh the model-visible policy on stock Codex. Explicit systemPrompt: "" sends
a withdrawal, not a fallback to older instructions.
Ordinary incognito turns can reuse unchanged generic policy, but changed or emptied
policy is rejected without sending another native turn or discarding the live
conversation. Turn-scoped collaboration instructions remain a separate surface.
See Hook boundaries for recovery.
Codex normally handles AGENTS.md itself through native project-doc discovery.
OpenClaw does not write synthetic Codex project-doc files or depend on Codex
fallback filenames for persona files, because Codex fallbacks only apply when
AGENTS.md is missing. Ordinary policy-restricted turns have no native
filesystem environment, so OpenClaw instead sends the bounded workspace
AGENTS.md snapshot as thread-level developer instructions. Ring-zero,
lightweight, message-only, and tool-disabled internal turns suppress that
carrier.
For OpenClaw workspace parity, local tool notes live in the ## Tools section
of AGENTS.md and normally ride Codex’s native project-doc discovery. The
Codex harness forwards the other bootstrap files as developer instructions:
SOUL.md,IDENTITY.md, andUSER.mdare forwarded as turn-scoped collaboration instructions. Native Codex subagents do not inherit them, which keeps subagent turns from picking up the parent agent’s persona and user profile.- The compact loaded OpenClaw skills list is also forwarded as turn-scoped collaboration developer instructions, so native Codex subagents do not inherit it either.
- Heartbeat turns receive generic initiative guidance through collaboration mode. Monitor cron scratch is appended to the heartbeat prompt instead of injected as workspace context.
MEMORY.mdcontent from the configured agent workspace is not pasted into native Codex turn input when memory tools are available for that workspace; when it exists, the harness adds a small workspace-memory pointer to turn-scoped collaboration developer instructions and Codex should usememory_searchormemory_getwhen durable memory is relevant. If tools are disabled, memory search is unavailable, or the active workspace differs from the agent memory workspace,MEMORY.mduses the normal bounded turn-context path instead.BOOTSTRAP.md, when present, is forwarded as OpenClaw turn input reference context.
Environment overrides
Environment overrides remain available for local testing:OPENCLAW_CODEX_APP_SERVER_BINOPENCLAW_CODEX_APP_SERVER_ARGSOPENCLAW_CODEX_APP_SERVER_MODE=yolo|guardianOPENCLAW_CODEX_APP_SERVER_APPROVAL_POLICYOPENCLAW_CODEX_APP_SERVER_SANDBOX
OPENCLAW_CODEX_APP_SERVER_BIN bypasses the managed binary when
appServer.command is unset.
OPENCLAW_CODEX_APP_SERVER_GUARDIAN=1 was removed. Use
plugins.entries.codex.config.appServer.mode: "guardian" instead, or
OPENCLAW_CODEX_APP_SERVER_MODE=guardian for one-off local testing. Config is
preferred for repeatable deployments because it keeps the plugin behavior in
the same reviewed file as the rest of the Codex harness setup.