Skip to content

Commit 78a7beb

Browse files
author
Mikhail Orlov
committed
Keep AI review gate on trusted scripts
1 parent 9047805 commit 78a7beb

6 files changed

Lines changed: 8 additions & 14 deletions

File tree

.github/workflows/ai-review.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,10 @@ jobs:
3131
runs-on: ubuntu-latest
3232
timeout-minutes: 30
3333
steps:
34-
- name: Checkout gate scripts
34+
- name: Checkout trusted gate scripts
3535
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
3636
with:
37-
ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository && github.event.pull_request.head.sha || github.event.repository.default_branch }}
37+
ref: ${{ github.event.repository.default_branch }}
3838

3939
- name: Check trusted gate script availability
4040
id: gate_scripts
@@ -58,7 +58,7 @@ jobs:
5858
- name: Bootstrap compatibility notice
5959
if: steps.gate_scripts.outputs.available != 'true'
6060
run: |
61-
echo "::notice::Skipping AI review gate because gate scripts are not yet present on the selected checkout ref: ${{ steps.gate_scripts.outputs.missing }}."
61+
echo "::notice::Skipping AI review gate because trusted scripts are not yet present on default branch: ${{ steps.gate_scripts.outputs.missing }}."
6262
echo "::notice::This is expected for the first bootstrap PR. After merge, AI Review runs normally."
6363
6464
- name: Resolve PR context

docs_project/project/devops/ai-pr-workflow.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ The `AI Review` workflow validates the configured native review backend from the
1010

1111
If `AI_REVIEW_GITHUB_TOKEN` is configured as a repository Actions secret, the workflow uses it for review-gate API calls; otherwise it falls back to the built-in `github.token`.
1212

13-
Same-repository pull request runs use gate scripts from the pull request head SHA, so changes to the review gate can be validated before merge. Fork and manual validation runs use the default branch gate scripts.
13+
The required gate executes scripts from the default branch so review validation is not controlled by pull request code.
1414

1515
Before merge, the author should also confirm the SENAR done gate:
1616

specs/002-main-branch-protection/plan.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ No new abstraction is added; the existing config list is extended with the missi
3838
| AC-004 | `tests/ai-review-workflow.test.mjs` verifies trigger comment permission denial is handled with an explicit degraded-mode warning. |
3939
| AC-005 | `tests/ai-review-workflow.test.mjs` verifies the workflow uses `secrets.AI_REVIEW_GITHUB_TOKEN` before falling back to `github.token`. |
4040
| AC-006 | `tests/ai-review-workflow.test.mjs` verifies resolved Codex review threads are filtered out before review evidence classification. |
41-
| AC-007 | `tests/ai-review-workflow.test.mjs` verifies same-repository pull request runs checkout gate scripts from the pull request head SHA. |
4241

4342
Negative scenario evidence:
4443

specs/002-main-branch-protection/spec.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ As a repository maintainer, I want `main` protected by a PR-only workflow, so th
3232
4. Given the `AI Review` workflow token cannot write issue comments, when the trigger comment cannot be posted, then the gate logs the permission limitation and waits for existing or human-triggered review evidence instead of crashing with a stack trace.
3333
5. Given `AI_REVIEW_GITHUB_TOKEN` is configured as a repository Actions secret, when `AI Review` runs, then review-gate API calls use that token instead of the built-in `github.token`.
3434
6. Given a blocking Codex review thread has been resolved, when `AI Review` evaluates review evidence, then the resolved comment is not treated as an active blocker.
35-
7. Given the `AI Review` gate itself changes in a same-repository pull request, when the required check runs, then it validates using the pull request head gate scripts instead of stale default-branch scripts.
3635

3736
## Negative Scenarios
3837

@@ -47,7 +46,6 @@ As a repository maintainer, I want `main` protected by a PR-only workflow, so th
4746
- FR-005: Trigger comment permission denial must be handled as an explicit degraded mode, not as an uncaught script exception.
4847
- FR-006: The `AI Review` workflow must support an `AI_REVIEW_GITHUB_TOKEN` repository secret override for review-gate API calls.
4948
- FR-007: Resolved Codex review threads must not count as active blocking review evidence.
50-
- FR-008: Same-repository pull request `AI Review` runs must use gate scripts from the pull request head SHA so gate changes are testable before merge.
5149

5250
## Success Criteria
5351

specs/002-main-branch-protection/tasks.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
- [x] T011 Handle trigger comment permission denial without an uncaught exception.
1616
- [x] T012 Add `AI_REVIEW_GITHUB_TOKEN` secret override for review-gate API calls.
1717
- [x] T013 Ignore resolved Codex review threads when classifying active review evidence.
18-
- [x] T014 Use same-repository pull request head gate scripts for `AI Review` validation.
1918
- [x] T015 Require `AI_REVIEW_GITHUB_TOKEN` before automatic review trigger comments.
2019

2120
## Verification
@@ -29,6 +28,7 @@
2928
### Dead Ends
3029

3130
- Direct GitHub branch protection and repository ruleset API calls returned HTTP 403 because this private repository does not currently have branch protection available on its GitHub plan.
31+
- Checking out same-repository pull request head gate scripts for the required `AI Review` job was rejected by Codex review as a P1 security issue because PR-controlled scripts would run with `GITHUB_TOKEN`/`AI_REVIEW_GITHUB_TOKEN`.
3232

3333
### Decisions
3434

@@ -38,7 +38,7 @@
3838
- Restricted automatic pull request trigger comments to same-repository PRs and treated 403 token write denial as a degraded mode that waits for existing or human-triggered review evidence.
3939
- Added `AI_REVIEW_GITHUB_TOKEN` as the repository secret override because the built-in GitHub Actions integration token can still be denied when posting native review trigger comments.
4040
- Resolved Codex review threads are filtered through GitHub GraphQL before classifying active REST review comments, because the REST pull-request comments endpoint does not expose thread resolved state.
41-
- Same-repository pull request `AI Review` runs checkout gate scripts from the pull request head SHA so fixes to the gate can satisfy the required check before the PR merges; fork and manual validation runs keep using default-branch gate scripts.
41+
- The required `AI Review` gate continues to execute default-branch scripts so review validation is not controlled by pull request code.
4242
- Automatic pull request review trigger comments require `AI_REVIEW_GITHUB_TOKEN` so command comments are authored by a trusted account instead of `github-actions[bot]`, which this repository's AI command policy rejects.
4343

4444
### Known Issues
@@ -51,5 +51,5 @@
5151
- `pnpm run preflight` passed:
5252
- feature-memory gate success for `specs/002-main-branch-protection/`
5353
- repository baseline check success
54-
- `pnpm run test` passed with 12/12 tests, including same-repository pull request AI Review trigger-mode coverage, same-repository head checkout coverage, trigger-comment permission-denial handling, `AI_REVIEW_GITHUB_TOKEN` fallback coverage, and resolved Codex thread filtering.
54+
- `pnpm run test` passed with 12/12 tests, including same-repository pull request AI Review trigger-mode coverage, trusted default-branch checkout coverage, trigger-comment permission-denial handling, `AI_REVIEW_GITHUB_TOKEN` fallback coverage, and resolved Codex thread filtering.
5555
- `git diff --check` passed with no whitespace errors.

tests/ai-review-workflow.test.mjs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,7 @@ const workflow = readFileSync(new URL("../.github/workflows/ai-review.yml", impo
66
const gate = readFileSync(new URL("../scripts/ai-review-gate.mjs", import.meta.url), "utf8");
77

88
test("same-repository pull request AI Review runs trigger the selected backend before polling", () => {
9-
assert.match(
10-
workflow,
11-
/ref:\s*\$\{\{\s*github\.event_name == 'pull_request' && github\.event\.pull_request\.head\.repo\.full_name == github\.repository && github\.event\.pull_request\.head\.sha \|\| github\.event\.repository\.default_branch\s*\}\}/
12-
);
9+
assert.match(workflow, /ref:\s*\$\{\{\s*github\.event\.repository\.default_branch\s*\}\}/);
1310
assert.match(workflow, /EVENT_NAME:\s*\$\{\{\s*github\.event_name\s*\}\}/);
1411
assert.match(workflow, /GITHUB_TOKEN:\s*\$\{\{\s*secrets\.AI_REVIEW_GITHUB_TOKEN\s*\|\|\s*github\.token\s*\}\}/);
1512
assert.match(workflow, /HAS_AI_REVIEW_GITHUB_TOKEN:\s*\$\{\{\s*secrets\.AI_REVIEW_GITHUB_TOKEN != ''\s*\}\}/);

0 commit comments

Comments
 (0)