fix(ci): INV-CI-3 blocked a Dependabot bump and told the reader to run something that cannot fix it (INV-CI-5) - #65
Merged
Merged
Conversation
…n something that cannot fix it (INV-CI-5) INV-CI-3 works — it blocked Dependabot PR #61, which bumped the three github/codeql-action sub-actions to a SHA the _AUTHORITATIVE table did not know. But it was not ACTIONABLE. Its message said to resolve each SHA against GitHub and that "SENTINEL_VERIFY_ACTION_PINS=1 does this". That was false, measured by reproducing PR #61 in the working tree: offline layer 2 failed (SHA not in the table) online layer (VERIFY_ACTION_PINS=1) PASSED (iterates only entries already in the table, so a new SHA is never seen) So the only route left was a human hand-copying a 40-hex SHA and hand-resolving it against the API — the manual work INV-CI-3 exists to eliminate, on Dependabot's weekly cadence. A guard that turns the labour it prevents into a mandatory ceremony has traded one defect for another. Fix: scripts/sync_action_pins.py + `make sync-action-pins`, re-deriving the table and comments from the AUTHORITATIVE direction (SHA -> the tag pointing at it, never comment -> table: reading the comment would launder a stale label into the source of truth, which IS INV-CI-3's defect). Verified end-to-end against PR #61's exact state: guard fails -> one command -> guard passes; table gained d1ba80a13dd9 = v4.37.5, dropped the superseded entry, 3 comments rewritten. On a clean tree it reports `nothing to do` for all 12 pins — the negative control proving tool and guard agree. It REFUSES to write when any SHA is unresolvable (verified live: rc=1, explicit UNRESOLVED line, zero writes), because a partial table is worse than a stale one. Two of my own defects are recorded rather than quietly fixed: 1. The tool's first tag ranking counted dot-separated components, and actions/deploy-pages has three tags on one commit: v5.0.0, the moving alias v5, and the historical re-tag v3.0.2-node.24. The count chose v3.0.2-node.24, so the tool proposed rewriting a CORRECT comment into a misleading one — the guard's own defect class, reintroduced by its remediation. Now ranked semantically and pinned by a test over the real ambiguous tag set. 2. Three of the new module's assertions initially SURVIVED mutation: - `"/tags" in <all strings>` was satisfied by the resolver's DOCSTRING while the code queried /commits — documentation standing in for implementation. - `"refusing to write" in main()` was satisfied by a SECOND refuse-to-write path when the first was deleted. - Locating the gate by `any(Name == "unresolved")` accepted `if False and unresolved:` — a guard must test whether a gate can FIRE, not whether it exists. All three now resolve structurally (call arguments only, branch-scoped strings, exact-condition match). Mutation-tested 10/10. Two existing packaging guards fired on the new scripts/ directory and both were real: INV-PKG-1 (no __init__.py -> a namespace package an installed `scripts` would outrank, the litellm/ accident) and INV-PKG-3 (the sdist shipped a test reading scripts/ but not scripts/). Fixed by adding __init__.py and registering scripts/ as deliberately-absent alongside .github/ — maintainer tooling is not source — with the guard made repository-scoped via require_git_checkout. Suite: 4083 passed / 9 skipped. ruff clean.
neosun100
added a commit
that referenced
this pull request
Aug 6, 2026
#66) Takes Dependabot PR #61's SHA bump for the three github/codeql-action sub-actions, with the authoritative table and the version comments re-derived by `scripts/sync_action_pins.py --write` (INV-CI-5) rather than hand-edited: _AUTHORITATIVE + d1ba80a13dd9 = v4.37.5 - f205ea1c3313 (was v4.37.4, no longer pinned) comments codeql.yml:55, codeql.yml:68, scorecard.yml:65 v4.37.4 -> v4.37.5 This is the first real use of the tool added in #65, and the reason it exists: PR #61 could not be merged as-authored because Dependabot cannot update the table, and the guard's only advice was a flag that does not regenerate it. Verified: guard failed on PR #61's tree, one command fixed it, guard passes. Suite 4083 passed / 9 skipped. Zero unrelated files touched.
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.
The defect
INV-CI-3 works — it blocked Dependabot PR #61, which bumped the three
github/codeql-actionsub-actions to a SHA the_AUTHORITATIVEtable did not know.But it was not actionable. Its failure message said to resolve each SHA against GitHub and that "
SENTINEL_VERIFY_ACTION_PINS=1does this". That was false, measured by reproducing PR #61 in the working tree:So the only route left was a human hand-copying a 40-hex SHA and hand-resolving it against the API — precisely the manual work INV-CI-3 exists to eliminate, on Dependabot's weekly cadence. A guard that turns the labour it prevents into a mandatory ceremony has traded one defect for another. ("The guards are code too, so they get invariants" — round 18.)
Fix
scripts/sync_action_pins.py+make sync-action-pins, re-deriving the table and comments from the authoritative direction (SHA → the tag pointing at it). Never comment → table: reading the comment would launder a stale label into the source of truth, which is INV-CI-3's defect (setup-pythonclaimed v6.3.0 while pinned to v7.0.0).Verified end-to-end against PR #61's exact state:
d1ba80a13dd9 = v4.37.5, dropped the superseded entry, 3 comments rewrittennothing to dofor all 12 pins — the negative control proving tool and guard agreerc=1, explicitUNRESOLVEDline, zero writes), because a partial table is worse than a stale one: the guard would pass on the resolved entries while the suspicious pin stayed unrecordedTwo of my own defects, recorded rather than quietly fixed
1. The tool nearly reintroduced the very defect it fixes. Its first tag ranking counted dot-separated components, and
actions/deploy-pageshas three tags on one commit:The count chose
v3.0.2-node.24, so the tool proposed rewriting a correctv5.0.0comment into a misleading one — the guard's own defect class, reintroduced by its remediation. Now ranked semantically, and pinned by a test over the real ambiguous tag set.2. Three of the new module's assertions initially SURVIVED mutation:
"/tags" in <all strings>was satisfied by the resolver's docstring while the code queried/commits— documentation standing in for implementation."refusing to write" in main()was satisfied by a second refuse-to-write path when the first was deleted.any(Name == "unresolved")acceptedif False and unresolved:— a guard must test whether a gate can FIRE, not whether it exists.All three now resolve structurally (call arguments only, branch-scoped strings, exact-condition match).
Two existing guards fired on the new directory — both real
scripts/had no__init__.py, making it a namespace package that any installedscriptspackage would silently outrank — thelitellm/accident.scripts/but notscripts/itself, so a downstream packager's bundled-suite run would hitFileNotFoundError.Fixed by adding
__init__.pyand registeringscripts/as deliberately-absent alongside.github/(maintainer tooling is not source), with the guard made repository-scoped viarepo_infra.require_git_checkoutso it skips honestly in an sdist.INV-MAKE-1also required the new target inKEY_TARGETSand.PHONY— added.Verification
ruffclean (the newscripts/tree is linted, not exempt).Once this merges,
make sync-action-pinsis the supported fix for PR #61 and every future Action bump.