Skip to content

feat(standards): add a scheduled org-wide conformance sweep - #43

Open
WomB0ComB0 wants to merge 3 commits into
mainfrom
feat/org-conformance-sweep
Open

feat(standards): add a scheduled org-wide conformance sweep#43
WomB0ComB0 wants to merge 3 commits into
mainfrom
feat/org-conformance-sweep

Conversation

@WomB0ComB0

@WomB0ComB0 WomB0ComB0 commented Aug 4, 2026

Copy link
Copy Markdown
Member

The hole this closes

repo-standards.yml (#42) catches drift on the PR that introduces it. It cannot catch a repo that already drifted and simply is not being touched — which is exactly how four repos ended up with a security scan that had never run once. Nobody had opened a PR against them since the day it broke.

This runs the same checks against every non-archived repo weekly, read-only, reporting a job summary.

It found a repo the manual pass missed

Verified against the live org — 21 repos:

repo finding
resQ uses zima without actionlint declaring it (fix pending in resQ#722)
scripts UNREADABLE — token lacks access; not assessed
vcpkg security.yml missing actions: read (startup_failure)

vcpkg is a fifth repo whose security workflow has never run — startup_failure on every run back to July. I missed it in the manual sweep because I only sampled repos I already knew about. That is the entire argument for automating this.

Three things learned by running it, not reasoning about it

1. Unreadable ≠ clean. GITHUB_TOKEN cannot read sibling repos. A naive sweep would report every repo as passing. Unreadable repos are now an explicit finding and count toward the failure gate — silence must never be mistaken for conformance, which is the same failure mode these checks exist to catch.

2. The first run aborted having assessed nothing, and exited 0-ish. head -1 / grep -m1 in a pipe close it early, the upstream writer takes SIGPIPE, and under set -o pipefail the whole script dies — exit 141, empty summary. Now sliced with parameter expansion, and no-match greps tolerate their exit 1.

3. A false positive in the already-merged check. #42 matched zima anywhere in a runs-on: line, including the dynamic toggle:

runs-on: <expression> USE_SELF_HOSTED ... fromJSON('["self-hosted",...,"zima"]') ... ubuntu-latest

actionlint cannot evaluate that expression, so it never errors on it — which is why landing passes today despite not declaring the label. Only the literal array form (runs-on: [self-hosted, linux, x64, zima]) trips it. landing was being flagged for a problem it does not have. Both the sweep and repo-standards.yml now match the literal form only.

Setup required

Needs an ORG_READ_TOKEN secret — fine-grained, org-wide, Contents: Read. Without it the sweep honestly reports every repo as UNREADABLE rather than falsely green.

Verification

  • actionlint clean on both files (it shellchecks the run: blocks)
  • Fixture suite re-run after narrowing the check: known-bad still 4/4 caught, known-good still 0, actionlint.yaml-present-but-missing-label still caught
  • Live org run: 21 scanned, 2 findings, 1 unreadable — and landing correctly no longer flagged

Summary by CodeRabbit

  • New Features

    • Added scheduled and manually triggered conformance checks across active repositories.
    • Reports configuration findings, unreadable repositories, and overall results in workflow summaries.
    • Manual runs can optionally fail when issues are detected.
  • Bug Fixes

    • Improved runner-label validation to recognize only explicit array-based declarations, avoiding incorrect findings from dynamic configuration.
    • Continued validation of workflow configuration through actionlint.

repo-standards catches drift on the PR that introduces it. It cannot catch a
repo that already drifted and simply is not being touched — which is exactly
how four repos ended up with a security scan that had never run once. Nobody
had opened a PR against them since the day it broke.

Runs the same checks against every non-archived repo weekly and reports a job
summary. Read-only.

Two things learned by actually running it:

  * A repo the token cannot read must be reported as UNREADABLE, never as
    clean. Silence is not conformance — that is the same failure mode the
    checks exist to catch, and it would be self-inflicted.

  * `head -1` and `grep -m1` in a pipe close it early, the upstream writer
    takes SIGPIPE, and under `set -o pipefail` the whole sweep aborts with
    exit 141 having assessed nothing. First run did precisely that. Sliced
    with parameter expansion instead, and no-match greps now tolerate their
    exit 1.

Also fixes a false positive in the merged repo-standards check: it matched
`zima` anywhere in a runs-on line, including the dynamic USE_SELF_HOSTED
toggle. That form embeds the label in an expression actionlint cannot
evaluate, so it never errors there — landing was being flagged for a problem
it does not have. Both now match only the literal array form.

Verified against the live org: 21 repos scanned, and it found vcpkg — a fifth
repo whose security workflow has been startup_failure since July, which the
manual pass missed entirely because it only sampled known repos.
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@WomB0ComB0, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 18 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 821fc307-8503-43d7-bc1e-14fbfa9afc93

📥 Commits

Reviewing files that changed from the base of the PR and between 376dcac and a38d034.

📒 Files selected for processing (1)
  • .github/workflows/org-conformance-sweep.yml
📝 Walkthrough

Walkthrough

The pull request adds a scheduled and manually triggered organization-wide conformance sweep. It checks repository workflows and configuration, reports findings, optionally fails the job, and narrows zima runner detection in repository standards.

Changes

Conformance validation

Layer / File(s) Summary
Sweep setup and repository discovery
.github/workflows/org-conformance-sweep.yml
The workflow lists non-archived repositories, retrieves workflow files through the GitHub API, handles unreadable repositories, and initializes the summary.
Repository conformance checks
.github/workflows/org-conformance-sweep.yml, .github/workflows/repo-standards.yml
The checks validate security permissions, Dependabot lockfile patterns, compiler versions, and zima runner declarations.
Findings summary and failure gating
.github/workflows/org-conformance-sweep.yml
The workflow reports findings and totals, tracks affected repositories, and optionally exits with failure when findings or unreadable repositories exist.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Scheduler
  participant ConformanceSweep
  participant GitHubAPI
  participant Repository
  Scheduler->>ConformanceSweep: Trigger weekly or manually
  ConformanceSweep->>GitHubAPI: List non-archived repositories
  GitHubAPI->>ConformanceSweep: Return repository list
  ConformanceSweep->>GitHubAPI: Fetch workflow and configuration files
  GitHubAPI->>Repository: Read repository contents
  Repository->>ConformanceSweep: Return files or readability errors
  ConformanceSweep->>ConformanceSweep: Validate repository conventions
  ConformanceSweep->>Scheduler: Publish summary, warnings, and optional failure
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the added scheduled organization-wide conformance sweep.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/org-conformance-sweep

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/org-conformance-sweep.yml:
- Around line 101-104: Update the security.yml validation in the sweep script to
detect org reusable-workflow calls and evaluate the caller’s effective
permissions using the same caller-scoped check as repo-standards.yml. Report no
finding only when either the calling job’s permissions or the workflow-level
permissions grant actions: read; otherwise retain the existing security.yml
finding.
- Line 50: Update the workflow’s GH_TOKEN configuration before repository
discovery so the sweep requires ORG_READ_TOKEN and does not fall back to
github.token. Fail the workflow configuration or otherwise stop the sweep when
ORG_READ_TOKEN is absent, ensuring gh repo list cannot perform a partial
discovery that produces a clean summary.
- Around line 72-73: Update the repository enumeration command in the workflow’s
repos assignment to use a limit of 1000 instead of 200, ensuring all
non-archived organization repositories are included while preserving the
existing JSON extraction and sorting.
- Around line 67-70: The ls_workflows() readability check currently treats a
GitHub 404 for a missing .github/workflows directory as an unreadable
repository. Update ls_workflows() and its caller to distinguish a missing
directory from genuine API or permission failures, returning an empty workflow
list for 404 while preserving unreadable classification for other failures; use
a read-only contents endpoint.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 5bd89f81-a97c-4f88-a999-90d0dc330261

📥 Commits

Reviewing files that changed from the base of the PR and between 0cc17c4 and 376dcac.

📒 Files selected for processing (2)
  • .github/workflows/org-conformance-sweep.yml
  • .github/workflows/repo-standards.yml

Comment thread .github/workflows/org-conformance-sweep.yml
Comment thread .github/workflows/org-conformance-sweep.yml
Comment thread .github/workflows/org-conformance-sweep.yml Outdated
Comment thread .github/workflows/org-conformance-sweep.yml Outdated
`scripts` is intentionally out of reach, so the sweep reported it UNREADABLE
on every run. A weekly report that cries wolf is one people stop reading —
which is the same failure mode these checks exist to prevent, just self
inflicted.

Adds a `skip-repos` input defaulting to `scripts`. Scheduled runs pass no
inputs, so the default is applied in `env:` too. Forwarded through env rather
than inlined into the shell, matching the pattern the other workflows use.

Verified live: 20 repos scanned, scripts skipped, 0 unreadable, 2 findings —
resQ (pending resQ#722) and vcpkg (pending vcpkg#34).
Every one of these could report a repo as fine when it is not — the failure
mode this sweep exists to prevent.

Readability was tested by listing .github/workflows, but a repo without that
directory returns 404, which is indistinguishable from an access failure by
exit status alone. `scripts` was being reported UNREADABLE while being
perfectly readable — it simply has no workflows. Readability is now established
against the repo object, and a missing directory means "no workflows".

That also removes the need for the skip-repos default added a commit ago:
scripts now scans clean on its own. The input stays as an escape hatch but
defaults to empty — a repo suppressed there is a repo nobody is checking.

The actions: read check was the loose file-wide grep, i.e. the exact bug caught
in repo-standards during #42 review and fixed there. I had copied the pre-fix
version into the sweep. It now uses the same caller-scoped awk, so a workflow
whose caller job overrides permissions without actions: read is caught.

A failed or partial `gh repo list` silently produced a short sweep that read as
all-clean. It now errors out, including when enumeration returns fewer than two
repos, which is the signature of GITHUB_TOKEN being used without
ORG_READ_TOKEN. Limit raised 200 -> 1000.

Verified live with and without skip-repos: 21 repos scanned, 0 unreadable,
2 findings (resQ pending resQ#722, vcpkg pending vcpkg#34).
@WomB0ComB0

Copy link
Copy Markdown
Member Author

All four correct — and one of them proved a claim in this PR wrong

The 404 finding was the important one, and it invalidated something I asserted. I had reported scripts as UNREADABLE and told the maintainer the token lacked access. It does not:

$ gh api /repos/resq-software/scripts --jq .name        # readable
scripts
$ gh api /repos/resq-software/scripts/contents/.github/workflows
404

scripts is perfectly readable — it simply has no .github/workflows directory, and my readability probe could not tell a missing path from an access failure. Readability is now established against the repo object, and a missing directory means "no workflows".

That also removes the need for the skip-repos default I had added a commit earlier to silence it. With the bug fixed, scripts scans clean on its own. The input stays as an escape hatch but now defaults to empty — a repo suppressed there is a repo nobody is checking, and I would rather not ship a lever that hides findings by default.

The actions: read check was the loose file-wide grep — the same bug you caught in repo-standards.yml during #42 review. I fixed it there and then copied the pre-fix version into this sweep. It now uses the identical caller-scoped awk, so a workflow whose caller job overrides permissions without actions: read is caught.

Enumeration failures read as all-clean. Fixed: it now errors out, and additionally errors when enumeration returns fewer than two repos, which is the signature of GITHUB_TOKEN being used without ORG_READ_TOKEN. Limit raised 200 → 1000.

Verification

Run live against the org both with and without skip-repos:

Scanned 21 repos — 2 with findings, 0 unreadable
| resQ  | uses `zima` without actionlint declaring it |
| vcpkg | security.yml caller job lacks effective `actions: read` |

scripts now scans and produces no finding. Both remaining findings have fixes in flight (resQ#722, vcpkg#34).

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