madt_branch_create/madt_branch_delete: rename name= → branch= (git-plane operand vocabulary) #58

Closed
opened 2026-07-14 15:49:32 +00:00 by hexajon · 1 comment
hexajon commented 2026-07-14 15:49:32 +00:00 (Migrated from codeberg.org)

The branch-tool family uses two different names for the same concept: madt_branch_create(name=), madt_branch_delete(name=), but madt_finish(branch=) and madt_worktrees(branch=). Coming off a finish/worktree flow, branch= is the natural reach, and it hard-errors:

madt_branch_delete: unknown argument "branch" (valid arguments: dir, name, raw_json)

Ask: accept branch= on madt_branch_create/madt_branch_delete (alias of name=, or make it canonical) so the branch tools share one parameter vocabulary and the obvious first call succeeds.

Hit 2026-07-14 deleting a merged worktree branch immediately after madt_finish(branch=...) - same concept, different required param name.

The branch-tool family uses two different names for the same concept: `madt_branch_create(name=)`, `madt_branch_delete(name=)`, but `madt_finish(branch=)` and `madt_worktrees(branch=)`. Coming off a finish/worktree flow, `branch=` is the natural reach, and it hard-errors: ``` madt_branch_delete: unknown argument "branch" (valid arguments: dir, name, raw_json) ``` Ask: accept `branch=` on `madt_branch_create`/`madt_branch_delete` (alias of `name=`, or make it canonical) so the branch tools share one parameter vocabulary and the obvious first call succeeds. Hit 2026-07-14 deleting a merged worktree branch immediately after `madt_finish(branch=...)` - same concept, different required param name.
hexajon commented 2026-07-14 15:59:27 +00:00 (Migrated from codeberg.org)

Proposed resolution: rename name=branch= (canonical, no alias) on madt_branch_create/madt_branch_delete. ADR 0005's recipe step 1 resolves this — the canonical name should align to the external vocabulary, and here it doesn't.

Upstream vocabulary. No direct CLI precedent exists: gh has no branch-management command, and git/tea take the branch as a positional (git's docs say <branchname>), so no upstream CLI ever names a flag for "which branch". But everywhere upstream must name this parameter, the word is branch:

  • gh's flag vocabulary is uniformly --branch wherever a branch is an argument (gh browse -b/--branch, gh codespace create --branch, gh repo edit --default-branch) — never --name.
  • The Forgejo/Gitea delete endpoint is DELETE /repos/{owner}/{repo}/branches/{branch} — the path param is literally branch. (name is only a field on the branch object; create's body field is new_branch_name.)

The internal split is drawn in the wrong place. name(s) is the ADR 0020 identifier convention for the forge branches resource (madt_branches_remote: name/names/new_name), while branch= is the operand vocabulary of the git-plane flow tools (finish, worktrees, pull, push, plus the branch= context params on files/gitobjects/repos). branch_create/branch_delete are git-plane flow tools — they sit in the same session sequence as finish(branch=) — but inherited the resource-identifier vocabulary. The boundary should run along the git-plane/forge-resource seam, not through the middle of the git plane. After the rename the split is principled: git-plane operations say branch=; forge branch-resource CRUD keys by name(s) (ADR 0020 untouched).

Why not the alternatives:

  • Alias — banned (one canonical name per operation; the sole exception is viewget, ADR 0016 #1874).
  • Description fix only (the usual ADR 0005 move) — doesn't fit: this isn't a schema-scanning miss. The agent knows the field holds the branch name; the miss is vocabulary carryover from the immediately preceding finish(branch=) call, which no description re-read prevents.
  • Did-you-mean — structurally can't catch it: Levenshtein(branch,name) is far past the ceiling of 2, neither token contains the other, and widening the synonym classes is exactly what ADR 0005 forbids.

Change shape:

  1. madt_branch_create: namebranch (alongside existing base=, dir=).
  2. madt_branch_delete: namebranch.
  3. removedArgHints entries for name= on both tools (the bounded-redirect pattern from the all= removals, #1964/#1995) so old callers get an actionable redirect, not a bare rejection.
  4. madt_branches_remote unchanged.
  5. Parameter descriptions per the naming-conventions checklist; regenerate reference docs; note the MCP param rename in the COMPARISON.md branch row.

Caveat to confirm before landing: tea's branch operations taking positionals (i.e. tea never names this as a flag either) is from memory, not verified against a tea checkout.

**Proposed resolution: rename `name=` → `branch=` (canonical, no alias) on `madt_branch_create`/`madt_branch_delete`.** ADR 0005's recipe step 1 resolves this — the canonical name should align to the external vocabulary, and here it doesn't. **Upstream vocabulary.** No direct CLI precedent exists: gh has no branch-management command, and git/tea take the branch as a positional (git's docs say `<branchname>`), so no upstream CLI ever names a flag for "which branch". But everywhere upstream *must* name this parameter, the word is `branch`: - gh's flag vocabulary is uniformly `--branch` wherever a branch is an argument (`gh browse -b/--branch`, `gh codespace create --branch`, `gh repo edit --default-branch`) — never `--name`. - The Forgejo/Gitea delete endpoint is `DELETE /repos/{owner}/{repo}/branches/{branch}` — the path param is literally `branch`. (`name` is only a field on the branch *object*; create's body field is `new_branch_name`.) **The internal split is drawn in the wrong place.** `name(s)` is the ADR 0020 identifier convention for the forge branches *resource* (`madt_branches_remote`: `name`/`names`/`new_name`), while `branch=` is the operand vocabulary of the git-plane flow tools (`finish`, `worktrees`, `pull`, `push`, plus the `branch=` context params on `files`/`gitobjects`/`repos`). `branch_create`/`branch_delete` are git-plane flow tools — they sit in the same session sequence as `finish(branch=)` — but inherited the resource-identifier vocabulary. The boundary should run along the git-plane/forge-resource seam, not through the middle of the git plane. After the rename the split is principled: git-plane operations say `branch=`; forge branch-resource CRUD keys by `name(s)` (ADR 0020 untouched). **Why not the alternatives:** - *Alias* — banned (one canonical name per operation; the sole exception is `view`↔`get`, ADR 0016 #1874). - *Description fix only* (the usual ADR 0005 move) — doesn't fit: this isn't a schema-scanning miss. The agent knows the field holds the branch name; the miss is vocabulary carryover from the immediately preceding `finish(branch=)` call, which no description re-read prevents. - *Did-you-mean* — structurally can't catch it: Levenshtein(`branch`,`name`) is far past the ceiling of 2, neither token contains the other, and widening the synonym classes is exactly what ADR 0005 forbids. **Change shape:** 1. `madt_branch_create`: `name` → `branch` (alongside existing `base=`, `dir=`). 2. `madt_branch_delete`: `name` → `branch`. 3. `removedArgHints` entries for `name=` on both tools (the bounded-redirect pattern from the `all=` removals, #1964/#1995) so old callers get an actionable redirect, not a bare rejection. 4. `madt_branches_remote` unchanged. 5. Parameter descriptions per the naming-conventions checklist; regenerate reference docs; note the MCP param rename in the COMPARISON.md branch row. Caveat to confirm before landing: tea's branch operations taking positionals (i.e. tea never names this as a flag either) is from memory, not verified against a tea checkout.
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#58
No description provided.