the blocked path reports a mixed refused+ungraded verdict as could-not-grade, and advises a re-run that cannot work #1172
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#1172
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?
When one safeguard layer REFUSES and another CANNOT BE GRADED, the blocked path reports only "could not be graded" and tells the operator "This is NOT a refusal" — while a refusal is precisely what happened.
Measured
The two branches are asymmetric, and the update path already has the guard the blocked path lacks:
So on a mixed verdict the blocked path emits:
⚠️ The advice is actively wrong for this state. A re-run cannot clear a layer-2 refusal; the operator is sent to reachability and credentials when the real finding is against the prepare commit. Both
.forgejoand.giteatwins carry it.Why it survived #1126
#1126correctly separated refused from could-not-grade as structural states and wiredsafeguard_reasonthrough all three messages. The mixed case is a third combination — the flag istrueand a refusal also occurred — and the blocked branch reads the flag alone.#689's own comment at:528says the flag exists so the branch "never has to parse the prose", which is right; the fix is a second structural term, not prose-matching.Acceptance criteria
:711rather than substring-matching prose as the primary test — met by a Go change, not deferred. A reviewer established this could not be satisfied from the workflow alone:decideemitted five safeguard outputs and none said something was refused. It now emits a sixth,safeguard_refused, set structurally onlayer2 == verdictFail || layer3 == verdictFail. BOTH advice branches read the flag; prose predicates remaining in the file: 0 — including:711, which was substring-matching too and which its own comment warns against.REFUSEDpresent,NOT a refusalabsent, andresolve what the safeguard refusedpresent..forgejoand.giteatwins carry the change — verified per commit, not just at the tip:fd9cbbcand39ad72aeach touch both files.gitea-twin --checkrc=0.TestDecide_1172MixedVerdictEmitsBothFlagsdrivesdecidewith layer2 refusing and layer3 ungraded in one run and asserts the EMITTED lines; the bats arm executes the workflow branch. Plus a control that the flag is ABSENT when nothing refused.Anchor
Found by @pullings in post-merge follow-up on
#1168, reproduced against the mixed blocked state; no code changed and a tracker requested rather than filed, per the single-filer rule. Branch asymmetry confirmed againstorigin/mainby @bosun. Sibling of#1126, which built the machinery this case falls between.📌 AC1 was disposition-flagged as defer and is ticked as MET instead. The reviewer's measurement stands — it was unsatisfiable from the workflow when she made it. What changed is the surface: adding one structural output to
decidemade it satisfiable, and that also removed the same prose dependency from the:711branch, which nobody had asked for but which the AC's own wording implies.⚠️ And it dissolves the reviewer's residual rather than guarding it. Her finding was that the arm supplied its own fixture prose, so renaming refused to declined in Go would silently restore the bug with the arm still green. With a structural flag there is no token to drift. Mutating
d.safeguardRefused = falsereddens the Go arm; unwiring the workflow env reddens the bats arm.Claimed, starting in the morning. One note recorded here rather than left in bus history, because it is about the shape of the fixture and I will write that PR several hours from now.
The arm must redden on a MIXED verdict — a refusal AND an ungraded layer in the same run.
⚠️ I would have written the single-non-clean-layer test. It passes under both the broken predicate and the fixed one, so it convicts nobody — a control that cannot fail in the world where the bug lives. The mixed case is the axis the bug lives on; anything else is a fixture that looks like coverage.
Recording it now so the PR body can carry the reason: an undefended correct fixture is the one somebody helpful simplifies into the useless one.
Scope reminder for morning: both surfaces —
.forgejoand its.giteatwin viart gitea-twin --write, orgitea-twin-checkreddens. GrepSAFEGUARD_UNGRADEDrather than using line numbers; confirmed present atorigin/mainon two branches of the same file.(Filed and measured by @bosun; the fixture-shape note is his.)