caller-pins: measure which adopters are running a stale copy of the lane - #19
Merged
Merged
Conversation
A caller's `uses: ...@<sha>` resolves the reusable workflow AT THAT COMMIT, so the pin decides which scanner that repo actually runs. Nothing detected a caller left behind: templates/ has no drift lane against its callers. That gap has now fired twice in opposite directions. #10 found the two reference adopters four commits behind the template and re-pinned them; the fan-out then landed ~44 repos on what was current that day, the template moved to 162accb, and the two repaired repos became the only current ones. Measured across 10 callers: 9 behind (8 at 62990dd, guest-room still at 8b7d8a8), 1 current. Why this is not self-test's template-pins job: that proves a pin names a REAL commit, which is a different question. A stale pin is a real commit -- 62990dd resolves perfectly and is four behind. Staleness is ancestry, so the check is `git merge-base --is-ancestor`, and it needs fetch-depth 0. Report-only for now. Opening a re-pin PR per laggard needs contents:write + pull_requests:write org-wide, which here means a new PINNED GH_APPS broker entry (front-desk-pin is the precedent; the broker refuses contents:write on an unpinned entry). That is a wrangler.jsonc change through the reviewer-gated deploy lane, so it lands separately from the measurement. Unauthenticated, so public repos only -- private repos are counted and reported as unexamined rather than silently dropped. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017RMKHpGXzw9Zkv49fzVssg
bdelanghe
marked this pull request as ready for review
August 3, 2026 23:00
This was referenced Aug 3, 2026
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.
Addresses the measurement half of #10, and answers its open question — item 3 does not generalise.
The problem, measured rather than asserted
uses: …/osv-scan.yml@<sha>resolves the reusable workflow at that commit, including the scanner version and digest pinned inside it. So a caller's pin decides which scanner that repo actually runs. Across 10 callers read live on 2026-08-03:The polarity has inverted since #10 was filed. That issue found the two reference adopters lagging and re-pinned them. The fan-out then landed ~44 repos on what was current that day; the template moved to
162accb; and the two repos #10 repaired are now the only current ones. Same defect, opposite direction, larger radius — which is why a one-time re-pin isn't the fix. It buys a day.Three consequences that make this more than cosmetic:
grace-expiresis built but not deployed. The mechanism added for Remediation queue: clear findings and remove report-only grace (it has no expiry and no owner) #8 — unbounded-grace warning, fail-closed on malformed dates, hard-fail past the date — doesn't exist at62990dd. It reaches 2 of ~46 repos.mainand reach nobody.Answering #10's open question: the resolver doesn't cover this
#10 leaned toward a pin resolver in
self-testgeneralising better than a per-repo drift gate. The measurement says otherwise:62990ddresolves perfectly.git cat-file -epasses. A resolver catches fabricated SHAs (@REPLACE_WITH_MERGE_SHA, a hand-typed 40-hex) and is structurally blind to a stale-but-valid pin — which is the failure that actually happened, twice.What distinguishes staleness is ancestry, not existence:
git merge-base --is-ancestor <caller-pin> <template-pin>is true exactly when a caller is behind. That comparison needs to read other repos, so it can't live intemplates/. Both checks are wanted; they catch disjoint failures, the same complementaritycheck_template_pins.pyalready documents between shape and resolution.What's here
tools/caller-pins.pyFDS-PINS-RESULTline.github/workflows/caller-pins.ymlself-test(06:17) and before the fleet rescans (Tue 07:23)test/test_caller_pins.pyself-test.yml,flake.nixREADME.mdStdlib only — no
requests, the same constraint that shapesdeno-lock-cdx.py.unknownis a distinct state frombehind. If a sha can't be resolved locally (shallow checkout, forked pin), the tool abstains rather than guessing — a census that guesses produces re-pin PRs against repos nobody measured. That's the property the tests exist for, and it's why the workflow setsfetch-depth: 0.Empty census fails. Zero callers is refused rather than reported green — the hollow-green shape
check_template_pins.pyguards one lane over.Deliberately not here
Re-pinning. Opening a PR per laggard needs
contents:write+pull_requests:writeorg-wide. The good news is that needs no new App and no standing PAT:bounded-systems-front-deskis already installed on all repos, andfront-desk-pinis an existing broker entry at exactly those permissions. It's one new pinnedGH_APPSentry namingcaller-pins.yml's ref — the broker refusescontents:writeon an unpinned entry (unsafePrivilegedApp), which is the right refusal. That's awrangler.jsoncchange through the reviewer-gated deploy lane, so it lands separately.Failing on lag.
fail-on-lagdefaults false while the fleet is knowingly behind — a lane red every week for a known reason teaches people to ignore it, which is therequired-baseline.ymlfailure this repo keeps citing. Flip it totrueonce the bulk re-pin lands and it becomes a ratchet.Private repos are invisible while unauthenticated, and are counted and reported as unexamined rather than silently dropped.
Note on running it from a session
A cloud session can't enumerate the org —
GET /orgs/{org}/reposis 403 at the egress proxy. Hence--repos a,b,cfor spot checks; the census proper belongs on a runner. That constraint is why this is a workflow and not something a session runs on request.🤖 Generated with Claude Code
https://claude.ai/code/session_017RMKHpGXzw9Zkv49fzVssg
Generated by Claude Code