Skip to content

fix(kanban): give each subtask its own worktree instead of inheriting parent path (#53983) - #54006

Closed
liuhao1024 wants to merge 3 commits into
NousResearch:mainfrom
liuhao1024:liuhao/cron-bugfix-53983-kanban-worktree-subtask
Closed

fix(kanban): give each subtask its own worktree instead of inheriting parent path (#53983)#54006
liuhao1024 wants to merge 3 commits into
NousResearch:mainfrom
liuhao1024:liuhao/cron-bugfix-53983-kanban-worktree-subtask

Conversation

@liuhao1024

Copy link
Copy Markdown
Contributor

What does this PR do?

Fixes concurrent subtask worktree collision in kanban's worktree workspace mode. When a parent task uses workspace_kind=worktree and spawns multiple child tasks, all children inherited the parent's workspace_path (its own .worktrees/{parent_task_id} directory) instead of getting their own. This caused file conflicts and git errors when concurrent workers operated in the same directory.

Related Issue

Fixes #53983

Type of Change

  • 🐛 Bug fix (non-breaking change that fixes an issue)

Changes Made

  • tools/kanban_tools.py: Skip workspace_path inheritance when workspace_kind == "worktree". Each subtask now gets its own worktree derived from the project repo by create_task. Dir and scratch workspace inheritance remain unchanged.
  • tests/tools/test_kanban_tools.py: Added test_create_worktree_subtask_gets_own_path — verifies a child task inheriting a worktree workspace gets a different path than the parent.

How to Test

  1. python -m pytest tests/tools/test_kanban_tools.py -x -q — all 91 tests should pass
  2. The new test test_create_worktree_subtask_gets_own_path directly verifies the fix: a child task inheriting workspace_kind=worktree from its parent must have a workspace_path that differs from the parent's.

Checklist

Code

  • I've read the Contributing Guide
  • My commit messages follow Conventional Commits (fix(scope):, feat(scope):, etc.)
  • I searched for existing PRs to make sure this isn't a duplicate
  • My PR contains only changes related to this fix/feature (no unrelated commits)
  • I've run pytest tests/ -q and all tests pass
  • I've added tests for my changes (required for bug fixes, strongly encouraged for features)
  • I've tested on my platform: macOS 26.4.1

Documentation & Housekeeping

  • I've updated relevant documentation (README, docs/, docstrings) — or N/A
  • I've updated cli-config.yaml.example if I added/changed config keys — or N/A
  • I've updated CONTRIBUTING.md or AGENTS.md if I changed architecture or workflows — or N/A
  • I've considered cross-platform impact (Windows, macOS) per the compatibility guide — or N/A
  • I've updated tool descriptions/schemas if I changed tool behavior — or N/A

Screenshots / Logs

The root cause is in tools/kanban_tools.py lines 820-826 (workspace inheritance). Before this fix, line 826 unconditionally copied the parent's workspace_path to the child. After the fix, worktree workspaces skip path inheritance so create_task in kanban_db.py derives a fresh .worktrees/{child-task-id} path.

… parent path

When a worker scoped to a worktree task spawns child tasks without an
explicit workspace arg, the children inherited the parent's workspace_path
(the parent's own .worktrees/<id> directory). All subtasks ended up
sharing one directory, causing file conflicts and git errors when
concurrent workers tried to operate in the same worktree.

Skip path inheritance for worktree workspaces so create_task derives a
fresh .worktrees/<child-id> path from the project repo for each subtask.
Dir and scratch inheritance remain unchanged.
@alt-glitch alt-glitch added type/bug Something isn't working comp/cron Cron scheduler and job management P3 Low — cosmetic, nice to have labels Jun 28, 2026

@tonydwb tonydwb left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review Summary

Verdict: Comment — Clean fix

Small, focused fix that prevents kanban subtasks from inheriting the parent's worktree path. Each subtask now gets its own worktree directory to avoid concurrent worker collisions.

Changes:

  • tools/kanban_tools.py: Adds a guard so worktree workspace types don't inherit workspace_path from the parent task. The child gets a fresh <repo>/.worktrees/<task-id> path via create_task.
  • tests/tools/test_kanban_tools.py: New test verifying that worktree subtasks get their own path, not the parent's.

Assessment:

  • Well-scoped: 2 files, 36 additions
  • Test coverage for the specific scenario
  • Comment explains the rationale clearly
  • No security concerns

Reviewed by Hermes Agent

@tonydwb tonydwb left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review Summary

Verdict: Approved

Inlines local send attachments as data URIs for Signal RPC calls. When signal-cli runs in a separate container without shared filesystem access, raw file paths are not dereferenceable. The fix converts local file paths to data:mime;base64,... URIs at the RPC boundary, preserving already-inlined, remote, or missing attachments. Clean implementation with good test coverage for conversion, no-op cases, and RPC integration.


Reviewed by Hermes Agent

@teknium1 teknium1 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks for the focused collision fix. The current-head premise is real: tools/kanban_tools.py:905-913 copies the running worktree task's persisted concrete path, and hermes_cli/kanban_db.py:5709-5711 reuses an existing linked checkout.

Problems

  • The proposed guard drops the repository anchor for unlinked worktree tasks. If the parent has no project_id and the board has no default_workdir, the child has no path; dispatch then raises at hermes_cli/kanban_db.py:5672-5699. Derive the parent repository root as the child anchor instead of dropping it.
  • The added test (tests/tools/test_kanban_tools.py:807-826) uses a fake non-repository path and only checks inequality, so it accepts a null child path without proving a dispatchable distinct worktree.

Suggested changes

  • Cover a real temporary git repository through dispatch and assert separate child/parent linked worktree paths and branches under the same repository.

Automated hermes-sweeper review.

Comment thread tools/kanban_tools.py
# 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
Contributor

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.

@teknium1 teknium1 added sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform labels Jul 15, 2026
@teknium1

Copy link
Copy Markdown
Contributor

Closing as superseded by #70143 (merged, SHA 781968b). Your PR was the earliest in this cluster to flag the workspace-inheritance bug (June 28) — thank you. The merged change removed the implicit literal-path inheritance in _handle_create entirely, so the worktree case you fixed (each subtask getting its own worktree instead of the parent's) is covered, along with the scratch and dir cases. The worktree-sibling half that lives in the decompose path (#53983 / #61911) is being addressed separately via a salvage of #61907.

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 sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Kanban worktree mode is not working for multiple tasks

4 participants