Skip to content

fix(kanban): decomposed siblings stop sharing one worktree checkout - #70177

Merged
teknium1 merged 1 commit into
mainfrom
salv-61907
Jul 23, 2026
Merged

fix(kanban): decomposed siblings stop sharing one worktree checkout#70177
teknium1 merged 1 commit into
mainfrom
salv-61907

Conversation

@teknium1

Copy link
Copy Markdown
Contributor

fix(kanban): decomposed siblings stop sharing one worktree checkout

Summary

Decompose fan-outs restore the one-worktree-per-task guarantee — worktree-kind children created by decompose_triage_task no longer inherit the root's literal workspace_path, and a checkout already occupied by a different task's branch triggers a fresh-worktree fallback at resolution instead of silent reuse.

Root cause: decompose children copied the root's workspace_path verbatim, and _resolve_worktree_workspace's existing-checkout shortcut reused that directory on whatever branch was checked out. Concurrently dispatched siblings (max_in_progress unbounded by default) ended up in one directory on the first sibling's branch: cross-task commits on the wrong wt/<id> branch, one shared index, no lock.

Salvage of #61907 by @ahmadashfq (cherry-picked, authorship preserved), rebased onto current main. Fixes #61911, and closes the decompose half of the workspace-sharing cluster (#53983): the kanban_create half landed in #70143.

Changes

  • hermes_cli/kanban_db.py::decompose_triage_task: worktree children leave workspace_path unset so dispatch materializes <repo>/.worktrees/<child-id> per child; dir/scratch inheritance unchanged.
  • hermes_cli/kanban_db.py::_resolve_worktree_workspace: an existing checkout on a different branch falls back to a fresh <repo>/.worktrees/<task-id> (heals rows already carrying a shared inherited path); same-branch reuse untouched; degenerate cases (no repo anchor, or the occupied path is the task's own canonical worktree) keep legacy reuse rather than failing dispatch.
  • tests/hermes_cli/test_kanban_worktree_isolation.py: 5 cases — fan-out isolation, explicit override, healing, same-branch reuse, anchor-less fallback.

Validation

Before After
Decompose with worktree root all children point at root's checkout each child workspace_path=NULL → own worktree at dispatch
Concurrent siblings one dir, first sibling's branch own dir + own wt/<id> branch each
Legacy row with shared path reused on wrong branch healed to fresh <repo>/.worktrees/<task-id>
Same-branch / explicit path reuse works unchanged
  • scripts/run_tests.sh worktree-isolation + decompose + kanban tools/project-link suites — 148 passed
  • Live E2E (real git repo, real worktrees): 2-sibling fan-out resolved to 2 distinct worktrees on 2 distinct branches; a legacy row pointing at the root's checkout healed to its own path

Infographic

infographic

Decompose children inherit the root's literal workspace_path (#37172),
so every sibling of a worktree-kind root points at the SAME checkout.
_resolve_worktree_workspace's existing-checkout shortcut then reuses
that directory on whatever branch is currently checked out, ignoring
the task's own branch_name. Net effect: sibling workers — which can be
promoted and dispatched concurrently — run in one directory on the
first sibling's branch, with no lock. Work lands on the wrong task's
branch (provenance corruption) and concurrent siblings trample each
other's index/tree.

Fix, two layers:
- decompose_triage_task: worktree-kind children no longer inherit the
  root's literal path; each child materializes its own
  <repo>/.worktrees/<child-id> at dispatch (dir/scratch inheritance
  unchanged — children legitimately share those).
- _resolve_worktree_workspace: when the requested path is an existing
  checkout of a DIFFERENT branch, fall back to a fresh
  <repo>/.worktrees/<task-id> instead of silently reusing it (heals
  rows that already carry a shared path). Same-branch reuse and the
  no-repo/own-path degenerate cases keep the legacy behaviour.

Tests: tests/hermes_cli/test_kanban_worktree_isolation.py (5); full
test_kanban_db.py + test_kanban_decompose_db.py suites pass unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

૮ >ﻌ< ა ci review

ran on a69107b

all good!

@alt-glitch alt-glitch added type/bug Something isn't working P3 Low — cosmetic, nice to have comp/cron Cron scheduler and job management labels Jul 23, 2026
@teknium1
teknium1 merged commit 65d42e3 into main Jul 23, 2026
73 of 76 checks passed
@teknium1
teknium1 deleted the salv-61907 branch July 23, 2026 16:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/cron Cron scheduler and job management P3 Low — cosmetic, nice to have type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

kanban: decompose siblings share one worktree checkout and run on each other's branches

3 participants