ocra

GitHub pull requests

Review pull requests with the GitHub Action or ocra review --pr.

GitHub Action

Add a workflow to the repository you want reviewed:

name: ocra
on: pull_request

permissions:
  contents: read
  pull-requests: write

jobs:
  review:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v7
        with:
          fetch-depth: 0
      - uses: jma49/Open-CR-Agent@main
        env:
          GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}

Store your model key as a repository secret. Models come from the base branch's .ocra/config.json, or from OCRA_MODEL_* variables in env.

InputDefaultMeaning
github-token${{ github.token }}Token for reading the pull request and posting the review
argsExtra ocra review options, such as --reviewers correctness,security
fail-on-concernsfalseFail the job when the verdict is significant_concerns (a critical finding the verifier confirmed). An incomplete review (exit code 3) always fails the job

The verdict is advice. The models read the pull request, so its author can plant text that steers a reviewer away from an issue or talks the judge out of one, and an unverified model claim can be wrong. Do not make the check a required status in place of human review; if you turn on fail-on-concerns, treat a pass as "nothing confirmed", not "safe".

Pull requests from forks do not receive repository secrets on pull_request, so the review fails with a message naming the missing key. Do not switch to pull_request_target to work around it: that runs with secrets on code the fork controls.

What gets posted

  • Inline comments for findings anchored inside the diff, each marked verified, unverified or not verified, in one review with the COMMENT event. ocra never approves. Set github.requestChanges to request changes when the verdict is significant_concerns.
  • One summary comment, updated in place on every push: verdict, summary, findings outside the diff, what was fixed since the last review, and coverage and cost.

On the next push ocra reviews only what changed: the files changed since the commit the previous review covered, plus any file that review did not finish (a failed task, for example). Findings in unchanged files carry over as they were: still open, still counted in the verdict, not commented again. Everything is reviewed again when the previous commit is no longer part of the branch (force-push or rebase), when the summary comment was last edited by someone other than ocra, or when you pass --full (for example in the action's args). The summary says which it was and why.

ocra then compares findings with the previous review:

  • A finding it already commented on is not commented again.
  • A finding counts as fixed only when the code it pointed at is no longer in the file, or the file was deleted. Fixed findings are listed and their inline threads resolved.
  • A finding that no reviewer reported this time, while its code is unchanged, is listed as not reported this time. Model runs vary, so it stays open: its thread is not resolved, it is not commented again, and it keeps counting towards the verdict with its original severity until the code changes or a reviewer dismisses it. The same code reviewed twice gets the same verdict.
  • A finding whose file was not reviewed this time (a failed task, for example) is listed as not re-checked and also stays open.

Reviewers stay in charge. If someone other than the pull request's author resolves one of ocra's threads, or a repository owner, member or collaborator (not the author) replies with a clear decline such as "won't fix", "by design", "false positive" or "acknowledged", the finding counts as dismissed: it is no longer reported and no longer affects the verdict, unless a later run finds it with a higher severity. Replying "I disagree" does not dismiss it, and the author cannot dismiss findings on their own pull request, so the check cannot be resolved away.

What the pull request can and cannot change

The pull request is untrusted input. ocra reads .ocra/config.json, .ocra/rules.json, .ocra/memory.json and AGENTS.md from the base commit, never from the pull request, and never loads repository plugins in this mode. The diff, title and description still reach the reviewers as data, with the protections described in Security.

Configuration

{ "github": { "requestChanges": false, "botLogin": "github-actions[bot]" } }

botLogin is the account whose summary comment counts as ocra's earlier review; change it if you post with another token.

From the command line

export GITHUB_TOKEN=...           # a token that can read the repository
ocra review --pr 42               # review and print, like a local review
ocra review --pr 42 --publish     # also post the review

The repository comes from --repo owner/name, GITHUB_REPOSITORY, or the origin remote. ocra fetches the pull request's commits if they are missing locally.

Edit on GitHub

On this page