AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified MIT Self-run

Worktree Agent Isolation

skill-arasz-ai-badger-worktree-agent-isolation · by Arasz

Use when running multiple agents in parallel, or when the user says 'worktrees only', 'agent isolation', 'parallel workstreams', or 'don't touch main': give each agent its own git worktree branched from origin/main (fetch first), integrate via GitHub PRs, keep the main checkout read-only, and avoid shared obj/ races and file-modification conflicts.

No reviews yet
0 installs
15 views
0.0% view→install

Install

$ agentstack add skill-arasz-ai-badger-worktree-agent-isolation

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-arasz-ai-badger-worktree-agent-isolation)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
17d ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Worktree Agent Isolation? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Worktree Agent Isolation

Run N independent coding agents in parallel, each in its own git worktree, with zero file conflicts. Integrate via GitHub PRs — the main checkout is read-only.

Why

Two agents in the same directory cause:

  • Build failures: Shared obj/ directories cause MSB3492 or "Building target

completely" errors. Workaround is rm -rf obj/ but it is destructive and racy.

  • File modification races: One agent patches stale content.
  • Test corruption: Process-global state (env vars, temp dirs) interferes.

When to Use

  • User says "worktrees only", "don't touch main", "agent isolation"
  • Multiple independent tasks can run in parallel
  • Another agent/session is using the main checkout
  • User wants to see draft PRs for in-flight work visibility

Setup

# Fetch latest main first — ensures worktrees branch from the true HEAD
git fetch origin main

# Create N worktrees from origin/main (not local main, which may be behind)
git worktree add ../project-task-a -b task/- origin/main
git worktree add ../project-task-b -b task/- origin/main

Each worktree gets its own branch, own working directory, own build artifacts.

Always use origin/main as the base, not main. Local main may lag behind after another agent merges. Fetching first ensures all worktrees share the same ancestor, reducing rebase conflicts when merging sequentially.

Dispatching Agents

delegate_task(tasks=[
    {"goal": "Implement issue #X: ...",
     "context": """Project: /abs/path/to/project-task-a
     Branch: task/x-slug (already checked out)
     Build: dotnet build
     Test: dotnet test --filter "..."
     DO NOT USE Rider MCP tools. Use terminal, read_file, write_file only.
     TDD MANDATORY: ..."""},
    {"goal": "Implement issue #Y: ...",
     "context": """Project: /abs/path/to/project-task-b
     ..."""},
])

Key: pass the absolute worktree path as Project. Each agent's working directory is isolated — they never see each other's files.

For full-stack projects, include BOTH backend and frontend build/test commands in the agent context. Backend-focused orchestrators default to dotnet build and miss frontend compilation errors:

{"goal": "Implement issue #X: ...",
 "context": """Project: /abs/path/to/project-task-a
 Branch: task/x-slug (already checked out)
 Build: dotnet build
 Test: dotnet test --filter "RequiresInfra!=true"
 Frontend build: cd src/frontend && bun run build
 Frontend test: cd src/frontend && bun run test
 Frontend lint: cd src/frontend && bun run lint
 DO NOT USE Rider MCP tools. Use terminal, read_file, write_file only.
 TDD MANDATORY: ..."""},

User Preferences (baked in from session corrections)

Docs bundled into feature PRs, push branches often, update GitHub issues after each merge, draft PRs for visibility, strict "don't touch main", and no Rider MCP when other agents use it: references/user-preferences.md.

Integration After Agents Complete

1. Verify in each worktree

cd /abs/path/to/project-task-a
dotnet build && dotnet test --filter "..."

2. Commit in worktree

git add -A && git commit -m "feat: description (#issue)"

3. Push branch

git push origin task/

4. Create draft PR for visibility

# From main checkout (or any checkout with gh auth)
gh pr create --head task/ --draft \
  --title "feat: description (#issue)" \
  --body "Summary. Closes #issue."

5. Update GitHub issue

gh issue comment  --body "## Implemented ✅
PR # opened. [details]
Awaiting merge."

6. Merge (admin bypass for CI limits)

gh pr ready 
gh pr merge  --squash --delete-branch --admin

--admin bypasses branch protection and CI check requirements. Use when:

  • CI quota/limits are reached
  • Checks are expected to fail for non-code reasons
  • User explicitly says "bypass rules and merge"

7. Clean up worktree

git worktree remove /abs/path/to/project-task-a --force

State Tracking Updates

When main checkout must not be touched, update the project state file via a short-lived worktree + PR:

git worktree add ../project-state -b task/state-update origin/main
# edit the state file in the worktree
cd ../project-state
git add  && git commit -m "chore: update state"
git push origin task/state-update
# PR + admin merge + remove worktree

> Merge conflicts: read references/merge-conflicts-rebase.md when a worktree branch hits merge conflicts (rebase pattern).

Scaling to N parallel issues

When the user says "continue" or "do all remaining issues":

  1. Plan the batch — identify which issues are unblocked (no unresolved blocked-by).
  2. Create all worktrees at once from origin/main:

``bash for issue in 179 203 205; do git worktree add ../project-$issue -b task/$issue-slug origin/main done ``

  1. Dispatch all agents in parallel via delegate_task(tasks=[...]).
  2. As each completes: verify in worktree → commit → push → create draft PR.
  3. Merge sequentially (not simultaneously):
  • Rebase worktree on latest main (other PRs may have merged).
  • gh pr ready + gh pr merge --squash --delete-branch --admin.
  • If rebase conflicts on docs: combine both sides (keep HEAD additions + add ours).
  1. Clean up each worktree immediately after merge.
  2. Batch state updates — one state-update worktree per batch, not per issue.

Subagent fix-up pattern

When a subagent's work has test failures after completion:

  1. Try a quick fix in the worktree yourself (enum casing, MSW handlers, type errors).
  2. If the fix is non-trivial, dispatch a dedicated fix-up subagent for that worktree.
  3. Only commit+push+PR after all tests pass in the worktree.

> Autonomous wave cycles: read references/autonomous-wave-cycle.md when running a fully autonomous wave-based cycle.

> Shared binary artifacts: read references/parallel-waves-shared-artifact.md when parallel waves share a committed binary artifact (corpus db, vector store).

Reading subagent background-process notifications (orchestrator)

Servers/processes a subagent starts in background (watch patterns like "Application started") forward their lifecycle notifications to the orchestrator session. Interpret them before reacting:

  • A SIGTERM/exit on a subagent-owned process is usually the AGENT deliberately killing its own hung run (full-suite hang → kill → isolate with a single-filter time dotnet test), not a crash.
  • Tail the subagent's live transcript (~/.hermes/cache/delegation/live//task-N.log) before reacting to any subagent-owned process notification — it shows whether the agent is mid-debug or actually dead.
  • Repeated server restarts in a transcript are progress, not loops: each restart often means one ingest/regeneration iteration with a fix baked in.
  • A re-run of a failed background command produces a DELAYED notification carrying the OLD failure output. If you already re-ran and verified green, the stale notification is noise — ignore it.

> A/B agent experiments: read references/comparative-agent-experiments.md when comparing agents or tools in parallel workstreams.

> Shared-worktree collisions: read references/shared-worktree-collisions.md when agents must share ONE worktree (WIP build collisions, git discipline, shared-main commits).

> Machine load: read references/machine-load.md before running parallel agents with background QoS (scripts/run_suite.py) enabled, or when a timing-sensitive suite starts flaking under load.

Gotchas

  • QoS tightens every timeout ~2.11xtaskpolicy -b (via scripts/run_suite.py) makes the wrapped process 2.11x slower, which shrinks the margin on any fixed startup timeout by the same factor: two overlapping worktrees measured TaskCanceledException at AspireInfraFixture.InitializeAsync with no assertion involved. Children inherit -b, so wrap only the test runner, never long-lived infra (AppHost/dev server/emulator); raise fixed timeouts >=2.5x when QoS is active, or set AI_BADGER_QOS=off to exempt a lane. See references/machine-load.md.
  • git worktree add origin/ without -b = DETACHED HEAD — commits silently vanish. When a task worktree was already removed and you re-add one just to fix a pushed PR branch, plain git worktree add /tmp/x origin/task/foo checks out the remote branch DETACHED: your commit lands on the detached HEAD, git push answers "Everything up-to-date" (the branch ref never moved), and git worktree remove discards the work with no error. The local branch often STILL EXISTS after a tracker finish — reuse it directly (git worktree add /tmp/x task/foo). Otherwise create one explicitly: git worktree add /tmp/x -b origin/, then push with git push origin :. After any post-hoc worktree commit, verify it landed: git log --oneline origin/ must show your commit before you report it.
  • Tooling that creates worktrees from LOCAL main builds on a stale base. When the user merges PRs via the GitHub UI and never pulls locally, local main lags origin — the fresh worktree silently lacks merged PRs AND user's direct commits. Symptom: your patches apply cleanly but the base is missing expected content. Before ANY work in a new worktree: git fetch origin main && git log --oneline -3 origin/main vs git log --oneline -1 in the worktree — if origin is ahead, rebuild: save ONLY your intended diffs, then git checkout -- . && git checkout -B origin/main, re-apply. Rebuild clobbering trap: files whose content depends on the base (csproj metadata, contract tests, server.json) carry the STALE base's values — re-copying a saved copy reverts the base's correct values. Restore each base-dependent file from git first (git checkout -- ), then re-apply ONLY the version/metadata delta; verify base identity after the rebuild with a marker your diff does NOT touch.
  • Main can move while your branch sits in review — with no remote PR flow, another agent/user session can merge into LOCAL main while your wave branch sits in review. Before EVERY integration, check git log ..main — if main moved, merge main back into the wave branch, resolve conflicts (keep the other session's newer work where it overlaps; their rewrite of a file your wave also touched is usually additive), re-run the full suite, and only then merge to main. A stale-base merge onto moved main produces conflicts that masquerade as your waves' fault.
  • Ownership seam-checks lie when main movedgit diff --name-only main..HEAD | grep -v -E '' flags out-of-scope files, but if main advanced (a wave merge, a user commit) after the branch was created, MAIN-side changes masquerade as branch edits. Before accusing a subagent of a scope violation: git merge-base main HEAD — a base older than main's tip means main-side diffs will appear; then git log --oneline main..HEAD -- — empty means the file changed on main's side, not the branch. Quick whole-branch version: git diff $(git merge-base origin/main HEAD)..HEAD --stat — a scary 91-file stat is usually a moved main (other sessions' commits appear as deletions/edits on your side), not a scope violation.
  • Full-suite failures at join: attribute before blaming the branch. A shared machine runs other sessions; the first full-suite run after a package lands can fail many tests (E2E/embedding/watch families are timing/env-sensitive: serial-collection env mutation, model files, concurrent builds). Do NOT treat that as your branch's failure: (1) re-run the full suite once (run 2 often passes — flake), (2) if it still fails, create a throwaway baseline worktree (git worktree add origin/main) and run ONLY the failing test classes there — failures on baseline = pre-existing environmental flakes, branch is clean; remove the worktree after. Only failures that reproduce on your branch but NOT on baseline are yours. The task skill's "run the suite as the only session working" is often impossible on a shared machine — the baseline-attribution drill is the practical substitute, and a single clean full-suite run on the final state is the gate.
  • A parallel task owning the same file beats duplicating the work — when two tasks both need to rewrite one surface (a file-watcher's CLI section vs a CLI-config refactor, both touching the same files), DEFER the section to the owning task instead of implementing it twice: shrink your wave (drop the section), pin the exact shared contract (settings keys, command formats) in BOTH subagent briefs, and re-validate the deferred scenarios at integration. Two branches rewriting the same file collide at merge no matter how clean each side is.
  • The verification tracker re-fires even after a recorded canonical run — the "one clean recorded run satisfies it" note is wrong as measured: it kept re-firing every turn on the stale changed-path list. Do not loop re-running identical checks on unchanged bytes. Per turn: either stat/mtime-prove byte-identity or run the check once, then state the blocker in one line. Re-run only when a new edit actually occurred.
  • Parallel branches adding the same interface method cause duplicate implementations at merge — when two branches both add the same method to an interface, the merge keeps both implementations (compile error CS0111). Fix: after sequential merge, grep for duplicate method signatures in the implementation files. Keep the one from the branch that owns the feature; delete the duplicate from the merged branch. This commonly hits repository interfaces, container configs, and DI registrations.
  • Committed conflict markers compile-fail loudly, but only at build — a merge committed with is ALL-OR-NOTHING — one bad pathspec makes the whole command fail silently (stderr suppressed with 2>/dev/null), leaving every file unresolved while the rest of the chain proceeds and git add -A stages the marker-laden files; (2) the merge repair itself then gets committed. Playbook: after ANY conflict resolution, grep -rl ' BEFORE committing; if markers remain, git show ^1: (the branch's pre-merge version) over each affected file, re-commit, then rebuild. Check each pathspec of a multi-path checkout individually when one might not exist.
  • Subagent file writes can silently produce empty files — always verify wc -l on files written by subagents. If a subagent says "file written" but wc -l shows 0, re-dispatch with explicit write verification instructions.
  • GitHub issue commentsgh issue comment takes -b for body, gh issue close takes -c (not interchangeable: gh issue comment -b "text", gh issue close -c "text"). Post a summary comment on each issue after the PR merges, not just after opening it: files created/modified, test counts, follow-ups.
  • PR/branch mechanics--delete-branch fails if the worktree still exists (remove it first); draft PRs can't be merged (gh pr ready first); --admin requires repo-owner privileges (won't work for contributors).
  • Commits land on wrong branch if agent checks out a different branch inside

its worktree — verify with git branch --show-current in agent context. A task worktree hosts ALL of a task's branches at once — the task branch plus every PR branch created during the task (git checkout -b switches the worktree, it does not create a second copy). Commits land on whichever branch is currently checked out, so a commit made while the worktree sits on PR A's branch pollutes PR A even when the work belongs to PR B. Repair a stray commit: git branch -f (only if the remote hasn't got it — a pushed stray needs a force-push or revert instead), then git checkout && git cherry-pick .

  • Subagent commits sometimes aren't committed — verify git status --short after agent completes, commit manually if needed. Iteration caps commonly cut an agent off RIGHT BEFORE committing: the summary usually names the intended commit

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.