fix(ci): pin-resolver probes ancestry for reusable pins — orphan-pin class (#782) - #832
Merged
Merged
Conversation
…#782) reachable != consumable. A reusable-workflow pin can name a REAL commit object that GitHub still refuses to run: the resolver needs the commit to be reachable from the repo's DEFAULT BRANCH. Estate census 2026-09 (435 repos x 4 reusable workflows): four such SHAs — 7fdc270 (squash-merge orphan, PR head discarded at squash), 892497f (deleted unmerged branch), 4696052 (alive on a remote branch, not an ancestor of main), 5b1d002 (not an object) — account for 61 dead workflow-run rows with ZERO alive rows, and this gate's existence predicate passed the first three. Changes: - Reusable-workflow pins (.github/workflows/*.yml@sha) now get a second, server-side probe after the commits-200: compare/<default>...<sha>. behind|identical => ancestor => consumable; ahead|diverged => NOT an ancestor => determinate negative, new failure class NOT-ANCESTOR with a remedy block ('repin to the merge commit, never a PR head'). An indeterminate probe (default-branch fetch, compare 4xx/5xx) is UNVERIFIED-loud, exactly like every other indeterminate answer. - Ordinary action pins are deliberately NOT probed: actions are fetched by object id at run time and non-default-branch commits are a working pattern there. A suite case asserts the compare endpoint is never even hit for an action-only fixture. - api() now also captures the response body (needed for default_branch and compare status). The newline test that isolates the code from the body is a BUILTIN — a printf | grep -q pipeline lets grep exit on the first match and kills printf with SIGPIPE under pipefail for any body over the 64 KB pipe buffer, smuggling the entire blob into $HTTP (caught live against the 146 KB codeql-action compare body; the gate silently soft-passed a real reusable pin). - Regression suite, stub-driven and offline: the four witness SHAs with their measured compare verdicts, probe semantics (behind/identical pass; diverged/ahead fail; compare-403 and default-branch-404 are loud-indeterminate, never verdicts), action-pin overreach guard, and three >64 KB SIGPIPE differential cases. 30 cases, all green; the piped-vs-builtin differential confirms the SIGPIPE tests bite. Out of scope per the issue's own disposition: the 61-row repin is owner-ordered; the pin-writer (apply-workflow-pins-remote.sh) already enforces the mirror-image rule (compare/<sha>...main must be identical|ahead) so the generator half needs no change. Refs #782
Contributor
|
Warning Review limit reachedNext included review available in 24 minutes. View limit detailsLimit details: You’ve used the included review currently available. You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Review configuration: ⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Advanced Run ID: 📒 Files selected for processing (2)
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. Comment |
|
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.



Closes #782 (detector + regression half).
The measured class
Estate census (435 repos × 4 reusable workflows, 31 distinct pin SHAs):
main?7fdc2705(squash-merge orphan),892497fe(deleted unmerged branch),46960521(remote-branch-only),5b1d0022(non-object)The orphan pins all return 200 from
commits/<sha>— the old predicate passed them.Fix (Defect 1 — the predicate)
Reusable-workflow pins (
.github/workflows/*.yml@sha) now get a second server-side probe aftercommits200:compare/<default>...<sha>—behind|identical⇒ consumable;ahead|diverged⇒ determinate negative, new failure class NOT-ANCESTOR with remedy ("repin to the merge commit, never a PR head — a PR head orphans at squash-merge"). Indeterminate probes (default-branch fetch failure, compare 4xx/5xx) stay loud-UNVERIFIED, never verdicts. Action pins are not probed (fetched by object id at run time; non-default-branch action commits are legitimate) — with a suite case proving the compare endpoint is never even called for an action-only fixture.Not in this PR, per the issue's disposition: the 61-row repin is owner-ordered; Defect 3's generator rule is already satisfied by
scripts/apply-workflow-pins-remote.sh(validate_targetaccepts onlyidentical|aheadfromcompare/<sha>...main— the mirror-image predicate); Defect 2's placement note (this gate runs insidegovernance-reusable.yml, inert when the host's own pin is fatal) is restated in the story — relocation is a separate governance decision.Found during live validation: a SIGPIPE bug in the fix itself
api()had to start capturing response BODIES (fordefault_branch/ comparestatus). My first cut isolated the code withprintf | grep -q— underpipefail, grep exits on first match, printf dies on SIGPIPE for any body over the 64 KB pipe buffer, and the whole blob landed in$HTTP. Caught live: a 146 KBgithub/codeql-actioncompare body turned a healthy pin into a mysteriously-shaped UNVERIFIED row. Fixed with a builtin glob test; the suite now carries three >64 KB differential cases, and the piped-vs-builtin differential was run to prove they bite (piped: swallows pin as UNVERIFIED / builtin: correct verdict).Validation
bash -n+ full offline suite: 30/30 — the 4 witness SHAs with their measured verdicts, probe semantics, overreach guard, SIGPIPE caseshyperpolymath/a2ml-ecosystemrepo redirect), exactly as the old script reportedClose-out per protocol on merge: evidence comment → close #782 completed → board → Done; detector docs ride in the script/test headers (no other doc references the gate).