Skip to content

fix(acp): preserve agent arguments and session ownership - #139776

Merged
steipete merged 2 commits into
mainfrom
codex/acpx-argv-owner-cleanup-20260906
Sep 6, 2026
Merged

steipete merged 2 commits into
mainfrom
codex/acpx-argv-owner-cleanup-20260906

Conversation

@steipete

@steipete steipete commented Sep 6, 2026 •

Copy link
Copy Markdown
Contributor

Closes #136246. Follow-up to #139685. Thanks @eddiedon for reporting the Windows configuration failure.

What Problem This Solves

Fixes an issue where users configuring custom ACP agents on Windows would receive a raw-command rejection despite using the documented command and args configuration. Arguments could also lose empty values or quoting, and converting an existing POSIX session command to argv could unexpectedly replace its session.

The same review found that changing cwd could lose the handle that needed closing, resetting options could start a backend with the invalid settings being reset, legacy stream abandonment could leave a turn running, and an explicit model selection could silently fall back when model control was unavailable.

Why This Change Was Made

Keep command arguments structured from config through generated wrappers, model overrides, process leases, persistence, and reconnect. A single agent-bound prepared launch command replaces repeated quoting and reconstruction. Existing published ACPX scalar session records retain their representation when the command is unchanged.

Legacy runTurn now adapts the canonical startTurn lifecycle, so terminal results own cleanup and abandoning iteration cancels the exact turn. The manager retains cwd-stale handles until its existing replacement/shutdown owner closes them; reset closes only a cached handle and never starts a backend to erase options. Fresh explicit model requests fail visibly. Reconnect preserves the existing request shape because saved options do not retain caller intent; the canonical control replay still validates saved model choices before a prompt. Newly dropped inherited defaults are omitted during initialization.

Production code: 300 added / 435 removed, net 135 lines removed. Tests and fixtures: 1,087 added / 707 removed. No dependency, schema version, protocol, or operator configuration keys are added. The assertion-safety allowance shrinks with the removed casts.

User Impact

Documented custom-agent configuration preserves executable paths and arguments on Windows and POSIX. Persistent sessions retain history across reconnect. Cwd changes and reset release owned backends, stopped consumers cannot leave legacy turns running, and explicit model choices are honored or rejected with an error. ACP setup/model documentation is updated.

Evidence

Independent Codex autoreview is clean through P2 after correcting both reported ownership findings.

  • Captured failing regressions before repair for argv loss/session replacement, cwd cleanup on next turn and shutdown, reset with invalid/unavailable backends, legacy turn abandonment, and explicit-model fallback. Additional review regressions cover selected models after restart, dropped-default reporting, and lease recognition with quote-bearing process arguments.
  • Full ACP suites: 531 tests passed across 51 files. Production build and authenticated smoke passed during development. The full changed-file gate passed, with final targeted production/test typechecks and lint also passing. Native Windows then exposed one remaining JSON-rendered wrapper-path check; its repair passes a new regression and 167 focused ACP/Gateway tests. Final Windows parser changes also pass 51 focused tests plus plugin production/test typechecks and targeted lint. Relative and combined command strings preserve native Windows backslashes; POSIX grammar stays unchanged.
  • Real ACP subprocesses preserve empty/spaced/quoted/backslash arguments through direct and generated leased wrappers, persisted argv, and reconnect with the same backend session and history. Both generated Codex and Claude command shapes are covered.
  • Real process-list and termination proof: exact leased children are closed through both regular and pending-lease recovery with spaces/apostrophes in wrapper paths and quote/backslash arguments.
  • Authenticated Codex smoke: complete delayed output, persistent recall, pre/post-prompt delivery cancellation, iterator abandonment, and successful subsequent turns. A real ACP subprocess lacking model controls rejects an explicit selection while accepting an inherited default.
  • Dependency contracts inspected directly in published ACPX 0.13.1: argv normalization/Windows launch, session reuse identity, and terminal result cleanup. Codex source checked at codex-rs/app-server/src/request_processors/turn_processor.rs:1555 and codex-rs/app-server/src/bespoke_event_handling.rs:1394 for interrupt/terminal behavior, and codex-rs/core/src/config/mod.rs:945 for explicit reasoning overrides.
  • Native Windows on the initial head passed direct argv/reconnect and the separate Scheduled Task proof, but caught missing lease identity for generated wrappers (runs 34013505073 and 34013505148). Wrapper detection now consumes literal argv paths and shares one root-prefix check. Native Windows on the corrected head passed all seven applicable ACP regressions, including leased, relative and combined commands plus reconnect; only the POSIX scalar case is skipped on Windows. Required CI is green for 76ebe2a1783e7f012efc126e6b7c21b095e2af5f. Earlier interactive environment setup/transport attempts executed no tests and their leases were stopped.

Follow-up: the local adaptive Vitest scheduler selected inconsistent worker counts for projects sharing groupOrder. The unchanged full core suite passed with the runner's documented fixed-worker setting (OPENCLAW_VITEST_MAX_WORKERS=1); investigate adaptive project scheduling separately.

CI recovery: refreshed onto main and corrected two stale pagination-fixture field names introduced across #139715 and #139753; no production/interface widening. The unrelated browser-route-handoff history=true E2E timed out while its live disclosure was collapsed, then passed unchanged in a focused native browser rerun. Its intermittent disclosure-expansion failure remains a test-harness follow-up; no timeout increase or speculative UI patch.

Legacy model handling: saved metadata does not encode caller intent, so reconnect keeps its existing semantics. Restart coverage is seeded through the old initialization contract without an applied-model annotation: status remains usable, unsupported model replay still rejects before a prompt, and supported Codex/Claude selections replay across a fresh manager. No new persistent provenance field or compatibility reader is introduced. Old unsupported overrides are not silently erased; reset-options remains the existing recovery path.

Current-main dependency proof: an independent ordinary checkout of merge 0817aa37b818ba18ecbf2e6c481a20633c407e35 (PR parent 76ebe2a1783e7f012efc126e6b7c21b095e2af5f) installed ACPX 0.13.2 and Codex ACP 1.6.2. All four probes exited 0: model-capability handling; actual process cleanup; authenticated legacy cancellation/reuse; complete delayed delivery (88 chunks), recall, delivery-failure cancellation and successful follow-up. Temporary credential homes and owned processes were cleaned.

Data-model review note: the package.json change only selects the Windows regression test. No SQLite schema, schema version, or new model-provenance field is introduced. Compatibility is covered by real POSIX scalar-session reuse and the old-producer model restart sequences above.

@clawsweeper

clawsweeper Bot commented Sep 6, 2026 •

Copy link
Copy Markdown
Contributor

🦞👀
ClawSweeper picked this up.

Pull request received. I will update this pull request when review starts.

ClawSweeper review complete

ClawSweeper finished reviewing this revision. The review result is being finalized.

View the workflow run.

@steipete
steipete marked this pull request as ready for review September 6, 2026 05:14
@openclaw-barnacle openclaw-barnacle Bot added docs Improvements or additions to documentation extensions: acpx size: XL maintainer Maintainer-authored PR labels Sep 6, 2026
Keep portable argv through wrappers, leases, and reconnects; consolidate legacy turns onto canonical result cleanup. Retain cwd handle ownership, reset without backend startup, and preserve explicit model choices across reconnects. Fixes #136246; follows #139685.
@clawsweeper clawsweeper Bot added P1 High-priority user-facing bug, regression, or broken workflow. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. labels Sep 6, 2026
@clawsweeper

clawsweeper Bot commented Sep 6, 2026 •

Copy link
Copy Markdown
Contributor

Codex review: blocked before merge. Reviewed September 6, 2026, 2:11 AM ET / 06:11 UTC.

ClawSweeper review

What this changes

Preserves custom ACP agent arguments and saved sessions, consolidates turn cleanup, and repairs working-directory reset and model-selection handling.

Merge readiness

⛔ Blocked before merge - 2 items remain

The prior legacy-model blocker is resolved, and no new blocking defect was found. This PR remains useful: current main still flattens custom agent arguments, and the merged delivery fix explicitly left this work for follow-up.

Priority: P1
Reviewed head: 76ebe2a1783e7f012efc126e6b7c21b095e2af5f

Review scores

Measure Result What it means
Overall readiness 🐚 platinum hermit (4/6) A coherent repair with meaningful compatibility coverage and the prior blocker resolved; native Windows completion remains part of normal validation.
Proof confidence 🌊 off-meta tidepool Not applicable: The ordinary external-contributor proof gate does not apply to this maintainer PR. Captured evidence reports real ACP subprocess and authenticated cancellation/reconnect results; final-head native Windows verification remains pending.
Patch quality 🐚 platinum hermit (4/6) No actionable review findings were identified.

Verification

Check Result Evidence
Real behavior Not applicable Not applicable: The ordinary external-contributor proof gate does not apply to this maintainer PR. Captured evidence reports real ACP subprocess and authenticated cancellation/reconnect results; final-head native Windows verification remains pending.
Evidence reviewed 9 items Prior finding resolved: Reconnect passes the saved model without inventing modelExplicit. The regression initializes metadata without an applied-model annotation, then checks status and prompt behavior through original and fresh managers. Unsupported replay rejects before the prompt runtime; supported selections remain saved. This addresses the finding and rank-up request recorded in the previous review.
Model validation remains before prompt submission: The turn runner awaits applyManagerRuntimeControls before beginning execution. Fresh explicit requests cannot take the missing-model-capability fallback, while newly dropped inherited defaults are reported to initialization.
Work remains absent from main and latest release: Both fetched main and v2026.9.2 still concatenate command and quoted args into a scalar string. Comparing the merge base with fetched main showed no changes to the central configuration, runtime, or runtime-options command files. The supplied merged #139685 explicitly identifies argv preservation as follow-up work.
Findings None None.
Security None None.

How this fits together

ACP connects OpenClaw sessions to external coding agents. The acpx plugin turns configuration and saved session metadata into agent subprocesses, then returns output while tracking session and process cleanup.

flowchart LR
  A[Agent configuration] --> C[ACP session manager]
  B[Saved session metadata] --> C
  C --> D[Prepare arguments and validate models]
  D --> E[acpx agent subprocess]
  E --> F[Output and terminal result]
  F --> G[Save session and release owned processes]
Loading

Before merge

  • Resolve merge risk (P1) - The captured native Windows evidence predates the final parser and wrapper-detection repairs; its rerun remains pending.
  • Add data-model compatibility proof - Confirm migration or upgrade compatibility proof before merge.
Agent review details

Security

None.

PR surface

Source -135, Tests +380, Docs +13, Config 0, Other 0. Total +258 across 26 files.

View PR surface stats
Area Files Added Removed Net
Source 10 300 435 -135
Tests 12 1087 707 +380
Docs 2 20 7 +13
Config 1 1 1 0
Generated 0 0 0 0
Other 1 1 1 0
Total 26 1409 1151 +258

Review metrics

None.

Stored data model

Persistent data-model change detected: migration/backfill/repair: package.json. Confirm migration or upgrade compatibility proof before merge.

Root-cause cluster

Relationship: fixed_by_candidate
Canonical: #136246
Summary: This PR is the implementation candidate for the documented Windows custom-agent configuration failure.

Members:

Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything.

Merge-risk options

Maintainer options:

  1. Decide the mitigation before merge
    Keep arguments structured through launch and persistence, preserve existing session representations on reconnect, and let canonical lifecycle owners validate models and release processes.
  2. Pause or close
    Do not merge this PR until maintainers decide whether the risk is worth taking.

Technical review

Best possible solution:

Keep arguments structured through launch and persistence, preserve existing session representations on reconnect, and let canonical lifecycle owners validate models and release processes.

Do we have a high-confidence way to reproduce the issue?

Yes, from source: current main converts custom-agent configuration into a scalar command, while pinned ACPX rejects scalar launches on Windows. No runtime reproduction was executed during this read-only review.

Is this the best way to solve the issue?

Yes. Using the existing argv contract and canonical turn lifecycle repairs the owning boundaries without adding configuration or reconstructing historical model intent.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning medium; reviewed against e9cedf96a463.

Labels

Label changes:

  • add rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🌊 off-meta tidepool and patch quality is 🐚 platinum hermit.
  • add status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Not applicable: The ordinary external-contributor proof gate does not apply to this maintainer PR. Captured evidence reports real ACP subprocess and authenticated cancellation/reconnect results; final-head native Windows verification remains pending.
  • remove rating: 🦐 gold shrimp: Current PR rating is rating: 🐚 platinum hermit, so this older rating label is no longer current.
  • remove merge-risk: 🚨 compatibility: Current PR review selected no merge-risk labels.
  • remove status: ⏳ waiting on author: Current PR status label is status: 👀 ready for maintainer look.

Label justifications:

  • P1: Repairs a reported Windows custom-agent launch failure and related ACP session-lifecycle failures.
  • rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🌊 off-meta tidepool and patch quality is 🐚 platinum hermit.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Not applicable: The ordinary external-contributor proof gate does not apply to this maintainer PR. Captured evidence reports real ACP subprocess and authenticated cancellation/reconnect results; final-head native Windows verification remains pending.

Evidence

What I checked:

  • Prior finding resolved: Reconnect passes the saved model without inventing modelExplicit. The regression initializes metadata without an applied-model annotation, then checks status and prompt behavior through original and fresh managers. Unsupported replay rejects before the prompt runtime; supported selections remain saved. This addresses the finding and rank-up request recorded in the previous review. (src/acp/control-plane/manager.runtime-handles.test.ts:786, 76ebe2a1783e)
  • Model validation remains before prompt submission: The turn runner awaits applyManagerRuntimeControls before beginning execution. Fresh explicit requests cannot take the missing-model-capability fallback, while newly dropped inherited defaults are reported to initialization. (src/acp/control-plane/manager.turn-runner.ts:230, 76ebe2a1783e)
  • Work remains absent from main and latest release: Both fetched main and v2026.9.2 still concatenate command and quoted args into a scalar string. Comparing the merge base with fetched main showed no changes to the central configuration, runtime, or runtime-options command files. The supplied merged fix(acp): preserve queued output and cancel failed deliveries #139685 explicitly identifies argv preservation as follow-up work. (extensions/acpx/src/config.ts:252, e9cedf96a463)
  • Dependency contract directly inspected: The patch imports acpx/runtime and relies on its argv persistence and lifecycle contracts. Version 0.13.1 accepts registry arrays, preserves agentArgv, renders their identity using the same rule as this patch, and rejects scalar launches on Windows. Sources: command normalization and runtime manager. Repository ownership was verified from its package.json. The separate reuse-policy helper could not be retrieved; its caller and the PR's real-subprocess compatibility regression were inspected. (src/acp/client-process.ts:68)
  • Codex cancellation contract inspected: The PR explicitly claims compatibility with Codex interruption and terminal notifications. The sibling source validates the requested active turn before interruption, and its terminal notification carries the turn ID and status. Ownership was verified through the cache repository's origin, https://github.com/openai/codex.git. (codex-rs/app-server/src/request_processors/turn_processor.rs:1560, 3d2ee51ca2d5)
  • Compatibility and process-boundary coverage: The added subprocess suite exercises empty, spaced, quoted, and backslash arguments, generated wrappers, persisted argv, reconnect identity, and legacy POSIX scalar records. Reset coverage checks that unavailable backends are not started and failed closes retain retryable state. Tests were inspected, not executed. (extensions/acpx/src/runtime-argv.process.test.ts:60, 76ebe2a1783e)

Likely related people:

  • steipete: Suggested for follow-up; no historical authorship or introduction is verified. (role: unverified routing candidate; confidence: low)
  • Shakker: Suggested for follow-up; no historical authorship or introduction is verified. (role: unverified routing candidate; confidence: low)

Rating scale

Score Internal tier Crab rank Meaning
6/6 S 🦀 challenger crab Exceptional readiness
5/6 A 🦞 diamond lobster Very strong readiness
4/6 B 🐚 platinum hermit Good normal PR; ordinary maintainer review
3/6 C 🦐 gold shrimp Useful, but confidence is limited
2/6 D 🦪 silver shellfish Proof or implementation needs work
1/6 F 🧂 unranked krab Not merge-ready
N/A NA 🌊 off-meta tidepool Rating does not apply

Overall follows the weaker of proof and patch quality.
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.

Workflow

  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

History

Review history (1 earlier review cycle)
  • reviewed 2026-09-06T05:24:17.558Z sha ba23679d4882feb02fbf274b32cfae4b35f20a76 :: blocked before merge. :: [P1] Handle legacy inherited models before marking them explicit

Inspect wrapper argv before serialization and preserve native Windows command paths. Keep legacy reconnect intent unknown while validating persisted models before prompts. Align the history pagination fixture with current projection fields.
@steipete
steipete force-pushed the codex/acpx-argv-owner-cleanup-20260906 branch from ba23679 to 76ebe2a Compare September 6, 2026 06:05
@github-actions github-actions Bot added the dependencies-changed PR changes dependency-related files label Sep 6, 2026
@github-actions

github-actions Bot commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

Dependency Guard

This PR changes dependency-related files. Maintainers should confirm these changes are intentional.

Changed files:

  • package.json

Maintainer follow-up:

  • Review whether the dependency changes are intentional.
  • Inspect resolved package deltas when lockfiles or workspace dependency policy changes are present.
  • Treat pnpm-lock.yaml and package-lock.json diffs as dependency security-review surfaces.
  • Run pnpm deps:changes:report -- --base-ref origin/main --markdown /tmp/dependency-changes.md --json /tmp/dependency-changes.json locally for detailed release-style evidence.

@github-actions

github-actions Bot commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

Dependency graph changes noted

This PR includes dependency graph changes. The dependency guard is informational because the PR author is a repository admin, a member of @openclaw/openclaw-secops, or an OpenClaw organization member with Maintain or Admin repository access.

  • Current SHA: 76ebe2a1783e7f012efc126e6b7c21b095e2af5f
  • Trusted actor: @steipete
  • Trusted role: pull request author; openclaw-secops

Security review is still recommended before merge when the dependency graph change is intentional.

@openclaw-barnacle openclaw-barnacle Bot added the gateway Gateway runtime label Sep 6, 2026
@steipete

steipete commented Sep 6, 2026

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

Addressed the legacy-model finding in 76ebe2a1783e7f012efc126e6b7c21b095e2af5f by removing inferred caller intent on reconnect. Existing metadata remains unchanged; fresh explicit requests stay strict, and the canonical runtime-control replay validates saved models before any prompt. No provenance field, migration, or compatibility reader was added.

The regression builds metadata through the old initialization contract with no applied-model annotation, then exercises both original and fresh managers. Before the correction, legacy status failed after restart. Afterward, all 28 focused tests pass: status remains usable, rejected model replay never reaches the prompt runtime, and supported Codex/Claude selections survive restart. This also covers the requested rank-up evidence without claiming to reconstruct historical intent.

Native Windows testing caught a separate wrapper-lease failure caused by inspecting JSON-escaped paths. Wrapper detection now consumes original argv, and configuration parsing preserves native Windows backslashes in relative/combined commands. Those repairs have passing local regressions and are being rerun in normal native Windows CI on the new head. The PR body records the initial failed proof and the current pending verification accurately.

@clawsweeper

clawsweeper Bot commented Sep 6, 2026 •

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event exact_review_queue).
Result: when the review finishes, ClawSweeper will create the durable review comment if needed or update the existing comment in place.

Re-review progress:

@clawsweeper clawsweeper Bot added rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. and removed rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. labels Sep 6, 2026
@steipete

steipete commented Sep 6, 2026

Copy link
Copy Markdown
Contributor Author

The remaining review proof items are complete. Native Windows on the final head passed all seven applicable ACP regressions, including leased, relative and combined commands plus reconnect. Required CI is green for 76ebe2a1783e7f012efc126e6b7c21b095e2af5f.

Authenticated smoke on exact merge 0817aa37b818ba18ecbf2e6c481a20633c407e35 with main's ACPX 0.13.2 also passed: complete delayed output, recall, both delivery-failure cancellations, legacy iterator abandonment and subsequent session reuse. All four probes exited 0; temporary credential homes and owned processes were cleaned.

The data-model detector's package.json item is only the Windows test selection. There is no SQLite/schema-version change or new provenance field. Real POSIX scalar-session reuse and the old-producer restart tests cover the relevant compatibility contracts, with saved choices preserved and rejected model replay blocked before prompts. Native prepare has passed.

@steipete
steipete merged commit 45d58aa into main Sep 6, 2026
205 checks passed
@steipete
steipete deleted the codex/acpx-argv-owner-cleanup-20260906 branch September 6, 2026 06:25
@steipete

steipete commented Sep 6, 2026

Copy link
Copy Markdown
Contributor Author

Merged via squash.

github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Sep 7, 2026
…9776)

* fix(acp): preserve agent arguments and session ownership

Keep portable argv through wrappers, leases, and reconnects; consolidate legacy turns onto canonical result cleanup. Retain cwd handle ownership, reset without backend startup, and preserve explicit model choices across reconnects. Fixes openclaw#136246; follows openclaw#139685.

* fix(acp): preserve Windows paths and legacy model replay

Inspect wrapper argv before serialization and preserve native Windows command paths. Keep legacy reconnect intent unknown while validating persisted models before prompts. Align the history pagination fixture with current projection fields.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies-changed PR changes dependency-related files docs Improvements or additions to documentation extensions: acpx gateway Gateway runtime maintainer Maintainer-authored PR P1 High-priority user-facing bug, regression, or broken workflow. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. size: XL status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Custom ACP agents are impossible to configure on Windows - schema rejects argv while the acpx runtime rejects command strings

1 participant