Parallel worktrees
Run several tasks at once without ever letting an agent touch your working copy.
The isolation model#
Every /spawn creates:
- a git worktree at
.khaelor/worktrees/<taskId>on branchkhaelor/<taskId>; - a child session — its own JSONL log, with
meta.parentpointing at the orchestrator session; - a full agent engine over that worktree with attenuated capabilities: permissions are non-interactive (every ask resolves to deny), scoped to the worktree — capability attenuation, a real security argument, not a convention.
tasks
● fix-auth-bug ◑ design $0.42 ⠹ edit…
✓ add-rate-limit done +118 −24 · verify ✓
✗ flaky-retry failed verify ✗ — see child sessionLifecycle#
| Step | What happens |
|---|---|
/spawn | Worktree + branch + child session created; a durable subtask.created event lands in the orchestrator log. |
| run | The child works with phase gates and the verify loop active — designs and checks happen inside the isolation too. |
| finish | Changes are committed onto the subtask branch; subtask.completed records the outcome, REAL git diff stats, and the verify verdict. |
/merge | Supervised git merge --no-ff of the branch into your current branch. Conflicts abort cleanly, leaving the tree untouched. |
Conflict resolution#
When two subtask branches collide, the merge aborts and reports. The recommended move: ask
KHAELOR to resolve, giving it both designs — they are in the logs — as context. The orchestrator
can even /spawn a dedicated resolution subtask.
The same mechanics power /replay#
/replay reuses the worktree machinery as a sandbox: the re-executed tool calls run
in a throwaway copy that is removed afterwards, branch and all. See
Fork · replay · sdiff.
Hygiene#
- Worktrees live under
.khaelor/worktrees/— add it to.gitignoreif you have not. - Merged branches are deleted; failed ones are kept for inspection.
- The daemon's goal runs use the same mechanism (
khaelor/goal-<runId>branches).
Previous← Verification
NextThe daemon →