feat: surface Claude PR review progress as a check run - #95
Draft
andychoquette wants to merge 1 commit into
Draft
andychoquette wants to merge 1 commit into
andychoquette wants to merge 1 commit into
Conversation
The review stage runs on workflow_run, and workflow_run runs never attach to a pull request -- so the PR only ever shows Stage 1's collect check going green in seconds, while the review itself runs invisibly and its comments trickle in with no signal for whether it is still working or already dead. Stage 1 cannot wait for the review: its completion is what fires the workflow_run event, so blocking on it would deadlock. A check run created against the PR head SHA does attach to the PR, so the review stage now opens one as in_progress once it resolves the PR and closes it in an always() step. Both calls are best-effort. The check run needs checks: write, which only a caller can grant, so a caller that bumps this workflow without adding the scope would otherwise 403 here and get no review at all -- a progress indicator must never be the reason a review does not run. A failed create warns and leaves the step output empty, which gates the closing step off. Cancellation reports neutral, not failure: a superseded push and the job timeout are indistinguishable from the step outcome, and neither says anything about the change -- findings posted before the cut still stand. Not safe to mark required in branch protection: the check is only created when a unique open PR resolves, so the existing clean-skip path would leave it pending forever. Signed-off-by: andychoquette <78888816+andychoquette@users.noreply.github.com>
andychoquette
force-pushed
the
claude-review-progress-check
branch
from
September 15, 2026 17:14
d8b50da to
86435c2
Compare
andychoquette
marked this pull request as draft
September 15, 2026 17:16
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Stage 2 runs on
workflow_run, andworkflow_runruns never attach to a pull request. So on the PR side all a maintainer sees is Stage 1'scollectcheck going green in seconds, after which the review runs invisibly and its comments trickle in — with no way to tell whether Claude is still working, was superseded, or died.Stage 1 can't be made to wait for the review: its completion is what fires the
workflow_runevent, so blocking on the review deadlocks.track_progresson the action isn't an option either — it only engages forpull_request/issueevents.A check run created against the PR head SHA does attach to the PR, so that's the signal used here: opened
in_progressonce the PR resolves, closed in analways()step.Decisions worth flagging
checks: write, which only a caller can grant (a caller'spermissionsblock is the ceiling for a reusable workflow). A caller that bumps this workflow without adding the scope would otherwise 403 on a hard-failing step and get no review at all — a progress indicator must never be the reason a review doesn't run. A failed create warns and leaves the step output empty, which gates the closing step off; a failed close warns rather than reddening a job whose review succeeded.neutral, notfailure. A superseded push (caller concurrency group) and the jobtimeout-minutesare indistinguishable from the step outcome, and neither says anything about the change — findings posted before the cut still stand. Only a genuine agent-step failure is red.You must authenticate via a GitHub App). Actions'GITHUB_TOKENis an installation token so it qualifies, but this step can't be reproduced by hand with a PAT, which is why there's no local repro below.collectgoing green and the check appearing. Unavoidable: Stage 1 haspermissions: {}and a fork PR gives it a read-only token, so it can't open the check itself.Test plan
Static only so far: YAML parses, both new shell blocks pass
bash -n, the jq payloads produce the documented shapes, and the create-failure branch was exercised against a stub. The Checks API's App-token requirement means the real path can only run inside Actions.End-to-end verification is a scratch PR on a caller repo after that caller grants
checks: write— note Stage 2 always executes the caller's default-branch copy, so a PR that only edits the caller in its own branch tests nothing. Until a caller is updated, its review runs behave exactly as today plus one warning annotation in the (unwatched)workflow_runjob log.Possible follow-up
The agent already has
Bash(gh api:*). Passing the check run id into the prompt and having itPATCHoutput.summaryafter each posted finding would turn this from a spinner into real progress ("4 of ~9 changed files reviewed, 2 findings posted"). Left out here to keep the change mechanical and to avoid spending agent wall-clock before the basic version is proven.