Skip to content

fix(decision-records): assign counters in argument order - #10

Merged
trungfinity merged 1 commit into
mainfrom
fix/decision-records-promote-argument-order
Aug 10, 2026
Merged

trungfinity merged 1 commit into
mainfrom
fix/decision-records-promote-argument-order

Conversation

@trungfinity

Copy link
Copy Markdown
Contributor

promote A B assigned counters in sorted order, not the order given. Observed in a real promotion: promote OPER DASH produced DASH=0041 and OPER=0042, because DASH sorts first. There was no way to choose which co-promoted record got which counter.

That matters whenever one record of a set is the foundation the others name — the record they build on should read as the earlier decision, and only the caller knows which one that is. It is not cosmetic once the set is merged: the counter is the permanent identity, so getting it backwards is only fixable by hand-renumbering records that are already referenced.

The fix

promote now keeps a deduped list in argument order and numbers from it. The seed set stays a set for reference classification, so the blocking-set closure, --deref, --allow-replace and the co-promoted counter↔counter rewrites are all untouched. _do_deref takes the ordered list and derives its own set.

The refusal messages each printed a suggested command built with sorted(). Under the new behaviour that would silently pick the counters for you, so each now prints the drafts in the order given:

  • the blocking-set suggestion prints the requested drafts first, in the caller's order, then whatever the closure pulled in — still a complete, valid promotion, and re-running it verbatim keeps the counters the caller asked for
  • the blocking listing is ordered to match the command it prints, and says the counters follow that order
  • --deref and --allow-replace re-run suggestions preserve the caller's order, so adding the flag does not change the numbering

Tests

Three added. Co-promotion in a deliberately reverse-alphabetical order (ZZZZ before AAAA) lands the counters on the arguments; the same pair reversed proves the order is read rather than incidental; and the blocking refusal's printed command is extracted from the error text and executed, asserting both that it is a valid promotion and that the requested draft keeps the first counter.

Two of the three fail against the previous implementation, which I checked before writing the fix. Suite: 100 pass (82 existing + 3 new here, plus the repo's own 15).

references/promotion.md, the module usage block and the --help text now state that co-promoted counters follow argument order.

`promote A B` built its seed set as a set and numbered it with
sorted(), so the counters followed the alphabet rather than the
caller. `promote OPER DASH` gave DASH the lower counter, and there
was no way to choose which co-promoted record got which number.

That matters whenever one record of a set is the foundation the
others name: the record they build on should read as the earlier
decision, and only the caller knows which one that is.

promote now keeps a deduped list in argument order and assigns
from it. The seed set stays a set for reference classification,
so the blocking-set closure, --deref and --allow-replace are
untouched.

The refusal messages printed sorted commands, which under the new
behaviour would silently pick the counters for you. Each now
prints the requested drafts in the order given -- the blocking
suggestion appends whatever the closure pulled in, so it stays a
valid promotion that keeps the caller's counters -- and the
blocking listing is ordered to match the command it prints.
@trungfinity
trungfinity merged commit 02465de into main Aug 10, 2026
10 checks passed
@trungfinity
trungfinity deleted the fix/decision-records-promote-argument-order branch August 10, 2026 13:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant