Skip to content

actions.lock: list the lock-sync gate, and make the checker require coverage - #108

Merged
hyperpolymath merged 1 commit into
mainfrom
fix/lock-coverage
Sep 22, 2026
Merged

hyperpolymath merged 1 commit into
mainfrom
fix/lock-coverage

Conversation

@hyperpolymath

Copy link
Copy Markdown
Owner

What this fixes

The lock-sync gate merged into this repository cannot start, and the
checker it ships cannot detect why. Both are fixed here.

A workflow file with no key in .github/workflows/actions.lock is refused
by GitHub at startup — jobs=0, startup_failure — even when it contains
zero uses: refs and so has nothing to pin.

Evidence — single-variable flip, two independent repositories

repo before after adding the one-line key
hyperpolymath/verisimdb 7 consecutive startup_failure success
hyperpolymath/blocky-writer 2 of 2 startup_failure success

Nothing else changed in either case. A control commit that touched the tree but
not the lock still failed; the commit adding the key passed. This is a state
effect, not a re-indexing side effect of "any lock change".

The spelling is not invented — gh actions-lock already emits the empty-list
form for other zero-uses: workflows in this same lockfile (labels.yml). The
generator simply omitted this file, which is itself an upstream defect.

The gate could not defend its own fix

This is the guard-asks-a-different-question-than-its-consumer trap:

  • clauses 1–3 ask: is every uses: locked under its own workflow path?
  • GitHub asks: is every workflow file represented in the lock?

A workflow with no uses: satisfies clauses 1–3 vacuously and is still
refused. Thirteen repositories passed the gate with exactly this gap present,
so a green gate today is not evidence a lock is complete.

Clause 4 (COVERAGE) diffs the set of files under .github/workflows/
against the set of lockfile keys, fails on any file with no key, names it, and
quotes the empty-list form to add. Remediation step 4 warns that re-running
gh actions-lock may not add it, because the omission is the tool's own defect.

Mutation-tested, both directions

mutant expected result
delete the lock-sync-gate.yml key gate fails ✅ fails, names the file
delete the unrelated labels.yml key gate fails ✅ fails, names the file
unmutated tree gate passes ✅ passes

A passing gate proves nothing until it kills a mutant, so both are recorded here.

Also included

workflow_dispatch: on the gate. A startup-failed run cannot be re-run
(gh run rerun refuses it), which is what made this defect expensive to
diagnose; a dispatch handle makes it reproducible on demand.

Scope

The checker is patched in place — each repository's copy has diverged
slightly in comments, and only the clause-4 block, its remediation step and one
success line are added. No existing clause is altered.

Verification

  • bash -n scripts/check-lock-sync.sh clean
  • checker passes on this tree after the lock key is added
  • both mutants killed
  • the gate run on this PR reports jobs > 0 (it could not start before)

🤖 Generated with Claude Code

https://claude.ai/code/session_01X3hgXxWm6umMgZkjYyHnnm

…overage

Two defects, one cause: a workflow file that has NO KEY in actions.lock is
refused by GitHub at startup (jobs=0, startup_failure) even when it contains
zero `uses:` refs and therefore has nothing to pin.

1. Add the missing key for the gate this repo already ships:

       '.github/workflows/lock-sync-gate.yml': []

   MEASURED, single-variable flip on two independent repositories:
     * hyperpolymath/verisimdb  - 7 consecutive startup_failure -> success
     * hyperpolymath/blocky-writer - 2 of 2 startup_failure -> success
   Nothing else changed in either case. An empty commit with the lock
   untouched still failed; the commit adding this line passed. `gh actions-lock`
   already emits this empty-list form for other zero-`uses:` workflows in this
   very lockfile (labels.yml), so the spelling is the generator's own
   convention - the generator simply omitted this file.

2. Teach scripts/check-lock-sync.sh to catch it (clause 4, COVERAGE).

   The gate could not defend the very fix it ships. Clauses 1-3 ask "is every
   `uses:` locked under its own workflow path?" GitHub asks a DIFFERENT
   question: "is every workflow file represented in the lock?" A workflow with
   no `uses:` satisfies clauses 1-3 vacuously and is still refused. Thirteen
   repositories passed the gate with exactly this gap present.

   Clause 4 diffs the set of files under .github/workflows/ against the set of
   lockfile keys and fails on any file with no key, naming it and quoting the
   empty-list form. Mutation-tested both ways: deleting the lock-sync-gate key
   fails the gate, and deleting the unrelated labels.yml key fails it too;
   the unmutated tree passes.

3. Add `workflow_dispatch:` to the gate so it can be exercised on demand.
   A startup-failed run cannot be re-run (`gh run rerun` refuses it), which is
   what made this defect expensive to diagnose.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01X3hgXxWm6umMgZkjYyHnnm
@coderabbitai

coderabbitai Bot commented Sep 22, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

Next included review available in 18 minutes.

Check out review usage here.

View limit details

Limit 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.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Advanced

Run ID: 7f6d5636-017d-4235-9778-af7ea14b11f7

📥 Commits

Reviewing files that changed from the base of the PR and between 6e40a86 and 33f17a0.

⛔ Files ignored due to path filters (1)
  • .github/workflows/actions.lock is excluded by !**/*.lock
📒 Files selected for processing (2)
  • .github/workflows/lock-sync-gate.yml
  • scripts/check-lock-sync.sh

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@sonarqubecloud

Copy link
Copy Markdown

@hyperpolymath
hyperpolymath merged commit 0ed70e8 into main Sep 22, 2026
48 of 51 checks passed
@hyperpolymath
hyperpolymath deleted the fix/lock-coverage branch September 22, 2026 19:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant