ux(steering): hard-steer raw git worktree to the madtea worktree surface (madt_worktrees / madtea worktree) #69

Closed
opened 2026-07-14 21:46:17 +00:00 by hexajon · 0 comments
hexajon commented 2026-07-14 21:46:17 +00:00 (Migrated from codeberg.org)

Raw git worktree in agent sessions should be blocked and pointed at madtea's worktree commands, the same way the existing git-steering hooks redirect other git operations to the madt_* surface. Rationale: madtea's worktree surface is deliberately more careful with destructive ops than raw git —

  • remove is non-force by default: git's refusal on a dirty/locked worktree is surfaced, never overridden; force=true is an explicit, documented opt-in. Raw git worktree remove --force silently discards uncommitted work.
  • On a forced remove that can't delete foreign-owned files, madtea returns a bounded manual-cleanup instruction — it never escalates privileges and never runs a recursive filesystem delete.
  • prune is the only sanctioned stale-metadata escape; rebase (action=rebase / madtea worktree rebase) replaces the raw cd <wt> && git rebase loop; status batches the pre-finish commit-clean check.

Evidence (dogfood, 2026-07-14)

An agent session doing parallel-worktree work used raw git worktree add (×7) and raw git worktree remove + git branch -d for teardown, despite madt_worktrees add/remove/status being loaded and available — nothing steered it. The guarded surface only gets used when the unguarded one is closed.

Ask

A PreToolUse steering hook (plugin hooks/hooks.json + hooks/scripts/) that denies Bash invocations of git worktree <subcommand> and points at the equivalent:

  • MCP sessions → madt_worktrees action=add|list|status|remove|rebase|prune
  • terminal humans → madtea worktree <subcommand>

Design notes:

  • Destructive subcommands (remove, prune) are the priority; add/list steer too for surface consistency (list is read-only — denying it is about habit-forming, call that out in the refusal so it doesn't read as a safety claim).
  • Subcommands with no madtea equivalent (move, lock/unlock, repair) need an explicit decision: pass through, or refuse with guidance. Don't leave them falling through with a misleading message.
  • Refusal text carries the rule, not tracker references (write it internal/danglingref-clean; #15's terminal-or-forwarding refusal UX applies when it lands).
  • Hook tests in the existing hook-tests suite: each steered subcommand form, the no-equivalent forms, and non-worktree git commands staying untouched.

Acceptance

  • git worktree remove/prune/add (and agreed others) via Bash are denied with a refusal naming the exact madtea replacement for that subcommand.
  • No-equivalent subcommands behave per the explicit decision above, with an accurate message.
  • Hook tests cover steered, exempt, and no-equivalent cases; gate green.
Raw `git worktree` in agent sessions should be blocked and pointed at madtea's worktree commands, the same way the existing git-steering hooks redirect other git operations to the `madt_*` surface. Rationale: madtea's worktree surface is deliberately more careful with destructive ops than raw git — - `remove` is **non-force by default**: git's refusal on a dirty/locked worktree is surfaced, never overridden; `force=true` is an explicit, documented opt-in. Raw `git worktree remove --force` silently discards uncommitted work. - On a forced remove that can't delete foreign-owned files, madtea returns a bounded manual-cleanup instruction — it never escalates privileges and never runs a recursive filesystem delete. - `prune` is the only sanctioned stale-metadata escape; `rebase` (action=rebase / `madtea worktree rebase`) replaces the raw `cd <wt> && git rebase` loop; `status` batches the pre-finish commit-clean check. ## Evidence (dogfood, 2026-07-14) An agent session doing parallel-worktree work used raw `git worktree add` (×7) and raw `git worktree remove` + `git branch -d` for teardown, despite `madt_worktrees` add/remove/status being loaded and available — nothing steered it. The guarded surface only gets used when the unguarded one is closed. ## Ask A PreToolUse steering hook (plugin `hooks/hooks.json` + `hooks/scripts/`) that denies Bash invocations of `git worktree <subcommand>` and points at the equivalent: - MCP sessions → `madt_worktrees action=add|list|status|remove|rebase|prune` - terminal humans → `madtea worktree <subcommand>` Design notes: - Destructive subcommands (`remove`, `prune`) are the priority; `add`/`list` steer too for surface consistency (list is read-only — denying it is about habit-forming, call that out in the refusal so it doesn't read as a safety claim). - Subcommands with **no madtea equivalent** (`move`, `lock`/`unlock`, `repair`) need an explicit decision: pass through, or refuse with guidance. Don't leave them falling through with a misleading message. - Refusal text carries the rule, not tracker references (write it `internal/danglingref`-clean; #15's terminal-or-forwarding refusal UX applies when it lands). - Hook tests in the existing hook-tests suite: each steered subcommand form, the no-equivalent forms, and non-worktree `git` commands staying untouched. ## Acceptance - `git worktree remove`/`prune`/`add` (and agreed others) via Bash are denied with a refusal naming the exact madtea replacement for that subcommand. - No-equivalent subcommands behave per the explicit decision above, with an accurate message. - Hook tests cover steered, exempt, and no-equivalent cases; gate green.
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#69
No description provided.