Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .claude-review-ignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
# One per line: owner/repo
# Lines starting with # are comments. Blank lines are ignored.
#
# The audit script (claude-review-audit.sh) skips these repos entirely.
# Use this for repos that should never have the review installed.
# Historical: the audit script that read this file was retired in #154.
# Only the broken nightowl-ruleset-rollout.sh.broken still names it.

nightowlstudiollc/networth-agent
smartwatermelon/headroom
6 changes: 6 additions & 0 deletions .github/workflows/claude-blocking-review.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
name: Claude Blocking Review

# DEPRECATED (smartwatermelon/github-workflows#154). Do not delete while any caller exists.

# Callers left: smartwatermelon/crazy-larry, nightowlstudiollc/networth-agent.

# Both still require its check. The kebab-tax repos may also call it.

# Reusable workflow: blocks PR merges when Claude finds bugs, reliability
# regressions, security issues, or data-loss risks.
#
Expand Down
3 changes: 1 addition & 2 deletions .github/workflows/dependabot-auto-merge.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,7 @@ name: Dependabot Auto-Merge
# out PR code here would expose those secrets to malicious dependency
# PRs (see the Ultralytics, nx, and tj-actions incidents). This
# invariant is also enforced by a CI guardrail — see self-review.yml's
# `guard-no-checkout` job in this repo, and the read-only fleet-wide
# check in claude-review-audit.sh. Closes #64.
# `guard-no-checkout` job in this repo. Closes #64.
#
# Callers MUST NOT use `secrets: inherit`. This workflow needs no
# secrets beyond the ambient `GITHUB_TOKEN` it mints itself — it does
Expand Down
42 changes: 5 additions & 37 deletions .github/workflows/self-review.yml
Original file line number Diff line number Diff line change
@@ -1,49 +1,17 @@
name: Self-Review

# Self-applying caller: runs this repo's reusable Claude Blocking Review
# workflow on its own PRs. Produces the `claude-review / run-review` status
# check that branch protection requires on main.
#
# Uses a local path (./.github/workflows/claude-blocking-review.yml) rather
# than a tag, so PR branches dogfood the proposed changes to the reusable
# workflow against themselves before release.
#
# Replaces the .github/workflows/claude-code-review.yml caller that was
# deleted in commit 52e688b during the v1 rename.
# Repo-local guardrails run on this repo's own PRs.

# The self-applying Claude review caller was removed in #154.

on:
pull_request:
types: [opened, synchronize, ready_for_review, reopened]

jobs:
claude-review:
permissions:
contents: read
pull-requests: write
issues: write
id-token: write
uses: ./.github/workflows/claude-blocking-review.yml
with:
pr_number: ${{ github.event.pull_request.number }}
extra_instructions: |
This repository hosts the reusable `claude-blocking-review.yml`
workflow itself. Pay particular attention to:
- Shell-injection risk in any step that interpolates PR data
- Changes to the verdict file / comment parsing contract that
consumer repos depend on
- Changes to allowed-tools that could broaden what Claude can run
- Grep/regex changes in the escape-hatch path (see #38 history)
secrets:
claude_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}

guard-no-checkout:
# Plain-shell job, no LLM call involved — deliberately NOT a step
# inside claude-review above (that job is `uses:
# ./.github/workflows/claude-blocking-review.yml`; a job is either a
# reusable-workflow call or a normal job with steps, not both) and
# deliberately not folded into the Claude review prompt (that job
# skips workflow-self-modification PRs, which is exactly the PR
# category this guardrail exists to check). Closes #64.
# Plain-shell job, no LLM call involved. Guards the
# dependabot-auto-merge.yml no-checkout invariant. Closes #64.
runs-on: ubuntu-latest
permissions:
contents: read
Expand Down
84 changes: 12 additions & 72 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,13 @@

Reusable GitHub Actions workflows.

## `claude-blocking-review`
## `claude-blocking-review` (DEPRECATED)

> **Deprecated (#154).** Do not add this to new repos. Use
> `standards-check.yml` instead. The file stays only because
> `smartwatermelon/crazy-larry` and `nightowlstudiollc/networth-agent` still
> require its check, as may the kebab-tax repos. Do not delete it while any
> caller exists. The bulk-install and audit scripts are retired.

Runs a Claude Code Review on every PR and **blocks merges** when Claude finds
bugs, reliability regressions, security vulnerabilities, or data-loss risks.
Expand Down Expand Up @@ -355,16 +361,11 @@ incidents (Ultralytics, nx, tj-actions) when combined with a checkout
of PR-controlled code. This workflow is safe today because it never
executes PR code: the only actions are API calls (`dependabot/fetch-metadata`,
`gh pr review`, `gh pr merge`). **`actions/checkout` must never be added
to this file.** Two guardrails enforce this (closes #64):
to this file.** The guardrail below enforces this (closes #64):

- `self-review.yml`'s `guard-no-checkout` job greps this repo's own
copy of `dependabot-auto-merge.yml` and fails the PR if
`actions/checkout` appears.
- `claude-review-audit.sh` performs a read-only, fleet-wide check: any
caller stub referencing `dependabot-auto-merge.yml` that contains
`actions/checkout` or `secrets: inherit` is flagged in the audit
report. This check does not block or gate anything — it's audit-only,
same as the rest of that script.

### Versioning

Expand Down Expand Up @@ -672,76 +673,15 @@ are not compatible with this reusable workflow.

---

## Audit script

`claude-review-audit.sh` audits Claude Review configuration across all
non-archived repos under `smartwatermelon` and `nightowlstudiollc`. Read-only —
reports gaps but makes no changes.

```bash
./claude-review-audit.sh [--verbose]
```

Requires: `gh` CLI (authenticated), `jq`, `bash` 4.0+.

### Excluding repos

Add repos to `.claude-review-ignore` (one `owner/repo` per line) to skip them
in audits. Useful for repos that should never have the review installed.

---

## Bulk-install script (`smartwatermelon` only)

`bulk-install-claude-review.sh` installs (or refreshes) the
`claude-blocking-review` caller workflow across all non-archived repos under
`smartwatermelon`. Workaround for the fact that GitHub's workflow-templates
picker is **organization-only** — `smartwatermelon` is a user account, so
the templates in `smartwatermelon/.github/workflow-templates/` never appear
in the "New workflow" picker for `smartwatermelon/*` repos.

```bash
./bulk-install-claude-review.sh # dry-run (default)
./bulk-install-claude-review.sh --apply # open PRs
./bulk-install-claude-review.sh --only smartwatermelon/foo --apply
```

The script classifies each repo:

| Class | Action |
| ------- | -------- |
| `CURRENT` | Already on the target version. No-op. |
| `STALE` | Different pin or floating tag. Opens a PR bumping the pin. |
| `MISSING` | No caller workflow at all. Opens a PR adding the canonical stub. |
| `CUSTOMIZED` | Has caller-side modifications (`paths-ignore`, `extra_instructions`, custom `model`/`timeout_minutes`, etc.). Skipped regardless of pin — flag for human review. |
| `LOCAL` | Uses a local-path reference (`./...`). Not bumpable; e.g. the `github-workflows` repo's own self-review. |

Target version is derived dynamically from the `@v…` pin in
`smartwatermelon/.github/workflow-templates/claude-blocking-review.yml`,
so a PR bumping that template is the single trigger to roll a new version
across the fleet.

PRs include `[skip-claude-review: bulk-install]` in the body so the
blocking-review workflow doesn't gate its own install/bump PR.

For `nightowlstudiollc`, this script is intentionally not used — that org gets
the workflow-templates picker via [`nightowlstudiollc/.github`](https://github.com/nightowlstudiollc/.github)
(mirrors `smartwatermelon/.github` workflow-templates; verified appearing under
"By Night Owl Studio" in the Actions → New workflow UI). Repository Rulesets
for org-wide enforcement were attempted once and rolled back (see
`docs/plans/2026-04-30-required-workflows-nightowlstudiollc.md`); a
re-attempt is deliberately not planned here and would need its own review
given that history.

## New-repo bootstrap script (`smartwatermelon` only)

`new-smartwatermelon-repo.sh` is the creation-time counterpart to the
bulk-install script above — for a genuinely *new* `smartwatermelon` repo,
rather than retrofitting an existing one. `smartwatermelon` being a User
`new-smartwatermelon-repo.sh` is the creation-time script for a
genuinely *new* `smartwatermelon` repo (the old fleet bulk-install script
is retired). `smartwatermelon` being a User
account means it can't use GitHub's org-only workflow-templates picker
*or* Repository Rulesets to auto-attach anything on repo creation, so this
script is the closest available approximation: one command instead of
"create repo, then remember to run the bulk-install script, then remember
"create repo, then remember to install the workflows, then remember
the one repo setting no template can seed."

```bash
Expand Down
Loading
Loading