Skip to content

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

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

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Advanced

Run ID: ddc28aa6-e4a0-4e66-8f65-be6194566aa3

📥 Commits

Reviewing files that changed from the base of the PR and between 7d30afd and 6a49150.

⛔ 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

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.

📜 Recent review details
⏰ Context from checks skipped due to timeout. (12)
  • GitHub Check: governance / Licence consistency
  • GitHub Check: governance / Check Workflow Staleness
  • GitHub Check: governance / Workflow security linter
  • GitHub Check: governance / Well-Known (RFC 9116 + RSR)
  • GitHub Check: governance / Code quality + docs
  • GitHub Check: governance / Guix primary / Nix fallback policy
  • GitHub Check: governance / Trusted-base reduction policy
  • GitHub Check: governance / Security policy checks
  • GitHub Check: governance / Language / package anti-pattern policy
  • GitHub Check: scan / rust-secrets
  • GitHub Check: hypatia / Hypatia Neurosymbolic Analysis
  • GitHub Check: CodeQL Analysis (actions, none)
⚠️ CI failures not shown inline (11)

GitHub Actions: Workflow Security Linter / 0_lint-workflows.txt: actions.lock: list the lock-sync gate, and make the checker require coverage

Conclusion: failure

View job details

##[group]Run errors=0
 �[36;1merrors=0�[0m
 �[36;1mfor f in .github/workflows/*.yml .github/workflows/*.yaml; do�[0m
 �[36;1m  [ -f "$f" ] || continue�[0m
 �[36;1m  if ! head -1 "$f" | grep -q "SPDX-License-Identifier"; then�[0m
 �[36;1m    echo "ERROR: $f missing SPDX header"�[0m
 �[36;1m    errors=$((errors + 1))�[0m
 �[36;1m  fi�[0m
 �[36;1mdone�[0m
 �[36;1mexit $errors�[0m
 shell: /usr/bin/bash -e {0}
 ##[endgroup]
 ERROR: .github/workflows/boj-build.yml missing SPDX header
 ERROR: .github/workflows/casket-pages.yml missing SPDX header
 ERROR: .github/workflows/codeql.yml missing SPDX header
 ERROR: .github/workflows/governance.yml missing SPDX header
 ERROR: .github/workflows/hypatia-scan.yml missing SPDX header
 ERROR: .github/workflows/instant-sync.yml missing SPDX header
 ERROR: .github/workflows/label-triage.yml missing SPDX header
 ERROR: .github/workflows/labels.yml missing SPDX header
 ERROR: .github/workflows/mirror.yml missing SPDX header
 ERROR: .github/workflows/pages.yml missing SPDX header
 ERROR: .github/workflows/push-email-notify.yml missing SPDX header
 ERROR: .github/workflows/quality-gates.yml missing SPDX header
 ERROR: .github/workflows/secret-scanner.yml missing SPDX header
 ERROR: .github/workflows/workflow-linter.yml missing SPDX header
 ##[error]Process completed with exit code 14.

GitHub Actions: Workflow Security Linter / lint-workflows: actions.lock: list the lock-sync gate, and make the checker require coverage

Conclusion: failure

View job details

##[group]Run errors=0
 �[36;1merrors=0�[0m
 �[36;1mfor f in .github/workflows/*.yml .github/workflows/*.yaml; do�[0m
 �[36;1m  [ -f "$f" ] || continue�[0m
 �[36;1m  if ! head -1 "$f" | grep -q "SPDX-License-Identifier"; then�[0m
 �[36;1m    echo "ERROR: $f missing SPDX header"�[0m
 �[36;1m    errors=$((errors + 1))�[0m
 �[36;1m  fi�[0m
 �[36;1mdone�[0m
 �[36;1mexit $errors�[0m
 shell: /usr/bin/bash -e {0}
 ##[endgroup]
 ERROR: .github/workflows/boj-build.yml missing SPDX header
 ERROR: .github/workflows/casket-pages.yml missing SPDX header
 ERROR: .github/workflows/codeql.yml missing SPDX header
 ERROR: .github/workflows/governance.yml missing SPDX header
 ERROR: .github/workflows/hypatia-scan.yml missing SPDX header
 ERROR: .github/workflows/instant-sync.yml missing SPDX header
 ERROR: .github/workflows/label-triage.yml missing SPDX header
 ERROR: .github/workflows/labels.yml missing SPDX header
 ERROR: .github/workflows/mirror.yml missing SPDX header
 ERROR: .github/workflows/pages.yml missing SPDX header
 ERROR: .github/workflows/push-email-notify.yml missing SPDX header
 ERROR: .github/workflows/quality-gates.yml missing SPDX header
 ERROR: .github/workflows/secret-scanner.yml missing SPDX header
 ERROR: .github/workflows/workflow-linter.yml missing SPDX header
 ##[error]Process completed with exit code 14.

GitHub Actions: Governance / 3_governance _ Workflow security linter.txt: actions.lock: list the lock-sync gate, and make the checker require coverage

Conclusion: failure

View job details

##[group]Run failed=0
 �[36;1mfailed=0�[0m
 �[36;1mfor file in .github/workflows/*.yml .github/workflows/*.yaml; do�[0m
 �[36;1m  [ -f "$file" ] || continue�[0m
 �[36;1m  if ! head -1 "$file" | grep -q "^# SPDX-License-Identifier:"; then�[0m
 �[36;1m    echo "ERROR: $file missing SPDX header"; failed=1�[0m
 �[36;1m  fi�[0m
 �[36;1m  if ! grep -q "^permissions:" "$file"; then�[0m
 �[36;1m    echo "ERROR: $file missing top-level 'permissions:' declaration"; failed=1�[0m
 �[36;1m  fi�[0m
 �[36;1mdone�[0m
 �[36;1m[ $failed -eq 1 ] && { echo "Add SPDX header + permissions:"; exit 1; }�[0m
 �[36;1mecho "All workflows have SPDX headers + permissions"�[0m
 shell: /usr/bin/bash -e {0}
 ##[endgroup]
 ERROR: .github/workflows/boj-build.yml missing SPDX header
 ERROR: .github/workflows/casket-pages.yml missing SPDX header
 ERROR: .github/workflows/codeql.yml missing SPDX header
 ERROR: .github/workflows/governance.yml missing SPDX header
 ERROR: .github/workflows/hypatia-scan.yml missing SPDX header
 ERROR: .github/workflows/instant-sync.yml missing SPDX header
 ERROR: .github/workflows/label-triage.yml missing SPDX header
 ERROR: .github/workflows/labels.yml missing SPDX header
 ERROR: .github/workflows/mirror.yml missing SPDX header
 ERROR: .github/workflows/pages.yml missing SPDX header
 ERROR: .github/workflows/push-email-notify.yml missing SPDX header
 ERROR: .github/workflows/quality-gates.yml missing SPDX header
 ERROR: .github/workflows/secret-scanner.yml missing SPDX header
 ERROR: .github/workflows/workflow-linter.yml missing SPDX header
 Add SPDX header + permissions:
 ##[error]Process completed with exit code 1.

GitHub Actions: Governance / governance _ Workflow security linter: actions.lock: list the lock-sync gate, and make the checker require coverage

Conclusion: failure

View job details

##[group]Run failed=0
 �[36;1mfailed=0�[0m
 �[36;1mfor file in .github/workflows/*.yml .github/workflows/*.yaml; do�[0m
 �[36;1m  [ -f "$file" ] || continue�[0m
 �[36;1m  if ! head -1 "$file" | grep -q "^# SPDX-License-Identifier:"; then�[0m
 �[36;1m    echo "ERROR: $file missing SPDX header"; failed=1�[0m
 �[36;1m  fi�[0m
 �[36;1m  if ! grep -q "^permissions:" "$file"; then�[0m
 �[36;1m    echo "ERROR: $file missing top-level 'permissions:' declaration"; failed=1�[0m
 �[36;1m  fi�[0m
 �[36;1mdone�[0m
 �[36;1m[ $failed -eq 1 ] && { echo "Add SPDX header + permissions:"; exit 1; }�[0m
 �[36;1mecho "All workflows have SPDX headers + permissions"�[0m
 shell: /usr/bin/bash -e {0}
 ##[endgroup]
 ERROR: .github/workflows/boj-build.yml missing SPDX header
 ERROR: .github/workflows/casket-pages.yml missing SPDX header
 ERROR: .github/workflows/codeql.yml missing SPDX header
 ERROR: .github/workflows/governance.yml missing SPDX header
 ERROR: .github/workflows/hypatia-scan.yml missing SPDX header
 ERROR: .github/workflows/instant-sync.yml missing SPDX header
 ERROR: .github/workflows/label-triage.yml missing SPDX header
 ERROR: .github/workflows/labels.yml missing SPDX header
 ERROR: .github/workflows/mirror.yml missing SPDX header
 ERROR: .github/workflows/pages.yml missing SPDX header
 ERROR: .github/workflows/push-email-notify.yml missing SPDX header
 ERROR: .github/workflows/quality-gates.yml missing SPDX header
 ERROR: .github/workflows/secret-scanner.yml missing SPDX header
 ERROR: .github/workflows/workflow-linter.yml missing SPDX header
 Add SPDX header + permissions:
 ##[error]Process completed with exit code 1.

GitHub Actions: Governance / 4_governance _ Well-Known (RFC 9116 + RSR).txt: actions.lock: list the lock-sync gate, and make the checker require coverage

Conclusion: failure

View job details

##[group]Run SECTXT=""
 �[36;1mSECTXT=""�[0m
 �[36;1m[ -f ".well-known/security.txt" ] && SECTXT=".well-known/security.txt"�[0m
 �[36;1m[ -f "security.txt" ] && SECTXT="security.txt"�[0m
 �[36;1mif [ -z "$SECTXT" ]; then�[0m
 �[36;1m  echo "::warning::No security.txt found."�[0m
 �[36;1m  exit 0�[0m
 �[36;1mfi�[0m
 �[36;1mgrep -q "^Contact:" "$SECTXT" || { echo "::error::Missing Contact field"; exit 1; }�[0m

GitHub Actions: Governance / governance _ Well-Known (RFC 9116 + RSR): actions.lock: list the lock-sync gate, and make the checker require coverage

Conclusion: failure

View job details

##[group]Run SECTXT=""
 �[36;1mSECTXT=""�[0m
 �[36;1m[ -f ".well-known/security.txt" ] && SECTXT=".well-known/security.txt"�[0m
 �[36;1m[ -f "security.txt" ] && SECTXT="security.txt"�[0m
 �[36;1mif [ -z "$SECTXT" ]; then�[0m
 �[36;1m  echo "::warning::No security.txt found."�[0m
 �[36;1m  exit 0�[0m
 �[36;1mfi�[0m
 �[36;1mgrep -q "^Contact:" "$SECTXT" || { echo "::error::Missing Contact field"; exit 1; }�[0m

GitHub Actions: Governance / governance _ Well-Known (RFC 9116 + RSR): actions.lock: list the lock-sync gate, and make the checker require coverage

Conclusion: failure

View job details

##[group]Run MIXED=$(grep -rE 'src="http://|href="http://' --include="*.html" --include="*.htm" . 2>/dev/null | grep -vE 'localhost|127\.0\.0\.1|example\.com|lol/|node_modules/|third-party/|vendor/' | head -5 || true)
 �[36;1mMIXED=$(grep -rE 'src="http://|href="http://' --include="*.html" --include="*.htm" . 2>/dev/null | grep -vE 'localhost|127\.0\.0\.1|example\.com|lol/|node_modules/|third-party/|vendor/' | head -5 || true)�[0m
 �[36;1mif [ -n "$MIXED" ]; then�[0m
 �[36;1m  echo "::error::Mixed content (HTTP in HTML)"�[0m

GitHub Actions: Governance / 5_governance _ Code quality + docs.txt: actions.lock: list the lock-sync gate, and make the checker require coverage

Conclusion: failure

View job details

##[group]Run editorconfig-checker/action-editorconfig-checker@840e866d93b8e032123c23bac69dece044d4d84c
 with:
   github-***REDACTED_SECRET_ASSIGNMENT***
   version: latest
 ##[endgroup]
 Find 'latest' release
 ##[error]Error: The binary 'ec-linux-amd64*' not found

GitHub Actions: Governance / governance _ Code quality + docs: actions.lock: list the lock-sync gate, and make the checker require coverage

Conclusion: failure

View job details

##[group]Run editorconfig-checker/action-editorconfig-checker@840e866d93b8e032123c23bac69dece044d4d84c
 with:
   github-***REDACTED_SECRET_ASSIGNMENT***
   version: latest
 ##[endgroup]
 Find 'latest' release
 ##[error]Error: The binary 'ec-linux-amd64*' not found

GitHub Actions: Governance / 6_governance _ Security policy checks.txt: actions.lock: list the lock-sync gate, and make the checker require coverage

Conclusion: failure

View job details

##[group]Run set -uo pipefail
 �[36;1mset -uo pipefail�[0m
 �[36;1mDIR=.github/canonical-references�[0m
 �[36;1mif [ ! -d "$DIR" ]; then�[0m
 �[36;1m  echo "ℹ️  [R5] no $DIR/ — skipped (repo has not opted in)"�[0m
 �[36;1m  exit 0�[0m
 �[36;1mfi�[0m
 �[36;1mif ! command -v python3 >/dev/null 2>&1; then�[0m
 �[36;1m  echo "❌ [R5] python3 missing on runner — required for YAML rule parsing"�[0m
 �[36;1m  exit 2�[0m
 �[36;1mfi�[0m
 �[36;1mpython3 - <<'PY'�[0m
 �[36;1mimport os, sys, glob, subprocess�[0m
 �[36;1mtry:�[0m
 �[36;1m    import yaml�[0m
 �[36;1mexcept ImportError:�[0m
 �[36;1m    sys.exit("❌ [R5] PyYAML not installed on runner; install python3-yaml")�[0m
 �[36;1m�[0m
 �[36;1mdir_ = ".github/canonical-references"�[0m
 �[36;1mfiles = sorted(glob.glob(f"{dir_}/*.yml") + glob.glob(f"{dir_}/*.yaml"))�[0m
 �[36;1mif not files:�[0m
 �[36;1m    print(f"ℹ️  [R5] {dir_}/ has no .yml/.yaml rules — skipped")�[0m
 �[36;1m    sys.exit(0)�[0m
 �[36;1m�[0m
 �[36;1mtotal = 0�[0m
 �[36;1mfor rf in files:�[0m
 �[36;1m    with open(rf, encoding="utf-8") as fh:�[0m
 �[36;1m        cfg = yaml.safe_load(fh)�[0m
 �[36;1m    if not isinstance(cfg, dict):�[0m
 �[36;1m        print(f"❌ [R5] {rf}: top-level must be a mapping"); total += 1; continue�[0m
 �[36;1m    rid  = cfg.get("id", os.path.basename(rf))�[0m
 �[36;1m    desc = cfg.get("description", "")�[0m
 �[36;1m    pats = cfg.get("patterns") or []�[0m
 �[36;1m    canon = cfg.get("canonical_pointer", "")�[0m
 �[36;1m    scope = (cfg.get("scope") or {})�[0m
 �[36;1m    includes = scope.get("include") or []�[0m
 �[36;1m    if not pats or not includes:�[0m
 �[36;1m        print(f"❌ [R5:{rid}] missing patterns or scope.include in {rf}")�[0m
 �[36;1m        total += 1; continue�[0m
 �[36;1m    # exclude self-references�[0m
 �[36;1m    skip = set(["CHANGELOG.md", "CHANGELOG.adoc", rf])�[0m
 �[36;1m    if canon: skip.add(canon)�[0m
 �[36;1m    rule_hits = 0�[0m
 �[36;1m    for f_ in includes:�[0m
 �[36;1m        if f_ in skip or not os...

GitHub Actions: Governance / governance _ Security policy checks: actions.lock: list the lock-sync gate, and make the checker require coverage

Conclusion: failure

View job details

##[group]Run set -uo pipefail
 �[36;1mset -uo pipefail�[0m
 �[36;1mDIR=.github/canonical-references�[0m
 �[36;1mif [ ! -d "$DIR" ]; then�[0m
 �[36;1m  echo "ℹ️  [R5] no $DIR/ — skipped (repo has not opted in)"�[0m
 �[36;1m  exit 0�[0m
 �[36;1mfi�[0m
 �[36;1mif ! command -v python3 >/dev/null 2>&1; then�[0m
 �[36;1m  echo "❌ [R5] python3 missing on runner — required for YAML rule parsing"�[0m
 �[36;1m  exit 2�[0m
 �[36;1mfi�[0m
 �[36;1mpython3 - <<'PY'�[0m
 �[36;1mimport os, sys, glob, subprocess�[0m
 �[36;1mtry:�[0m
 �[36;1m    import yaml�[0m
 �[36;1mexcept ImportError:�[0m
 �[36;1m    sys.exit("❌ [R5] PyYAML not installed on runner; install python3-yaml")�[0m
 �[36;1m�[0m
 �[36;1mdir_ = ".github/canonical-references"�[0m
 �[36;1mfiles = sorted(glob.glob(f"{dir_}/*.yml") + glob.glob(f"{dir_}/*.yaml"))�[0m
 �[36;1mif not files:�[0m
 �[36;1m    print(f"ℹ️  [R5] {dir_}/ has no .yml/.yaml rules — skipped")�[0m
 �[36;1m    sys.exit(0)�[0m
 �[36;1m�[0m
 �[36;1mtotal = 0�[0m
 �[36;1mfor rf in files:�[0m
 �[36;1m    with open(rf, encoding="utf-8") as fh:�[0m
 �[36;1m        cfg = yaml.safe_load(fh)�[0m
 �[36;1m    if not isinstance(cfg, dict):�[0m
 �[36;1m        print(f"❌ [R5] {rf}: top-level must be a mapping"); total += 1; continue�[0m
 �[36;1m    rid  = cfg.get("id", os.path.basename(rf))�[0m
 �[36;1m    desc = cfg.get("description", "")�[0m
 �[36;1m    pats = cfg.get("patterns") or []�[0m
 �[36;1m    canon = cfg.get("canonical_pointer", "")�[0m
 �[36;1m    scope = (cfg.get("scope") or {})�[0m
 �[36;1m    includes = scope.get("include") or []�[0m
 �[36;1m    if not pats or not includes:�[0m
 �[36;1m        print(f"❌ [R5:{rid}] missing patterns or scope.include in {rf}")�[0m
 �[36;1m        total += 1; continue�[0m
 �[36;1m    # exclude self-references�[0m
 �[36;1m    skip = set(["CHANGELOG.md", "CHANGELOG.adoc", rf])�[0m
 �[36;1m    if canon: skip.add(canon)�[0m
 �[36;1m    rule_hits = 0�[0m
 �[36;1m    for f_ in includes:�[0m
 �[36;1m        if f_ in skip or not os...
🔇 Additional comments (2)
scripts/check-lock-sync.sh (1)

217-243: LGTM!

Also applies to: 281-291

.github/workflows/lock-sync-gate.yml (1)

23-23: LGTM!


📝 Summary

Summary by CodeRabbit

  • Chores
    • Added support for manually running the lock synchronisation check.
    • Improved validation to ensure every workflow is represented in the lock file, including workflows without external actions.
    • Updated validation guidance and success messages to reflect the broader coverage.

Walkthrough

The lock synchronisation gate can run manually. The checker now requires every workflow file to have an actions.lock key, including workflows with no uses: references.

Changes

Lock synchronisation gate

Layer / File(s) Summary
Workflow coverage validation
scripts/check-lock-sync.sh
The script detects unlisted workflows, reports their paths, exits with status 1, and provides repair guidance for zero-uses workflows.
Manual gate execution
.github/workflows/lock-sync-gate.yml
The workflow adds the workflow_dispatch trigger.

Priority: ⬇️ Low

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix

Merge Risk: ⚪ Minimal · up to 6a491

The lock synchronisation gate covers the intended workflows and can be run manually, with no established merge-blocking risk.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the lockfile entry and the checker coverage requirement, which are the main changes in the pull request.
Description check ✅ Passed The description directly explains the missing lockfile coverage, the new coverage clause, the workflow dispatch support, and the verification results.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 1…
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Commit to this branch
  • Create a new PR
📝 Generate docstrings

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

A rabbit checks each workflow path
Empty lists now count in the math
The gate can run by hand
Missing keys are clearly planned
Lock sync stays on track

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

@coderabbitai

coderabbitai Bot commented Sep 22, 2026 •

Copy link
Copy Markdown

✅ Coding Agent task started: View task and status

The task will inspect the CI failures, validate its fix, and commit the fix to this branch automatically.

Note: Fixing CI failures is a beta feature and may encounter errors. Expect some limitations and changes as we gather feedback and continue to improve it.

⏭️ 1 check(s) skipped — already failing on `main` (not caused by this PR)
  • GitHub Actions: Workflow Security Linter / 0_lint-workflows.txt

@coderabbitai

coderabbitai Bot commented Sep 22, 2026 •

Copy link
Copy Markdown

@hyperpolymath
hyperpolymath merged commit f02b589 into main Sep 22, 2026
19 of 22 checks passed
@hyperpolymath
hyperpolymath deleted the fix/lock-coverage branch September 22, 2026 21:10
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