Skip to content

fix(bg): v0.11.1 background dispatch isolation split (non-git cwd fix) - #19

Merged
rz1989s merged 9 commits into
mainfrom
fix/spec-bg-non-git
Jul 28, 2026
Merged

fix(bg): v0.11.1 background dispatch isolation split (non-git cwd fix)#19
rz1989s merged 9 commits into
mainfrom
fix/spec-bg-non-git

Conversation

@rz1989s

@rz1989s rz1989s commented Jul 28, 2026

Copy link
Copy Markdown
Member

Proper-fix for the background dispatch 100%-failure in non-git cwds (repro: ~/local-dev/bug-bounty, session 019fa956… — 7 parallel bg dispatches all died with worktree create failed: not a git repository, then the model polled fleet_results 90s for runs that already failed).

Root cause

Worktree isolation was conflated with background execution. runBackground unconditionally called git worktree add (needs a git repo), and the failure surfaced as an async ctx.ui.notify toast the model never saw as a tool result — so it returned background run: fl-… (looks successful) then waited on a dead inbox.

The fix (proper architectural split, not a flag)

  • runBackgroundInPlace — git-agnostic core (pool + journal + runLifecycle in ctx.cwd, no worktree).
  • runBackgroundIsolated — worktree wrapper with a synchronous isGitRepo() pre-flight → returns {status:"failed", error} (no runId, no pool slot, no async toast) on failure. The tool maps this to isError.
  • runBackgroundAuto — router: isolated when cwd is git (current behavior preserved), in-place + one per-session notify when not.
  • subagent tool + scheduler gain isolation: "worktree" | "none" | "auto" (default auto).
  • RunStartedEvent.worktree? / RunCompletedEvent.branch? / RunLifecycleOpts.worktreePath?/branch? optional (additive; old events still parse).
  • scanResumeCandidates handles in-place interrupted runs (abort + canResume:false, honest reason).
  • The index.ts adapter becomes isolation-aware (conditional artifactDiscovery + parentCwd).

Tests

450/450 pass (+12 new: in-place in non-git, sync-fail worktree-in-non-git, auto-fallback dedup, git-auto regression, explicit-none-in-git, journal optional round-trips, old-event parse, in-place interrupted abort, isGitRepo, subagent sync-fail isError, scheduler persist+load). Typecheck clean. Bug repro covered.

Design

  • Spec: docs/superpowers/specs/2026-07-28-bg-non-git-isolation-split-design.md
  • Plan: docs/superpowers/plans/2026-07-28-bg-non-git-isolation-split.md

This produces the seam SPEC-6-3's agent() isolation opt-in will inherit.

rz1989s added 9 commits July 28, 2026 22:48
Proper-fix spec for the background dispatch 100%-failure in non-git
cwds. Splits runBackground into a git-agnostic core (runBackgroundInPlace)
+ a worktree wrapper (runBackgroundIsolated) + an auto router. Adds
isolation: worktree|none|auto (default auto) to the subagent tool + scheduler.
Synchronous fail-fast on worktree failures. Closes the conflation of
background-execution with worktree-isolation; produces the seam SPEC-6-3's
agent() isolation opt-in inherits.
6-task TDD implementation plan for the v0.11.1 patch. Task 1: foundation
(isGitRepo + optional journal/lifecycle fields). Task 2: the split (core +
wrapper + router + index adapter). Task 3: subagent tool isolation param +
sync-fail isError. Task 4: scheduler isolation plumbing. Task 5:
scanResumeCandidates in-place handling. Task 6: release v0.11.1.
Foundation for the background isolation split. WorktreeService gains a
cheap isGitRepo() pre-flight. RunStartedEvent.worktree and
RunCompletedEvent.branch become optional (in-place runs have neither).
RunLifecycleOpts.worktreePath/branch become optional. Additive — old
events still parse; no behavior change.
…r + auto router

runBackgroundInPlace (core) is git-agnostic: pool + journal + runLifecycle
in ctx.cwd, no worktree. runBackgroundIsolated (wrapper) does a SYNCHRONOUS
isGitRepo pre-flight + worktree.create before returning, so worktree failures
surface as { status: 'failed', error } (no runId) — the tool maps to isError,
not an async toast + 90s poll. runBackgroundAuto routes: isolated when cwd is
git (current behavior preserved), in-place + one per-session notify when not.
The index.ts adapter becomes isolation-aware (conditional artifactDiscovery +
parentCwd). Closes the 100% bg failure in non-git cwds.
The subagent tool accepts isolation: worktree|none|auto (default auto).
On a synchronous worktree failure (e.g. 'worktree' in a non-git cwd) the
tool now returns isError with the actionable message, instead of
'background run: undefined' + an async toast the model never sees.
Scheduled runs are background runs; they inherit the isolation opt-in.
ScheduleSpec gains optional isolation (default auto). The onFire callback
+ subagent tool's schedule branch thread it through to runBackground.
An interrupted in-place run (run:started with no worktree field) has no
worktree to clean; abort it + mark canResume=false with an honest reason
(partial edits may remain in cwd). ResumeCandidate.worktreePath/branch
become optional. Isolated-run handling unchanged.
@rz1989s
rz1989s merged commit 51956e0 into main Jul 28, 2026
1 check passed
@rz1989s
rz1989s deleted the fix/spec-bg-non-git branch July 28, 2026 16:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant