Observed 2026-08-09 during a 25-worker fan-out over one project pool (25 spawns, two batches ~10min apart).
Failure 1 - preserved work recycled. A captain-held task's worktree (endpoint deliberately dead, work preserved by explicit order, task held in backlog) was handed to a new spawn because the lease reads owner_pid liveness. The reuse moved the checkout off the task's branch and wiped untracked state (venv/caches; any uncommitted edits would have been lost - committed state survived, verified via reflog + fsck). fm-teardown carefully refuses to discard unlanded work, but pool recycling bypasses that gate entirely.
Failure 2 - double-booked slots. The second spawn batch was handed slots 1-9 while the first batch's workers were still live inside them: task metas ended up with 9 pairs sharing a worktree, and treehouse-state showed those slots' created_at refreshed during the second batch. Suspected cause: the recorded owner pid is a spawn-time process that exits, not the long-lived agent, so every lease looks stale within minutes.
Suggested direction: pid liveness is not a sufficient free-slot test. A slot referenced by any not-torn-down task's state/.meta worktree= should never be considered free; fm-teardown (which already owns the landed-work test) should be the only release path, with pid liveness at most a hint for crash cleanup behind that check.
Observed 2026-08-09 during a 25-worker fan-out over one project pool (25 spawns, two batches ~10min apart).
Failure 1 - preserved work recycled. A captain-held task's worktree (endpoint deliberately dead, work preserved by explicit order, task held in backlog) was handed to a new spawn because the lease reads owner_pid liveness. The reuse moved the checkout off the task's branch and wiped untracked state (venv/caches; any uncommitted edits would have been lost - committed state survived, verified via reflog + fsck). fm-teardown carefully refuses to discard unlanded work, but pool recycling bypasses that gate entirely.
Failure 2 - double-booked slots. The second spawn batch was handed slots 1-9 while the first batch's workers were still live inside them: task metas ended up with 9 pairs sharing a worktree, and treehouse-state showed those slots' created_at refreshed during the second batch. Suspected cause: the recorded owner pid is a spawn-time process that exits, not the long-lived agent, so every lease looks stale within minutes.
Suggested direction: pid liveness is not a sufficient free-slot test. A slot referenced by any not-torn-down task's state/.meta worktree= should never be considered free; fm-teardown (which already owns the landed-work test) should be the only release path, with pid liveness at most a hint for crash cleanup behind that check.