fix: fall back to workflow runs for CI status reads - #100
Merged
Merged
Conversation
added 5 commits
August 7, 2026 21:42
quinnbot-ai
force-pushed
the
fm/fm-ci-read-workflow-runs
branch
from
August 8, 2026 05:43
1356708 to
461833d
Compare
quinnbot-ai
added a commit
that referenced
this pull request
Aug 10, 2026
* fix(ci): fall back to exact-head workflow runs * no-mistakes(review): Harden exact-head CI fallback guarantees * no-mistakes(review): Narrow CI fallback to exact monitor failures * no-mistakes(review): Match observed statusCheckRollup permission denial * no-mistakes(document): Refresh GitHub shim verification evidence --------- Co-authored-by: QuinnBot <quinnbot@proton.me>
quinnbot-ai
added a commit
that referenced
this pull request
Aug 10, 2026
* fix(ci): fall back to exact-head workflow runs * no-mistakes(review): Harden exact-head CI fallback guarantees * no-mistakes(review): Narrow CI fallback to exact monitor failures * no-mistakes(review): Match observed statusCheckRollup permission denial * no-mistakes(document): Refresh GitHub shim verification evidence --------- Co-authored-by: QuinnBot <quinnbot@proton.me>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Intent
Prevent the zombie-CI-loop failure class in firstmate when gh pr checks receives a 403 from the check-runs API under the fine-grained token even though the workflow-runs API remains readable. Build the durable local fix in this repository scripts and launch path without patching the external no-mistakes monitor or its parallel upstream proposal. Preserve least privilege: keep the ambient narrow token for CI reads, never expose the classic PR-capable config/gh-credential token to every crew or to the fallback, never print or commit a secret, and document token routing in the owning script header. After only the known 403 and only for the exact JSON gh pr checks shapes used by no-mistakes, resolve the PR current exact head SHA and query every paginated Actions workflow run using actions/runs?head_sha=; never approximate by branch name or stale head. Return correct green, red, cancellation, skipping, and pending buckets, with no runs remaining non-green. Preserve all non-403 failures, interactive check commands, every unrelated gh call, and the existing privileged routing only for pr create and pr edit. Document that workflow-run evidence is GitHub Actions only and cannot reconstruct hidden third-party check providers. Add shellcheck-clean colocated behavioral tests proving a crew whose check-runs read 403s reaches correct green and red exact-head verdicts while the broader token is absent, and run full no-mistakes validation. Deliver only to quinnbot-ai/firstmate: push the branch to its origin and use PR 100 against quinnbot-ai/firstmate main; never push to or open a PR against kunchenguid/firstmate. The accepted starting base is ae95570 from the fork; do not import the rejected 38-commit upstream bundle or require an upstream prerequisite.
What Changed
statusCheckRolluppermission denial.gh pr checksbehavior while keeping the broader PR credential restricted topr createandpr edit.Risk Assessment
✅ Low: The fallback is narrowly bounded to the observed statusCheckRollup denial and exact monitor vectors while preserving least-privilege routing, exact-head atomicity, and fail-closed behavior.
Testing
The baseline focused suite passed, expanded pagination and verdict-bucket coverage also passed, and a CLI-level fixture demonstrated exact-head green/red results without privileged-token exposure or stale-head leakage; this is CLI-only, so no visual screenshot applies.
Evidence: Exact-head CI fallback CLI transcript
Green and redgh pr checksfallback results used the exact PR head SHA, read the head twice, retained only the narrow CI token, and excluded stale-head results.Pipeline
Updates from git push no-mistakes
✅ **intent** - passed
✅ No issues found.
✅ **Rebase** - passed
✅ No issues found.
🔧 **Review** - 3 issues found → auto-fixed (3) ✅
bin/fm-gh-ci-fallback.sh:168- The requirement says to return pending evidence "with no runs remaining non-green," butcat "$FALLBACK_OUT"; exit 0also accepts an empty workflow response as[]. The supported no-mistakes v1.41.2 monitor marks an empty check list ready after its grace period, so a head with no registered Actions runs can be falsely certified green. At this fallback output boundary, emit an explicit pending check or retain the original 403 until at least one exact-head run exists.bin/fm-gh-ci-fallback.sh:130- The requirement says "resolve the PR current exact head SHA" and "never ... stale head," but the new code reads.head.shaonly once before paginating workflow runs. If the PR advances from A to B during that query, green runs for A are returned as the current verdict. Re-read the PR head after pagination and reject or retry when it differs before emitting results.bin/fm-gh-shim.sh:32- The requirement says "Preserve ... interactive check commands," butchecks) ROUTE=ci-fallbacksends everygh pr checksinvocation through the helper before validating the exact no-mistakes JSON shape. The helper redirects stdout and stderr to files, so successful--watchcalls no longer stream and realghno longer sees the caller's terminal. Restrict routing at this dispatch boundary, or pre-parse and directly exec non-matching invocations before capture.🔧 Fix: Harden exact-head CI fallback guarantees
3 issues (2 errors, 1 warning) still open:
bin/fm-gh-ci-fallback.sh:135- The intent requires fallback "after only the known 403," but this condition accepts either any standalone403or the token-denial message. An unrelated failure such asHTTP 403: API rate limit exceededcan therefore be replaced by a workflow verdict if the later reads succeed. Require the known personal-token/check-runs denial signature rather than a bare status code.bin/fm-gh-ci-fallback.sh:47- The accepted correction requires bypassing capture for every invocation outside the exact no-mistakes JSON shapes, but this parser also accepts-R, assignment-form flags, arbitrary flag ordering, duplicates, and repository-less PR URLs. Those manual commands can still enter the capturing fallback. Match only the two literal no-mistakes argument vectors at this dispatch boundary.docs/no-mistakes-pr-credential.md:44- This owning documentation still says zero exact-head runs return an empty list, while the corrected implementation emits a pending placeholder. Update this statement and the stale verification counts/transcript, which still describe 15 total/four CI cases instead of 17/six.🔧 Fix: Narrow CI fallback to exact monitor failures
1 error still open:
bin/fm-gh-ci-fallback.sh:111- The requirement says fallback must activate “after only the known 403,” but the new hunk matches onlyHTTP 403: ... check-runs. The installed GitHub CLI 2.92.0 queries GraphQLstatusCheckRollup, not the REST check-runs endpoint (source), and fine-grained permission failures are surfaced asGraphQL: Resource not accessible by personal access token (<field path>)(example). Consequently, the real denial misses this matcher, the original failure is replayed, and the zombie polling loop remains reachable. Replace the fabricated REST-shaped fixture with the observedstatusCheckRollupdenial and narrowly match that actual signature.🔧 Fix: Match observed statusCheckRollup permission denial
✅ Re-checked - no issues remain.
✅ **Test** - passed
✅ No issues found.
Baselinebash tests/fm-gh-shim.test.shAddedtest_ci_maps_cancel_skipping_and_pending_across_pages, then reranbash tests/fm-gh-shim.test.shManually exercisedgh pr checks 7 --repo o/r --json name,state,bucket,completedAt,linkthrough the installed-path shim fixture for exact-head green and red outcomes✅ **Document** - passed
✅ No issues found.
✅ **Lint** - passed
✅ No issues found.
✅ **Push** - passed
✅ No issues found.