Skip to content

ci(triage): tell "no gate to triage" apart from "squabble is broken" - #36

Merged
hyperpolymath merged 3 commits into
mainfrom
fix/gate-triage-no-gate
Sep 21, 2026
Merged

hyperpolymath merged 3 commits into
mainfrom
fix/gate-triage-no-gate

Conversation

@hyperpolymath

Copy link
Copy Markdown
Owner

What was red

Gate triage (cicd-squabbler) was the only failing job on
JoshuaJewell/MetaManifold-WebUI#6 — hygiene and the Julia matrix were green.
It died at Fetch the live gate for this PR:

squabble fetch: no `required_status_checks` rule found on
`JoshuaJewell/MetaManifold-WebUI` branch `main` —
an unprotected branch has no gate to squabble over
Error: Process completed with exit code 2.

squabble was right. That base branch really is unprotected — 0 rulesets and
404 Branch not protected on the classic API, both verified directly rather
than taken from the tool's own message. It refused to emit a verdict it could
not support, which is the emptiness guard working.

The defect was that the refusal was indistinguishable from a malfunction:
run_fetch mapped every Err to exit 2, the same code as a serialisation
failure, a missing argument or an unknown subcommand. A caller could not tell
"nothing to measure" from "failed to measure" — which is precisely the pressure
that makes people write || true and mute genuine breakage along with it.

⚠ This is not a cross-repo artefact. This fork's own main is equally bare,
so the job dies identically on our own PRs. The cross-repo PR only made it
visible on a repo where we have pull-only access.

What lands here

Two commits, and the second is the one that matters:

f7a3e51 teaches the step the difference. It captures the exit code and
branches on it — 0 triage, 3 skip with a notice, anything else still
hard-fails
. It discriminates on the code, not on the message text, so the
producer answers the question rather than the consumer guessing at it. It also
removes the 0-byte gate.json the redirect leaves behind on failure, which
would otherwise upload as though an empty gate had been fetched.

4af3d1d re-pins SQUABBLER_SHA onto 9846169c, the merge of
hyperpolymath/cicd-squabbler#99 — which is what introduced FetchError::NoGate
and exit 3 in the first place.

Without the second commit the first is inert. At the old pin there is no
exit 3; rc=2 falls into the * arm and hard-fails exactly as it does today.
The diff would read as a fix and change nothing. The pin comment now records
the floor rather than just a value, because moving this pin backwards would
silently revert the handling above without touching a line of it.

A skip is not a pass, and the step says so

The exit-3 branch is deliberately loud. It writes to the step summary:

This job is green because nothing was triaged, not because a gate passed.
Merges into that branch are gated by no required status check.

and emits ::warning title=No gate to triage::. A green check that quietly
means "I verified nothing" is the vacuous-gate pattern; this one states its own
denominator.

Verification

  • 9846169c carries NO_GATE_EXIT: u8 = 3 and ExitCode::from(e.exit_code()),
    so NoGate → 3 and every other error → 2. Traced end to end in the merged
    source, not assumed from the PR title.
  • The bump window (6be52e3..9846169c) is #94–#99: a permissions-indentation
    repair, two DEED grammar gate fixes, an actions.lock reconcile, a
    harden-runner bump, and #99. None touches squabble's CLI behaviour.
  • ci.yml parses; the rewritten step body passes bash -n.
  • This PR is its own positive control. Our main is unprotected too, so
    Gate triage here must exercise the exit-3 path: green, with the warning above.
    If it goes red, the fix is wrong. If it goes green without the warning,
    something else is wrong.

Known gap, tracked not fixed

hyperpolymath/cicd-squabbler#100 — fetch reads only the rulesets API
(rules/branches/{branch}) and never classic branch protection
(branches/{branch}/protection). A classically-protected repo has a real
enforced gate and squabble reports none.

That gap gets worse after #99, not better: this consumer will now render it
as a confident green "nothing was gated" on a branch that is in fact
protected. A wrong answer nobody investigates beats a wrong answer that stops
the line. Neither repo in this PR is affected — both are genuinely unprotected
by both mechanisms — but the ordering matters, and #100 carries the acceptance
criteria.

🤖 Generated with Claude Code

https://claude.ai/code/session_01WPSJ7fBhVAMcpSffCBWUDo

hyperpolymath and others added 2 commits September 21, 2026 19:15
The preceding commit branches on `squabble fetch` exit 3 for "the base
branch has no required_status_checks rule". That code did not exist at
the pinned revision, so the fix was inert: rc=2 fell into the `*` arm
and hard-failed exactly as before. An ordering trap, and one that looks
identical to a working fix from the diff alone.

hyperpolymath/cicd-squabbler#99 merged at 2026-09-21T18:55Z and is what
introduced `FetchError::NoGate` and `ExitCode::from(e.exit_code())`.
Re-pinning onto its merge commit is what makes the preceding commit live.

The window also carries #94..#98 -- CI permissions indentation, two DEED
grammar gate fixes, an actions.lock reconcile, and a harden-runner bump.
None touches squabble's CLI behaviour.

The pin comment now records the FLOOR rather than just the value, because
moving this pin backwards would silently revert the exit-code handling
below without touching a line of it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WPSJ7fBhVAMcpSffCBWUDo
@coderabbitai

coderabbitai Bot commented Sep 21, 2026

Copy link
Copy Markdown

Review Change StackReview Change Stack

Note

Currently processing new changes in this PR. This may take a few minutes, please wait...

⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Advanced

Run ID: 137035c7-40ea-4047-93c0-bdf5054fd839

📥 Commits

Reviewing files that changed from the base of the PR and between 7d3213d and 4af3d1d.

📒 Files selected for processing (1)
  • .github/workflows/ci.yml
 ______________________________________________________________________________________________________
< What one programmer can do in one month, two programmers can do in two months. - Frederick P. Brooks >
 ------------------------------------------------------------------------------------------------------
  \
   \   (\__/)
       (•ㅅ•)
       /   づ

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@hyperpolymath
hyperpolymath merged commit e9d554c into main Sep 21, 2026
@hyperpolymath
hyperpolymath deleted the fix/gate-triage-no-gate branch September 21, 2026 19:01
@sonarqubecloud

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant