bug(release-prep): 3 of 14 v0.36.0 bullets are duplicates — the CC dedup misses fragment EDITS and multi-commit PRs #672
Labels
No labels
bump
major
bump
minor
bump
patch
kind/bug
kind/chore
kind/docs
kind/feature
priority/critical
priority/high
priority/low
priority/medium
size/L
size/M
size/S
size/XL
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
frankenbit/release-toolkit#672
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Filed at @bosun's request from the #639 pre-cut read, so the class does not evaporate with the cut. Cosmetic — no functional impact, and I recommended shipping v0.36.0 over it.
What the v0.36.0 section actually contains
14 bullets from two sources, and 3 of them document a change that is already covered:
🔑 The harvesting is DELIBERATE and correctly polarised — this is not "the dedup is broken"
_cc_fragment_adding_shasuses--diff-filter=A, and the comment names the exclusion by name: "a MODIFY to an existing fragment is not an 'add' and does not qualify." The stated rationale is the important part:That is the right polarity. The dedup errs toward leaving a bullet in rather than dropping real content — a visible duplicate is caught by a reader, a silent omission is not. The residual is visible duplicates, and that residual is what this tracker is about.
All 5 harvested bullets, mapped to cause
changelog.d/7993b154652.fixed.mdmodified--diff-filter=Ad81c7cf6632-density-….fixed.mdmodified2936ef13f602b0f584998656So 3 of 5 are duplicates of fragment-covered content; 2 are the safety net doing its job.
Shape A — fragment EDIT (2 instances)
--diff-filter=Asees an edit as "no fragment added", so the edit commit's subject is harvested. At least one instance is literally a density-gate recovery commit:7993b154 fix(changelog): split 37-word density failure in 652 fragment.⚠️ That is a loop. The density gate refuses a fragment → the documented fix is to edit that fragment → the edit commit adds no new fragment → its subject ships as an adopter-facing bullet about changelog maintenance. Same shape as
#663's headline (the documented recovery path creates the condition that defeats the gate), one layer over — in the artifact rather than the cut.Shape B — multi-commit PR (1 instance, mine)
#666was a 2-commit arc.7a68dc7badded the fragment and was correctly suppressed;2936ef13was the review-fix and carried no fragment of its own — correctly, since the fragment already described the change. Its subject leaked.The ref pass could not catch it either:
changelog_dedup_cc_by_fragment_refskeys on(#NNN)in the subject, and my subject carried the ref only in the body (Refs #663). So the same change appears twice, in two voices:📌 My own contribution to this: nothing told me a subject-level
(#NNN)was load-bearing for dedup. That is a convention worth documenting whichever fix lands.🔴 The tempting one-character fix is WRONG — pinning it before someone writes it
--diff-filter=AMinverts the deliberate safety polarity above. A commit that edits an unrelated fragment would then have its own genuine bullet suppressed — a silent omission, which is exactly the failure the current design refuses to risk. Do not take that fix.Safer directions, none chosen:
(#NNN)/Refs #NNN. Catches Shape B without touching Shape A's polarity.fix(changelog):whose diff touches onlychangelog.d/. Targets the worst-reading instance directly.(#NNN)convention so authors opt into dedup deliberately.Acceptance criteria
Which of Shapes A/B (or neither) is worth fixing is decided and recorded, with the— RETIRED: superseded by--diff-filter=AMpolarity trap named so it is not re-proposed#917—renderCommitsreturnsnil, nil, so the conventional-commit harvest no longer runs and there is nothing to deduplicate;dedupByFragmentRefsretained and testedIf Shape B is fixed: body-level refs are read, and an arm pins that a subject-ref-less commit whose fragment covers it is suppressed — RED against current— RETIRED: superseded bymain, or it is a pin and not an arm#917—renderCommitsreturnsnil, nil, so the conventional-commit harvest no longer runs and there is nothing to deduplicate;dedupByFragmentRefsretained and testedIf Shape A is fixed: an arm pins that editing an unrelated fragment does not suppress that commit's own genuine bullet (the silent-omission direction)— RETIRED: superseded by#917—renderCommitsreturnsnil, nil, so the conventional-commit harvest no longer runs and there is nothing to deduplicate;dedupByFragmentRefsretained and testedThe subject-level— RETIRED: superseded by(#NNN)dedup convention is documented wherever fragment authoring is described#917—renderCommitsreturnsnil, nil, so the conventional-commit harvest no longer runs and there is nothing to deduplicate;dedupByFragmentRefsretained and testedScope of this read
Measured over loopback at
main = 7993b154against PR#639 headf2c85841. All five commits mapped bystatusonchangelog.d/paths, with a fixed-string control returning 0 matches. I did not readchangelog_dedup_cc_by_fragment_refs's regex — that it requires a parenthesised subject ref is inferred from the code comment plus 5 observations, not from the predicate. Anyone implementing should read the regex before trusting that sentence.✅ FIXED ON MAIN — and by NEITHER of the two PRs that reference this tracker. The fix is
rt#917, which does not cite#672at all.Verified at source on
main(3d79511)internal/prep/prep.go:131returnsnil, nilunconditionally. Nothing is being deduplicated because nothing is being emitted. The duplicate class this tracker describes cannot form.The reproduction — three arms, and the third is what settles the MECHANISM
Constructed fixture carrying a fragment-ADD, a fragment-EDIT (this tracker's stated cause) and a fragment-LESS commit:
🔑 Arm 3 is the control in its inverted form. A fragment-less subject has no fragment to dedup against — under a working dedup it would still appear. It does not appear. So the mechanism is structural (the harvest is gone), not a better dedup. Arms 1 and 2 alone are satisfied by both explanations; only arm 3 separates them.
📌 Attribution, measured rather than assumed
#898fixed body-referenced duplicates two hours before#917removed the whole harvest. So of the two PRs a citation screen surfaces, one is a partial fix superseded the same afternoon and the other is a cut that touched the fragment. The real fix is a third PR that never mentions this number — which is why no citation-based screen could have found it, and why the arms were necessary.✅ The near-miss machinery is dormant, not deleted
dedupByFragmentRefsis still present ininternal/prep/prep.goand still exercised —TestDedupByFragmentRefsandTestDedupByFragmentRefs_noRefsPassthroughboth pass. If the render seam is ever re-opened, the dedup is there.⚠️ An instrument note, chased and eliminated rather than reported
The first fixture computed
0.1.0 → 0.0.1— which looks like a bump defect on a patch-release day. It was the fixture: aCHANGELOG.mdwith no released section resolves the baseline to0.0.0. Adding## [0.1.0]gives the correct0.1.1, and all three arms were re-run on the corrected fixture before this was reported. A malformed fixture returning a plausible wrong number, on the exact axis today's release depends on.Acceptance criteria
the CC dedup drops fragment-referenced duplicates— RETIRED (superseded by#917): the conventional-commit harvest no longer runs, so there is nothing to deduplicate. Machinery retained and tested for a future re-opening of the seam.📌 Patch-safe: no code change, so nothing to weigh against today's bugfix-only bar.
📌 Reproduction, the arm-3 discriminator and the attribution by @shipwright; source verified independently by @bosun.