Skip to content

feat(compliance-audit): detect non-stub centralized workflow copies#89

Merged
don-petry merged 3 commits intomainfrom
feat/compliance-audit-stub-detection
Apr 8, 2026
Merged

feat(compliance-audit): detect non-stub centralized workflow copies#89
don-petry merged 3 commits intomainfrom
feat/compliance-audit-stub-detection

Conversation

@don-petry
Copy link
Copy Markdown
Contributor

@don-petry don-petry commented Apr 8, 2026

Summary

Closes the loop on the workflow centralization effort started in #87 (build reusables) and #88 (pin to v1, document tiers). Now that the canonical stubs exist and are versioned, the weekly compliance audit can detect when a downstream repo carries an inline copy or a stale @main/@v0 reference instead of the v1 stub.

What the check does

Adds check_centralized_workflow_stubs to scripts/compliance-audit.sh and wires it into the per-repo audit loop. For each Tier 1 workflow (claude.yml, dependency-audit.yml, dependabot-automerge.yml, dependabot-rebase.yml, agent-shield.yml, feature-ideation.yml):

  • If the file is missing → no finding (already covered by check_required_workflows)
  • If the file contains uses: petry-projects/.github/.github/workflows/<reusable>.yml@v1 → compliant
  • If it references the reusable but with a different ref → "not pinned to @v1"
  • If it references the reusable but the line is malformed → "uses: line does not match canonical stub"
  • Otherwise → "is an inline copy — re-sync from standards/workflows/<file>"

The central .github repo is exempt because it owns the reusables.

Test plan

  • bash -n and shellcheck clean
  • Hand-fixture unit test in /tmp covering:
    • stub@v1 → no finding
    • stub@main → flagged with @v1 message
    • inline copy → flagged with inline message
    • missing file → no finding
  • CI on this branch
  • After merge: the next scheduled audit run will surface real findings across the 8 downstream repos that haven't yet adopted the v1 stubs — that's the input to the sweep work.

Why this matters

Without this check, the centralization is best-effort: a future agent could copy an old inline workflow into a new repo and nobody would notice until something broke. With it, drift is detected at the next audit run and surfaced as a remediation issue with a precise fix instruction (re-sync from the named template).

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Chores
    • Added automated compliance validation for workflow configurations to ensure adherence to organizational standards.

Adds a new check to compliance-audit.sh that flags downstream repos
whose Tier 1 workflows are not the canonical thin caller stubs pinned
to @v1. For each centralizable workflow (claude, dependency-audit,
dependabot-{automerge,rebase}, agent-shield, feature-ideation), the
check distinguishes three failure modes for actionable findings:

  1. Inline copy of pre-centralization logic
     → "is an inline copy instead of a thin caller stub"
  2. References the reusable but not pinned to @v1 (e.g. @main, @v0)
     → "references the reusable but is not pinned to @v1"
  3. Some other malformed uses: line
     → "the uses: line does not match the canonical stub"

The central .github repo is exempt because it owns the reusables and
may legitimately reference them by @main during release preparation.

Verified locally with hand-crafted fixtures: stub@v1 → no finding,
stub@main → flagged with the @v1 message, inline copy → flagged with
the inline message, missing file → no finding (handled by
check_required_workflows).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings April 8, 2026 03:25
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 8, 2026

Warning

Rate limit exceeded

@don-petry has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 4 minutes and 4 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 4 minutes and 4 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 1d2faa79-fed3-40cd-9e62-b2091a13c7ac

📥 Commits

Reviewing files that changed from the base of the PR and between 6377c8a and da30f52.

📒 Files selected for processing (1)
  • scripts/compliance-audit.sh
📝 Walkthrough

Walkthrough

Adds a new compliance check function check_centralized_workflow_stubs() to scripts/compliance-audit.sh that validates Tier-1 workflow files properly delegate to centralized reusable workflows using the canonical pattern uses: petry-projects/.github/.github/workflows/<reusable>.yml@v1.

Changes

Cohort / File(s) Summary
Compliance Audit Check
scripts/compliance-audit.sh
Added check_centralized_workflow_stubs() function that fetches and validates Tier-1 workflow files contain proper delegation patterns to centralized reusables. Reports specific findings for missing @v1 pinning, deviations from canonical stub, or inline copies. Integrated function call into main() after existing Claude workflow check.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly and specifically describes the main change: detecting non-stub centralized workflow copies is the primary purpose of the new check_centralized_workflow_stubs function added to the compliance audit script.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/compliance-audit-stub-detection

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

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@scripts/compliance-audit.sh`:
- Around line 524-525: The grep pattern used to test decoded for
"petry-projects/.github/.github/workflows/${reusable}" uses unescaped dots so
BRE's dot will match any character; update the check in
scripts/compliance-audit.sh that uses echo "$decoded" | grep -q
"petry-projects/.github/.github/workflows/${reusable}" to perform a literal
match (either escape the dots as \\.github or switch grep to fixed-string mode
with -F) so the path is matched exactly against the variable ${reusable}.
🪄 Autofix (Beta)

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: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 7f7dc496-5c21-4111-bb30-fafbe4b680c8

📥 Commits

Reviewing files that changed from the base of the PR and between 6ba1b56 and 6377c8a.

📒 Files selected for processing (1)
  • scripts/compliance-audit.sh

Comment thread scripts/compliance-audit.sh Outdated
CodeRabbit on #89: the second-branch grep used an unescaped
"petry-projects/.github/.github/workflows/${reusable}" pattern,
where BRE dots could in principle match any character. Switch to
\`grep -F\` (fixed-string) to match the path literally. No real-world
false positive observed (workflow paths contain literal dots), but
the hygiene is right.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR extends the weekly scripts/compliance-audit.sh to detect drift from the org’s Tier 1 “centralized workflow” model by checking that downstream repos use the canonical thin caller stubs pinned to @v1 (and flagging inline copies or non-@v1 refs).

Changes:

  • Added check_centralized_workflow_stubs to validate Tier 1 workflow stubs reference petry-projects/.github reusables at @v1.
  • Wired the new check into the per-repo audit loop in main().

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread scripts/compliance-audit.sh Outdated
Comment thread scripts/compliance-audit.sh Outdated
Comment thread scripts/compliance-audit.sh
Comment thread scripts/compliance-audit.sh Outdated
Address remaining Copilot review feedback on #89:

1. Anchor the \`uses:\` regex to start-of-line + optional indent
   (\`^[[:space:]]*uses:\`) so a commented \`# uses: ...@v1\` line
   cannot fool the check into marking an inline workflow as compliant.
   Verified with a fixture: a workflow whose only mention of @v1 is in
   a YAML comment is now correctly flagged.

2. List \`.github/workflows/\` once per repo and short-circuit the
   per-file check when the workflow isn't present, instead of probing
   each of the six centralized files individually. Cuts up to 5 wasted
   gh api calls per repo (worst case ~2500 fewer requests across the
   org per audit run).

3. Drop the misleading "missing workflow caught by check_required_workflows"
   comment — only some of the six are required (claude, dependency-audit,
   dependabot-automerge, agent-shield); dependabot-rebase and feature-ideation
   are intentionally optional/conditional. The new directory-listing
   short-circuit handles all of these uniformly.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud Bot commented Apr 8, 2026

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.

2 participants