fix(kanban): decomposed siblings stop sharing one worktree checkout - #70177
Merged
Conversation
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>
Contributor
૮ >ﻌ< ა ci reviewran on a69107b all good! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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_taskno longer inherit the root's literalworkspace_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_pathverbatim, and_resolve_worktree_workspace's existing-checkout shortcut reused that directory on whatever branch was checked out. Concurrently dispatched siblings (max_in_progressunbounded by default) ended up in one directory on the first sibling's branch: cross-task commits on the wrongwt/<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_createhalf landed in #70143.Changes
hermes_cli/kanban_db.py::decompose_triage_task: worktree children leaveworkspace_pathunset so dispatch materializes<repo>/.worktrees/<child-id>per child;dir/scratchinheritance 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
workspace_path=NULL→ own worktree at dispatchwt/<id>branch each<repo>/.worktrees/<task-id>scripts/run_tests.shworktree-isolation + decompose + kanban tools/project-link suites — 148 passedInfographic