Skip to content

backfill registers pre-existing worktrees with an empty port map — no collision protection against the allocator #83

Description

@ikeikeikeike

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)

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions