Skip to content

Migrate PR review workflows to Morrison-Lab/gha's claude-code-review.yml@v2 - #110

Merged
d-morrison merged 6 commits into
mainfrom
chore/gha-review-workflows
Aug 24, 2026
Merged

Migrate PR review workflows to Morrison-Lab/gha's claude-code-review.yml@v2#110
d-morrison merged 6 commits into
mainfrom
chore/gha-review-workflows

Conversation

@d-morrison

@d-morrison d-morrison commented Aug 24, 2026

Copy link
Copy Markdown
Member

Closes #101

Replaces this repo's two hand-rolled PR-review workflows with a single caller stub for Morrison-Lab/gha's reusable claude-code-review.yml@v2.

Before After
Files claude-code-review.yml + claude-review-comment.yml claude-code-review.yml only
Calls anthropics/claude-code-action@v1 directly, twice Morrison-Lab/gha/.github/workflows/claude-code-review.yml@v2
claude_args allowlist hand-copied between two files, with a "keep in sync" comment gone --- the reusable workflow owns it

What is preserved

What changes

  • /review replaces @claude review as the comment trigger. Deliberate, and gha documents why: any @claude substring also wakes claude.yml, so a mention would dispatch two paid review runs of possibly the same PR. The OWNER/MEMBER/COLLABORATOR gate is unchanged.
  • The review is posted by the workflow, not by the plugin. This is the substantive change --- see the Confirm claude-review actually posts a review (never yet observed) #105 section below.
  • workflow_dispatch is added. Required so claude.yml can re-dispatch a review of commits an @claude run pushes. This is what creates the merge-order constraint with Migrate claude.yml (@claude agent) to Morrison-Lab/gha's claude.yml@v2 #111.
  • No top-level concurrency: block. The reusable workflow manages per-PR concurrency internally (group: claude-review-<PR>); a PR-scoped group in the caller deadlocks against the nested job and cancels the run (gha#437).
  • Secrets are passed explicitly rather than via secrets: inherit. GitHub only inherits secrets into a reusable workflow owned by the same org/user, and this is a UCD-SERG repo calling a Morrison-Lab workflow --- inherit would hand it an empty token.

What the reusable workflow does NOT cover

Fork PRs are still not reviewed. This does not close #90.

I checked both paths in the reusable workflow rather than assuming:

# automatic path
github.event.pull_request.head.repo.full_name == github.repository
# dispatch path
needs.gather-context.outputs.dispatch-guard-blocked != 'true'   # gha#235 blocks fork/Dependabot

gha blocks forks on both, and states the reason: forks cannot read the OAuth token.

The deleted claude-review-comment.yml was this repo's attempt at a fork path --- an issue_comment trigger checking out refs/pull/<n>/head in base-repo context. Removing it is a capability loss on paper. In practice it is not, because it was exercised once and was non-functional:

$ gh run list --workflow claude-review-comment.yml --limit 200
25 runs: 23 skipped, 1 success, 1 in flight

Corrected. An earlier revision of this body said it "never executed once (5/5 runs skipped)". That was wrong, and it came from reading --limit 5 and generalizing to the population. Round 2 of the self-review caught it.

The one success is run 30687108541, 2026-08-01, event: issue_comment --- on fork PR #77, the exact case the workflow was written for. It ran every step to completion and posted nothing, because its prompt never carried --comment:

$ git show origin/main:.github/workflows/claude-review-comment.yml | grep prompt:
prompt: '/code-review:code-review ${{ github.repository }}/pull/${{ github.event.issue.number }}'

That is #96 --- fixed for the other review workflow by #97, and never for this one. So the path was tried on a real fork PR and could not have posted anything, which is consistent with #98 saying it has never been confirmed to post a review end-to-end. This trades a non-functional path for a maintained one, and #90 and #98 stay open on their own terms.

/review on a fork PR now says so, rather than promising a review. An adversarial self-review of this diff caught that the stub (copied from gha's example) detected the fork, dispatched anyway, and posted :mag: dispatched a Claude review of this PR. The dispatch guard then blocks the run, and both jobs skip rather than fail --- so the PR would carry a promise, no review, and no red check to contradict it. The stub now short-circuits with an explicit fork notice linking #90. Filed upstream as Morrison-Lab/gha#613, since gha's own example stub has the same bug.

The dispatch itself is now failure-aware, after round 2 found that the round-1 fix broke it. Removing gha's REF_ARGS fallback left the dispatch always passing --ref "$PR_BRANCH" --- and a workflow_dispatch runs the workflow file as it exists at that ref. This PR is what adds the workflow_dispatch trigger, so three of the four open same-repo PR branches do not have it. Either the dispatch is rejected and set -euo pipefail kills the step before the acknowledgment posts, or it runs a copy that matches no job and the acknowledgment posts anyway --- the same false promise, through a different door. It now tries the PR branch, falls back to a no-ref dispatch, and acknowledges only if one actually started a run. Details in the round-2 self-review comment.

Three new skip gates arrive with the reusable workflow, and the trigger list being unchanged hides them. The hand-rolled workflow had no job-level if: at all; the reusable one skips draft PRs, fork PRs, and bot-sender events. The third turns #84 (Copilot-authored PRs 401 on token exchange) from a red failure into a gray skip --- better signal, not a fix. All three are documented in the file; #84 stays open.

On #105 (claude-review has never posted a review)

Two things, and I want to be careful to separate the one I verified from the one I did not.

Verified: the root cause named in #96/#105 cannot recur under this workflow. #105's root cause was that the upstream code-review plugin's step 7 gates its own gh pr comment on a --comment argument the workflow had to remember to pass. gha's reusable workflow does not rely on the plugin to post at all --- it captures the review to a file and posts it itself from the workflow:

COMMENT_URL="$(gh pr comment "$PR_NUMBER" --repo "$REPO" --body-file "$BODY_FILE")"

So the "plugin decided not to post" failure mode is structurally absent, not merely fixed.

Not verified: whether a review will actually appear. #105's most recent comment (2026-08-24) documents runs that completed with is_error: false, 4--6 turns, real cost, and posted nothing --- and names two remaining candidate causes (the plugin's step-1 eligibility gate, or a denied tool call) that it could not separate. A different posting mechanism removes one of those candidates. It does not establish that the other is gone. This PR does not close #105, and the test is the same one #105 already describes: push to an open PR that does not touch this workflow file, and read the result.

What it does add is the lever #105 asks for. Its "concrete next step" is:

Setting show_full_output: true on the anthropics/claude-code-action@v1 step is the one lever that would name them.

The reusable workflow exposes exactly that as an input, described upstream for exactly this symptom. It is wired in this stub at show-full-output: false (gha's default), with a comment saying when to flip it. That turns #105's next step from a workflow edit into a one-word change.

Why no automated review ran on this PR

The self-modification guard, and only that. This PR edits .github/workflows/claude-code-review.yml, and claude-code-action requires that file to match the default branch or its token exchange fails. The bot said so itself at 16:38:30Z:

No review ran --- this PR edits .github/workflows/claude-code-review.yml, the review workflow itself.
claude-code-action requires that file to match the default branch, so its token exchange fails until this change merges.
The review is skipped by design, and re-running or re-dispatching will not change that: the skip lifts only if the PR stops editing that file.
require-review reports a gray skipped rather than green.

So the skip is by design, it lifts only on merge, and re-running cannot clear it. The warning prescribes the remedy directly: merge on a self-review or a human review.

This is not #105, despite the shared symptom. #105 is a different failure --- a review that genuinely executes and posts nothing. It did not apply here, because no review executed at all. A clean reproduction of #105 did land during this work, on #111, which touches no workflow file and so is not subject to this guard; it is written up on #105. Keeping the two apart matters, since they call for opposite responses: this one resolves on merge, and #105 does not.

What gha improves here is legibility rather than outcome. The warning above, and require-review reporting gray instead of green, are both new. Under the hand-rolled workflow this case was a silent green, which is what made #89, #91 and #97 hard to read at the time --- #105 lists it as one of the three distinct meanings a green claude-review check currently carries.

check-pr-fully-clean.py reports this PR clean, and that report is wrong. It exits 0 while printing:

verdict scan: examined 1 dated automated review item(s), 0 bore a verdict, latest = NONE

latest = NONE means nothing reviewed this head. The one item it examined is the self-modification skip notice, which is admitted as a review item and states no verdict --- exactly the false-clean that line exists to expose. #111 reports the same underlying state honestly, exiting 1 with "No automated review comments or reviews found".

This PR is therefore blocked on an external verdict, not ready. Per self-review-fallback, the fallback is an adversarial self-review (posted separately on this PR), with a cross-vendor reviewer requested in parallel. A human approval is required to merge regardless: the main ruleset requires 1 approving review, require_last_push_approval, and thread resolution.

Merge order

Merge this before #111. gha's claude.yml dispatches the review workflow via workflow_dispatch, and the current bespoke claude-code-review.yml has no such trigger, so #111's dispatch would fail until this lands. The two PRs touch disjoint files (gh pr diff --name-only on each: this one is claude-code-review.yml + claude-review-comment.yml, #111 is claude.yml), so there is no conflict --- only an ordering constraint.

Other self-review fixes

Validation

actionlint and yamllint clean on the new file, and it is ASCII-only.

Note that workflow_dispatch and the /review path only become usable once this file is on main --- gh workflow run resolves against the default branch. The pull_request path works from the PR branch immediately.

Related

Same class of gha-caller defect, found from a separate probe today: UCD-SERG/serocalculator#663 and UCD-SERG/serodynamics#297, both gha callers that fail to forward WORKFLOW_TOKEN. This PR is unaffected --- no gha review workflow references that secret, and the reviewer never pushes, so omitting it here is correct.

The standing rule authorizing this migration is Morrison-Lab/ai-config#2127, merged 2026-08-24 at 16:42Z.

@github-actions

github-actions Bot commented Aug 24, 2026

Copy link
Copy Markdown
Contributor
PR Preview Action v1.8.1-2-g6ad689f
Preview removed because the pull request was closed.
2026-08-24 17:57 UTC

…yml@v2

Replaces the two hand-rolled review workflows with one caller stub targeting
the reusable workflow, retiring the manually-synced `claude_args` allowlist
that both copies had to keep in step by hand.

- claude-code-review.yml becomes a caller stub (pull_request +
  issue_comment `/review` + workflow_dispatch).
- claude-review-comment.yml is deleted; its on-demand path is now the
  `/review` slash command, and its fork-PR checkout trick never executed
  once (5/5 runs skipped, 2026-08-01 through 2026-08-24).

Refs #101
- Stop dispatching a review for a fork PR. The reusable workflow's dispatch
  guard blocks forks, so dispatching posted ":mag: dispatched a review" and
  delivered nothing, with no red check to contradict it. Post an explicit
  fork notice linking #90 instead.
- Add `pull-requests: read` to dispatch-on-comment. It calls
  `gh api repos/../pulls/N`, and declaring any scope zeroes the unlisted ones.
- Document the three skip gates the reusable workflow adds (draft, fork,
  bot-sender) and the #84 red-to-gray interaction.
- Correct three comments that asserted capabilities this repo does not have
  until #100 lands: claude.yml cannot dispatch a review, and `@claude review`
  does not produce one.
- Restore the deleted rationale for `pull-requests: write` (#91) and for
  `--ref` on the dispatch.
- State the inherited upstream defaults (report-cost, use-ai-config,
  lab-manual, require-review) instead of accepting them silently.
- Document the exact accepted `/review` comment form.
- Narrow the gha#437 and `secrets: inherit` claims to what each source says.

Refs #101
Keeps the `with:` block carrying only deviations, per the same convention
used in the claude.yml stub. All four values equal upstream's defaults.

Refs #101
d-morrison added a commit that referenced this pull request Aug 24, 2026
- setup-r: false, against gha's default. This repo's own
  copilot-setup-steps.yml already recorded the same conclusion ("we don't
  have any R code to run yet"), and it still holds: zero .qmd files contain
  an R chunk and _quarto.yml is html-only. Enabling it would also run
  `local::.` on every invocation -- an install nothing on main exercises,
  against a DESCRIPTION with `LazyData: true` and no data/ directory -- and
  a failure there happens before Claude runs, killing every @claude run.
- Document the tag-mode to agent-mode switch and the tool-surface narrowing
  it brings. gha sets a `prompt:`, and its default claude-args REPLACES the
  allowlist rather than extending it, denying git push, gh pr create, and
  the write forms of gh api.
- Correct the `actions: write` comment: the review dispatch it enables only
  resolves once #110 adds a workflow_dispatch trigger to
  claude-code-review.yml.
- Correct the enumerated upstream defaults. `reviewer` defaults to
  'd-morrison' rather than being unset, so d-morrison is re-requested on
  every Claude push -- new behaviour worth naming.
- Carry across gha's WORKFLOW_TOKEN caveat (a PAT push fires other
  push-based workflows) and its upside (it fires `synchronize`, so Claude's
  commits would get reviewed even without the dispatch path).
- Note the retained `assigned` trigger's changed cost, the unconditional
  TinyTeX install, and the omission of SUBMODULES_TOKEN.
- Restate the `secrets: inherit` rule as GitHub documents it (same
  organization or enterprise).

Refs #100
@d-morrison
d-morrison marked this pull request as ready for review August 24, 2026 16:38
@github-actions

This comment has been minimized.

@d-morrison

Copy link
Copy Markdown
Member Author

Context for reviewers: this is one of a pair of migrations driven by a standing instruction to move repos onto Morrison-Lab/gha's reusable workflows where they would benefit. #111 is the other half.

Two things found while doing it that are worth reading alongside the diff:

Five gaps found upstream while diffing against gha and filed there: Morrison-Lab/gha#608, #609, #610, #612, #613. The last two are bugs in gha's own example stub for this workflow, both fixed consumer-side here.

@d-morrison

Copy link
Copy Markdown
Member Author

Self-review (fallback under self-review-fallback)

Posting this because no automated verdict can arrive on this PR: it edits .github/workflows/claude-code-review.yml, so the self-modification guard skips the review by design until the change merges. That is a different failure from #105 and is explained in the PR body.

Method. Dispatched to a read-only adversarial-reviewer subagent against git diff origin/main...HEAD, briefed with the diff and the standards only --- deliberately not with my rationale for the change, since handing over the author's account of a diff is what makes a reviewer agree with it. Two rounds; the second is running against the current head and I will post its findings here when it returns.

Round 1 --- 12 findings, all addressed

Blocking

  1. /review on a fork PR promised a review that could never arrive. The stub (copied from gha's example) detected the fork, dispatched anyway, and posted :mag: dispatched a Claude review of this PR. The reusable workflow's dispatch guard then blocks it, and both jobs skip rather than fail --- so the PR would carry a promise, no review, and no red check. Fixed by short-circuiting with an explicit fork notice linking Fork PRs get no Claude review, and pull_request_target is not the fix #90. Filed upstream as examples/claude-code-review.yml: /review on a fork PR posts "dispatched a review" for a run the dispatch guard then blocks Morrison-Lab/gha#613, since gha's own example has the same bug.
  2. A comment asserted @claude review still routes to a review. It does not, until Migrate claude.yml (@claude agent) to Morrison-Lab/gha's claude.yml@v2 #111 lands. Reworded to state what is true today: /review is the only comment phrasing that produces a review right now.

Should-fix

  1. A comment claimed this repo's agent workflow can re-dispatch a review. It cannot --- it holds actions: read and has no dispatch step. Corrected, with the dependency on Migrate claude.yml (@claude agent) to Morrison-Lab/gha's claude.yml@v2 #111 named.
  2. "Second paid review" was wrong; the duplicate would be a second paid agent run. Corrected.
  3. Three skip gates the reusable workflow adds were undocumented --- draft PRs, fork PRs, bot-sender events. The trigger list being unchanged hides them. Now documented, including that the bot-sender gate turns claude-review 401s on App token exchange for Copilot-authored PRs #84 from a red failure into a gray skip (better signal, not a fix).
  4. dispatch-on-comment was missing pull-requests: read. It calls gh api repos/../pulls/N, and declaring any permission scope zeroes every unlisted one. Added. gha's example has the same gap; filed as examples/claude-code-review.yml: dispatch-on-comment reads a PR without declaring pull-requests: read Morrison-Lab/gha#612.
  5. /review is position-sensitive with no feedback on a near-miss. Documented the exact accepted form.
  6. Several upstream defaults were being inherited silently. Now enumerated in a comment (report-cost, use-ai-config, lab-manual, track-progress), each verified against the reusable workflow's own workflow_call.inputs.

Nits

  1. show-full-output: false was dead configuration. Commented out, with the note about when to enable it for Confirm claude-review actually posts a review (never yet observed) #105.
  2. "same org/user" restated as "same organization or enterprise", matching GitHub's own wording.
  3. The gha#437 claim was overstated. Narrowed to the identical-name case that issue actually tested.
  4. Two load-bearing rationales deleted along with the old file were restored: why pull-requests: write is safe under pull_request (Restore pull-requests: write for claude-review #91), and what --ref on the dispatch is for.

Independent verification I ran

  • actionlint and yamllint clean on the changed file; ASCII-only.
  • Every with:, secrets:, and uses: reference checked against the reusable workflow at @v2 rather than against the example stub's comments.
  • Both composite actions (parse-workflow-ref, detect-review-request) confirmed to exist at @v2.
  • require-review confirmed not in this repo's branch ruleset (required checks are build-deploy, lint-project, Spellcheck), so it cannot block a merge.
  • The claim that claude-review-comment.yml never executed re-derived from gh run list: 5/5 runs skipped.
  • File-set intersection with Migrate claude.yml (@claude agent) to Morrison-Lab/gha's claude.yml@v2 #111 derived and empty, so the ordering constraint carries no conflict risk.

Status

No known open findings. Blocked on an external verdict rather than ready --- a self-review does not satisfy criterion 2 of fully-clean. Copilot was requested on this PR; it has not answered, and an empty pending-reviewer list does not discriminate between a blocked request and one still in flight. A human approval is required to merge regardless: the ruleset requires 1 approving review, require_last_push_approval, and thread resolution.

Note for whoever reads check-pr-fully-clean.py on this PR: it exits 0 and its report is wrong here. Its verdict scan: line says 0 bore a verdict, latest = NONE --- the one item it counted is the self-modification skip notice, which states no verdict. Read that line, not the exit status.

Fixes a blocking defect introduced by the previous round's own fix, and a
factual claim I published in three places.

- BLOCKING: the dispatch always passed `--ref "$PR_BRANCH"`, and a
  workflow_dispatch runs the workflow file as it exists at that ref. This PR
  is what ADDS the workflow_dispatch trigger, so every branch cut before it
  lacks it -- three of the four open same-repo PRs. Either the dispatch is
  rejected and `set -e` kills the step before the acknowledgment posts, or
  it runs a copy that selects no job and the acknowledgment posts anyway,
  reintroducing the false promise the fork short-circuit was added to
  prevent. Now tries the PR branch, falls back to a no-ref dispatch, and
  acknowledges only if one actually started a run -- reporting the failure
  on the PR otherwise. Removing upstream's REF_ARGS array last round had
  also removed the only no-ref path, which is what left a deleted head
  branch with no fallback.
- FACTUAL: "it never executed once (5/5 runs skipped)" was wrong. That came
  from reading `--limit 5` and generalizing to the population. The real
  history is 25 runs: 23 skipped, one still in flight, and one success --
  run 30687108541 on 2026-08-01, against fork PR #77, the exact case the
  workflow was written for. It executed and posted nothing because its
  prompt never carried `--comment` (#96), which #97 fixed for the other
  review workflow and never for this one. The justification for deleting it
  is that it was non-functional, not that it never ran.
- FACTUAL: the user-facing fork notice blamed the OIDC exchange. That is the
  `pull_request`-path story (#90); a dispatched run executes in base-repo
  context with no fork token involved, and upstream describes its guard as
  failing a mistaken dispatch fast rather than closing a hole.
- "produces no run at all" corrected -- a skipped run is still recorded.
- `pull-requests: read` restated as declared rather than required, since a
  public repo would permit the read anyway.
- The `pull-requests: write` rationale covered only the pull_request
  trigger; added what bounds the workflow_dispatch path.
- Disambiguated "Set this to true", which sat five lines from its referent
  with `require-review` as the nearer antecedent, and split the three
  unrelated paragraphs sharing one heading.
- report-cost's description corrected to "appends".

Refs #101
@github-actions

This comment has been minimized.

@d-morrison

Copy link
Copy Markdown
Member Author

Self-review, round 2 --- one blocking defect and a correction to my own published claim

Second adversarial round against 34f05b4. It found a blocking defect that the first round's fix introduced, and a factual claim I had asserted in the PR body, a commit message, and my round-1 self-review comment above. Both are fixed in 34f05b4.

Blocking: the dispatch would have failed on three of four open PRs

Round 1 had me remove upstream's REF_ARGS fallback so the dispatch always passed --ref "$PR_BRANCH". A workflow_dispatch runs the workflow file as it exists at the dispatched ref --- and this PR is what adds the workflow_dispatch trigger, so every branch cut before it lacks it. Measured against the live repo:

software-rendering (#108)             on: / pull_request:   <- no workflow_dispatch
doi-update (#107)                     on: / pull_request:   <- no workflow_dispatch
claude/issue-73-20260516-0819 (#76)   on: / pull_request:   <- no workflow_dispatch

Both possible outcomes are bad, so it does not matter which GitHub applies: either the dispatch is rejected and set -euo pipefail kills the step before the acknowledgment posts (red X, no explanation), or it runs the ref's copy, no job matches, the run records skipped, and the ":mag: dispatched a review" acknowledgment posts anyway --- exactly the false promise the round-1 fork fix was added to prevent, arriving through a different door.

Removing REF_ARGS had also removed the only no---ref path, which left a second hole: a /review on a closed same-repo PR whose head branch was deleted (#92, #93, #94, #95, #97 all qualify) would hit --ref <deleted-branch> with no fallback.

Fixed by trying the PR branch, falling back to a no-ref dispatch against the default branch, and acknowledging only if one of them actually started a run --- reporting the failure on the PR otherwise.

Correction: "it never executed once" was wrong, and I published it three times

I wrote, here and in the PR body and a commit message, that the deleted claude-review-comment.yml "never executed once (5/5 runs skipped)". That came from reading gh run list --limit 5 and generalizing to the population. The population:

$ gh run list --workflow claude-review-comment.yml --limit 200
25 runs: 23 skipped, 1 success, 1 in flight

The success is run 30687108541, 2026-08-01, event: issue_comment --- on fork PR #77, the exact case the workflow was written for. It ran every step to completion and posted nothing, because its prompt never carried --comment:

$ git show origin/main:.github/workflows/claude-review-comment.yml | grep prompt:
prompt: '/code-review:code-review ${{ github.repository }}/pull/${{ github.event.issue.number }}'

That is #96 --- which #97 fixed for the other review workflow and never for this one.

So the honest justification for deleting it is that it was exercised once and non-functional, not that it was never exercised. The conclusion is unchanged and arguably better supported; the evidence I gave for it was wrong, and it was the evidence offered for dropping fork-review coverage without a replacement. The PR body and the workflow comment now say the accurate thing.

Also corrected

  • The fork notice asserted the wrong cause. It told contributors a fork's token cannot complete the OIDC exchange. That is the pull_request-path story (Fork PRs get no Claude review, and pull_request_target is not the fix #90); a dispatched run executes in base-repo context with base-repo secrets and no fork token involved, and upstream describes its guard as failing a mistaken dispatch fast rather than closing a hole. The notice now says the dispatch guard declines fork PRs and points at Fork PRs get no Claude review, and pull_request_target is not the fix #90.
  • "produces no run at all" --- a non-matching comment does create a run; it records as skipped. This repo's own history has 23 of them.
  • pull-requests: read "is required" --- restated as declared, since this repo is public and the read would generally succeed anyway. That is precisely why omitting it would go unnoticed until the repo went private.
  • The pull-requests: write rationale covered one of two triggers. It explained safety under pull_request only; the job also runs on workflow_dispatch, where the token is not forced read-only and the PR number is caller-supplied. Added what bounds that path.
  • Ambiguous referent. "Set this to true" sat five lines from show-full-output with require-review as the nearer antecedent --- a reader taking the nearest one gets a coherent, wrong instruction. Named the input and split three unrelated paragraphs that shared one heading.
  • report-cost described as posting its own comment; it appends to an existing one on all but one path.

Verified clean this round

Shell semantics of the fork short-circuit (set -e exempts the left operand of ||; exit 0 correct; backtick escaping yields a Markdown code span, not command substitution; no injection surface --- COMMENT_BODY is only ever the quoted left operand of [[ =~ ]]). Permission sufficiency, with nothing declared unused. pr-number and show-full-output both exist at @v2 with the assumed defaults. All four named upstream defaults verified individually. require-review confirmed absent from ruleset 2948195. The three job-level gates confirmed exactly draft == false, head.repo.full_name == github.repository, sender.type != 'Bot', and #84's failing run confirmed actor_type: "Bot", so the gate does convert it to a gray skip. actionlint exits 0; ASCII-only; file ends with a newline.

One regression check I ran unprompted: deleting the --comment prompt does not reintroduce #96, because the reusable workflow posts the review itself via gh pr comment --body-file and this caller grants the pull-requests: write that needs.

Status

No known open findings. Still blocked on an external verdict rather than ready --- the self-modification guard means no automated reviewer can weigh in until this merges, and Copilot has not answered.

@github-actions

Copy link
Copy Markdown
Contributor

Warning

No review ran --- this PR edits .github/workflows/claude-code-review.yml, the review workflow itself.
claude-code-action requires that file to match the default branch, so its token exchange fails until this change merges.
The review is skipped by design, and re-running or re-dispatching will not change that: the skip lifts only if the PR stops editing that file.

require-review reports a gray skipped rather than green.
A green there attests that a reviewer ran, never that one approved; here none ran at all.
Merge on a self-review or a human review instead.

View run

@d-morrison
d-morrison merged commit e11ef34 into main Aug 24, 2026
8 checks passed
@d-morrison
d-morrison deleted the chore/gha-review-workflows branch August 24, 2026 17:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant