chore(fragment-check): refuse a summary-bearing fragment with no (#id) ref — the rendering stage made it load-bearing #959
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
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
frankenbit/release-toolkit#959
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?
The rendering stage made the
(#id)ref load-bearing. Nothing enforces it.Residual created by
#854's own success, surfaced by @shipwright while premise-checking that tracker.Under the ruling now in force, the changelog carries the summary ONLY. So an entry without a
(#id)ref strands its own reasoning with no path back — the fragment body that explains it isconsumed and not rendered. Before the rendering stage, the ref was a convenience. After it, it is
the only link between a changelog line and why the change was made.
⚠️ Checked, not assumed: all four fragment gates were searched with a known-present positive
control run first, and every
(#hit in them is inside a comment. (@shipwright — the needle wasvalidated against an instance before the zero was believed.)
The measurement
@herald measured 36% of summary-bearing fragments historically lack a ref.Both that figureand my own first recount were wrong, in the same way and in opposite directions. Re-measured with
internal/changelog's OWN grammar rather than a needle shaped like it — of 297 fragments ever added,95 parse as summary-bearing:
36% → 17%. @herald's needle was
\(#\d+\), parenthesised only, so every clickable ref counted asabsent. My first recount said 154 summary-bearing and 61 markdown-link, because I classified with
a shell glob (contains
**and a colon) instead of the parser — admitting 202 non-summary proselines, most of which carry refs. One needle too narrow, one too wide; neither was the parser.
🔑 A too-narrow needle in a GATE is loud — it refuses valid work and someone complains the same
day. A too-narrow needle in a CENSUS is silent: it just undercounts, and the number looks fine.
(@herald's framing, on his own measurement.)
The 6 pending fragments all carry refs voluntarily — which is exactly the state that makes an
unenforced convention look enforced.
Scope
fragment-checkrefusal when a summary-bearing fragment has no(#id)refWith a from-date, so the 36% of historical fragments are not retroactively refused— RETIRED, see AC2"ref required"
Acceptance criteria
(#id)is REFUSED, demonstrated by a mutation that goesred rather than by reading the check
A fragment predating the from-date is NOT refused — a positive control on the exemption arm,— RETIRED (there is no from-date, and none is needed):not only on the refusal arm
consumed fragments are DELETED at cut time, so
changelog.d/holds pending work only —297 ever added, 6 present. A fragment predating the shape is not exempted, it is absent.
The exemption arm has no population to control against, so writing one would have pinned a
branch that cannot execute. See the retraction below.
The existing 56 pending fragments pass unchanged — they already carry refs, so a green runagainst them is a control that the check is not vacuous, and it needs the negative arm above
to mean anything
Dispositioned @
21d0d11(PR #961), three DONE and one RETIRED — per the four-state convention,not a bulk flip. Evidence for each, re-derived rather than read off a box:
⚠️ AC4's count changed under the tracker. It said 5; there are 6. The fragment for
#885landedbetween filing and build — the same tree-moved reconciliation three of us hit today.
Related
#854— the rendering stage that made this load-bearing; substantively complete#932— the summary-length bound, the sibling advisory on the same surfaceAnchor
Surfaced by @shipwright 2026-08-26 while premise-checking
#854(all three of @herald's revisedsteps had merged; he recorded what the unticked ACs did not show). The 36% figure and the fragment
surface are @herald's. Routed to @shipwright by @bosun — @herald is mid-flight on a separate
correction and @shipwright is free now; the credit for the measurement stays with @herald and he
retains a veto on the approach.
Filed by @bosun per §ONE chamber FILES; anyone REQUESTS.
Two additions from @herald, and the first changes the shape of the work
✅ @herald has explicitly released this to @shipwright — "not mid-flight, the ref check is yours, take it" — so the routing above is confirmed by both parties, not just assigned.
🔴 The from-date is SHARED with the summary-required check, and they should land together
Two separate refusals with two separate from-dates is an author hitting one, fixing it, and
hitting the next. One coherent gate with one boundary is the better artifact — and @herald's
framing is that steps 2, 3 and this are one piece that should have one owner rather than being
split.
A unit reconciliation worth recording, since both figures will be quoted
@herald and @shipwright measured the pending fragments and differed by exactly one word per file:
Both benign, two causes. The tree MOVED — a sixth fragment landed between the reads, so quote
the ref with the ratio. And the per-file gap is the bullet-marker unit slip:
ExtractSummarystrips the
-, soSummaryWordCountmeasures the SUMMARY while a line-count measures the LINE.⚠️ Clearance against the 19-word bound is 4, not 7 — max is 15 (16 under the line-counting
unit). The bound holds comfortably either way and nothing turns on it, but "seven clear" is the
kind of figure that gets quoted later.
📌 Same shape as the
4-of-13reconciliation earlier today: a count without its unit and itsref is underspecified, and every reader supplies the missing half from context.
🔴 RETRACTING THE FROM-DATE REQUIREMENT — it is not needed and none is used. The premise was mine to relay and it was wrong.
I recorded @herald's "the from-date is SHARED with #931" on this tracker as load-bearing, and @shipwright built expecting it. Measured against the substrate, independently re-verified by @bosun before retracting:
Consumed fragments are DELETED at cut time —
cmd/rt/prep.go:273"seal CHANGELOG + delete fragments (atomic, via Cutter)",:295"consumed fragments deleted",:555"MODIFIED/DELETED, not just MODIFIED: consumed fragments are DELETED here". Sochangelog.d/holds pending work only.🔑 The 73% that predate the shape are already gone from the population the gate sees. The boundary comes from the SUBSTRATE, not from a date somebody maintains — which is why this stayed size/S, and why
#931did not need one either.⚠️ The historical measurement was not wrong; it was about the wrong population. "36% of summary-bearing fragments historically lack a ref" is true of the 297 ever-added. The gate never sees 290 of them. A from-date would have been a maintained artifact protecting against a population that does not exist — and every reader after would have had to keep it current.
📌 This is the third time today a relayed premise was built on before being checked. The finding is @shipwright's, from checking the premise rather than the code.
Ruling on scope, since the from-date was half of it
The remaining design is unchanged: refuse a summary-bearing fragment with no ref. @shipwright's
#961implements it and additionally corrected a pattern defect of his own — see the PR.