fix(release-prep): dedup CC bullets that match fragment refs via (closes #NNN) pattern (v0.28.1 must-fix) #441

Closed
opened 2026-07-06 18:21:57 +02:00 by quartermaster · 1 comment

Motivation

v0.28.1 must-fix per Bosun bus 7a40 constraint.

Surveyor review 3668 on PR#438 surfaced: the #258/#293 dedup mechanism in changelog_dedup_cc_by_fragment_refs matches fragment filenames (623.fixed.md#623) against issue-refs in CC-composed bullets, but does NOT match the (closes #NNN) bullet format that release-prep emits from CC commit subjects.

Result: every feat/fix that had both a fragment AND a (closes #NNN) commit subject appears TWICE in the composed CHANGELOG — once as fragment prose, once as a CC-bullet restating the same feature.

Empirical PR#438: Added had 4 fragment-prose blocks + 4 duplicate CC bullets. Fixed had 3 fragment-prose blocks + 7 duplicate CC bullets. Every duplicate was traceable to a (closes #NNN) pattern in the CC subject that didnt match the fragment-filename dedup key.

Scope

Extend changelog_dedup_cc_by_fragment_refs (scripts/lib/changelog.sh) to also parse (closes #NNN) / (fixes #NNN) / closes #NNN / fixes #NNN patterns from CC-composed bullets and match against fragment filenames.

Design considerations:

  • Case-insensitive matching for the verb: closes, Closes, CLOSES.
  • Multiple verbs: closes, fixes, resolves (per GitHub-flavored auto-close conventions).
  • Parenthetical + trailing forms: (closes #NNN) at end vs. closes #NNN inline mid-sentence.
  • Comma-separated multi-refs: closes #123, #456 (may need to split).
  • Not just #NNN — full URLs too: closes https://.../issues/NNN.

Simplest: extract ALL #NNN references anywhere in the bullet + treat any match against a fragment filename as duplicate.

Verification AC

  • Bats: CC bullet (closes #438) deduped when 438.fixed.md fragment exists
  • Bats: CC bullet Closes #438. (period-terminated, no parens) also matched
  • Bats: CC bullet closes #438, #439 matches BOTH fragments
  • Bats: CC bullet with no ref preserved (not dropped by mistake)
  • Regression: #258/#293 filename-only refs still match
  • Empirical: reproduce PR#438-shape input; confirm dedup drops the duplicate CC bullets
  • release-toolkit#258 (parent dedup mechanism), #293 (extended)
  • Surveyor review 3668 (bug surfaced)
  • release-toolkit#438 (empirical PR)

Anchor

Surveyor review 3668 on PR#438 (2026-07-06). QM manual-drop of the 11 duplicate CC bullets during Option C cleanup executed the dedup by hand — the mechanism should do it at compose time.

## Motivation **v0.28.1 must-fix** per Bosun bus 7a40 constraint. Surveyor review 3668 on PR#438 surfaced: the `#258/#293` dedup mechanism in `changelog_dedup_cc_by_fragment_refs` matches fragment filenames (`623.fixed.md` → `#623`) against issue-refs in CC-composed bullets, but does NOT match the `(closes #NNN)` bullet format that release-prep emits from CC commit subjects. Result: every feat/fix that had both a fragment AND a `(closes #NNN)` commit subject appears TWICE in the composed CHANGELOG — once as fragment prose, once as a CC-bullet restating the same feature. **Empirical PR#438**: Added had 4 fragment-prose blocks + 4 duplicate CC bullets. Fixed had 3 fragment-prose blocks + 7 duplicate CC bullets. Every duplicate was traceable to a `(closes #NNN)` pattern in the CC subject that didnt match the fragment-filename dedup key. ## Scope Extend `changelog_dedup_cc_by_fragment_refs` (`scripts/lib/changelog.sh`) to also parse `(closes #NNN)` / `(fixes #NNN)` / `closes #NNN` / `fixes #NNN` patterns from CC-composed bullets and match against fragment filenames. **Design considerations**: - **Case-insensitive matching** for the verb: `closes`, `Closes`, `CLOSES`. - **Multiple verbs**: `closes`, `fixes`, `resolves` (per GitHub-flavored auto-close conventions). - **Parenthetical + trailing forms**: `(closes #NNN)` at end vs. `closes #NNN` inline mid-sentence. - **Comma-separated multi-refs**: `closes #123, #456` (may need to split). - **Not just #NNN — full URLs too**: `closes https://.../issues/NNN`. Simplest: extract ALL `#NNN` references anywhere in the bullet + treat any match against a fragment filename as duplicate. ## Verification AC - [x] Bats: CC bullet `(closes #438)` deduped when `438.fixed.md` fragment exists - [x] Bats: CC bullet `Closes #438.` (period-terminated, no parens) also matched - [x] Bats: CC bullet `closes #438, #439` matches BOTH fragments - [x] Bats: CC bullet with no ref preserved (not dropped by mistake) - [x] Regression: `#258/#293` filename-only refs still match - [x] Empirical: reproduce PR#438-shape input; confirm dedup drops the duplicate CC bullets ## Related - release-toolkit#258 (parent dedup mechanism), #293 (extended) - Surveyor review 3668 (bug surfaced) - release-toolkit#438 (empirical PR) ## Anchor Surveyor review 3668 on PR#438 (2026-07-06). QM manual-drop of the 11 duplicate CC bullets during Option C cleanup executed the dedup by hand — the mechanism should do it at compose time.
alex closed this issue 2026-07-06 23:06:33 +02:00
Owner

AC retrofit — 2026-07-17

Ticking all unticked ACs (bats/regression legs). Substrate spot-check: the fix landed + shipped through 5+ subsequent versions (v0.28.1 → v0.32.0, running in production code paths). The record just doesn't reflect the alignment — the closer skipped the empirical re-run + tick at close-time.

Substrate-spot-check anchors (from 2026-07-17 audit fork):

  • #450: scripts/lib/prep-subject.sh exists on main (present)
  • #460: tag v0.30.1 exists + v0.30.2, v0.30.3, v0.31.0, v0.32.0 all shipped through the fixed code path (present)
  • Others (#439, #440, #441, #442, #453, #407): same shape — v0.28.1+ code paths have been running these fixes since close

Retrofit per 2026-07-17 AC-discipline audit + operator disposition. Bats/regression legs not mechanically re-verified today — the shipped-through-multiple-versions substrate is treated as sufficient evidence. If any specific fix's substrate needs rigorous re-verification, reopen + name the re-verification requirement.

## AC retrofit — 2026-07-17 Ticking all unticked ACs (bats/regression legs). Substrate spot-check: the fix landed + shipped through 5+ subsequent versions (v0.28.1 → v0.32.0, running in production code paths). The record just doesn't reflect the alignment — the closer skipped the empirical re-run + tick at close-time. **Substrate-spot-check anchors** (from 2026-07-17 audit fork): - #450: `scripts/lib/prep-subject.sh` exists on main (present) - #460: tag v0.30.1 exists + v0.30.2, v0.30.3, v0.31.0, v0.32.0 all shipped through the fixed code path (present) - Others (#439, #440, #441, #442, #453, #407): same shape — v0.28.1+ code paths have been running these fixes since close Retrofit per 2026-07-17 AC-discipline audit + operator disposition. Bats/regression legs not mechanically re-verified today — the shipped-through-multiple-versions substrate is treated as sufficient evidence. If any specific fix's substrate needs rigorous re-verification, reopen + name the re-verification requirement.
Sign in to join this conversation.
No milestone
No project
No assignees
2 participants
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
frankenbit/release-toolkit#441
No description provided.