worktrees: rebase resolves dir=/path= differently than add/remove - sanctioned worktrees get falsely refused as foreign #174

Closed
opened 2026-07-16 23:19:35 +00:00 by hexajon · 0 comments
hexajon commented 2026-07-16 23:19:35 +00:00 (Migrated from codeberg.org)

Hit live today. A worktree created seconds earlier via the sanctioned flow:

madt_worktrees action=add    dir=/path/to/repo path=.worktrees/task branch=feat/task   -> ok
madt_worktrees action=rebase dir=/path/to/repo path=.worktrees/task onto=origin/main   -> REFUSED

The refusal claimed dir/path resolves to the PRIMARY checkout ("a worktree of a FOREIGN repository that does NOT match the caller-created convention") - i.e. rebase resolved the target from dir alone, apparently ignoring path=, and the foreign guard then correctly rejected what it wrongly thought was the target. The same dir=primary + path=relative addressing works for add and remove. The successful workaround was pointing dir= at the worktree itself and omitting path=:

madt_worktrees action=rebase dir=/path/to/repo/.worktrees/task onto=origin/main   -> ok

One tool should have one addressing scheme: rebase should join dir+path exactly the way add/remove do. An agent that just used add/remove with this shape will reflexively reuse it, hit the false "not caller-created" refusal, and burn a retry.

Acceptance:

  • action=rebase dir=<primary> path=<relative worktree> targets the worktree, same as add/remove
  • a sanctioned .worktrees/<task> checkout this session created is never refused as not-caller-created due to path resolution
  • a test covers the dir+path shape for every worktree action, so addressing can't drift per-action again
Hit live today. A worktree created seconds earlier via the sanctioned flow: ``` madt_worktrees action=add dir=/path/to/repo path=.worktrees/task branch=feat/task -> ok madt_worktrees action=rebase dir=/path/to/repo path=.worktrees/task onto=origin/main -> REFUSED ``` The refusal claimed dir/path resolves to the PRIMARY checkout ("a worktree of a FOREIGN repository that does NOT match the caller-created convention") - i.e. rebase resolved the target from `dir` alone, apparently ignoring `path=`, and the foreign guard then correctly rejected what it wrongly thought was the target. The same `dir=primary + path=relative` addressing works for `add` and `remove`. The successful workaround was pointing `dir=` at the worktree itself and omitting `path=`: ``` madt_worktrees action=rebase dir=/path/to/repo/.worktrees/task onto=origin/main -> ok ``` One tool should have one addressing scheme: `rebase` should join `dir`+`path` exactly the way `add`/`remove` do. An agent that just used add/remove with this shape will reflexively reuse it, hit the false "not caller-created" refusal, and burn a retry. Acceptance: - [ ] `action=rebase dir=<primary> path=<relative worktree>` targets the worktree, same as add/remove - [ ] a sanctioned `.worktrees/<task>` checkout this session created is never refused as not-caller-created due to path resolution - [ ] a test covers the dir+path shape for every worktree action, so addressing can't drift per-action again
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
sixfold-space/madtea#174
No description provided.