Skip to content

[reviewer] Add phase-1 AI code reviewer#4022

Draft
brentvatne wants to merge 9 commits into
mainfrom
add-ai-code-reviewer
Draft

[reviewer] Add phase-1 AI code reviewer#4022
brentvatne wants to merge 9 commits into
mainfrom
add-ai-code-reviewer

Conversation

@brentvatne

Copy link
Copy Markdown
Member

Why

Phase 1 of an AI code reviewer for eas-cli, per the internal spec. The goal is to prove the pipeline end-to-end and tune signal quality on real PRs before granting it any authority — so it runs comment-only / non-blocking: it never blocks a merge and never auto-approves.

How

Adds a self-contained reviewer under tools/reviewer/:

  • Two specialist agents run in parallel — correctness & code-quality and security & secrets — then a coordinator consolidates (dedupe → re-judge severity → decide) into one structured review.
  • One invariant core (src/core.ts) with swappable edges: a Source (GitHubPRSource for CI, LocalGitSource for local) and a Reporter (GitHubReporter posts one PR comment, TerminalReporter prints + exit code). CI and local produce identical findings from the same core.
  • CI mode: .github/workflows/ai-review.yml, triggered on pull_request, continue-on-error throughout. Break-glass via a maintainer /skip-review comment.
  • Local mode: cd tools/reviewer && bun run review [--staged | --base <ref> --head <ref> | --json | --no-fail]. Also exposed as an /expo-review Claude Code command.
  • Noise filtering (lockfiles, generated, snapshots), prompt-injection sanitization of PR metadata, and JSONL run logging.

Built on Bun + the OpenCode SDK, fully isolated from eas-cli's yarn/lerna toolchain: its own package.json/bun.lock, excluded from the root oxlint/oxfmt config, and no imports from packages/ (it only reads the repo as text). Structured for later extraction into a standalone expo/opencode-reviewer repo.

Two known phase-1 limitations are documented rather than fixed: CI runs PR-controlled code with secrets (mitigated for forks by on: pull_request withholding secrets + the first-time-contributor approval gate; residual risk on trusted same-repo PRs), and the break-glass check reads only the most recent 100 comments.

Test Plan

  • bunx tsc --noEmit in tools/reviewer/ passes.
  • Ran the full pipeline end-to-end locally against the working tree (REVIEWER_MODEL=openai/gpt-5.4-mini-fast bun run review): server → 2 concurrent reviewers → coordinator → terminal report → exit code → JSONL log, ~3.5 min/run. It surfaced real findings (including in its own code, which were then fixed).
  • Verified --staged short-circuit (no changes → approve, exit 0, valid --json).
  • No automated tests yet (deferred to a follow-up); phase 1 is comment-only and non-blocking so a reviewer failure cannot fail PR checks.

🤖 Generated with Claude Code

Two-agent (correctness + security) AI code reviewer under tools/reviewer/,
consolidated by a coordinator into one structured review. Runs in CI
(comment-only, non-blocking) via .github/workflows/ai-review.yml and locally
via `bun run review`.

Built on Bun + the OpenCode SDK and fully isolated from eas-cli's yarn/lerna
toolchain: its own package.json/bun.lock, excluded from root oxlint/oxfmt, and
no imports from packages/. Also adds an /expo-review Claude Code command.
@brentvatne brentvatne added the no changelog PR that doesn't require a changelog entry label Jul 15, 2026
The SDK spawns `opencode` from PATH; CI only had the npm SDK. Pin opencode-ai
as a dependency and run the CI step as a package script with node_modules/.bin
on PATH so the binary resolves.
… from run log

- handle is now let handle: OpencodeHandle | null = null with handle?.close()
  in finally (defensive; the flagged crash path was not actually reachable).
- Run log records only baseRef/headRef, never author-controlled PR title/body,
  so secrets pasted into a PR description are not persisted to reviews.jsonl.
… ls-files

- --base/--head now error clearly if given no value (or another flag).
- Untracked-file listing uses git ls-files -z so filenames with newlines parse.
@codecov

codecov Bot commented Jul 16, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 60.57%. Comparing base (ac761ed) to head (ca8fd12).

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #4022   +/-   ##
=======================================
  Coverage   60.57%   60.57%           
=======================================
  Files         955      955           
  Lines       42073    42073           
  Branches     8834     8834           
=======================================
  Hits        25480    25480           
+ Misses      16499    16494    -5     
- Partials       94       99    +5     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

…PR comment

- Reviewers and coordinator now emit only critical/warning; core drops any
  stray suggestion and downgrades approve_with_comments to approve if nothing
  substantive remains.
- Each finding gets a stable fingerprint (file + category + normalized title,
  line-independent), embedded hidden in the comment.
- GitHubReporter now upserts one comment: updates the existing reviewer comment
  in place and deletes older duplicates, so re-reviews converge instead of
  posting a fresh comment each run.
Models occasionally return malformed/truncated JSON; a single run should not
fail the whole review. promptAndParse re-prompts once with a corrective nudge in
a fresh session before giving up.
@expo expo deleted a comment from github-actions Bot Jul 16, 2026
This is the general Expo AI code reviewer, not eas-specific. Centralize the tag
so the comment marker and embedded-fingerprint marker can't drift.
@github-actions

Copy link
Copy Markdown

⏩ The changelog entry check has been skipped since the "no changelog" label is present.

@github-actions

Copy link
Copy Markdown

🤖 AI code review

Decision: Approve

Both specialist reviewers completed their analysis with no critical or warning-level findings. The PR is clean and ready to merge.

No findings.


Phase 1: comment-only. This review never blocks a merge and never auto-approves.

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

Labels

no changelog PR that doesn't require a changelog entry

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant