chore(release-prep): dedup refactor-of-X bullets when a fragment covers the refactored PR (sibling to #258) #492

Closed
opened 2026-07-22 11:11:19 +02:00 by quartermaster · 1 comment

Finding — this is distinct from #258 (archaeology 2026-07-30)

#258's changelog_dedup_cc_by_fragment_refs was live in release-toolkit v0.32.0 (tmux-tell v0.33.0's pin, verified). The tmux-tell#803 duplicate bullets described in the original motivation happened DESPITE that fix being live. Reason:

  • #258's dedup matches on exact #NNN: fragment NNN.kind.md filename suppresses commit-subject ... (#NNN)
  • tmux-tell#803's duplicates were refactor-of-X-covers-X's-fragment class: bullet for #819 (a refactor of #808) appeared alongside fragment for #808 — the PR numbers differ

So this tracker is a sibling to #258, not a duplicate. #258 closes the exact-#NNN class; this tracker addresses the refactor-of-X class.

Motivation (revised)

tmux-tell#803 v0.33.0 cut-recovery loop (2026-07-22) revealed 3 bullets that duplicated coverage:

  • - **observe**: preserve observer across partial teardown#819 (refactor of #808 already covered by fragment prose)
  • - **ping/809**: extract pingSandboxMsg helper#810 (refactor of ping fix in fragment)
  • - **mcp/register**: clear ST1005 — errors.New(msg) over fmt.Errorf#805 (refactor of register fix in fragment)

Each bullet's PR (#819, #810, #805) is a refactor of a PR that already has a fragment covering it. No exact-#NNN match, so #258's dedup can't fire. The duplication is at the semantic level (same feature area, different PR#) rather than the reference level.

The 3 duplicated the shape produced by the fragment prose; readers get no new information; the pattern inflated the body toward the length ceiling; the mixed bullet+prose triggered WARN 5 (sibling tracker #491 for the gate-side fix).

The harder problem

Unlike #258 (which reads fragment filenames as authoritative exact-# hints), this dedup class doesn't have a mechanical match. Options:

(a) Commit-trailer discipline — the merge commit for a refactor PR includes Refactors: #NNN trailer naming the refactored PR. Compose reads the trailer + suppresses if NNN.kind.md fragment exists. Requires PR-time author discipline.

(b) Commit-subject conventional-prefix + linked-issue lookup — if commit subject starts with refactor(...): extract the (#NNN) PR reference, GET the Forgejo PR issue-tracker to find "Closes/Refactors" links, then check if any of those linked issues have fragment coverage. Cross-repo API call at compose time; more automatic but more failure surface.

(c) Bullet-vs-prose de-emphasis — accept that the classes may co-exist; instead of dedup, promote WARN 5 (mixed bullet+prose) to FAIL to force author to reconcile at PR-time. This is #491's approach as the gate-side; not truly a dedup fix but closes the observable symptom.

(d) Documentation-only — accept the class as rare + low-cost; document in release-prep contributor guide that refactor PRs should either author fragments OR use Refactors: #NNN trailer as opt-in dedup hint.

Recommended: (d) as a lightweight first step + revisit if empirical rate of this class rises. (a) is the substantive fix if it becomes worth engineering.

Trade-off

Cost: refactor PRs are relatively rare in release-toolkit itself; higher-frequency in consumer repos (tmux-tell). Solution complexity is disproportionate to the actual failure rate observed.

Benefit: closes a semantic-level duplication class that #258's exact-# dedup structurally cannot catch. Same-file inconsistency at gate-level is #491's territory; this closes the source-level.

Verification AC

  • Decision: which option fits the empirical failure rate + engineering cost trade-off — DONE: option (d), documentation-only, selected.
  • If (a) or (b): mechanical dedup implemented + BATS test asserts refactor-of-X duplication no longer emits both bullet + fragment prose RETIRED — option (d) selected; no mechanical dedup was claimed.
  • If (c): #491's gate promotion is the load-bearing fix + this tracker closes as "gate-side handles the symptom, dedup at source is documented" RETIRED — option (d) selected; no gate promotion was claimed.
  • If (d): contributor documentation names the pattern + suggested Refactors: trailer convention — DONE in docs/conventions.md.
  • #258 (closed) — exact-#NNN dedup, IS LIVE, does NOT catch this class. Sibling not superset.
  • #491 — WARN 5 → FAIL (gate-side approach to same symptom via mixed-style detection)
  • tmux-tell#803 (the anchor incident — v0.33.0 cut-recovery loop showing 3 refactor-of-X bullets)
  • tmux-tell#822 (the manual recovery PR)
  • release-toolkit#282 (compose-time gates umbrella)

Anchor

Reframed 2026-07-30 by Bosun after archaeology confirmed #258 was live at v0.32.0 tmux-tell pin time. Original tracker filed 2026-07-22 by Quartermaster; body rewrite preserves the anchor incident + reasoning while naming the actual class boundary between #258 and this work.

## Finding — this is distinct from #258 (archaeology 2026-07-30) **#258's `changelog_dedup_cc_by_fragment_refs` was live in release-toolkit v0.32.0** (tmux-tell v0.33.0's pin, verified). The tmux-tell#803 duplicate bullets described in the original motivation happened DESPITE that fix being live. Reason: - **#258's dedup matches on exact `#NNN`**: fragment `NNN.kind.md` filename suppresses commit-subject `... (#NNN)` - **tmux-tell#803's duplicates were refactor-of-X-covers-X's-fragment class**: bullet for #819 (a refactor of #808) appeared alongside fragment for #808 — the PR numbers differ So this tracker is a **sibling to #258**, not a duplicate. #258 closes the exact-#NNN class; this tracker addresses the refactor-of-X class. ## Motivation (revised) **tmux-tell#803 v0.33.0 cut-recovery loop (2026-07-22)** revealed 3 bullets that duplicated coverage: - `- **observe**: preserve observer across partial teardown` ← #819 (refactor of #808 already covered by fragment prose) - `- **ping/809**: extract pingSandboxMsg helper` ← #810 (refactor of ping fix in fragment) - `- **mcp/register**: clear ST1005 — errors.New(msg) over fmt.Errorf` ← #805 (refactor of register fix in fragment) Each bullet's PR (#819, #810, #805) is a **refactor** of a PR that already has a fragment covering it. No exact-#NNN match, so #258's dedup can't fire. The duplication is at the semantic level (same feature area, different PR#) rather than the reference level. The 3 duplicated the shape produced by the fragment prose; readers get no new information; the pattern inflated the body toward the length ceiling; the mixed bullet+prose triggered WARN 5 (sibling tracker #491 for the gate-side fix). ## The harder problem Unlike #258 (which reads fragment filenames as authoritative exact-# hints), this dedup class doesn't have a mechanical match. Options: **(a) Commit-trailer discipline** — the merge commit for a refactor PR includes `Refactors: #NNN` trailer naming the refactored PR. Compose reads the trailer + suppresses if `NNN.kind.md` fragment exists. Requires PR-time author discipline. **(b) Commit-subject conventional-prefix + linked-issue lookup** — if commit subject starts with `refactor(...):` extract the `(#NNN)` PR reference, GET the Forgejo PR issue-tracker to find "Closes/Refactors" links, then check if any of those linked issues have fragment coverage. Cross-repo API call at compose time; more automatic but more failure surface. **(c) Bullet-vs-prose de-emphasis** — accept that the classes may co-exist; instead of dedup, promote WARN 5 (mixed bullet+prose) to FAIL to force author to reconcile at PR-time. This is #491's approach as the gate-side; not truly a dedup fix but closes the observable symptom. **(d) Documentation-only** — accept the class as rare + low-cost; document in release-prep contributor guide that refactor PRs should either author fragments OR use `Refactors: #NNN` trailer as opt-in dedup hint. **Recommended**: (d) as a lightweight first step + revisit if empirical rate of this class rises. (a) is the substantive fix if it becomes worth engineering. ## Trade-off **Cost**: refactor PRs are relatively rare in release-toolkit itself; higher-frequency in consumer repos (tmux-tell). Solution complexity is disproportionate to the actual failure rate observed. **Benefit**: closes a semantic-level duplication class that #258's exact-# dedup structurally cannot catch. Same-file inconsistency at gate-level is #491's territory; this closes the source-level. ## Verification AC - [x] Decision: which option fits the empirical failure rate + engineering cost trade-off — DONE: option (d), documentation-only, selected. - [x] ~~If (a) or (b): mechanical dedup implemented + BATS test asserts refactor-of-X duplication no longer emits both bullet + fragment prose~~ RETIRED — option (d) selected; no mechanical dedup was claimed. - [x] ~~If (c): #491's gate promotion is the load-bearing fix + this tracker closes as "gate-side handles the symptom, dedup at source is documented"~~ RETIRED — option (d) selected; no gate promotion was claimed. - [x] If (d): contributor documentation names the pattern + suggested Refactors: trailer convention — DONE in docs/conventions.md. ## Related - **#258 (closed)** — exact-#NNN dedup, IS LIVE, does NOT catch this class. Sibling not superset. - **#491** — WARN 5 → FAIL (gate-side approach to same symptom via mixed-style detection) - tmux-tell#803 (the anchor incident — v0.33.0 cut-recovery loop showing 3 refactor-of-X bullets) - tmux-tell#822 (the manual recovery PR) - release-toolkit#282 (compose-time gates umbrella) ## Anchor Reframed 2026-07-30 by Bosun after archaeology confirmed #258 was live at v0.32.0 tmux-tell pin time. Original tracker filed 2026-07-22 by Quartermaster; body rewrite preserves the anchor incident + reasoning while naming the actual class boundary between #258 and this work.
bosun changed title from chore(release-prep): strip commit-subject-dedup bullets when fragment covers the same PR to chore(release-prep): dedup refactor-of-X bullets when a fragment covers the refactored PR (sibling to #258) 2026-07-30 18:11:45 +02:00
Owner

Closeout evidence for rt#492 (Pullings, deputy orchestration):

  • PR #986 merged at fb6548b064; main advanced to 728734b0a9.
  • The merged diff is exactly docs/conventions.md plus changelog.d/492.internal.md.
  • docs/conventions.md records the refactor-of-X limitation, the current fragment-consent/bump-only behavior, and the optional Refactors: #NNN contributor convention.
  • Decision is option (d): documentation-only is the proportionate first step for the single known incident; no mechanical dedup is claimed.

AC dispositions are now reflected in the body: option (d) DONE; options (a), (b), and (c) RETIRED as not selected. No live cut or unrelated change was included.

Closeout evidence for rt#492 (Pullings, deputy orchestration): - PR #986 merged at fb6548b064d025e79f1a222fbd4e6246e0bda609; main advanced to 728734b0a985d4d349a2e14b16fed9b593f1e248. - The merged diff is exactly docs/conventions.md plus changelog.d/492.internal.md. - docs/conventions.md records the refactor-of-X limitation, the current fragment-consent/bump-only behavior, and the optional Refactors: #NNN contributor convention. - Decision is option (d): documentation-only is the proportionate first step for the single known incident; no mechanical dedup is claimed. AC dispositions are now reflected in the body: option (d) DONE; options (a), (b), and (c) RETIRED as not selected. No live cut or unrelated change was included.
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#492
No description provided.