Summary
Worktree cleanup is the step where an agent tooling system deletes the git worktree and branch it created for a worker. When that step runs unconditionally — at exit, on a write-failure path, or on an age-based sweeper — it becomes a data-destruction sink: uncommitted or uncommitted-but-unhandoffable work is discarded silently. The Claude Code 2.1.303–2.1.304 delta fixes several instances of this class, and mapping them onto yoyo's spawn code shows the same defect shapes present there. The safe rule: never force-remove a worktree whose work was not durably committed — keep it and tell the user where it is.
Key Points
- No unasked removal at exit.
claude --worktreepreviously removed the worktree and its branch without asking when HEAD was detached or on another branch — a case where commits could be lost. Now it does not. - Age is not liveness. A cleanup sweeper that keys off directory mtime will happily delete a worktree that a long-running background worker is still using, because editing nested files does not touch the root directory's mtime.
- Failed handoff must not trigger cleanup. If the commit that preserves a worker's changes fails (pre-commit hook, GPG signing, missing identity), the worktree must survive; removing it
--forcedestroys the uncommitted diff behind only a warning. - Human-only approval is a distinct decision tier.
decider: "person"on a mod'stool.checkallows only a human to approve, and refuses with the mod's own reason in contexts where no human can be asked — the same shape as a fence that prompts at a tty and refuses without one. - Reason preservation across composed hooks. A PreToolUse hook's deny reason must not be replaced by a timeout error just because a different hook timed out.
- Turn budgets must bind subagents. A plugin spawning subagents can no longer keep a headless run alive past
--max-turns, Stop, or ended input. - Bounded hook fan-out. Skill hooks are capped at 1,024 per source per session.