Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions tests/tools/test_kanban_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -798,6 +798,36 @@ def test_create_inherits_worker_dir_workspace(monkeypatch, worker_env):
conn.close()


def test_create_worktree_subtask_gets_own_path(monkeypatch, worker_env):
"""A worker scoped to a worktree task that spawns a child should give
the child its own workspace_path, not the parent's worktree dir."""
from tools import kanban_tools as kt
from hermes_cli import kanban_db as kb

parent_wt = "/tmp/fake-worktree"
conn = kb.connect()
try:
self_tid = kb.create_task(
conn, title="wt worker", assignee="test-worker",
workspace_kind="worktree", workspace_path=parent_wt,
)
kb.claim_task(conn, self_tid)
finally:
conn.close()
monkeypatch.setenv("HERMES_KANBAN_TASK", self_tid)

d = json.loads(kt._handle_create({"title": "wt child", "assignee": "peer"}))
assert d["ok"] is True
conn = kb.connect()
try:
child = kb.get_task(conn, d["task_id"])
assert child.workspace_kind == "worktree"
# The child must NOT inherit the parent's worktree path.
assert child.workspace_path != parent_wt
finally:
conn.close()


def test_create_explicit_workspace_beats_inheritance(monkeypatch, worker_env):
"""An explicit workspace arg overrides worker-task inheritance."""
from tools import kanban_tools as kt
Expand Down
8 changes: 7 additions & 1 deletion tools/kanban_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -823,7 +823,13 @@ def _handle_create(args: dict, **kw) -> str:
_self_task = kb.get_task(conn, _self_tid)
if _self_task is not None and _self_task.workspace_kind:
workspace_kind = _self_task.workspace_kind
workspace_path = _self_task.workspace_path
# For worktree workspaces, don't inherit the parent's
# path — each subtask needs its own worktree so
# concurrent workers don't collide on the same
# directory. create_task will derive a fresh
# <repo>/.worktrees/<task-id> from the project repo.
if workspace_kind != "worktree":
workspace_path = _self_task.workspace_path

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For an unlinked parent worktree, skipping inheritance leaves the child without a repository anchor. create_task can only derive a fresh path from a resolved project or board default; otherwise dispatch fails. Please derive and pass the parent repository root as the child anchor rather than dropping the path.

# Keep follow-up children inside the same project so the
# whole subtree shares one repo + branch convention.
if project_id is None and _self_task.project_id:
Expand Down
Loading