Review Workflow
This page covers day-to-day Apex Ray usage after installation and project initialization.
Choose A Review Target
Use one target per review run:
| Target | Command | Use when |
|---|---|---|
| Unstaged worktree changes | apex-ray review --worktree |
You are iterating locally before staging. |
| Staged changes | apex-ray review --staged |
You want review to match the next commit. |
| Branch diff | apex-ray review --base main |
You want PR-like review of main...HEAD. |
| Supplied diff file | apex-ray review --diff change.diff |
You captured a patch outside the current worktree. |
| Partial report continuation | apex-ray review --continue-from .apex-ray/reports/review.json |
You need to review skipped or residual context packs. |
Reports are written under .apex-ray/reports/ by default. For stable automation, pass explicit paths:
apex-ray review \
--base main \
--llm \
--output .apex-ray/reports/review.md \
--json .apex-ray/reports/review.json \
--html .apex-ray/reports/review.html \
--sarif .apex-ray/reports/review.sarif
For --worktree, every writable report or cache path inside the repository
must be untracked and Git-ignored so report/checkpoint/cache writes cannot
change the review target. This includes custom LLM and analyzer cache paths and
relative APEX_RAY_CACHE_HOME/XDG_CACHE_HOME values. The defaults created by
apex-ray init satisfy this requirement; an external absolute path is also
safe. Apex Ray checks these paths before running analyzers or providers.
Review Modes
No-LLM mode is deterministic and cheap:
It still parses the diff, runs available language analyzers, builds context packs, and reports review coverage surfaces.
LLM mode sends selected context packs to the configured provider, which may be a local CLI, a built-in direct API, or a custom compatible endpoint:
By default, the configured verifier reviews candidate findings before they are published. Use --no-verify only for exploratory runs where speed matters more than publication quality.
Reports
Apex Ray writes:
- Markdown for local reading.
- JSON for durable automation and continuation.
- Optional HTML for browser-based inspection.
- Optional SARIF 2.1.0 for GitHub code scanning and other compatible systems.
Reports include findings, analyzer warnings, selected context packs, skipped packs, LLM routes, cache usage, token estimates, coverage status, and continuation commands.
Report paths are latest snapshots by default. Reusing the same paths overwrites the previous latest report. apex-ray init enables report archives so per-run artifacts survive short-lived worktrees:
Report artifacts can include source snippets, findings, file paths, provider metadata, and token estimates. Keep generated reports ignored unless a team intentionally curates a specific artifact.
Coverage And Continuation
LLM coverage modes control how broadly Apex Ray reviews a diff:
fast: capped deep review.balanced: deep review for high-value packs plus shallow breadth under token budget.exhaustive: prioritize every reviewable pack, while still honoring pack, deep-review, input-token, and provider limits.
Large diffs can still be partial. The report makes partial coverage explicit with reviewed and unreviewed pack IDs, residual priorities, skipped reasons, and continuation commands.
The report-level LLM completion status has a separate, deliberately strict meaning:
complete: every context pack and matching reviewer assignment in the report scope was reviewed and no partial coverage debt remains;partial: reviewable work remains, but the run did not record a hard execution or budget failure;incomplete: work remains because a pack could not fit the configured budget, a reviewer execution or verification failed, or required-reviewer policy debt remains;disabled: LLM review was not enabled for the run.
Findings always describe the reviewed scope. “No blocking findings” or zero findings in a partial/incomplete report does not mean that the entire diff was reviewed cleanly. Unique context-pack coverage and reviewer assignments are also different counters: one pack reviewed by two specialists is one reviewed pack but two completed reviewer-pack assignments.
Continue only unreviewed P0 packs:
An ordinary continuation is one budgeted reviewer pass. The effective
max_packs, max_deep_packs, and max_input_tokens values still apply to
each selected reviewer; CLI --llm-max-* overrides remain run-wide cost
limits. Repeat the command for another manual pass, or use bounded completion
when the selected reviewer scope must be drained automatically.
Drain one baseline reviewer scope in bounded batches:
apex-ray review \
--continue-from .apex-ray/reports/review.json \
--reviewer correctness \
--until-complete \
--followup-max-pack-reviews 16 \
--max-followup-passes 8 \
--llm
--until-complete writes the best report it can produce and reports why it
stopped. Add --strict-coverage when an incomplete result must exit non-zero;
reports are still written before that exit. --strict-coverage implies the
same completion loop, so it can also be used without spelling
--until-complete.
After every completed follow-up batch, Apex Ray writes each configured
Markdown and JSON latest-report file through an atomic replacement. If the
process is later interrupted, the JSON file is a valid resume point for
another --continue-from run rather than a partially written artifact.
Optional HTML, SARIF, telemetry, and archives are finalized after the loop.
Each follow-up batch is capped in reviewer-pack assignments by
--followup-max-pack-reviews, and --max-followup-passes bounds the number of
batches. Provider retries and verification requests are additional calls. The
loop stops early on completion, no eligible work, or no measurable progress.
It cannot be combined with --auto-followup, continuation pack/slice/priority
filters, or --no-llm.
Pass one or more --reviewer flags to make the completion scope explicit. If
they are omitted, a configuration with several enabled reviewers must have
exactly one required: true baseline reviewer; otherwise the command rejects
the ambiguous scope. A configuration with only one enabled reviewer and the
built-in general-reviewer configuration are unambiguous. On a fresh review,
that uniquely required baseline is the only reviewer run by the completion
command; other configured reviewers are not started implicitly.
Explicit reviewer completion applies only to context packs matching the
selected reviewer filters and to that reviewer's assignments. It does not
drain unrelated global packs. The scoped coverage_completion result can
therefore be complete while the report-level LLM coverage remains partial
because debt exists outside the selected matching scope. Use an unfiltered
baseline reviewer when the completion check is intended to cover the full
reviewable diff.
exhaustive alone is not a completion contract: it still obeys the configured
caps. Use bounded completion when the selected reviewer scope is a release or
CI requirement, and size its limits for the expected worst case.
Safe Continuation Targets
New reports fingerprint their review input. Before a continuation makes an LLM call, Apex Ray verifies the saved target:
- base reviews retain
HEAD, merge-base, and diff identities; - staged and worktree reviews retain
HEADand diff identities; - incremental pre-push Git ranges retain their range start,
HEAD, and diff identities and remain live Git targets; - only user-supplied
--difffiles become immutable, detached report snapshots.
If the live base, staged, worktree, or incremental range target changed,
continuation stops and asks for a fresh review instead of attributing archived
context packs to the new diff. The completion loop repeats this check around
every batch. A detached --diff continuation prints a notice because live Git
state is not part of its target.
Reports produced by older Apex Ray versions have no input snapshot. Ordinary
non-completion --continue-from remains available for compatibility, but Apex
Ray prints a warning and can only review archived context packs; it cannot
prove that they match the current Git state. --until-complete and
--strict-coverage reject such reports because a multi-batch completion
contract cannot run safely without target validation. Run a fresh review to
use bounded completion.
Continue with automatic P0 follow-up after a first pass:
This CLI switch retains the focused P0 behavior. The automatic pass is capped
by reviewer-pack assignment, so a context pack matched by two specialist
reviewers consumes two assignments. Explicit --continue-from or bounded
completion commands remain available when you intentionally want to process
more residual work.
Pre-Push Gate
apex-ray gate pre-push runs the configured gate policy over review.base...HEAD.
Default gate behavior:
- writes
.apex-ray/reports/pre-push.mdand.apex-ray/reports/pre-push.json; - blocks on verified
highorcriticalfindings; - blocks on failed LLM coverage quality gate;
- blocks on
criticalpartial coverage; - prints live progress to stderr and a compact blocking summary to stdout.
The generated configuration enables a generalized automatic follow-up capped
at 16 primary reviewer-pack assignments. It selects the exact packs behind the
blocking decision: the default critical partial threshold contributes P0
work, major expands threshold debt to P0/P1, and minor to P0/P1/P2;
provider/verifier failures, unfinished selected required-reviewer assignments, configured
source/high-risk thresholds, and high-risk depth debt remain eligible by their
concrete pack IDs. Matching assignments deferred by reviewer limits remain
visible as warnings unless an explicit strict/complete coverage policy requires
them.
Retries, provider fallbacks, and finding verification may add requests. See
Pre-Push Gate configuration for the canonical
and legacy keys.
Run it manually before relying on hook behavior:
If a bounded pass leaves blocking P0 debt, the next eligible incremental attempt resumes the validated pre-push report for another bounded pass. The printed continuation commands also write back to that report, so a completed manual continuation clears the carried debt. If commits were added in the meantime, Apex Ray requires one additional gate run to review that pending delta. Response and analyzer caches reduce repeated work throughout this process. If a carried coverage retry has no eligible work while newer commits are pending, the gate refreshes the full current base range immediately instead of repeatedly starving that delta. Continuation guidance uses POSIX shell syntax on macOS/Linux and explicitly PowerShell-safe syntax on Windows.
Local False Positives
For a confirmed one-off local false positive, create an expiring local suppression instead of bypassing the gate:
apex-ray findings list --from-report .apex-ray/reports/pre-push.json
apex-ray findings suppress apex-<id> \
--from-report .apex-ray/reports/pre-push.json \
--reason "This path is guarded before the reviewed helper is called."
Use suppressions sparingly. Inspect the finding evidence, current code, and relevant tests or invariants before suppressing. The reason should be concrete enough for a later agent to audit; do not suppress uncertain findings or real defects just to get a push through.
The next apex-ray gate pre-push run still writes the raw finding in the report, but the gate decision lists it under suppressed findings and does not block on it. Suppressions are local, expire automatically, and become stale when the matching context pack changes. When that happens, the gate output/report prints the stale suppression and prior reason, and the finding blocks again until it is re-checked. Use apex-ray findings suppressions, apex-ray findings unsuppress sup-<id>, or apex-ray findings prune for cleanup.
Commit a kind: false_positive memory card only for repeated, generalizable calibration. Do not commit raw local suppressions.
Caches
Apex Ray uses two local caches by default:
${local_data}/cache/llmfor provider responses keyed by prompt context and routing. With the defaultreview.local_data.root: git_common, linked worktrees from the same local clone share this cache.- analyzer repo index caches where a backend supports them. Today this applies to TypeScript/JavaScript and Dart repository analysis; the Python analyzer is in-process and does not yet maintain a persistent repo index cache.
Refresh LLM cache entries:
Refresh analyzer cache entries:
Disable the LLM cache for one run:
Privacy Boundary
Without --llm, Apex Ray stays local and deterministic.
With --llm, Apex Ray sends selected diff and context-pack content to the
configured provider. A local CLI controls its own network and account boundary;
a direct API provider sends HTTPS requests to its configured service endpoint.
Review the applicable CLI, API, gateway, account, privacy, and retention policy
before using Apex Ray on private code. Caches, telemetry, and archived reports
are local files, while CI artifacts and SARIF follow the retention and access
policy of the CI platform. All may contain repository paths, model names,
finding counts, provider metadata, and source snippets.
For a pull-request workflow with protected API secrets, reviewer matrices, artifacts, and SARIF upload, see GitHub Actions.
Common Troubleshooting
Run setup diagnostics:
Typical issues:
Config: not found: runapex-ray initin the target repository or pass--config.Python analyzer available: false: reinstall Apex Ray or run from a healthy source checkout. The Python analyzer is built in and should normally be available whenever the CLI imports successfully.TypeScript analyzer built: false: reinstall the published package, or in a source checkout run the TypeScript analyzer build from Development.Dart analyzer available: false: select the project's Dart/Flutter SDK, activate FVM, or configurereview.analyzer.dart.command; then resolve dependencies with the same SDK. See Dart analyzer configuration.- Dart package imports are unresolved: run
flutter pub getordart pub getin the relevant workspace or package using the SDK shown bydoctor. - Dart results remain stale after an SDK or package metadata change: run one
review with
--refresh-analyzer-cache, then return to normal cached reviews. - Provider command not found: for a CLI provider, install the configured Codex CLI or Claude Code CLI, or override its executable path in
.apex-ray/config.local.yml. - API credential or endpoint rejected: check the selected environment-variable names and, in CI,
APEX_RAY_API_ALLOWED_HOSTSplus the role-specificAPEX_RAY_API_ALLOWED_BASE_URL_ENV_VARS,APEX_RAY_API_ALLOWED_API_KEY_ENV_VARS, andAPEX_RAY_API_ALLOWED_HEADER_ENV_VARSpolicies. For a custom CI orchestrator, set trusted job variableAPEX_RAY_CI=true. - Hook cannot find
apex-ray: install Apex Ray on the userPATHused by git hooks, or update the hook environment.