Skip to content

fix(coding-agent): open isolated subagent sessions in worktree cwd#2626

Merged
can1357 merged 1 commit into
can1357:mainfrom
bjin:fix/isolated-subagent-cwd
Jun 15, 2026
Merged

fix(coding-agent): open isolated subagent sessions in worktree cwd#2626
can1357 merged 1 commit into
can1357:mainfrom
bjin:fix/isolated-subagent-cwd

Conversation

@bjin

@bjin bjin commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

What

Fixed isolated task subagents with persisted JSONL sessions so their built-in
file tools resolve paths against the isolated worktree cwd instead of the parent
repository cwd.

This change updates the session-opening path used by isolated task execution:

  • SessionManager.open() now accepts an optional initialCwd.
  • initialCwd is used only when the target session file is empty or missing and
    therefore has no persisted session header yet.
  • Existing resumes still prefer the cwd stored in the session header, preserving
    the current cross-project resume behavior.
  • Isolated task execution now passes worktree ?? cwd as that initialCwd when
    opening the persisted subagent JSONL.
  • The regression test now asserts the important invariant directly: a persisted
    isolated subagent session exposes the isolated worktree via
    sessionManager.getCwd().

Why

rcopy isolation was creating and using the isolated worktree correctly for the
subagent process-level cwd. A probe from the failing session showed subagents
running under paths like:

~/.omp/wt/<agentId>-<repoHash>/merged

However, the actual file-tool writes did not participate in isolated patch
capture. The first symptom was confusing:

  • subagents reported successful file writes;
  • task merge summaries said No changes to apply.;
  • <agentId>.patch artifacts were empty;
  • in the original repro, parent-repo files appeared without any patch being
    applied.

The relevant code path split cwd ownership in two places:

  1. TaskTool creates the isolated worktree and calls runSubprocess() with
    worktree: isolationDir.
  2. runSubprocess() passes cwd: worktree ?? cwd into createAgentSession().
  3. But built-in tools do not resolve paths from CreateAgentSessionOptions.cwd.
    They resolve through ToolSession.cwd.
  4. ToolSession.cwd is backed by sessionManager.getCwd().
  5. For persisted subagents, runSubprocess() opened the JSONL with
    SessionManager.open(sessionFile).
  6. Fresh subagent JSONL files have no header yet, so SessionManager.open() fell
    back to getProjectDir().

That meant the prompt and some setup paths knew about the isolated worktree, but
file tools saw the parent/global project cwd through the session manager. Patch
capture then inspected the isolated worktree, found no git-visible delta, wrote
an empty patch artifact, and correctly reported No changes to apply..

This is why the fix is intentionally at the persisted-session boundary rather
than in the file tools. The file tools were already using the right abstraction:
sessionManager.getCwd() is the session cwd. The bug was that new isolated
subagent sessions were initialized with the wrong cwd before their first header
was written.

The manual follow-up test also distinguished this root cause from a separate
untracked-file setup issue. A first retest created new arbitrary root files in an
AUR repository. Those writes stayed inside the isolated worktree after this fix,
but patch capture still produced empty patches because the files were not
visible to:

git ls-files --others --exclude-standard

That was not the original cwd bug: the parent repository did not receive direct
writes. A second retest edited existing tracked files (PKGBUILD and
.SRCINFO), and those changes were captured and merged through non-empty patch
artifacts.

Testing

Automated verification:

  • bun test packages/coding-agent/test/task/subagent-lsp.test.ts
    • includes the new regression case for persisted isolated subagent cwd;
    • the test would fail before this fix because sessionManager.getCwd() would
      remain the parent/default project cwd instead of the isolated worktree.
  • bun --cwd=packages/coding-agent run check
    • runs the coding-agent package checks, including type checking and Biome.

Manual patched-binary validation in a separate git repository:

  • tested in a separate private git repository with a patched OMP binary;
  • task.isolation.mode=rcopy;
  • task.isolation.merge=patch;
  • spawned two isolated subagents in one task batch;
  • both subagents had isolated: true;
  • both used normal file tools, not shell redirection or git commands;
  • each subagent edited a different tracked file;
  • parent marker search found no matches before merge;
  • both merge summaries reported Applied patches: yes;
  • both patch artifacts were non-empty and targeted the expected tracked files;
  • parent repo contained both marker edits after merge;
  • subagent JSONL cwd values were isolated worktrees under ~/.omp/wt/.../merged;
  • cleanup removed both marker edits.

This validates the intended end-to-end behavior: file-tool edits made by
persisted isolated subagents are captured in the isolated worktree, emitted as
patch artifacts, and merged back to the parent repository by patch mode.


  • bun check passes
  • Tested locally
  • CHANGELOG updated (if user-facing)

Persisted isolated subagents created their fresh JSONL session through
SessionManager.open(), which fell back to getProjectDir() when the file had no
header. createAgentSession still received the isolated worktree cwd, but built-in
tools resolve paths through sessionManager.getCwd(), so file tools could target
the parent repository while patch capture saw no isolated delta.

Allow SessionManager.open() to take an initial cwd for empty/missing session
files and pass the isolated worktree cwd from task execution. Non-empty resumes
still use the persisted header cwd. Add regression coverage asserting persisted
isolated subagent sessions expose the worktree cwd through their session
manager.
@roboomp roboomp added agent Agent runtime planning and orchestration fix review:p0 tool Tool behavior and integrations triaged labels Jun 15, 2026

@roboomp roboomp left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

P0 — focused root-cause fix: persisted isolated subagent sessions now seed SessionManager.open() with the worktree cwd only for fresh JSONL files, preserving header cwd on resume.
No inline findings. Changelog and regression coverage are present for the observable sessionManager.getCwd() contract.
Thanks @bjin.

@can1357 can1357 merged commit 336f1a8 into can1357:main Jun 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agent Agent runtime planning and orchestration fix review:p0 tool Tool behavior and integrations triaged

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants