Summary
claude-code-action refuses to run on any PR that touches .github/workflows/. The claude-review job handles this by skipping the review step — but the job still reports SUCCESS, and on most repos claude-review / run-review is a required check.
So a PR that modifies CI workflows passes its required AI review having reviewed nothing.
Observed
smartwatermelon/github-workflows#165, run 34550692109:
DOC_SKIP: true
DOC_SKIP_REASON: workflow-self-modification
##[notice] PR modifies .github/workflows/ (.github/workflows/claude-assistant.yml)
— claude-code-action refuses to run by design. Skipping; real review
will run on the next non-workflow PR after merge.
Step timings for that job:
| Step |
Result |
| 5. Check for doc-only diff |
success |
| 10. Run Claude Code Review |
skipped |
| 13. Check review verdict |
success |
Job conclusion: success. Elapsed: 7 seconds (01:26:53 → 01:26:58).
For contrast, a genuine review on the same workflow — claude-config run 34551173017 — spends 96 seconds in step 10 (01:34:02 → 01:35:38). The 7s/96s gap is the tell.
That PR changed run-standards.sh, a reusable workflow, and a test file. None of it was AI-reviewed in CI.
Why the skip itself is correct
The underlying refusal is a sound security boundary: a PR that can modify the workflow reviewing it could neutralise its own review. claude-code-action declining is right, and this issue is not a request to bypass it.
What is wrong
Three things, in order of severity:
- A required check reports SUCCESS without performing its function. This is the false-OK shape that has bitten repeatedly in this fleet (see the false-OK pattern notes). Green means "reviewed and passed" everywhere else; here it means "not reviewed".
- The deferral does not do what it says. "Real review will run on the next non-workflow PR after merge" reviews a different diff, after the risky change has already landed on
main. The workflow change is never reviewed, by anything, ever.
- The blind spot is exactly inverted. The class of change most worth reviewing — CI/CD plumbing, permissions, triggers, secrets handling — is precisely the class CI structurally cannot review.
Relationship to the CI-deterministic decision
This is independent support for the decision recorded at docs/STATUS.md:203 ("No judgment reviewer stays in CI"), on structural rather than cost grounds.
Local hooks have no such constraint. #165's workflow diff was reviewed locally — code-reviewer and adversarial-reviewer both PASS, plus a codebase-mode review — because local review reads the diff directly instead of running inside the permission boundary the change would alter.
Options
- A — Fold into W3 and drop it. Once
standards-check is required and claude-blocking-review.yml is removed, this disappears with it. Zero extra work; the gap persists until W3 lands.
- B — Fail the check instead of passing it. Make the workflow-self-modification path report failure (or neutral, where branch protection accepts it), forcing a human to acknowledge the change went unreviewed. Honest, but noisy on every workflow PR, and neutral-vs-failure interacts with required-check config per repo.
- C — Surface it without gating. Keep SUCCESS but post a PR comment naming the unreviewed files, so the reviewer knows. Cheapest; relies on someone reading it.
Recommend A, with C as a stopgap if W3 slips — the gap is real but its window is bounded by work already planned.
Verification notes
DOC_SKIP_REASON: workflow-self-modification was read from the run log, not inferred from the step name.
- The skip is specific to workflow-touching PRs. It is not universal: the same workflow performed a real 96-second review on a non-workflow PR in the same hour.
- No evidence of token/session limits in these runs — the
Verify CLAUDE_CODE_OAUTH_TOKEN is configured step passes wherever it executes. A separate concern about session-limited tokens was raised but is not what this run shows.
Found while investigating standards-check failure rates (github-workflows#165, dev-env#115).
Summary
claude-code-actionrefuses to run on any PR that touches.github/workflows/. Theclaude-reviewjob handles this by skipping the review step — but the job still reports SUCCESS, and on most reposclaude-review / run-reviewis a required check.So a PR that modifies CI workflows passes its required AI review having reviewed nothing.
Observed
smartwatermelon/github-workflows#165, run 34550692109:Step timings for that job:
Job conclusion:
success. Elapsed: 7 seconds (01:26:53 → 01:26:58).For contrast, a genuine review on the same workflow —
claude-configrun 34551173017 — spends 96 seconds in step 10 (01:34:02 → 01:35:38). The 7s/96s gap is the tell.That PR changed
run-standards.sh, a reusable workflow, and a test file. None of it was AI-reviewed in CI.Why the skip itself is correct
The underlying refusal is a sound security boundary: a PR that can modify the workflow reviewing it could neutralise its own review.
claude-code-actiondeclining is right, and this issue is not a request to bypass it.What is wrong
Three things, in order of severity:
main. The workflow change is never reviewed, by anything, ever.Relationship to the CI-deterministic decision
This is independent support for the decision recorded at
docs/STATUS.md:203("No judgment reviewer stays in CI"), on structural rather than cost grounds.Local hooks have no such constraint.
#165's workflow diff was reviewed locally —code-reviewerandadversarial-reviewerboth PASS, plus a codebase-mode review — because local review reads the diff directly instead of running inside the permission boundary the change would alter.Options
standards-checkis required andclaude-blocking-review.ymlis removed, this disappears with it. Zero extra work; the gap persists until W3 lands.Recommend A, with C as a stopgap if W3 slips — the gap is real but its window is bounded by work already planned.
Verification notes
DOC_SKIP_REASON: workflow-self-modificationwas read from the run log, not inferred from the step name.Verify CLAUDE_CODE_OAUTH_TOKEN is configuredstep passes wherever it executes. A separate concern about session-limited tokens was raised but is not what this run shows.Found while investigating standards-check failure rates (
github-workflows#165,dev-env#115).