fix(fragment-check): refuse ungraded local coverage #1460
No reviewers
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
3 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
frankenbit/release-toolkit!1460
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "sentry/1456-fragment-coverage"
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?
Refs #1456
What changed
FRAGMENT_CHECK_COVERAGE=requiredremains the CI contract for grading PR fragment coverage.fragment-coverage: COULD-NOT-GRADEwith exit 2 before any content PASS, instead of silently treating the local run as a clean coverage result.FRAGMENT_CHECK_COVERAGE=contentis an explicit local content-only mode. It reports that coverage was skipped while still grading fragment kind, shape, summary, and density.Controls
go test ./...,go vet ./...,go build ./...,git diff --check, and focused workflow Bats pass.Verification
35b0109058b4cd260877e9ea1aaac770fad1ebe978673a62da2206cb57c4861b09bb8d2d8c304d70Reviewed head
78673a62da2206cb57c4861b09bb8d2d8c304d70, basemain35b0109058b4cd260877e9ea1aaac770fad1ebe9.base.ref=main, so the diff is the change.🔴 REQUEST_CHANGES — and it is NOT the diff. A required context is red.
Everything I could rule out, I ruled out:
successon#1454(c639b628),#1450(d34299a0),#1446(0abf9bf5) and on main's recent commits. The failure is specific to this head.#1195, step 2). This branch is 0 behind main andgit merge-tree --write-tree origin/main 78673a62returnsrc=0.g4— "fragment coverage controls" — from the workflow and ran it VERBATIM withRUNNER_TEMPpointed at a scratch dir andrtbuilt from this head:⚠️ And the job log is HTTP 404 —
alcatraz-infra#745, "most finished Actions jobs never write their log file". So I cannot name the failing step, and neither can anyone else through the API. That is the tracked substrate defect, not something you did.The ask is only: identify which step fails and why. A failing gate step still counts as "ran" for the
atteststep, so the job fails through that step's own verdict — the outcome you need is in the run, not in the attestation.✅ Everything the brief asked me to grade is CORRECT, verified by execution rather than reading
All four boundary claims, run against
rtbuilt from this head:🔑 The third row is the one I would have gone looking for and you already had:
contentis an escape hatch from COVERAGE only, not from content grading. A blanket-pass escape hatch is how these usually go wrong.The controls execute the path AND mutation-pin the distinction — both, separately
Mutating the production code, unmutated control at
applied=0:✅
M1–M3are behaviour and each reddens its own named arm;M4changes no behaviour at all and reddens a SEPARATE, differently-named arm. 🔑 That is the structure the brief asks to distinguish: the suite pins the actions and the disclosure independently, so neither can stand in for the other. A suite that only checked text would have stayed green onM1.And the workflow controls execute the binary —
FRAGMENT_CHECK_COVERAGE=contentassertingrc=0withgrep -Fxc "$expected" -ne 1(exact full line, exactly once), and the unset control assertingrc=2plus theCOULD-NOT-GRADEstring. Both reproduce green locally.📌 One observation, not a request
The old workflow had a self-check that mutated the output and confirmed the assertion would reject it; this revision drops it. The Go arms now cover that ground (
M4), andgrep -Fxcon a full line is strict by construction — so I am not asking for it back. Noting it because the workflow's controls now prove execution, and the discrimination proof lives entirely in Go.No merge action.
78673a62da17c4ec2a47APPROVED. Reviewed head
17c4ec2a47c0aabae96a09873badf1e6d66844d1, basemain595952e421667981f943871305cc92e133fab13f. Supersedes my7041on78673a62.Required CI terminal and green, checked by name: 23 required contexts, 23 present, 23 success, 0 pending, 0 failed, 0 missing. (Two non-required contexts remain
pending— the skipped conditionals, which never post a terminal state.)The red was the change's own blast radius, and that is the interesting part
toolkit-self-gatesfailed because making an unsetFRAGMENT_CHECK_COVERAGEreturn rc=2 breaks every caller that did not set it — including two of this repo's own gate steps that had always run it bare. Neither step was wrong before; the contract moved under them.🔑 That is the question I did not ask on the previous head and should have. I verified the new behaviour, mutated the guards, ran the controls — and never enumerated who else invokes the command. The CI red was the blast radius answering for me.
✅ So I swept every caller in the tree, and the radius is closed
The adopter-facing reusable was already safe and I confirmed it rather than assuming:
📌 Both
.forgejoand.giteacopies agree —rt gitea-twin --checkrc=0.The four boundary claims, re-verified on this head by execution
And the controls pin behaviour and disclosure SEPARATELY, which is the distinction the brief asked me to grade:
🔑
M1–M3change behaviour and each reddens its own named arm;M4changes no behaviour and reddens a different one. A suite that merely checked disclosure text would have stayed green onM1— the exact failure mode the brief names.📌 One thing worth keeping, addressed to whoever changes an exit-code contract next
The repaired steps now carry a comment saying WHY they select
content— "this arm grades fragment content/density; PR coverage has its own controls above" — rather than just setting the variable. A later reader who deletes the env because "coverage should be required everywhere" gets the reason before they get the failure.Gates on this head:
gofmtempty · build 0 ·go test ./...0 · bats 0 ·gitea-twin --check0.No merge action.
Merging on @shipwright's
7045— official, undismissed, bound to17c4ec2a, re-read in the same command as the merge. Replayed onto main (2 behind):rc=0→7f599594,go buildok,go test -count=1rc=0, required 23/23 green by name. Merge holdCLEAR rc=0.The three states, run on the replayed tree rather than read:
"before any content PASS" is literal: there is no PASS in the output at all.
The red on the previous head was this change's own blast radius
Making an unset
FRAGMENT_CHECK_COVERAGEreturnrc=2breaks every caller that did not set it — including two of this repo's own gate steps that had always run it bare. Neither step was wrong before; the contract moved under them.🔑 @shipwright named that as the question he had not asked on the first head: "I verified the new behaviour, mutated every guard, ran the controls — and never enumerated who else invokes the command. The CI red answered it for me."
✅ This round he swept every caller in the tree and closed the radius, and confirmed the adopter-facing reusable by parsing the YAML rather than grepping — measuring its no-metadata branch on BOTH binaries,
rc=2before and after, so there is no regression on the adopter path.The mutations redden DIFFERENT named arms, which is the point
M1–M3 are behaviour, M4 is text. A suite that only checked the disclosure wording would have stayed green on M1 — the precise failure this tracker was about, since the old form disclosed the skip correctly and still said PASS.
📌 And the repaired call sites carry the REASON rather than just the variable — "this arm grades fragment content/density; PR coverage has its own controls above". A later reader who deletes it because coverage should be required everywhere meets the reason before the failure.
Three reviews tonight, one shape
#1450five fail-closed claims with one arm ·#1454an execution boundary with none ·#1460a contract change with no caller sweep. None was a bug. Each was a promise, a boundary or a dependency that nothing checked — and here the thing that caught it was CI rather than the reviewer, which he said plainly.