Renamed identifier args reject the old name instead of aliasing it (e.g. branch-delete name -> branch) #423

Open
opened 2026-08-17 15:51:19 +00:00 by hexajon · 2 comments
Owner

Several madt_* tools renamed their identifier argument without keeping the old name as an alias, so a call using the previous name fails and has to be redone.

Example: madt_branch_delete renamed name to branch. A call with name=<branch> returns:

unknown argument "name" (valid arguments: branch, dir, raw_json). name= was renamed to branch=

and has to be repeated with branch=.

It is self-correcting, since the error states the fix, but it costs a wasted round-trip whenever a caller reuses or guesses the old argument name, and it recurs across the renamed identifier args as they drift.

Request: for a renamed identifier argument, accept the previous name as a deprecated alias (map it to the new one, optionally warn), or converge on one consistent identifier name across the tools, so a reasonable first call does not hard-fail.

Several `madt_*` tools renamed their identifier argument without keeping the old name as an alias, so a call using the previous name fails and has to be redone. Example: `madt_branch_delete` renamed `name` to `branch`. A call with `name=<branch>` returns: ``` unknown argument "name" (valid arguments: branch, dir, raw_json). name= was renamed to branch= ``` and has to be repeated with `branch=`. It is self-correcting, since the error states the fix, but it costs a wasted round-trip whenever a caller reuses or guesses the old argument name, and it recurs across the renamed identifier args as they drift. Request: for a renamed identifier argument, accept the previous name as a deprecated alias (map it to the new one, optionally warn), or converge on one consistent identifier name across the tools, so a reasonable first call does not hard-fail.
Author
Owner

This runs straight into the naming rule (ADR 0016 and docs/contributing/naming-conventions.md): one canonical name per operation, no aliases except view and get, enforced by the parity test. A permanent deprecated alias cuts against that rule.

Open question I need to settle: converge, or alias. My lean is to converge on ONE identifier name across the renamed tools, so a reasonable first call does not hard-fail, rather than add lasting aliases that the parity test then has to tolerate forever. The tradeoff is that convergence renames more args now, and every rename is another one-round-trip failure for callers who learned the old name.

The softer path stays possible: accept the old name with a deprecation warning. That needs a parity-test carve-out and a removal date, which is a cost the converge option does not carry.

This runs straight into the naming rule (ADR 0016 and `docs/contributing/naming-conventions.md`): one canonical name per operation, no aliases except `view` and `get`, enforced by the parity test. A permanent deprecated alias cuts against that rule. Open question I need to settle: converge, or alias. My lean is to converge on ONE identifier name across the renamed tools, so a reasonable first call does not hard-fail, rather than add lasting aliases that the parity test then has to tolerate forever. The tradeoff is that convergence renames more args now, and every rename is another one-round-trip failure for callers who learned the old name. The softer path stays possible: accept the old name with a deprecation warning. That needs a parity-test carve-out and a removal date, which is a cost the converge option does not carry.
hexajon self-assigned this 2026-08-17 17:45:48 +00:00
Author
Owner

Answered by ADR 0016. The policy is one canonical name per operation on both surfaces, no aliases, with the single view<->get carve-out; adding a synonym needs an ADR 0016 amendment (docs/adr/0016-gh-tea-vocabulary-parity.md:29-33, :150-169). So a renamed identifier arg converges on the new name; it does not alias the old one.

The current behavior already implements this correctly: it does not silently drop the old name, it rejects with a teaching redirect (removedArgHints maps e.g. name= to "name= was renamed to branch=" for madt_branch_create/madt_branch_delete, internal/mcp/arg_suggest.go:65-81, emitted at :200-213). That is the migration UX without a permanent alias.

The only open lever is executional and lands via #441: which canonical name each rename converges on. If a time-boxed deprecation alias is ever wanted for a specific rename, that is an ADR 0016 amendment (a parity-test exception plus a removal date), not the default. Absent that, converge stands. Clearing needs-decision.

Answered by ADR 0016. The policy is one canonical name per operation on both surfaces, no aliases, with the single `view`<->`get` carve-out; adding a synonym needs an ADR 0016 amendment (`docs/adr/0016-gh-tea-vocabulary-parity.md:29-33`, `:150-169`). So a renamed identifier arg converges on the new name; it does not alias the old one. The current behavior already implements this correctly: it does not silently drop the old name, it rejects with a teaching redirect (`removedArgHints` maps e.g. `name=` to "name= was renamed to branch=" for `madt_branch_create`/`madt_branch_delete`, `internal/mcp/arg_suggest.go:65-81`, emitted at `:200-213`). That is the migration UX without a permanent alias. The only open lever is executional and lands via #441: which canonical name each rename converges on. If a time-boxed deprecation alias is ever wanted for a specific rename, that is an ADR 0016 amendment (a parity-test exception plus a removal date), not the default. Absent that, converge stands. Clearing needs-decision.
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#423
No description provided.