feat(worktrees): conflict-bearing operations run in an ephemeral linked worktree, never the primary checkout — revert/reconcile stop wedging the user's tree #20

Closed
opened 2026-07-11 21:41:15 +00:00 by hexajon · 0 comments
hexajon commented 2026-07-11 21:41:15 +00:00 (Migrated from codeberg.org)

Problem (2026-07-10, companion to #19/#18/#14)

Operations that can conflict currently execute in the caller's PRIMARY checkout and, on conflict, leave it mid-operation:

  • madt_prs action=revert on a recent PR ran git revert in the primary checkout (freshly on main): on the modify/delete conflict it returned "resolve and commit manually", leaving the checkout on an auto-created revert branch in revert-in-progress state. Resolution then happened via raw rm of a tracked file + a --continue form (the #19 gap) — in the primary tree.
  • madt_orchestrate reconcile= (when reachable, #18) likewise checks out and merges in the caller's checkout.
  • The hand-rolled equivalents (agent runs git merge origin/main on a PR branch) have the same shape: conflicted state parked in the shared checkout.

If the session dies mid-operation the primary checkout is wedged (MERGE_HEAD/REVERT_HEAD, unmerged index) — the next session or the human inherits it. The clobber surface is the one tree everybody shares, when the house pattern (ADR 0019 for foreign repos; .worktrees/ for parallel agents) already says: mutation-risky work belongs in a disposable linked worktree.

Ask

  1. madtea-initiated conflict-capable ops run in an ephemeral linked worktree (e.g. .worktrees/madtea-revert-<pr> or an OS-temp worktree): madt_prs action=revert, orchestrate reconcile (once #18 fixes its schema), and orchestrate's bisect/revert stages. Clean path: operate in the worktree, push/PR from there, remove the worktree; the primary checkout never changes branch and never enters an in-progress state. Conflict path: the error rail names the WORKTREE path and the sanctioned resolution tools (madt_add dir= + madt_commit dir= per #19's capability), and madt_worktrees action=remove force=true as the clean abandon — abandoning a conflicted attempt becomes discarding a disposable directory, not un-wedging the shared tree.
  2. Hook-side steer for the hand-rolled case: when raw git merge <ref>/git revert targets a primary checkout, the (advisory, per ADR 0021 — merge is a read-adjacent local op with legitimate uses) steer suggests the worktree flow for conflict-risky merges instead of the in-place one.
  3. Ephemeral worktree placement honors scratch conventions: inside the repo's .worktrees/ (gitignored) or the OS temp dir — never a second permanent checkout.

Acceptance

  • A conflicted madt_prs action=revert leaves the primary checkout untouched (same branch, clean tree, no in-progress state) with the conflict parked in a named worktree; hermetic test.
  • Clean revert/reconcile round-trips (worktree created → commit → push → PR → worktree removed) leave no residue.
  • Error rails for the conflict case name the worktree path + madt_* resolution/abandon steps only (no raw-git forms; #15 rail rules, ADR 0023 text rules).
## Problem (2026-07-10, companion to #19/#18/#14) Operations that can conflict currently execute in the caller's PRIMARY checkout and, on conflict, leave it mid-operation: - `madt_prs action=revert` on a recent PR ran `git revert` in the primary checkout (freshly on main): on the modify/delete conflict it returned "resolve and commit manually", leaving the checkout on an auto-created revert branch in revert-in-progress state. Resolution then happened via raw `rm` of a tracked file + a `--continue` form (the #19 gap) — in the primary tree. - `madt_orchestrate reconcile=` (when reachable, #18) likewise checks out and merges in the caller's checkout. - The hand-rolled equivalents (agent runs `git merge origin/main` on a PR branch) have the same shape: conflicted state parked in the shared checkout. If the session dies mid-operation the primary checkout is wedged (MERGE_HEAD/REVERT_HEAD, unmerged index) — the next session or the human inherits it. The clobber surface is the one tree everybody shares, when the house pattern (ADR 0019 for foreign repos; `.worktrees/` for parallel agents) already says: mutation-risky work belongs in a disposable linked worktree. ## Ask 1. **madtea-initiated conflict-capable ops run in an ephemeral linked worktree** (e.g. `.worktrees/madtea-revert-<pr>` or an OS-temp worktree): `madt_prs action=revert`, orchestrate reconcile (once #18 fixes its schema), and orchestrate's bisect/revert stages. Clean path: operate in the worktree, push/PR from there, remove the worktree; the primary checkout never changes branch and never enters an in-progress state. Conflict path: the error rail names the WORKTREE path and the sanctioned resolution tools (`madt_add dir=` + `madt_commit dir=` per #19's capability), and `madt_worktrees action=remove force=true` as the clean abandon — abandoning a conflicted attempt becomes discarding a disposable directory, not un-wedging the shared tree. 2. **Hook-side steer for the hand-rolled case:** when raw `git merge <ref>`/`git revert` targets a primary checkout, the (advisory, per ADR 0021 — merge is a read-adjacent local op with legitimate uses) steer suggests the worktree flow for conflict-risky merges instead of the in-place one. 3. **Ephemeral worktree placement** honors scratch conventions: inside the repo's `.worktrees/` (gitignored) or the OS temp dir — never a second permanent checkout. ## Acceptance - A conflicted `madt_prs action=revert` leaves the primary checkout untouched (same branch, clean tree, no in-progress state) with the conflict parked in a named worktree; hermetic test. - Clean revert/reconcile round-trips (worktree created → commit → push → PR → worktree removed) leave no residue. - Error rails for the conflict case name the worktree path + madt_* resolution/abandon steps only (no raw-git forms; #15 rail rules, ADR 0023 text rules).
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#20
No description provided.