Commit Graph

1574 Commits

Author SHA1 Message Date
Peter Steinberger fd8326c5bf fix(codex): reap sandbox process trees before termination (#125908) 2026-08-18 10:48:10 -07:00
Peter Steinberger d204ebe6a4 fix(codex): recover replies after compaction failure (#125895)
Preserve completed tool work when native Codex compaction fails, close failed compaction progress, and bypass unrelated model/auth failover before isolated finalization. Fixes #125789.
2026-08-18 10:22:35 -07:00
Peter Steinberger b9d0e13b5d fix(agents): share one delegation policy across agent runtimes (#125892)
The `## Delegation` guidance added in #125691 lived only in
buildAgentSystemPrompt, so Codex-runtime agents never received it: the
Codex harness builds its own developer instructions in
extensions/codex/src/app-server/thread-prompt.ts and imports nothing
from the system-prompt builders. Live A/B on gpt-5.6-luna had the native
runtime answer "spawn a visible session" while the Codex runtime
answered "spawn a hidden subagent".

Move the policy into src/agents/delegation-guidance.ts, owning both the
main-session mode resolver and the section text, and export it through
the agent-harness plugin SDK barrel that the Codex harness already uses.
The hidden-delegation vocabulary is injected by each runtime, so core
never names a plugin-owned tool: native passes `sessions_spawn`, Codex
passes native `spawn_agent`. Visible sessions stay `sessions_spawn`
with visible=true on both runtimes because Codex-native children are
never OpenClaw sessions.

Also narrows the Codex line that told the model to use `sessions_spawn`
only for OpenClaw/ACP delegation; it now scopes that to internal
legwork, so user-facing deliverables still route to a visible session.
2026-08-18 09:57:52 -07:00
Peter Steinberger 9e24399e82 fix(ci): stop the codex lane hanging on a cold real-tool graph (#125864)
* fix(ci): stop codex lane cold-graph hangs

The side-question domain-policy test loaded the complete agent-harness tool graph inside a one-second readiness race, making the serial non-isolated Codex shard fail or stay silent under cold imports. Build the test's web_search marker and real web_fetch tool from the narrow implementation, then synchronize on turn startup before issuing the tool call. Cap each Codex test process at 12 files so CI gets bounded time-to-first-output as defense in depth.\n\nRefs #125839

* fix(test): keep codex web fetch fixture on sdk boundary

Load the real web_fetch factory on demand through the existing local-only plugin test runtime. This preserves the narrow cold-graph fix without letting a bundled plugin test reach into core internals.
2026-08-18 09:15:38 -07:00
Peter Steinberger 1ed682f883 fix(codex): explain timed-out MCP approvals (#125860) 2026-08-18 08:02:54 -07:00
Peter Steinberger c7022eb117 feat: nudge progress cards only when visible (#125701)
* feat(agents): gate progress card adoption nudge

* fix(agents): gate progress-card nudge on tool policy

* fix(agents): keep tool factory within lint budget
2026-08-18 07:42:20 -07:00
Peter Steinberger efaa867d93 feat(nodes): publish exact runner slots (#125708)
* feat(nodes): publish exact runner slots

* docs(runners): link slot inventory PR

* fix(ui): keep session menus clickable under previews

* perf(protocol): keep runner slot schema off broad barrel

* test(codex): tolerate elapsed media startup budget

* test(codex): type media client factory mocks

* fix(protocol): reject impossible runner slot counts

* test(ci): stabilize loaded lifecycle checks

* test(ui): allow loaded bulk-delete scheduling

* test(ui): stabilize loaded interaction checks

* test(ui): isolate loaded update notice checks

* test(ui): colocate bulk-delete lifecycle coverage

* test(gateway): publish session config before async setup
2026-08-18 07:08:06 -07:00
Peter Steinberger 4589d8514c fix(gateway): stop agent terminal processes after session archive (#125784)
* fix(gateway): stop terminal PTYs on session archive

Bind agent terminals to the durable session incarnation, drain exact ownership during archive, and terminate every job-control process group in the PTY session.\n\nCloses #125769

* test(gateway): cover terminal cleanup on archive

* test(gateway): align terminal outcome assertions

* test(gateway): preserve session exports in invoke test

* fix(gateway): await terminal exit before archive

* test(codex): consolidate supervised instruction coverage

Move the duplicated two-attempt regression into the canonical thread lifecycle test so the exact two-worker extension shard stays bounded on low-core CI.\n\nRelated: #125783
2026-08-18 06:27:42 -07:00
Ayaan Zaidi d412c6b284 fix(codex): inherit agent workspace instructions in native subagents (#125783)
* fix(codex): inherit agent workspace instructions in native subagents via thread developer instructions

* fix(codex): satisfy lint on thread instruction changes

* fix(codex): persist frozen agent instructions across supervised materialization
2026-08-18 17:15:15 +05:30
Jason (Json) 7c65bbcee3 fix(sessions): track context window provenance (#124303)
* fix(sessions): track context window provenance

* fix(sessions): complete context provenance coverage

* fix(sessions): honor authored context window caps

* fix(agents): distinguish context source helpers

* fix(sessions): clear context provenance on model invalidation

* test(codex): preserve local operator authority provenance

* fix(context): clamp effective caps to native windows

* fix(cron): use the runtime model facade

* fix(status): honor session context provenance

* test(status): use public context token inputs

* test(status): split session row cases

* test(status): classify split cases as test support

* test(status): declare runtime context provenance

* fix(sessions): preserve context ownership through finalization

* fix(sessions): apply context provenance to listings

* fix(cron): preserve projected context ownership

* fix(sessions): scope locked context ownership

* fix(status): share session context projection
2026-08-18 05:03:01 -06:00
Peter Steinberger f72782d87b refactor(test): restore auth persistence integrity (#125699)
* test: restore auth persistence integrity

Restore the SQLite-backed auth wizard assertions traced to 43ea501f38 and consolidate duplicated message-action and temp-directory fixtures.

* test: support npm 12 pack results
2026-08-18 02:58:30 -07:00
ClawSweeper 1bf4c1d18c fix(sessions): inherit agent bootstrap outside workspace (#125675)
* fix(sessions): inherit agent bootstrap outside workspace

* fix(sessions): layer execution-dir project context over agent bootstrap

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: Ayaan Zaidi <hi@obviy.us>
2026-08-18 14:23:28 +05:30
Peter Steinberger 8fa06aeaaf fix(agents): preserve fallback context history (#125714) 2026-08-18 01:40:41 -07:00
Peter Steinberger 9ad1c0c682 fix(auth): surface revoked OAuth state without masking provider failures (#125515)
* fix(auth): preserve WHAM classifications and failure recording

WHAM 401/403 state now drives accurate re-auth guidance, while inline hook failures are contained after persistence so recorded failures cannot escape or be masked.

* docs(plugin-sdk): define auth cooldown classifications

document the additive cooldown diagnostic contract and cover its canonical public-SDK projection.

* fix(auth): keep WHAM diagnostics source-compatible

keep cooldownReason canonical, persist exact WHAM diagnostics in optional cooldownClassification, and preserve operator guidance plus failure-hook containment.

* fix(auth): keep failover on canonical cooldown reasons

ensure optional WHAM diagnostics never drive scheduling and discard mismatched persisted reason/classification pairs.
2026-08-18 00:35:06 -07:00
Peter Steinberger 9564b9fc00 fix(codex): preserve approval timeout outcomes (#125671)
Preserve operator approval terminal reasons through the harness, map denials and timeouts to Codex decline, and retain visible timeout evidence so the turn can continue instead of being killed.
2026-08-18 00:29:15 -07:00
Hannes Rudolph 34c3d15a6b fix(macos): complete Codex onboarding and model picker (#124829)
* fix(setup): refresh Codex registry with staged install

* fix(macos): verify inference before onboarding handoff

* fix(setup): use native Codex home for subscription auth

* fix(codex): honor attempt-scoped setup config

* fix(macos): align onboarding handoff with reopen

* fix(setup): await prepared model convergence

* fix(ui): avoid false auth state for empty catalog

* fix(setup): scope catalog convergence to Codex gateway

* fix(setup): publish the committed runtime catalog

* fix(models): project configured static runtime models

* fix(codex): expose app-server model catalog

* fix(models): preserve Codex auth across reloads

* fix(ci): align Codex onboarding checks

* test(ui): stabilize dock suppression environment

* fix(codex): honor discovery config in app-server model catalog

The manifest documents discovery.enabled (bundled fallback list) and
discovery.timeoutMs (default 2500ms) for model discovery; the new catalog
path used the generic 60s request timeout and ignored the enable gate.
Also drop the test-only listModels injection seam in favor of vi.mock.

* fix(setup): refuse prepared Codex auth over an explicit remote transport

configureCodexCliPreparedAuth silently rewrote an explicitly configured
websocket/unix app-server to local stdio (keeping a dangling url), moving
the credential boundary onto this host. Fail setup with actionable
guidance instead; also surface the root cause when the prepared model
catalog refresh fails after activation.

* refactor(agents): one canonical model-catalog identity key

Three near-identical key helpers existed (models-list-result,
models-list-configured-static, harness/model-catalog). Export
resolveModelCatalogIdentityKey from the route-policy owner, collapse the
duplicate dedupe loops into dedupeByKey, make donor enrichment Map-based,
and inline the one-off harness-augment wrapper.

* fix(macos): restore custodian handoff for fresh activations

Landing every finish on the plain dashboard stranded the custodian
first-run flow (memory import, channels, permissions, hatch). Fresh
activations now hand off to custodian onboarding; live-verified
pre-existing setups reopen the normal dashboard, matching the removed
already-configured shortcut. Tests pin the destination per path.

Also isolate the post-startup Codex login test from developer machines:
ambient OPENAI_API_KEY and a real Codex login made it assert-fail.

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-08-17 23:31:12 -07:00
Peter Steinberger bbf7454b17 fix(codex): retain structured tool result details (#125610) 2026-08-17 22:13:33 -07:00
Peter Steinberger 7fc3371eac fix(codex): enforce hosted search domains for web fetch (#125574)
* fix(codex): apply hosted search domains to web fetch

* fix(net): preserve allowlist error wording

* fix(codex): enforce search domains in side questions
2026-08-17 21:49:35 -07:00
Peter Steinberger 7e7b860bca fix: preserve message delivery after result middleware (#125497)
* fix(agents): carry typed message delivery receipts

* fix(agents): preserve receipts across harness middleware

* fix(agents): preserve plugin broadcast delivery receipts

* fix(agents): preserve partial broadcast delivery receipts
2026-08-17 21:16:14 -07:00
Marvinthebored 3d016975c3 fix(codex): degraded-engine continuity no longer projects the whole context window per turn (#125324)
* fix(codex): bound no-engine continuity projections to half the context window

A degraded or absent context engine sends fresh-thread continuity through
projectContextEngineAssemblyForCodex with the whole-window projection cap
((window - 20k) x 4 chars), so a large uncompacted transcript renders into
a single turn/start input consuming up to 90% of the model context window.
That turn fills its own native thread, the next turn's token fuse rotates
it, and the following fresh thread re-projects the transcript again -
observed as 11 near-window turn inputs on cold threads in one day
(openclaw/openclaw#125254).

Continuity projections now use a dedicated cap that reserves half the
context token budget, so the fresh thread keeps headroom for later turns
and the existing delta-resume path can actually engage. The active-engine
projection path keeps its whole-window cap unchanged.

Related: #125254

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JKtoZgXWnaAH8rmLiSydpN

* fix(codex): size continuity projections from real token cost, not the optimistic estimate

The continuity cap reserved half the context window in tokens but converted
that budget to characters with APPROX_RENDERED_CHARS_PER_TOKEN = 4, so at a
258,400-token window it permitted 516,800 chars. A live projection measured
703,134 chars for 226,146 input tokens, meaning that cap really costs about
166k tokens (~64% of the window), not the intended 129.2k.

Codex reports input tokens only after a turn and bounds turn input by
characters, so the projection cannot be sized in verified tokens before it is
sent. Convert the continuity budget at a conservative 3 chars/token instead,
which holds the reserved half in real tokens at the densest ratio observed.

Related: #125254

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JKtoZgXWnaAH8rmLiSydpN

* fix(codex): scope the continuity sizing claim to the density it was measured at

The half-window claim was stated as a guarantee, but the 3 chars/token
conversion rests on one observed projection. Input that tokenizes more densely
(CJK, base64, minified code) still exceeds the reserved half, so the constant is
renamed to CONTINUITY_EMPIRICAL_CHARS_PER_TOKEN and its comment says plainly
that it is an empirical floor rather than a bound.

The invariant test is narrowed to the measured density, and a companion test
pins the break-even ratio at 3 chars/token so the limitation is visible in the
suite instead of implied. Choosing between a guaranteed worst-case bound and
this empirical cap is a maintainer-owned tradeoff, left open on the PR.

Related: #125254

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JKtoZgXWnaAH8rmLiSydpN

* feat(codex): size continuity projections from the session's observed token density

Each completed Codex turn now records a calibration sample on the thread
binding: prompt chars actually sent vs the provider-reported input token cost
(uncached + cache read + cache write). The no-engine continuity cap converts
its half-window token budget at that observed ratio instead of a fixed
chars-per-token guess, so capChars / ratio stays at the reserved budget for
any content density - CJK, base64, and minified code included. The sample is
captured before startup rotation so a rotated-away thread's density still
sizes the fresh thread's projection; without a sample the empirical 3
chars/token default applies, and degenerate samples clamp to [0.5, 4].

Related: #125254

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JKtoZgXWnaAH8rmLiSydpN

* fix(codex): make continuity calibration monotone - samples only tighten the cap

Red-team finding: a loose sample (up to 4 chars/token) followed by denser
content could size the cap past the empirical default, and stale or
non-continuity samples persist on the binding. Clamping the calibrated ratio
at the empirical default makes every such failure mode degrade to the
uncalibrated behavior instead of past it, and the invariant test asserts
monotonicity across poisoned samples directly.

Related: #125254

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JKtoZgXWnaAH8rmLiSydpN

* fix(codex): record continuity calibration only from continuity projections

ClawSweeper P2: calibration ran after every successful turn filtered only by
prompt size, so a dense direct or active-engine prompt could persist a sample
whose density later shrinks continuity history it never measured. The
no-engine continuity appliers now mark the prompt state, finalize gates the
sample on that marker, and a cross-mode regression proves a large direct
prompt records nothing.

Related: #125254

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JKtoZgXWnaAH8rmLiSydpN

---------

Co-authored-by: Marvinthebored <262704729+Marvinthebored@users.noreply.github.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-17 17:41:45 -07:00
Peter Steinberger f67602a7b4 fix(codex): keep valid tools when one name is unsupported (#124932)
* fix(codex): quarantine invalid dynamic tool names

Amp-Thread-ID: https://ampcode.com/threads/T-01a00b7c-b9f0-73d5-8fb7-e619e8e458e1

* fix(mcp): preserve safe server names across fallbacks

Amp-Thread-ID: https://ampcode.com/threads/T-01a00b7c-b9f0-73d5-8fb7-e619e8e458e1

* fix(codex): report retained tools after quarantine

* fix(codex): preserve shared MCP identifiers

---------

Co-authored-by: Amp <amp@ampcode.com>
2026-08-17 16:33:39 -07:00
Peter Steinberger 6e458d84bf feat(agents): configure per-agent GitHub identities (#125199)
* feat(agents): add managed GitHub identities

* fix(agents): use opaque GitHub setup handles

* style(codex): format managed shell environment call

* refactor(agents): own managed GitHub process identity

* chore(config): refresh baseline after rebase

* fix(ci): satisfy managed GitHub identity gates

* fix(ci): repair managed GitHub identity checks

* test(agents): align GitHub identity CI coverage

* fix(codex): scope login shell isolation

* fix(agents): let managed gh profiles authenticate

* fix(agents): harden GitHub identity setup

* test(gateway): align method suffix counts

* fix(ui): serialize GitHub identity mutations

* fix(protocol): generate GitHub configure requests

* test(ui): restore timers after identity tests

* fix(ui): preserve GitHub identity mutation ownership

* fix(agents): preserve native GitHub CLI auth
2026-08-17 15:54:03 -07:00
Peter Steinberger 7170a6231a feat(agents): unify agent status into a durable progress_card (#125125)
* feat(agents): unify agent status into a durable progress_card

Replace the write-only update_plan to-do tool and the fragmented plan
rendering with one durable status artifact per session: progress_card
({plan?, markdown?}, replace-on-write, 8 KiB markdown / 50-step caps).
Cards persist in a lazy-additive session_progress_cards table in the
per-agent DB (no schema-version bump), broadcast progressCard.changed,
and render from the store with exactly one live placement per view
(session rail when visible, else the composer-adjacent bar); transcripts
collapse to one-line receipts, and the sidebar hovercard shows other
sessions' cards inline (markdown + <progress>, DOMPurify allowlist, no
iframes). The three stream-derived plan renderers and their dedup
heuristics are deleted.

Codex runs disable the native plan tool per thread
(tools.update_plan.enabled=false) and receive progress_card via the
dynamic-tool bridge; compaction restore now reinjects the card (steps +
bounded markdown). Card writes still emit the legacy plan stream event so
native apps and channels keep working until their per-platform
migrations. Policy names map update_plan -> progress_card; the shipped
tools.updatePlan=false kill switch is honored.

Net -277 production LOC; -480 test LOC.

* test(agents): regenerate Codex prompt snapshots for update_plan thread-config disable

* chore(protocol): allowlist progressCard.changed for native apps pending card migration

* fix(ci): repair progress card integration checks

* fix(codex): canonicalize native progress cards

* test(gateway): reconcile progress card method order

* test(codex): stabilize native approval fixture
2026-08-17 09:44:04 -07:00
Peter Steinberger 4f898a4081 fix(state): migrate legacy state to system agent (#125266) 2026-08-17 05:32:40 -07:00
Peter Steinberger 4b0d573437 feat: session permission modes with worktree-scoped defaults (#124909)
* feat(gateway): add session permission modes

* feat(agents): enforce session permission policies

* test: cover session permission modes

* docs: explain session permission modes

* fix(agents): preserve apply patch default root

* feat(codex): map session permission modes

* feat(ui): add session permission controls

* test: cover session permission surfaces

* fix(agents): enforce session permissions from entry

* fix(codex): pass params object to requirements reader

* fix(codex): honor session permission modes

* fix(codex): preserve exec approval floors

* chore: revert changelog edit (release-owned)

* test: align full-mode promotion with upstream semantics

* chore(protocol): regenerate session permission models

* docs: register session permission modes

* fix(ui): use shared permission dropdown

* fix(sessions): restore permission mode contracts

* fix(ci): record session permission startup JS growth in the budget baseline

* refactor(agents): prepare session exec mode at dispatch

Host dispatch owns permissionMode→exec override preparation; the codex
plugin consumes prepared facts and the SDK barrel export is removed,
keeping the plugin-sdk surface at its recorded budget.

* test: type exec mode fixtures as ExecMode

* fix(codex): require admin scope for yolo permissions

* test: isolate codex permission command state

* ci: refresh PR checks against current main

* ci: refresh checks after gateway test repair

* test: fix main-fallout CI suites

* chore: refresh CI merge ref

* fix(worker): fence permission-mode cloud placements

* fix(sessions): clear worktree policy on detach

* chore(protocol): generate session permission mode enum

* test(gateway): type dispatch fixtures from session entries

* fix(ui): allow clearing session permission mode

* chore: refresh CI merge ref

* fix(ci): record permission picker startup growth in the budget baseline

* fix(gateway): gate session root projections
2026-08-17 04:37:35 -07:00
Ayaan Zaidi 75c5d9e208 fix(agents): show waiting reply when sessions_yield pauses a turn (#125106)
Show an explicit waiting acknowledgment when sessions_yield ends an otherwise-silent interactive turn, while keeping private resume context out of channel delivery and preserving existing visible replies.

Co-authored-by: Ayaan Zaidi <hi@obviy.us>
2026-08-17 17:01:48 +05:30
Peter Steinberger e30b425e18 fix: recovery no longer claims interrupted commands succeeded (#125209)
* fix(agents): report interrupted tool outcomes honestly

Prevent restart recovery from claiming that an interrupted tool call completed when no successful matching result was recorded.

* fix(agents): keep ambiguous recovery restart-safe

Classify failed replay-unsafe tool results at the shared restart-recovery owner so interrupted side effects remain unavailable until their external state is verified.

* fix(agents): distinguish missing tool outcomes

Carry the existing missing_tool_result fact into projected Codex transcripts so restart recovery restricts only genuinely unknown outcomes, while confirmed failures remain retryable.
2026-08-17 04:11:57 -07:00
Peter Steinberger 6d04fe5305 fix(heartbeat): avoid claiming excluded outcomes were recorded (#125207)
* fix(heartbeat): report accepted outcomes honestly

* test(heartbeat): refresh response tool snapshots

* fix(heartbeat): align tool catalog wording
2026-08-17 03:58:23 -07:00
Peter Steinberger 916932b007 fix(agents): standardize image inspection as view_image (#125024)
* chore: refresh CI after main fix

* fix(agents): standardize image inspection as view_image

* fix(agents): preserve view_image activity display

* fix(agents): satisfy view_image display gates

* fix(ui): snapshot cloud worker draft before save

* perf(ui): compact fallback tool catalog

* fix(agents): preserve view_image upgrade boundaries

* chore(ui): refresh historical image display snapshot
2026-08-17 03:01:12 -07:00
Peter Steinberger 5ebfbbf8d7 fix(plugins): honor per-agent runtime config (#124978)
* fix(plugins): resolve per-agent config through SDK

* test(codex): preserve agent runtime exports

* test(telegram): make default owner explicit

* refactor(plugins): use lightweight agent scope runtime

* fix(codex): preserve multi-agent execution ownership

* chore(plugin-sdk): record approved agent scope exports

* fix(codex): keep scoped sandbox ownership authoritative

* fix(codex): preserve agent scope in native side actions

* fix(ci): avoid counting node check as environment variable
2026-08-17 01:53:08 -07:00
Peter Steinberger 4e1f26dc18 refactor(gateway,ui): one bounded display projection; delete marker strip sites (#124997)
* refactor(gateway,ui): one bounded display projection; delete marker strip sites

Persisted transcripts are marker-free since the write-boundary projection
(#124793), the historical migration (#124888), and TTS facts (#124913), so
display surfaces stop compensating. sessions.list.lastMessagePreview and its
siblings (sessions.preview/describe, TUI picker, sessions_list tool, MCP) now
share one bounded role-aware projection (240 chars, tool/system/thinking and
suppressed control replies excluded, directive-only rows fall through). The
web reply chip reads the typed openclawDelivery fact instead of parsing text;
chat.history preserves the field to the UI. Post-hoc display strips are
deleted across web/TUI/MCP/sessions-list; live streaming cleaners stay.
Stale gateway-protocol preview comments corrected; no schema change.
Assertion-safety baseline pruned for shrunk files (sanctioned direction).

Production net -173, tests net -137. Fixes the sidebar [[reply_to_current]]
preview leak and the empty-code-pill overstrip of quoted markers.

* fix(agents): preserve restart recovery transcript reads

* refactor(gateway): remove obsolete transcript exports

* fix(gateway): normalize injected delivery directives

* fix(ci): scope projection and recovery checks

* chore(ci): shrink plugin SDK surface budgets

* test: deflake loaded side question and worker checks

* test: align display projection CI fixtures

* style: format display projection fixture
2026-08-16 23:44:29 -07:00
Peter Steinberger dd1ee7b375 fix(codex): report dynamic tool audit starts once (#124976)
* fix(codex): dedupe dynamic tool audit starts

* fix(codex): preserve eager dynamic tool audit starts

* test(codex): make audit timing proof nonblocking

* test(codex): consolidate dynamic audit lifecycle proof

* test(codex): declare side-question tool arguments
2026-08-16 20:51:25 -07:00
PollyBot13 cef77d1aeb fix(codex): reject malformed native tool arguments (#124649)
* fix(codex): reject invalid native tool arguments

* fix(codex): preserve raw argument preparation

Signed-off-by: sallyom <somalley@redhat.com>

---------

Signed-off-by: sallyom <somalley@redhat.com>
Co-authored-by: sallyom <somalley@redhat.com>
2026-08-16 22:48:40 -04:00
Peter Steinberger 13872f4338 fix: plugin tools disappear from Codex and restricted profiles (#124947)
* fix(memory): make standing intents reachable

* fix(agents): dedupe macOS read path variants

* docs(plugins): document profile tool metadata

* test(codex): complete prepared runtime fixtures

* fix(agents): preserve prepared tool boundaries
2026-08-16 19:38:07 -07:00
Peter Steinberger 43f127823a fix(codex): preserve resumed session usage (#124969) 2026-08-16 19:28:28 -07:00
Peter Steinberger b65879e4b6 fix: deliver requested image artifacts across agent runtimes (#124910)
* fix: distinguish image inspection from delivery

Clarify that image-reading tools only load private model context, prefer native Codex image inspection when available, and preserve explicit outbound tool media across Claude CLI loopback runs.

Co-authored-by: pash <pash@openai.com>

* fix: propagate CLI vision capability

* chore: refresh CI after main fix

---------

Co-authored-by: pash <pash@openai.com>
2026-08-16 18:32:49 -07:00
Peter Steinberger ab5611f0be fix(security): prevent approved scripts from changing before execution (#124858)
* fix(security): bind exec approvals to mutable operands

* test: align approval fixtures with operand binding

* fix(security): close durable operand binding gaps

* fix(security): preserve independent exec policy grants
2026-08-16 18:26:42 -07:00
Peter Steinberger 2740d9cc95 fix(codex): prevent app-server leaks after desktop fallback (#124885)
* fix(codex): reuse app server after managed fallback

* test(codex): opt relay fixtures into loop detection
2026-08-16 16:36:40 -07:00
Peter Steinberger 2523943ef1 feat(codex): name additional session-catalog homes (#124807) 2026-08-16 13:30:49 -07:00
Peter Steinberger ed1799315e feat(ui): surface approvals passively and redesign the approval card (#124767)
* feat(ui): surface approvals passively and redesign the approval card

Approvals no longer auto-open the centered modal: the queue is reachable
only through the sidebar attention chip, while the owning session shows
the inline card and other sessions surface via the session-row shield
icon, agent badges, and the chip. Deletes the inline-vs-modal exclusion
machinery (modalApprovalQueue, inlineApprovalId, forceShowAll) and makes
modal dismissal close the view instead of denying the active request.

Card: severity now drives the accent color instead of a table row,
plugin/agent render as header chips, the session key moves behind a
collapsed Details disclosure (modal only), and low-value exec rows
(Resolved/Security/Ask) collapse into the same disclosure. The codex
app-server bridge stops duplicating the session key into description
text; the envelope already carries it.

* fix(ui): gate settings Escape on the approval dialog's recorded open state

ClawSweeper caught that shouldIgnoreSettingsEscape still inferred an open
approval dialog from queue non-emptiness; with passive approvals a pending
queue no longer implies a visible dialog, so settings would swallow Escape.
The exec-approval element now records dialogOpen as a fact and the guard
reads it.
2026-08-16 12:47:08 -07:00
Peter Steinberger 4667d188f2 fix(codex): honor session node exec host (#124777) 2026-08-16 12:41:48 -07:00
Peter Steinberger 6cc72f9b3d fix: honor context caps on Codex-routed models (#124735)
* fix(codex): forward authored context caps

* test(codex): keep binding fixtures uncapped

* fix(agent-harness): separate authored context cap
2026-08-16 12:31:20 -07:00
WhatsSkiLL 08786d32b2 feat(codex): show sessions from additional homes (#124660)
* feat(codex): register additional session homes

* fix(codex): preserve automatic session homes

* docs(codex): explain automatic home discovery around sessionCatalog.homes

---------

Co-authored-by: IWhatsskill <284122573+IWhatsskill@users.noreply.github.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-08-16 12:14:10 -07:00
Peter Steinberger 568b920b21 feat(lint): enforce import ordering and deduplication (#124730)
* refactor(imports): dedupe and hoist imports

* feat(lint): enforce import/no-duplicates and import/first
2026-08-16 11:44:52 -07:00
Peter Steinberger ffa0929c7f fix(agents): stop advertising unavailable tools (#124716)
* fix(agents): gate tool description cross-references

* test(gateway): include metadata copier in invoke mock
2026-08-16 11:20:45 -07:00
Marvinthebored 2404d41de2 fix(codex): preserve delegation when image generation is denied (#124598)
Forward exact audited tool denies into agent harnesses so Codex can disable native image generation without dropping delegation. Fail closed when managed policy forces image generation and rotate retained threads when effective native config changes.

Co-authored-by: Marvinthebored <262704729+Marvinthebored@users.noreply.github.com>
2026-08-16 21:42:38 +05:30
Jason (Json) eb174bcaff fix(codex): candidate checks reject a mismatched app-server (#124137)
* fix(codex): validate managed app-server candidates

* docs(codex): document managed binary preflight

* test(codex): review managed preflight execution

* docs(codex): document managed app-server check

* fix(pr): support macOS system Bash operation locks

* fix(codex): scope managed preflight to Codex agents
2026-08-16 09:27:12 -06:00
SunnyShu 16cde04136 fix(agents): allow required-preflight native Codex compaction (#120197)
* fix(agents): allow required-preflight native Codex compaction

Required reply-preflight compaction on a Codex app-server-backed session
returns the intentional `ok: true, compacted: false` "codex app-server owns
automatic compaction" no-op because the preflight caller never passes
`allowNonManualNativeRequest`. The reply/preflight path then misclassifies
that successful skip as a failure and throws, dropping the user's turn with
"Context is too large and auto-compaction could not recover this turn." The
equivalent CLI path was fixed by #88207; this is the second, unpatched caller.

Route required-preflight through the existing private
`compactAfterContextEngine` harness capability (which already passes
`allowNonManualNativeRequest: true`) by adding a typed
`nativeCompactionRequest: "required_preflight" | "after_context_engine"`
origin on `maybeCompactAgentHarnessSession` and the Codex compact bridge.
The non-manual skip guard is bypassed for preflight, so Codex actually
compacts the thread.

A binding change between the initial read and the native request is a
stale-binding race, not a benign skip. For `required_preflight` (and the
non-manual CLI path) it now surfaces as the canonical recoverable
`stale_thread_binding` failure so the queued harness falls back to the
context engine instead of treating an uncompacted `ok: true` result as a
completed turn. A genuine post-context-engine request may still skip,
because the context engine has already compacted. Required-preflight is also
the one scoped exception to the model-locked terminal rule: missing or stale
Codex thread bindings recover via the shared context-engine fallback while
the persisted harness lock stays intact; other locked failures remain
terminal.

Rebased onto main after #120740 restructured the guarded native compaction
block; the recoverable-binding semantics are reintroduced on the new
structure and scoped by `nativeCompactionRequest` so #120740's
post-context-engine skip behavior is preserved.

Closes #119971.

* test(evidence): commit inspectable required-preflight live proof scripts for #119971

Adds the two live codex app-server proof scripts (binding-race +
locked-preflight) so the redacted terminal traces in the PR body are
inspectable on the exact head. Both drive the real codex binary and real
maybeCompactCodexAppServerSession with nativeCompactionRequest:
"required_preflight"; neither runs in CI (no codex binary).

* fix(agents): scope locked-preflight compaction fallback to Codex

Restrict the required-preflight model-lock exception to the Codex harness
so missing/stale thread bindings in other locked native harnesses (e.g.
Copilot) stay terminal instead of escaping the persisted model-lock
boundary via context-engine fallback. Add a model-locked Copilot
required-preflight regression covering both missing and stale thread
bindings.

* fix(codex): require native preflight compaction

* chore(plugin-sdk): account for native compaction exports

* test(codex): use complete cron authority fixtures

* chore(lint): shrink compaction assertion baseline

* fix(lint): honor root boundary timeout

* fix(lint): extend package boundary timeout

* fix(plugins): verify native compaction owner

---------

Co-authored-by: fuller-stack-dev <263060202+fuller-stack-dev@users.noreply.github.com>
2026-08-16 08:00:38 -06:00
Peter Steinberger 7173aeb663 fix: surface hidden-pane steer failures and demote per-turn gateway log noise (#124560)
* fix(ui): surface hidden-pane steer terminal failures globally

Three terminal branches in steer-lifecycle.ts (transport null result,
failed queue-row restore, failed queue-row removal) still gated their
error on itemStillVisible, so a steer that failed after the operator
navigated away parked the error on the queue row with no visible
outcome — the exact invariant #124473 introduced
surfaceChatDeliveryFailure() to protect.

Route all three through the canonical helper and delete the divergent
visibility-only branches. Regression test fails pre-fix
(stash-verified): steer transport failure with the pane hidden now
surfaces the session-named global toast.

* fix(logging): demote per-turn gateway log noise to debug

Live campaign evidence showed three lines dominating operator logs at
info level with no per-turn diagnostic value:

- 'tool policy removed N tool(s)': the policy pipeline runs on every
  turn, so this repeated 42x in one session. Demote to debug and delete
  the now-dead toolPolicyAuditLogLevel/auditLogLevel plumbing that only
  existed to lower diagnostic probes to the level that is now the
  default (net -13 production LOC).
- 'codex app-server one-shot cleanup checked shared client retirement':
  routine per-attempt teardown detail; demote to debug.
- 'codex trajectory capture requires the SQLite host recorder': static
  config condition warned per attempt; warn once per process.

Skipped: the [model-fetch] info carve-out in model-transport-debug.ts is
a named contract (docs/logging.md, #89648) — always-info by design.

* fix(codex): drop test-only trajectory warn-once reset export

Knip's production unused-export gate rejects
resetCodexTrajectoryRecorderWarningForTest — it was a test-only seam in
production code. Reset the process-wide warn-once flag via
vi.resetModules() + fresh dynamic import in the test instead.

* test(cron): wait for backoff re-arm instead of fixed sleep

The 0ms retry timer arms only after async watcher-state persistence, so
'await delay(5)' races it on loaded CI workers (flaked on
checks-node-compact-large-2: spawn called 1 time, expected 2). Replace
both fixed-sleep re-arm waits with vi.waitFor on the spawn count. The
remaining delay(5) guards a negative no-further-spawn assertion after
cancel, where a bounded sleep is the correct shape.

* fix(codex): scope trajectory recorder warn dedupe to session

ClawSweeper P2: the host recorder factory returns null for per-session
target-mapping conflicts, not only static config, so a process-wide
warn-once flag silenced a later distinct session's recorder loss. Warn
once per session (bounded set, cleared past 64 entries) so retries stay
quiet but each newly affected session records its loss. Regression
covers a later distinct session still warning.
2026-08-16 06:23:44 -07:00
Peter Steinberger ebd23631ae perf(cli): build root help from plugin metadata (#124562) 2026-08-16 05:43:35 -07:00