PR workflow

What CrossCheck does on every pull request, and the knobs that change it.

What posts on every PR

Out of the box, every PR against a connected repo gets:

  1. A GitHub Check named "CrossCheck" — appears with status in_progress while the review runs, then flips to success / failure / neutral based on the results.
  2. A single sticky comment on the PR listing every check as pass, fail, or needs_review, grouped by check group, with file:line evidence on the non-pass rows. Each subsequent run on the same PR updates the same comment — your PR doesn't fill up with comment history.
  3. A link to the run on CrossCheck at the top of the comment for the full timeline, agent reasoning, and evidence viewer.

The default behavior is report-only: CrossCheck never approves, merges, or blocks unless you opt in.

When reviews run

A review fires automatically when:

  • A PR is opened, synchronized (new commits pushed), or reopened.
  • The repo is in the GitHub App's scope.

If a new commit is pushed mid-review, the in-flight run is cancelled (its partial results are kept and billed for) and a fresh run starts against the new head SHA. The CrossCheck comment always reflects the most recent run.

Manual re-review

Open any PR on CrossCheck and click Re-review. This fetches the current head SHA from GitHub and enqueues a fresh run, bypassing the dedupe window. Useful when:

  • You changed a check or attached a new check group and want to apply it to an existing PR.
  • A run failed for an infrastructure reason (the agent timed out, a sandbox died) and you want to retry.

Re-review counts against your credit pool. If the pool is exhausted the button returns a 402; see Credits and billing.

Auto-approve and auto-merge

Per-repo setting on the Settings tab, or in cross-check.yaml as config.pass_behavior.

SettingBehavior
report_onlyDefault. CrossCheck posts the comment and check; never modifies PR state.
approveWhen all checks pass on a non-draft PR, CrossCheck submits a APPROVE review.
approve_and_mergeAs above, plus enables GitHub's auto-merge so the PR merges once required checks turn green. Falls back to a direct merge if every required check is already green at approve time.

Branch protection still gates the actual merge. If your branch requires two human approvers, CrossCheck's approval counts as one. If it requires no AI approvals, CrossCheck's approval is ignored. CrossCheck never bypasses branch protection.

When approve_and_merge is on and the merge can't proceed (failing checks, conflicts, missing approvals), the reason is included in the sticky PR comment under an "auto-merge" section so it's visible without leaving GitHub.

Drafts

By default, CrossCheck reviews every PR — drafts included — as soon as it sees a pull_request webhook for a connected repo.

To pause reviews on a specific repo without uninstalling the GitHub App, detach all check groups from the repo. With nothing to evaluate, the runner exits immediately and no comment is posted. (More granular trigger modes — skip drafts, manual-only — are on the roadmap.)

General review (inline code review)

Per-repo setting; off by default. When general_review.mode: enabled is set, CrossCheck additionally runs a Claude-Code-style code review on every PR:

  • Inline comments appear on lines the reviewer flagged with high-confidence findings (style nits, bugs it spotted while reading, security smells). On the next run, threads the reviewer thinks are addressed are auto-resolved.
  • A "General review" section is added to the sticky CrossCheck comment with a top-level summary and verdict.

Tuneables:

SettingDefaultBehavior
general_review.modeoffenabled turns the feature on.
general_review.required_for_approvefalseWhen true, the general-review verdict must be "approve" for pass_behavior to fire.
general_review.prompt_overridenullReplace the built-in code-review prompt with your own.

General review uses the deep tier and burns credits on top of your statement evaluation — turn it on per repo, not org-wide, until you know your usage shape.

Failure handling

Today, CrossCheck never blocks a PR. A failing check shows up as a failure on the GitHub Check and the sticky comment lists the violations, but GitHub doesn't require a passing CrossCheck check unless you add it to branch protection yourself.

If you want CrossCheck to be a required check on your protected branches:

  1. Open the branch's protection rules on GitHub.
  2. Under Require status checks, add CrossCheck.
  3. Open and merge one PR so GitHub sees the check name.

After that, branch protection won't let a PR merge while CrossCheck is failure.

A fail_behavior field exists in the config schema (report_only | configurable_block | always_block) but is reserved for future versions of CrossCheck-driven blocking. For now, use branch protection.

What happens if CrossCheck breaks

SymptomWhat happens
The agent itself crashesThe check shows failure with an error message in the run detail. Click Re-review to retry.
The worker dies mid-runThe CrossCheck check eventually flips to failure (the stale-run sweeper catches it within ~90 min). Click Re-review to retry sooner.
A check repeatedly returns needs_reviewThe agent isn't getting evidence it can use. Sharpen the description; see Writing good checks.
Your credit pool is exhaustedA comment is posted explaining how to enable overage. New reviews don't run until you do.

CrossCheck won't make a PR un-mergeable on its own. Even when a review fails infrastructurally, your branch protection rules decide what happens next.