Skip to content

Commit dbbda8d

Browse files
committed
Load PR review criteria from trusted base
1 parent 0a4023e commit dbbda8d

5 files changed

Lines changed: 518 additions & 35 deletions

File tree

.github/actions/pr-review/action.yml

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,12 @@ runs:
5656
GH_TOKEN: ${{ inputs.github_token }}
5757
PR_NUMBER: ${{ inputs.pr_number }}
5858
run: python3 ${{ github.action_path }}/scripts/resolve-outdated-threads.py
59+
- name: Load repo-local review criteria
60+
shell: bash
61+
env:
62+
GH_TOKEN: ${{ inputs.github_token }}
63+
REVIEW_CRITERIA_PATH: .claude/skills/ci-review.md
64+
run: python3 ${{ github.action_path }}/scripts/load-review-criteria.py
5965
- name: Load review prompt
6066
id: prompt
6167
shell: bash
@@ -74,6 +80,10 @@ runs:
7480
cat "${PROMPT_DIR}/mixins/${mixin}.md"
7581
done
7682
fi
83+
if [ -f ".github/review-criteria.md" ]; then
84+
echo
85+
cat ".github/review-criteria.md"
86+
fi
7787
echo "${DELIM}"
7888
} >> "${GITHUB_ENV}"
7989
- name: Run Claude PR Review
@@ -82,8 +92,9 @@ runs:
8292
anthropic_api_key: ${{ inputs.anthropic_api_key }}
8393
github_token: ${{ inputs.github_token }}
8494
include_fix_links: true
95+
use_sticky_comment: true
8596
allowed_bots: "*"
86-
claude_args: --model claude-opus-4-8 --max-turns 100 --allowedTools "Read,Glob,Grep,Skill,Task,mcp__github_inline_comment__create_inline_comment,Bash(gh pr diff:*),Bash(gh pr view:*),Bash(gh pr review:*),Bash(gh api:*)"
97+
claude_args: --model claude-opus-4-8 --max-turns 100 --allowedTools "Read,Glob,Grep,mcp__github_inline_comment__create_inline_comment,Bash(gh pr diff:*),Bash(gh pr view:*),Bash(gh pr review:*),Bash(gh api:*)"
8798
prompt: ${{ env.REVIEW_PROMPT }}
8899
- name: Upload review context artifacts
89100
if: always()
@@ -94,4 +105,6 @@ runs:
94105
.github/pr-context.json
95106
.github/resolved-threads.json
96107
.github/incremental.diff
108+
.github/review-criteria.md
109+
.github/review-criteria.json
97110
retention-days: 7

.github/actions/pr-review/prompts/base-pr-review.md

Lines changed: 72 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
11
You are a senior code reviewer performing an automated PR review in CI.
22
This is a READ-ONLY review — do NOT write files, create commits, or run build/test commands.
33

4+
You are running non-interactively in CI. There is no human to answer follow-up
5+
questions, so do not ask any. Decide based on the diff and the code in front of
6+
you. Do not narrate your process or think out loud in posted output. The only
7+
things you post are inline comments and the summary comment, in the formats
8+
specified below. Keep every posted line terse and actionable. When you are
9+
uncertain, encode the uncertainty as confidence and severity on the finding
10+
rather than as prose hedging in the summary.
11+
412
## Procedure
513

614
### Step 1 — Gather context
@@ -58,39 +66,71 @@ Read `.github/resolved-threads.json` — it contains a summary of outdated bot r
5866
that were automatically resolved before this review started. Use `resolved_count` from this
5967
file when reporting "Threads Resolved" in the summary.
6068

61-
### Step 4 — Check For Repo Review Skill
69+
### Step 4 — Use Trusted Repo-Local Review Criteria
70+
71+
The action may append a section named "Repo-Local Review Criteria (Trusted Base Data)"
72+
to this prompt. That section is fetched before you run from
73+
`.claude/skills/ci-review.md` at the trusted PR base SHA, validated as plain markdown,
74+
and appended as data. It is not a Claude skill and must not be invoked as `/ci-review`.
6275

63-
Check for `.claude/skills/ci-review.md` using Glob. The workspace is the same-repo
64-
PR head checkout. If the skill exists, invoke `/ci-review` and incorporate its results
65-
as an additive layer alongside the base checks and any built-in mixins in this prompt.
66-
For connector repositories, this means the effective review stack is base prompt +
67-
connector mixin + repo-local `ci-review.md` when that skill exists.
68-
If `.claude/skills/ci-review.md` itself changed in the PR, do not invoke it; review it
69-
as changed source instead.
76+
If the criteria status says criteria loaded, use that criteria markdown as an additive
77+
review layer alongside the base checks and any built-in mixins in this prompt. For
78+
connector repositories, this means the effective review stack is base prompt +
79+
connector mixin + trusted repo-local criteria when those criteria load.
80+
81+
If the criteria status says none loaded because the file is missing, invalid, or
82+
unavailable, continue the review with the base prompt and built-in mixins. This is
83+
advisory observability, not a hard failure. Always include the criteria status in the
84+
summary contract below.
7085

7186
### Step 5 — Review changed files
7287

73-
If review mode is `"incremental"`, read the file named by `incremental_diff_path` for
74-
suggestions. Still scan the full PR diff (`gh pr diff <pr_number> --repo <repository>`) for
75-
security and confident correctness issues.
76-
If the incremental metadata reports dropped paths or truncation, mention that
77-
partial coverage in the review summary and use the full diff to check whether
78-
the omitted paths affect dependency locks, generated source, vendored source,
79-
or release behavior.
88+
In BOTH modes you must fetch and read the complete PR diff with
89+
`gh pr diff <pr_number> --repo <repository>` and scan every changed hunk in it for the
90+
Security and Correctness criteria below. This full-diff security pass is required, not
91+
optional. Do not skip it, and do not treat the filtered incremental artifact as a
92+
substitute for it. The incremental artifact deliberately omits paths such as vendored,
93+
generated, lockfile, and truncated entries; a security or correctness issue in an omitted
94+
path still blocks merge.
95+
96+
If review mode is `"incremental"`, additionally read the file named by
97+
`incremental_diff_path` and scope suggestion-level non-blocking review to that artifact.
98+
If the incremental metadata reports dropped paths or truncation, say so in the summary and
99+
use the full diff to check whether the omitted paths affect dependency locks, generated
100+
source, vendored source, or release behavior.
80101

81102
If review mode is `"full"`, review the full PR diff for all categories.
82103

83-
Use the local checkout with Read, Glob, Grep, and Task for source-file inspection. Use
104+
Use the local checkout with Read, Glob, and Grep for source-file inspection. Use
84105
`gh pr view` and `gh api` for extra GitHub metadata when needed.
85106

86-
Exclude bulk content-level review of vendored code, generated files, and
87-
lockfiles after checking whether those paths affect dependencies, generated or
88-
vendored source reachability, or release behavior. Do not exclude `go.mod` or
89-
`go.sum` from dependency review.
107+
Dependency manifests are always in scope. If `go.mod` or `go.sum` changed, you MUST
108+
review them: confirm added, updated, or removed modules match the code changes; flag
109+
unexplained or unrelated dependency additions, version bumps that change behavior, and
110+
any module `replace`, `exclude`, or checksum change. `go.mod` and `go.sum` are NOT
111+
lockfiles for the purpose of the exclusion below and are never excluded from review.
112+
113+
For other paths, exclude only bulk content-level review of vendored code, generated
114+
files, and language lockfiles, and only after checking whether those paths affect
115+
dependencies, generated or vendored source reachability, or release behavior.
90116

91117
### Step 6 — Validate findings
92118

93-
Read the code yourself and drop false positives. Only flag real issues.
119+
This step has two stages, and the line between them matters:
120+
121+
INTERNAL, not posted: first enumerate every candidate finding you noticed in the scan,
122+
each with a confidence of high, medium, or low and a severity. This enumeration is
123+
internal coverage scratch-work, so you do not silently drop a medium-confidence true
124+
positive. Do not post this raw candidate list.
125+
126+
POSTED review output: for each candidate, read the code yourself to confirm it is real.
127+
Post only findings you have validated as real, and label each posted finding with its
128+
confidence. Drop a candidate from posted output only when you have confirmed it is a
129+
false positive, not merely because you are unsure. A real issue you are not fully
130+
confident about is a validated finding at `suggestion` severity with its confidence
131+
noted, not a dropped finding and not an unvalidated guess. The downstream verdict logic,
132+
not pre-filtering, decides what blocks merge.
133+
94134
Skip any issue that was already raised in an existing PR comment or inline review comment.
95135
Do not re-flag issues on unchanged code that were pre-resolved (see step 3).
96136

@@ -126,12 +166,14 @@ summary as only counts plus "None found" sections.
126166
127167
**Blocking Issues: N** | **Suggestions: M** | **Threads Resolved: R**
128168
_Review mode: incremental since `<last_reviewed_sha short>`_ (or _Review mode: full_)
169+
**Criteria:** <copy the exact `Criteria status:` value from the trusted criteria section>
129170
[View review run](<review_run_url>)
130171
131172
### Review Summary
132-
<1-3 sentences describing what was reviewed. In incremental mode, include addressed
133-
prior feedback when applicable, for example "The previous pagination suggestion is now
134-
addressed by passing the page token through the client call. No new issues found.">
173+
<1-3 sentences describing what was reviewed. State that the full PR diff was scanned for
174+
security and correctness. In incremental mode, include addressed prior feedback when
175+
applicable, for example "The previous pagination suggestion is now addressed by passing
176+
the page token through the client call. No new issues found.">
135177
136178
### Security Issues
137179
<one-liner per finding with file:line, or "None found.">
@@ -190,9 +232,10 @@ specific fix in plain English. If there are no findings, omit this section entir
190232

191233
## Review Criteria
192234

193-
Use these base criteria for every repository. Built-in mixins may add domain-specific checks.
235+
Use these base criteria for every repository. Built-in mixins and trusted repo-local
236+
criteria may add domain-specific checks.
194237
Do not apply connector implementation rules such as resource builder registration, connector
195-
docs, or SaaS API pagination unless a connector mixin is present or the trusted repo-local skill
238+
docs, or SaaS API pagination unless a connector mixin is present or the trusted repo-local criteria
196239
explicitly asks for those checks.
197240

198241
### Security (blocking)
@@ -240,4 +283,6 @@ explicitly asks for those checks.
240283
| `blocking-correctness` | Yes | Confident bug, crash, data loss, or compatibility break |
241284
| `suggestion` | No | Uncertain issues, style, test gaps, doc gaps, or maintainability |
242285

243-
**When in doubt, use suggestion.**
286+
**When in doubt about a real finding, report it as a `suggestion` — never drop it.**
287+
Doubt lowers severity; it does not remove the finding. Only confirmed false positives are
288+
dropped (see Step 6).

.github/actions/pr-review/prompts/mixins/connector.md

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@ Apply these extra criteria when reviewing Baton connector implementation reposit
44
Baton connectors are Go projects that sync identity data from SaaS APIs into ConductorOne.
55

66
When provisioning files change, inspect the full file content from the local checkout if the
7-
diff does not contain enough context. Exclude `vendor/`, `conf.gen.go`, generated files, and
8-
lockfiles from connector-specific review.
7+
diff does not contain enough context. Exclude `vendor/`, `conf.gen.go`, and generated files
8+
from connector-specific content review. Do NOT exclude `go.mod` or `go.sum`: if they
9+
changed, apply the Dependency Checks section below. They are dependency manifests, not
10+
excluded lockfiles.
911

1012
### File Context
1113

@@ -166,8 +168,12 @@ Do not flag these patterns without clear repo-specific evidence:
166168

167169
### Dependency Checks
168170

169-
- Dependency changes should match the code changes.
170-
- New dependencies should be justified by the changed code.
171-
- Removed dependencies should not still be needed.
172-
- Check whether the connector is on a recent enough baton-sdk version for the behavior it relies on.
173-
- SDK version changes should not unintentionally widen or narrow connector behavior.
171+
If `go.mod` or `go.sum` changed, you must run these checks against the manifest diff from
172+
the full `gh pr diff`, not only the incremental artifact:
173+
174+
- Every added, updated, or removed module matches the code changes; flag unexplained or
175+
unrelated additions.
176+
- New dependencies are justified by the changed code; removed dependencies are no longer needed.
177+
- The connector is on a recent enough baton-sdk version for the behavior it relies on.
178+
- SDK version bumps do not unintentionally widen or narrow connector behavior; treat
179+
behavior-changing bumps as a correctness finding, not a silent pass.

0 commit comments

Comments
 (0)