Skip to content

Honor cwd for native subagent spawns#81896

Merged
giodl73-repo merged 2 commits into
openclaw:mainfrom
giodl73-repo:fix/subagent-cwd-79840
May 16, 2026
Merged

Honor cwd for native subagent spawns#81896
giodl73-repo merged 2 commits into
openclaw:mainfrom
giodl73-repo:fix/subagent-cwd-79840

Conversation

@giodl73-repo

@giodl73-repo giodl73-repo commented May 14, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Thread sessions_spawn cwd through the native runtime="subagent" path.
  • Resolve the spawned child workspace once, using explicit cwd before same-agent inherited workspace and target-agent fallback.
  • Use the resolved child workspace for inline attachment materialization while keeping workspaceDir internal and out of Gateway agent params.

Closes #79840

Real behavior proof

  • Behavior or issue addressed: native sessions_spawn({ runtime: "subagent", cwd }) should carry explicit cwd into native spawn workspace resolution; spawned runs and inline attachments should use the requested workspace, while public Gateway agent params should not receive internal workspaceDir.
  • Real environment tested: WSL Ubuntu-24.04 source worktrees created from upstream/main and PR head 3246e902cfa20da8a03dca318cb6b4442b9038e5.
  • Exact steps or command run after this patch: created clean detached worktrees for upstream/main and fork/fix/subagent-cwd-79840; in each worktree ran node --import ./node_modules/tsx/dist/loader.mjs ./probe-subagent-cwd.mjs. The probe checked the real source plumbing for cwd on the native spawn path and called the real materializeSubagentAttachments() with an explicit workspace plus a different target-agent fallback workspace.
  • Evidence after fix (screenshot, recording, terminal capture, console output, redacted runtime log, linked artifact, or copied live output):

PR #81896 native subagent cwd before/after proof

Fresh proof artifact: https://raw.githubusercontent.com/giodl73-repo/openclaw/proof-artifacts/pr-81896-fresh/pr-81896/pr-81896-native-subagent-cwd-before-after-proof.png
Proof summary: https://raw.githubusercontent.com/giodl73-repo/openclaw/proof-artifacts/pr-81896-fresh/pr-81896/summary.txt

BEFORE upstream/main:
status=0
sourceParamHasCwd=false
sourceToolForwardsCwd=false
materializeStatus=ok
explicitRootExists=false
targetRootExists=true
materializedUnderExplicitCwd=false
receiptCount=1
ok=false

AFTER PR #81896 head:
status=0
sourceParamHasCwd=true
sourceToolForwardsCwd=true
materializeStatus=ok
explicitRootExists=true
targetRootExists=false
materializedUnderExplicitCwd=true
receiptCount=1
ok=true
  • Observed result after fix: upstream/main does not accept/forward cwd on the native spawn path, and attachment materialization falls back to the target agent workspace. PR head accepts/forwards cwd and materializes attachments under the explicit child workspace instead of the target-agent fallback workspace.
  • What was not tested: no live Telegram/macOS same-workspace canary was run from this WSL environment. The proof verifies the runtime attachment materialization seam plus the native spawn cwd plumbing, and the PR includes focused spawn/attachment regression tests.

Validation

  • node scripts/test-projects.mjs src/agents/tools/sessions-spawn-tool.test.ts src/agents/subagent-spawn.workspace.test.ts src/agents/subagent-spawn.attachments.test.ts src/agents/spawned-context.test.ts
  • pnpm check:changed

@openclaw-barnacle openclaw-barnacle Bot added agents Agent runtime and tooling size: S maintainer Maintainer-authored PR labels May 14, 2026
@clawsweeper

clawsweeper Bot commented May 14, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs real behavior proof before merge.

Summary
The branch adds cwd to native subagent spawn params, forwards sessions_spawn.cwd, reuses one resolved workspace for metadata and attachment materialization, and adds focused regression tests.

Reproducibility: yes. source-reproducible: current main exposes and reads sessions_spawn.cwd, forwards it to ACP, but omits it from native spawnSubagentDirect, and attachments resolve the target workspace. I did not run a live native child canary in this read-only review.

Real behavior proof
Needs stronger real behavior proof before merge: The new screenshot/copy is useful source and attachment-seam proof, but it does not show a real native child observing pwd; contributor should add redacted terminal/live output, logs, or a recording, removing IPs, keys, phone numbers, and private endpoints, then update the PR body for re-review.

Next step before merge
Human review remains because this is protected by the maintainer label and the remaining blocker is contributor-side runtime proof, not a repairable code defect.

Security
Cleared: Cleared: the diff changes internal workspace routing and tests without new dependencies, scripts, workflows, permissions, secret handling, or supply-chain inputs.

Review details

Best possible solution:

Land this narrow cwd-threading fix after maintainer review, green focused checks, and redacted runtime proof showing a native child pwd plus attachment paths follow explicit cwd.

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

Yes, source-reproducible: current main exposes and reads sessions_spawn.cwd, forwards it to ACP, but omits it from native spawnSubagentDirect, and attachments resolve the target workspace. I did not run a live native child canary in this read-only review.

Is this the best way to solve the issue?

Yes for the code shape: forwarding cwd as internal native spawn state and reusing one resolved workspace is the narrow maintainable fix. Merge readiness still needs maintainer review and real native runtime proof.

What I checked:

  • Current main reads cwd but omits it from native spawn: sessions_spawn reads cwd and forwards it to ACP, but the native spawnSubagentDirect argument object does not include cwd, so the explicit value cannot affect native workspace resolution on current main. (src/agents/tools/sessions-spawn-tool.ts:476, bea4f0d2f4b4)
  • Current native params and attachments lack explicit cwd: SpawnSubagentParams has no cwd, and materializeSubagentAttachments() always resolves the target agent workspace, independent of an explicit spawn cwd. (src/agents/subagent-spawn.ts:123, bea4f0d2f4b4)
  • PR patch forwards cwd through the native path: The PR head adds cwd?: string, normalizes params.cwd, resolves one spawnedWorkspaceDir, passes it to attachment materialization, and keeps workspaceDir stripped from public Gateway agent params. (src/agents/subagent-spawn.ts:130, 3246e902cfa2)
  • PR adds focused regression coverage: The diff adds coverage for tool forwarding, cross-agent explicit cwd workspace metadata without Gateway param leakage, and attachment materialization under the explicit cwd. (src/agents/subagent-spawn.workspace.test.ts:168, 3246e902cfa2)
  • Contributor proof artifact inspected: The supplied proof summary and image show before/after source forwarding and real materializeSubagentAttachments() behavior: main falls back to the target workspace, while PR head materializes under explicit cwd. It does not show an actual native child process observing pwd. (3246e902cfa2)
  • Subagent security boundary is policy-gated: The docs already treat sessions_spawn as a delegation boundary controlled by tool policy, target-agent allowlists, and sandbox: "require"; this patch does not add dependencies, workflows, install scripts, or secret handling. Public docs: docs/gateway/security/index.md. (docs/gateway/security/index.md:1124, bea4f0d2f4b4)

Likely related people:

  • steipete: Commit eed403dc74b5e9cde9651c855c1dee05f5b9a1d2 unified spawned metadata and extracted the attachments service, shaping the metadata and attachment seams changed here. (role: recent area contributor; confidence: high; commits: eed403dc74b5; files: src/agents/spawned-context.ts, src/agents/subagent-attachments.ts, src/agents/subagent-spawn.ts)
  • moshehbenavraham: Commit 55e79adf6916ffed4b745744793f1502338f1b92 added the target-agent workspace fallback for cross-agent subagent spawns, which this PR modifies by giving explicit cwd precedence. (role: introduced adjacent workspace behavior; confidence: high; commits: 55e79adf6916; files: src/agents/spawned-context.ts, src/agents/subagent-spawn.ts, src/agents/subagent-spawn.workspace.test.ts)
  • mcaxtr: The squash commit for the cross-agent workspace fallback records mcaxtr as reviewer and co-author, making them a reasonable routing candidate for this workspace inheritance behavior. (role: reviewer and adjacent contributor; confidence: medium; commits: 55e79adf6916; files: src/agents/spawned-context.ts, src/agents/subagent-spawn.ts)

Remaining risk / open question:

  • The contributor proof shows source/seam behavior but not an actual native subagent child observing pwd under the explicit cwd.
  • This read-only review did not apply the PR branch or run the focused tests; the verdict is based on current main source, PR diff/raw files, supplied proof artifacts, and history.

Codex review notes: model gpt-5.5, reasoning high; reviewed against bea4f0d2f4b4.

@giodl73-repo giodl73-repo force-pushed the fix/subagent-cwd-79840 branch 2 times, most recently from 03f57bf to 41b8c6f Compare May 15, 2026 02:11

@martingarramon martingarramon left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The workspace-resolution refactor is clean. toolSpawnMetadata is moved earlier so spawnedWorkspaceDir can be resolved once and shared between materializeSubagentAttachments and normalizeSpawnedRunMetadata — eliminates the prior duplication where resolution happened inline only for metadata, leaving attachments without access to the resolved path.

Precedence chain is correct: explicitWorkspaceDir ?? inheritedWorkspaceDir — explicit params.cwd wins; inherited workspace applies only for same-agent spawns (targetAgentId !== requesterAgentId ? undefined); cross-agent spawns fall back through resolveSpawnedWorkspaceInheritance to the target agent's config. The original cross-agent guard is preserved.

normalizeOptionalString returns undefined for empty/blank cwd, so cwd: "" gracefully falls through to inherited — no edge case.

LGTM.

@giodl73-repo giodl73-repo force-pushed the fix/subagent-cwd-79840 branch 6 times, most recently from dc606b2 to 4087f75 Compare May 16, 2026 14:10
giodl73-repo and others added 2 commits May 16, 2026 07:15
Thread sessions_spawn cwd through the native subagent path, use the resolved child workspace for attachment materialization, and keep workspace metadata internal to the gateway boundary.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@giodl73-repo giodl73-repo force-pushed the fix/subagent-cwd-79840 branch from 4087f75 to 3246e90 Compare May 16, 2026 14:15
@giodl73-repo

Copy link
Copy Markdown
Contributor Author

Updated #81896 with a fresh deterministic proof image and gate-friendly proof section.

The proof compares upstream/main against PR head 3246e902cfa20da8a03dca318cb6b4442b9038e5:

  • Before: native spawn source does not accept/forward cwd, and attachments materialize under the target-agent fallback workspace.
  • After: native spawn source accepts/forwards cwd, and attachments materialize under the explicit child workspace.

Fresh proof image: https://raw.githubusercontent.com/giodl73-repo/openclaw/proof-artifacts/pr-81896-fresh/pr-81896/pr-81896-native-subagent-cwd-before-after-proof.png
Proof summary: https://raw.githubusercontent.com/giodl73-repo/openclaw/proof-artifacts/pr-81896-fresh/pr-81896/summary.txt

@clawsweeper clawsweeper Bot added the P2 Normal backlog priority with limited blast radius. label May 16, 2026
@giodl73-repo giodl73-repo merged commit 3b2cd0d into openclaw:main May 16, 2026
122 checks passed
galiniliev pushed a commit to galiniliev/openclaw that referenced this pull request May 20, 2026
* Honor cwd for native subagent spawns

Thread sessions_spawn cwd through the native subagent path, use the resolved child workspace for attachment materialization, and keep workspace metadata internal to the gateway boundary.

* Refresh checks after proof update
SebTardif pushed a commit to SebTardif/openclaw that referenced this pull request May 24, 2026
* Honor cwd for native subagent spawns

Thread sessions_spawn cwd through the native subagent path, use the resolved child workspace for attachment materialization, and keep workspace metadata internal to the gateway boundary.

* Refresh checks after proof update
SebTardif pushed a commit to SebTardif/openclaw that referenced this pull request May 24, 2026
* Honor cwd for native subagent spawns

Thread sessions_spawn cwd through the native subagent path, use the resolved child workspace for attachment materialization, and keep workspace metadata internal to the gateway boundary.

* Refresh checks after proof update
SebTardif pushed a commit to SebTardif/openclaw that referenced this pull request May 24, 2026
* Honor cwd for native subagent spawns

Thread sessions_spawn cwd through the native subagent path, use the resolved child workspace for attachment materialization, and keep workspace metadata internal to the gateway boundary.

* Refresh checks after proof update
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request May 24, 2026
* Honor cwd for native subagent spawns

Thread sessions_spawn cwd through the native subagent path, use the resolved child workspace for attachment materialization, and keep workspace metadata internal to the gateway boundary.

* Refresh checks after proof update
galiniliev pushed a commit to galiniliev/openclaw that referenced this pull request May 25, 2026
* Honor cwd for native subagent spawns

Thread sessions_spawn cwd through the native subagent path, use the resolved child workspace for attachment materialization, and keep workspace metadata internal to the gateway boundary.

* Refresh checks after proof update
SebTardif pushed a commit to SebTardif/openclaw that referenced this pull request May 26, 2026
* Honor cwd for native subagent spawns

Thread sessions_spawn cwd through the native subagent path, use the resolved child workspace for attachment materialization, and keep workspace metadata internal to the gateway boundary.

* Refresh checks after proof update
SebTardif pushed a commit to SebTardif/openclaw that referenced this pull request May 26, 2026
* Honor cwd for native subagent spawns

Thread sessions_spawn cwd through the native subagent path, use the resolved child workspace for attachment materialization, and keep workspace metadata internal to the gateway boundary.

* Refresh checks after proof update
SebTardif pushed a commit to SebTardif/openclaw that referenced this pull request May 26, 2026
* Honor cwd for native subagent spawns

Thread sessions_spawn cwd through the native subagent path, use the resolved child workspace for attachment materialization, and keep workspace metadata internal to the gateway boundary.

* Refresh checks after proof update
jameslcowan pushed a commit to jameslcowan/openclaw that referenced this pull request Jun 2, 2026
* Honor cwd for native subagent spawns

Thread sessions_spawn cwd through the native subagent path, use the resolved child workspace for attachment materialization, and keep workspace metadata internal to the gateway boundary.

* Refresh checks after proof update
SYU8384 pushed a commit to SYU8384/openclaw that referenced this pull request Jun 3, 2026
* Honor cwd for native subagent spawns

Thread sessions_spawn cwd through the native subagent path, use the resolved child workspace for attachment materialization, and keep workspace metadata internal to the gateway boundary.

* Refresh checks after proof update
sablehead pushed a commit to sablehead/openclaw that referenced this pull request Jun 10, 2026
* Honor cwd for native subagent spawns

Thread sessions_spawn cwd through the native subagent path, use the resolved child workspace for attachment materialization, and keep workspace metadata internal to the gateway boundary.

* Refresh checks after proof update
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling maintainer Maintainer-authored PR P2 Normal backlog priority with limited blast radius. size: S

Projects

None yet

Development

Successfully merging this pull request may close these issues.

sessions_spawn(runtime="subagent") should honor explicit cwd for same-workspace delegated execution

2 participants