Surfaced by the wave-2 retrospective /code-review sweep of PR #1 (initial implementation, unchanged since).
runBackfill (internal/cli/backfill.go) registers every unregistered .worktrees/<name> dir with reg[name] = map[string]int{} — an empty port map. The doc comment is explicit that this is intentional scope: "backfill alone is the 'stop allocator from re-issuing this name's slot' pass" and doesn't restart or re-probe the engine.
The gap: an empty port map means the registry has no <kind>.main key for that worktree at all, so internal/registry's TakenByKind (which the allocator's collision-avoidance depends on) can't see the real port a backfilled worktree's engine is already bound to. A worktree migrated from a hand-rolled pre-bough hook (exactly this repo's own documented backfill use case for 16 flat-layout worktrees, per CLAUDE.md) may be bound to a port the deterministic crc32 allocator later happens to compute for a brand-new worktree name — bough would hand out an already-occupied port with no OS-level check anywhere in the allocation path.
This is a real, not theoretical, gap given this repo's own migration plan backfills 16 pre-existing worktrees. It isn't a "bug" in the sense of contradicting backfill's stated contract (registration-only, no restart) — it's a scope question: should backfill also attempt to discover each worktree's real bound port (e.g. by probing .local/<kind>-data presence + lsof-based port discovery), or should port-collision protection for backfilled worktrees be a documented, accepted limitation?
Needs a design decision before a fix, since "reliably discover the real port of an engine bough didn't start" is nontrivial and risks being wrong in a way worse than the current known gap (false confidence from a mis-detected port).
Files
internal/cli/backfill.go (runBackfill)
internal/registry/registry.go (TakenByKind)
Surfaced by the wave-2 retrospective
/code-reviewsweep of PR #1 (initial implementation, unchanged since).runBackfill(internal/cli/backfill.go) registers every unregistered.worktrees/<name>dir withreg[name] = map[string]int{}— an empty port map. The doc comment is explicit that this is intentional scope: "backfill alone is the 'stop allocator from re-issuing this name's slot' pass" and doesn't restart or re-probe the engine.The gap: an empty port map means the registry has no
<kind>.mainkey for that worktree at all, sointernal/registry'sTakenByKind(which the allocator's collision-avoidance depends on) can't see the real port a backfilled worktree's engine is already bound to. A worktree migrated from a hand-rolled pre-bough hook (exactly this repo's own documented backfill use case for 16 flat-layout worktrees, perCLAUDE.md) may be bound to a port the deterministic crc32 allocator later happens to compute for a brand-new worktree name — bough would hand out an already-occupied port with no OS-level check anywhere in the allocation path.This is a real, not theoretical, gap given this repo's own migration plan backfills 16 pre-existing worktrees. It isn't a "bug" in the sense of contradicting backfill's stated contract (registration-only, no restart) — it's a scope question: should backfill also attempt to discover each worktree's real bound port (e.g. by probing
.local/<kind>-datapresence +lsof-based port discovery), or should port-collision protection for backfilled worktrees be a documented, accepted limitation?Needs a design decision before a fix, since "reliably discover the real port of an engine bough didn't start" is nontrivial and risks being wrong in a way worse than the current known gap (false confidence from a mis-detected port).
Files
internal/cli/backfill.go(runBackfill)internal/registry/registry.go(TakenByKind)