Uh oh!
There was an error while loading. Please reload this page.
feat(caller-drift): enumerate the SOURCE reusables, not just the inventory list (backend#1681) - #214
Merged
Conversation
…ntory list (backend#1681) `reusables` is a hand-written list and the audit iterates it, so a reusable added to tracebloc/.github but never added to that list was compared against no repo and reported by nothing. That is the one direction of drift this guard could not see: it checked that every LISTED reusable is handled, never that every SHIPPED reusable is listed. `version-bump-pr.yml` is how it surfaced. It exists, has ZERO callers org-wide, and cannot be called as written -- it requires a `pr-token` secret no repo supplies. It is Layer 2 of backend#1563, the automated post-release bump-PR opener meant to prevent the version staleness that stalled tracebloc-py-package's prod leg (backend#1561). It shipped, was never wired up, and nothing said so. `check_source_reusables()` now walks the source workflow directory, parses each file, and refuses in BOTH directions: * a `workflow_call` workflow absent from the list (checked against nobody) * a listed name that is not a reusable there (a rename or delete leaves every repo's row asserting a ghost) Deliberately a die(), not a finding: the inventory is the contract, and a contract that does not mention half the artifacts it governs cannot be audited against. `on:` is read as both `"on"` and `True`, because YAML 1.1 parses the bare key as a boolean. version-bump-pr.yml is now listed and exempt in all 20 repos behind one shared reason that states plainly that it was never wired -- the same posture as wip-limit-check. That turns an invisible gap into a written decision: wire it or delete it. Verified: * selftest 97 -> 102 pass, 0 fail. New cases: an unlisted reusable is refused, a listed-but-absent one is refused, a push-triggered workflow is correctly NOT demanded, a missing workflows dir is refused rather than passed, and a fully-tracked tree passes. * Against the real source dir BEFORE the inventory rows: died naming version-bump-pr.yml. AFTER: passes. * Mutation: removing any single entry from the list makes it die (exit 2). * ruff --isolated --select E4,E7,E9,F scripts/ -> All checks passed! Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
saadqbal
approved these changes
Aug 11, 2026
Uh oh!
There was an error while loading. Please reload this page.
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 freeto 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.
The blind spot
reusablesis a hand-written list and the audit iterates it. So a reusable added totracebloc/.githubbut never added to that list is compared against no repo and reported by nothing.The guard checked that every listed reusable is handled. It never checked that every shipped reusable is listed — the one direction of drift it could not see.
How it surfaced
version-bump-pr.ymlexists, has zero callers org-wide, and cannot be called as written: it requires apr-tokensecret no repo supplies.It's Layer 2 of backend#1563 — the automated post-release bump-PR opener, meant to prevent exactly the version staleness that stalled
tracebloc-py-package's prod leg (backend#1561). It shipped, was never wired up, and nothing said so.The check
check_source_reusables()walks the source workflow directory, parses each file, and refuses in both directions:workflow_callworkflow absent from the list → checked against nobodyA
die(), not a finding: the inventory is the contract, and a contract that doesn't mention half the artifacts it governs can't be audited against.(
on:is read as both"on"andTrue— YAML 1.1 parses the bare key as a boolean, which is a classic way this kind of check silently matches nothing.)The inventory rows
version-bump-pr.ymlis now listed andexemptin all 20 repos behind one shared reason stating plainly that it was never wired — the same posture aswip-limit-check. That converts an invisible gap into a written decision: wire it or delete it.Test plan / evidence
version-bump-pr.ymlruff --isolated --select E4,E7,E9,F scripts/New selftest cases: an unlisted reusable is refused, a listed-but-absent one is refused, a push-triggered workflow is correctly not demanded, a missing workflows dir is refused rather than passed, and a fully-tracked tree passes.
Note for the reviewer
Based on
develop; #212 (rulesets) also touchesrepo-inventory.ymlandcaller-drift.py, so whichever lands second needs a trivial rebase. Kept separate per the one-self-contained-change-per-PR rule rather than stacking.Found by the round-2 pipeline audit, backend#1681. Parent epic: backend#1680.
Note
Medium Risk
Changes org-wide conformance guard startup behavior so any future unlisted reusable blocks CI until inventory is updated; inventory-only YAML bulk change with no runtime app impact.
Overview
Closes a caller-drift blind spot: the audit only walked the hand-written
reusableslist, so aworkflow_callworkflow shipped intracebloc/.githubbut never listed was never checked against any repo.check_source_reusables()now scans the source checkout’s.github/workflows, treats eachworkflow_callfile as a reusable (including YAML 1.1on:/True), anddie()s (exit 2) if the inventory is out of sync in either direction—unlisted reusables in source, or listed names that are not reusables there. It runs at the start of the guard, before per-repo drift.Inventory follow-up for
version-bump-pr.yml(surfaced by this check): added toreusables, documented viaversion_bump_pr_never_wired, and markedexempton all 20 repos (never wired, nopr-tokensecret)—same written posture aswip-limit-check.Selftests cover pass, unlisted reusable, phantom listed name, push-only workflows ignored, and missing workflows dir.
Reviewed by Cursor Bugbot for commit 6f1ccbd. Bugbot is set up for automated code reviews on this repo. Configure here.