Skip to content

fix(slots): slot-model consistency — switch reclaim/brick fixes, doctor slot repair, slots.json as source of truth (3.1.2)#32

Merged
ashmitb95 merged 4 commits into
mainfrom
fix/slot-model-consistency
Jul 4, 2026
Merged

fix(slots): slot-model consistency — switch reclaim/brick fixes, doctor slot repair, slots.json as source of truth (3.1.2)#32
ashmitb95 merged 4 commits into
mainfrom
fix/slot-model-consistency

Conversation

@ashmitb95

Copy link
Copy Markdown
Owner

What

Four commits of slot-model (Wave 3.0) consistency fixes found dogfooding in canopy-test, shipped as 3.1.2.

switch (5aa6fcc)

  • Cold-Y fall-through reclaims the vacated slot. When Y has a slots.json entry but this repo's slot dir is missing, X now reclaims Y's about-to-be-freed slot instead of allocating a fresh one. Previously the vacating slot counted against the cap → bogus no_free_slot (the canopy-test billing-export lock-out).
  • Pre-mutation failures no longer brick the workspace. Precondition BlockerErrors raised before any git mutation (no_free_slot, unknown_slot, evict_to_occupied, warm_worktree_dirty_on_promote) no longer stamp in_flight when nothing was touched — a clean no-op failure used to make every later switch fail with slot_state_inconsistent.

doctor (6653d33)

  • New slot_repo_worktree_missing check + auto-repair (git worktree prune + worktree add) for half-materialized slots — a slot holding feature F where one repo's worktree is gone. Advice-only when the branch itself is missing (branches_missing owns that).
  • The pre-3.0 worktree_orphan check skips worktree-N slot dirs — doctor --fix no longer deletes warm slots.

slots.json as source of truth (42b932c)

  • worktree_bootstrap resolves paths via slots.json (legacy features.json cache is empty in 3.0 — bootstrap raised no_worktrees for every warm feature). Pre-3.0 fallback kept.
  • canopy init / workspace_reinit report worktrees by occupant feature via new summarize_worktree_dirs, not slot ids as feature names.
  • coordinator.status() / feature_changes honor the per-repo branches map (lane.branch_for) instead of assuming branch == feature name.

release (67bb724)

  • __version__ → 3.1.2, CHANGELOG entry.

Tests

868 passed (284 lines of new tests across switch/doctor/bootstrap/coordinator/discovery).

ashmitb95 added 4 commits July 4, 2026 08:06
… on pre-mutation failures

When promoting a feature that holds a slot whose per-repo worktree dir is
missing, switch fell through to cold-Y allocation and counted the feature's
own about-to-be-freed slot against the cap — raising a bogus no_free_slot.
It now reclaims the vacated slot for the outgoing canonical.

Separately, a pre-mutation precondition failure (no_free_slot, dirty warm
worktree, bad --evict-to) on the first repo stamped an in_flight marker even
though nothing was flipped, permanently locking out switching via
slot_state_inconsistent. Pre-mutation failures with no completed repos no
longer persist in_flight.
…x deleting warm slots

Add a slot_repo_worktree_missing check + repair. A slot can hold a feature
whose worktree dir is gone for one repo while sibling repos survive —
invisible to slot_entry_orphan (inspects only the worktree-N/ top dir) and
slot_branch_mismatch (skips non-existent per-repo paths). The repair
recreates the worktree from the feature's branch (advice-only if the branch
itself is gone). Adds git.worktree_prune to clear stale registrations first.

Also fix check_worktree_orphan, which treated Wave-3.0 slot dirs
(worktree-N/<repo>) as pre-3.0 feature-named orphans — so `doctor --fix`
would git-worktree-remove every warm slot. It now skips worktree-N dirs,
which are owned by the slot_* checks.
…of truth

The Wave-3.0 slot migration left code assuming dir-name == feature and
branch == feature-name:

- init/reinit reported slot ids (worktree-N) as if they were feature names.
  Add summarize_worktree_dirs to resolve slot->feature via slots.json, and
  use it in `canopy init` and workspace_reinit.
- bootstrap read the legacy features.json worktree_paths (empty in 3.0), so
  worktree_bootstrap raised no_worktrees for every warm feature. Resolve via
  slots.json, with a pre-3.0 features.json fallback.
- coordinator.status() dropped the per-repo branches map when building the
  lane, and _enrich_lane/feature_changes/_find_stale_worktrees used the
  feature name as the branch. Carry the branches map and honor
  branch_for(repo) throughout.
@ashmitb95 ashmitb95 merged commit a898d26 into main Jul 4, 2026
3 checks passed
@ashmitb95 ashmitb95 deleted the fix/slot-model-consistency branch July 4, 2026 02:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant