Skip to content

Gate merge-pr on CI; bring the triad under standard-check - #194

Merged
l1a merged 2 commits into
mainfrom
feature/merge-pr-ci-gate
Aug 13, 2026
Merged

Gate merge-pr on CI; bring the triad under standard-check#194
l1a merged 2 commits into
mainfrom
feature/merge-pr-ci-gate

Conversation

@l1a

@l1a l1a commented Aug 13, 2026

Copy link
Copy Markdown
Owner

Description

just merge-pr had no CI gate. It went straight from the branch check to:

gh pr merge --squash --delete-branch

gh pr merge will happily merge a red PR when the repository has no branch protection, and "wait
for the checks to settle" is not "wait for them to pass". Every merge in this repo has been
ungated
— safe only because whoever merged happened to look at CI first.

rusticprofile added this gate in its v0.1.5 after PR #19 went in with build (fedora-x64) red,
and extended it in 0.2.1 after an empty rollup passed vacuously — printing "CI is green." over
a commit CI had never seen, which happened for real when GitHub stopped creating workflow runs for
pushed commits. Neither fix reached here. Same cross-repo staleness as the nushell completion path,
this time on the recipe that performs the irreversible act.

Three refusals

state why
a failing check the original reason the gate exists
an empty rollup "nothing ran" is not "everything passed", and the arm below cannot tell them apart
checks still running refuse rather than race them

The empty state is compared as a string rather than through jq -e length: gh --jq is gh's
built-in jq, but an external jq is not on a default Windows PATH — and a gate that silently
degrades where its dependency is missing is the thing being fixed, not a way to fix it.

The triad is now checked

scripts/gate_conformance.py (template v3) is vendored and run by standard-check, which
just check depends on — so these guards cannot quietly disappear again. It asserts nine of them
across pr, open-pr and merge-pr, with comments stripped first, so a comment explaining a
guard cannot satisfy the check for a recipe that lost it.

It is structural, not behavioural, and its docstring says so — it proves a guard is present, not
that it works. The install helpers can be checked behaviourally because they are pure functions
their self-test can call; these recipes run the suite, push branches and merge PRs, so executing
them from check would be slow and occasionally destructive.

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (gate_conformance.py in standard-check)
  • Breaking change
  • This change requires a documentation update

How Has This Been Tested?

  • The gate was verified firing, without merging anything. This branch had no PR when it was
    tested, so the rollup is empty — merge-pr refused and exited before reaching
    gh pr merge:

    ```
    Checking CI on this branch...
    Error: no checks have reported for this commit at all.
           That is not the same as passing. ...
    ```
    
  • The jq expression was checked by asking gh's own jq to parse it, rather than reasoning
    about how many backslash layers survived — a real hazard here, and one that has corrupted
    output earlier in this series.

  • gate_conformance.py now reports this repo conformant; before the change it reported the
    same three missing merge-pr guards that etr still reports.

  • just pr green: fmt, clippy --workspace and --features graphics, 69 + 114 + 15 tests, man
    page at retch 0.6.23, audit advisory-only.

Backup safety

n/a — tooling only.

Checklist

  • Style, self-review, comments explaining why each refusal exists
  • Documentation updated — NOTES.md release entry
  • just man re-run after the bump and committed
  • No new warnings
  • Version bumped 0.6.220.6.23 (patch)
  • No failure mode introduced can degrade silently — this removes one: merge-pr now
    refuses three distinct bad states instead of merging regardless, and standard-check fails
    the build if any guard is removed

Wiki not updated: §4.8's pages cover config/theming, workspace architecture, and just recipes /
build prerequisites / the PR-merge workflow. This does change merge-pr's behaviour, but
Development-Setup.md documents it as "squash-merge, switch to main, pull, delete branch" — still
accurate; the gate is a refusal added in front, not a change to what a successful merge does.

l1a added 2 commits August 12, 2026 21:03
merge-pr went straight from the branch check to gh pr merge --squash
--delete-branch, with no inspection of the status rollup. gh pr merge
happily merges a red PR when there is no branch protection, so every
merge in this repo has been ungated -- safe only because whoever merged
happened to look first.

rusticprofile added this in v0.1.5 after a PR went in with a leg red,
and extended it in 0.2.1 after an EMPTY rollup passed vacuously.
Neither reached here.

Three refusals now: a failing check, an empty rollup, and checks still
running. The empty state is compared as a string rather than via jq -e
length, because an external jq is not on a default Windows PATH and a
gate that degrades where its dependency is missing is the thing being
fixed.

gate_conformance.py (template v3) is vendored and run by
standard-check, so the guards cannot vanish again. It is structural,
not behavioural, and says so.

Verified safely: on a branch with no PR the rollup is empty, so
merge-pr refuses before reaching gh pr merge.

Assisted-By: Claude Opus 5
Assisted-By: Claude Opus 5
@l1a
l1a merged commit 25a63eb into main Aug 13, 2026
18 checks passed
@l1a
l1a deleted the feature/merge-pr-ci-gate branch August 13, 2026 04:18
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