-
Notifications
You must be signed in to change notification settings - Fork 1
Description
Problem
Running multiple agents simultaneously causes conflicts across several shared resources. There's no isolation between concurrent runs, so two agents targeting the same repo (or even different repos) can corrupt each other's state.
Shared mutable state risks
| Resource | Location | Risk |
|---|---|---|
| task.json files | tasks/active/ |
Two agents writing the same .task.json simultaneously → last write wins, data loss |
.case/active marker |
Target repo root | Multiple agents in the same repo overwrite each other's active task marker |
| Task state transitions | task-status.sh |
Read-then-write with no atomic CAS — race between checking current status and writing new status |
| Task ID generation | Counts existing .md files |
Two agents creating tasks simultaneously get the same sequential ID |
| Git branches | Target repos | Two agents calling git checkout -b on the same repo can collide |
Hardcoded paths
/Users/nicknisi/Developer/case is hardcoded in ~100+ locations across:
skills/case/SKILL.md(~50 references)skills/from-ideation/SKILL.md(~20 references)agents/*.md(implementer, verifier, closer, retrospective)scripts/mark-*.sh(CASE_REPOvariable)AGENTS.mddocs/playbooks/implement-from-spec.mddocs/ideation/specs
The TypeScript orchestrator (src/) already resolves paths dynamically via CASE_ROOT, but the SKILL.md and agent prompt files are stale and still reference the hardcoded path. Anyone running from a different location (or in a worktree) will hit broken paths.
Proposal
Make agent runs worktree-isolated by default so multiple bots can operate concurrently without interference.
1. Git worktree per agent run
Each agent run should create a temporary git worktree for the target repo. This gives each agent an isolated working directory with its own branch, index, and working tree — no branch collisions, no uncommitted changes bleeding between runs.
2. Dynamic path resolution everywhere
Replace all hardcoded /Users/nicknisi/Developer/case references with dynamic resolution:
- SKILL.md / agent prompts: use a
$CASE_ROOTplaceholder or resolve at render time - Shell scripts: derive
CASE_REPOfrom$CASE_ROOTor$(dirname "$0")/..instead of hardcoding - The orchestrator code already does this — the docs just need to catch up
3. Per-run task isolation
- Use run-scoped directories or file locks to prevent concurrent writes to the same
.task.json - Atomic task ID generation (lock file or DB-backed counter instead of counting
.mdfiles) - Scoped
.case/markers per worktree rather than per repo root
4. Consolidate .case/ marker approach
The recent refactor (3aa5f23) consolidated .case-* markers into .case/<task-slug>/. Extend this so each worktree gets its own marker scope, preventing cross-agent marker conflicts.
Context
The ideation docs already reference worktree support as future work:
docs/ideation/orchestrator-refinement/spec-phase-2.mdmentions--worktreeflagsdocs/ideation/case-multi-agent/contract.mdreferences agent isolation
This issue is about actually delivering on that — making worktree isolation the default rather than an opt-in flag.