Skip to content

feat(tmq): always allocate a worktree for dispatched issues#6

Open
jakecelentano wants to merge 1 commit into
mainfrom
feat/worktree-policy-all-types
Open

feat(tmq): always allocate a worktree for dispatched issues#6
jakecelentano wants to merge 1 commit into
mainfrom
feat/worktree-policy-all-types

Conversation

@jakecelentano

Copy link
Copy Markdown
Contributor

Summary

Prior behavior: only `feature` dispatches got a worktree; `fix` and `chore` went in-place on the main checkout on `main`. The dispatch-loop skill (Step 1) requires every dispatched agent to isolate its work, and the in-place path was slipping into merged-but-uncommitted-on-main PRs (see `tower-fleet#200` for the concrete failure mode: `feat/ui-e2e-convention` branched in `/root/tower-fleet` on `main` instead of a worktree).

This change makes tmq honor the dispatch-loop convention uniformly:

  • All non-review dispatched types (`feature`, `fix`, `chore`) in a worktree-enabled repo get an isolated worktree at `/root/wt--` on a typed branch (`feat/`, `fix/`, or `chore/`).
  • Review dispatches and work in a worktree-disabled repo are unchanged.
  • New `_branch_name(issue_number, title, issue_type)` produces the type-prefixed branch; `_feature_branch_name` stays as a thin shim for callers that imported it before the refactor.

What changed

File Change
`src/tmq/worktree.py` Type-aware branch naming; `create()` routes `fix`/`chore` through the worktree path
`tests/test_worktree.py` Replaced `test_fix_in_worktree_repo_uses_main_checkout` (now wrong) with `test_fix_in_worktree_repo_creates_worktree` + `test_chore_in_worktree_repo_creates_worktree`. Added `test_review_in_worktree_repo_uses_main_checkout` and `test_branch_name_type_prefix`
`src/tmq/init.py` Bumped `version` to `0.2.0`
`aoe-plugin.toml` Bumped plugin `version` to `0.2.0`

Net: +92 / -23. Bump to 0.2.0 — observable behavior change (dispatched agents will start landing in worktrees even for fix/chore types).

Out of scope

  • AGENTS.md / dispatch-loop prompt updates — those live outside this repo (`~/.pi/agent/skills/dispatch-loop/SKILL.md`). The skill already requires isolation; this PR brings tmq in line with it.
  • The 3 shared trees list (`feedback-working-tree-hazard.md`) — those are about human writes on certain repos; this PR is about agent dispatches.
  • Dist-packages sync — `pip install --upgrade bogocat-tmq` will pull 0.2.0 once merged.

Review

@Reviewer / @reviewer-m3 — please verify:

  • `_branch_name` prefix map covers all `issue_type` values tmq emits (`feature`, `fix`, `chore`); `review` bypasses the function entirely via the early `return` in `create()`.
  • The legacy `_feature_branch_name` shim still produces `feat/issue-N-...` for callers that imported the old name.
  • The fall-back-to-main path (when `git worktree add` raises) still surfaces a warning and returns the main checkout, never silently dropping the dispatch.

Test plan

  • `python3 -m pytest tests/` — 58 passed in 0.52s.
  • New tests: `test_fix_in_worktree_repo_creates_worktree`, `test_chore_in_worktree_repo_creates_worktree`, `test_review_in_worktree_repo_uses_main_checkout`, `test_branch_name_type_prefix`.

Verification

  • Manual: `python3 -c 'from tmq.worktree import _branch_name; print(_branch_name(245, "test", "fix"))'` → `fix/issue-245-test`.
  • Manual: a fresh `tmq --type fix` should land in `/root/wt--` on `fix/issue-N-...`, not in `/root/` on `main`.

Follow-ups

  1. Add `bogocat/tmq/AGENTS.md` documenting per-repo gotchas (test command, worktree path conventions). Independent of this PR.
  2. After merge, the live dist-packages copy at `/usr/local/lib/python3.13/dist-packages/tmq/worktree.py` is stale until `pip install --upgrade bogocat-tmq` runs. Worth a reminder to dispatch operators after the merge.

Closes: the in-place-on-main gap from the dispatch-loop skill's Step 1.
References: `bogocat/tower-fleet#202`, `bogocat/tower-fleet#200`, dispatch-loop skill Step 1.

Prior behavior: only `feature` dispatches got a worktree; `fix` and
`chore` went in-place on the main checkout on `main`. The dispatch-loop
skill (Step 1) requires every dispatched agent to isolate its work, and
the in-place path was slipping into merged-but-uncommitted-on-main PRs
(see tower-fleet#200 for the concrete failure mode: `feat/ui-e2e-convention`
branched in /root/tower-fleet on main instead of a worktree).

This change makes tmq honor the dispatch-loop convention uniformly:

- All non-review dispatched types (`feature`, `fix`, `chore`) in a
  worktree-enabled repo get an isolated worktree at /root/wt-<short>-<num>
  on a typed branch (`feat/`, `fix/`, or `chore/`).
- Review dispatches and work in a worktree-disabled repo are unchanged
  (review edits live on the PR's branch; non-worktree repos opt out).
- New `_branch_name(issue_number, title, issue_type)` produces the
  type-prefixed branch; `_feature_branch_name` stays as a thin shim
  for callers that imported it before the refactor.

Bumps to 0.2.0 — this is an observable behavior change (dispatched
agents will start landing in worktrees even for fix/chore types).

Tests: `test_fix_in_worktree_repo_creates_worktree` and
`test_chore_in_worktree_repo_creates_worktree` cover the new paths;
`test_review_in_worktree_repo_uses_main_checkout` locks the unchanged
review behavior. Full suite: 58 passing.
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