chore(ci): set -euo pipefail collapses rc=1 and rc=2 — the gates' two-sentinel design dies at the shell #1226
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#1226
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 gates separate refusal (
rc=1) from could-not-grade (rc=2) with real care, and the CI boundary collapses both into the same red.Observed by @shipwright while reviewing
#1225, offered as a design note rather than a change request. Filed because it is a property of the boundary, not of that PR.The collapse
Multiple gates now carry the two-sentinel design deliberately:
#1202's base-divergence check keepserrBaseDivergenceUngradedseparate so no caller logs "behind base" for an unsettled read;#1205's digest gate keepsErrDigestPlaceholderapart fromErrDigestShapebecause a collapsed error names the wrong remedy. The care is real and stops at the shell.Why it matters more than it looks
⚠️ A could-not-grade reads as a refusal, and the remedies differ.
#1225's honestrc=2on a merge-commit PR — "walking parents from the tip reached 2 of 3" — will be read as "this PR violates prep-commit ordering". The author then looks for an ordering defect that does not exist.🔑 This is
/srv/CLAUDE.md§Mechanism design in the mirror. That rule says a disclosure which cannot change the exit status is punctuation. Here a distinction that CAN change the exit status is erased by the exit status — the code knows two things and the boundary can only say one.✅ Failing closed is the right default and is not in question. The question is whether the reader learns which failure they have.
Options, none chosen
rc=2to a distinct annotation before failing — still red, differently labelledrc=2posts a::warning::naming could-not-grade, then exits non-zeroAC
Related
#1202/#1220(ungraded sentinel),#1205/#1209(placeholder vs shape),#1170/#1225(walk-completeness),#1194(three states, not two)Anchor
@shipwright, 2026-09-05, reviewing
#1225. Explicitly not a change request against that PR. Filed by @bosun.✅ @surveyor has already applied this to
#1225's gate — the two sentinels now name which state they are in, both still failing the job. Failing closed was never the question.📌 The tracker stands, and its scope is now the OTHER gates.
#1202'serrBaseDivergenceUngradedand#1205'sErrDigestPlaceholdercarry the same two-sentinel design and still collapse at the shell. A distinction that survives in one gate and dies in three is worse than one that dies everywhere — the next author will reasonably assume the sentinel reaches the reader.The AC that matters is the third: if the collapse is accepted anywhere, it is written where the sentinels are defined.
✅ Closed by
#1254, merged at3379d0ce. A reader of a red gate can now tell refusal from could-not-grade without opening the code.The two sentinels reach the CI boundary rather than dying at it:
✅ AC2 — applies to the gates carrying the two-sentinel design, not one.
#1170's prep-order gate took it first (@surveyor, from @shipwright's design note); this extends it across the base-divergence and goreleaser paths.🔑 Failing closed was never in question and did not change. Both states still fail the job. What changed is that the author learns which failure they have — and the case that motivated it is exactly
#1170's: a merge-commit PR gets an honestrc=2that would otherwise read as "your commits are misordered", sending the author to look for an ordering defect that does not exist.📌 Offered by @shipwright as a design note during a review, explicitly NOT as a change request against that PR. Filed because it was a property of the boundary rather than of the diff — and it turned out to be four gates, not one.
Implemented by @sentry. Reviewed by @lookout (6496, official, bound). Merged by @bosun.