Skip to content

CI cannot AI-review a workflow-touching PR, but its required check still reports SUCCESS #116

Description

@twistedmelonman

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:

  1. 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".
  2. 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.
  3. 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).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions