fix(reusable-release): #637 post-condition fetch had no credentials — the guard could never run #674
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
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
frankenbit/release-toolkit!674
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "i/673-postcondition-fetch-needs-auth"
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?
Closes #673.
The defect
#637's post-condition fetches the default branch to assert the manifest bookkeeping commitlanded, rather than trusting that the push step ran. It sits three lines after the push
credential is deleted:
Under
set -ethe step dies at:727, so the comparison at:730and itsFATAL/exit 1at:735are unreachable. The guard reddens whether or not the bookkeeping landed — it cannotdistinguish the case it exists for. A guard that fails identically in both worlds is not a guard.
The fix
Scope a credential to this fetch, matching the
TOKEN_CFG2idiom already used for the Commit-2 pushbelow. The first credential's lifetime stays one command long (
#381round-2) — this does notwiden it, and it does not move the existing
rm.Mutation verification — closed loop
Arm A, the defect reproduced against a real remote:
Same exit code and same message as the v0.36.0 runner log (
exitcode '128',.824).Arm B, the fix:
And the guard's own query, which had never once executed:
Why it survived sixteen days
Every
release.ymlrun in between took the skip path and never reached this code. Eleven greenruns, and none of them could have caught it.
Gates run locally (exit codes, not prose)
What this PR does NOT do
release(task 21208) has no log on disk and never appearsin the runner's pickup sequence (21204–21207, 21209–21212 present; 21208 absent). A job the runner
never claimed is a different fault and stays open on #673.
a PR run takes. Only a real cut exercises
:727— so the next cut is the test, and if it goesgreen at the post-condition with
manifest bookkeeping VERIFIEDin the log, that is theconfirmation.
Uncertainty I would flag
I chose a third short-lived credential over extending the first one's scope, because
:713-719and
:806-812both deliberately scope one credential per command and I did not want to be the onewho widened that. If a reviewer prefers one credential spanning push-then-verify, that is a
defensible call and a smaller diff — but it lengthens the window
#381round-2 shortened on purpose.APPROVED at
27bf155f848b82cc007db303843a4456f6d17f30— SHA named in the body, since the field is caller-supplied.The fix is correct, minimal, and matches the idiom already in the file three times over. Both concerns I opened it with resolve.
The two things I checked that could have sunk it
① Does the new
trapclobber an armed one? No — the file arms and disarms in scoped pairs, and the new block is the third instance of an established pattern:The first is already disarmed at
:719, twenty-two lines before the new one arms. Nothing is overwritten and nothing is left unarmed.② Is bare
${RELEASE_TOKEN_OVERRIDE}safe here? Yes — the whole region sits inside the path-alpha gate at:652,if [[ -n "${RELEASE_TOKEN_OVERRIDE:-}" ]]. Inside it the variable is guaranteed non-empty, and the new line uses the identical expansion as the push three lines above. If the push works, so does the fetch. A:-default here would have been inconsistent with its neighbour rather than safer.The design call — I think you picked right, and it is arguable as you said
Widening the first credential to span push-then-verify is the smaller diff. But
:713-719and:806-812both scope one credential per command deliberately (#381 round-2), and lengthening that window to save four lines trades a security property for brevity. Declaring the alternative rather than presenting yours as the only shape is what made this quick to review.The claim I would ask a reviewer to weigh, and I weigh it as sound
Your arm A reproduces the exact rc and message from the runner log (
128, "could not read Username"), which is what makes it a reproduction rather than a plausible story. Arm B resolvesFETCH_HEADtod7266d08. And the guard's own query returnslast_released_sha=f2c85841== the cut'sHEAD_SHA, so it would have reported VERIFIED.So this converts an unreachable assertion into one that asserts — a stronger claim than "make the red go away", and the one that justifies the change on its own.
Fragment density — pre-checked, since this gate froze six cuts
Clear of the 25-word PASS ceiling throughout, so nothing here will stall the next prep run.
⚠️ My first count said
WARN 29wand it was my own splitter's fault — it joined the bullet to the first body sentence because the bullet has no terminal period. Reported here because a WARN I manufactured and then quietly dropped would be exactly the kind of thing this file's reflex table exists to catch.Both of your caveats stand and I am not softening either
Scope
I reviewed the diff, the enclosing control flow, the trap idiom, the path gating and the fragment. I did not exercise the release path — nobody can, short of a cut. My confidence rests on the reproduction matching the runner log and on the change being a third instance of a pattern already proven twice in the same file.