|
Some checks are pending
CI / test (push) Waiting to run
CI / cross-compile (amd64, darwin) (push) Waiting to run
CI / cross-compile (amd64, windows) (push) Waiting to run
CI / cross-compile (arm64, darwin) (push) Waiting to run
CI / cross-compile (arm64, linux) (push) Waiting to run
CI / cross-compile (arm64, windows) (push) Waiting to run
* refactor(examples): extract GitLab CI heredoc into post_review.py with unit tests Extracts the ~270-line inline heredoc from .gitlab-ci.yml into a standalone, testable post_review.py module, matching the publish() + make_poster() pattern established by gerrit_ci/ and gitflic_ci/. Key design decisions (from spec issue #1 and wayfinder tickets #3, #4, #5): - publish(result, diff_refs, post, config, sleep) — transport-agnostic - make_poster(api_base, token, auth_header, config) — GitLab REST transport - fetch_diff_refs(api_base, token, auth_header, config) — /versions GET with retry - Single config dict built by main() from env vars; no module-level config state - post() returns {success, rate_limit_remaining, is_rate_limit_exhausted} to preserve failure-pacing behavior (rate-limit vs non-rate-limit delays) - _sleep = time.sleep module-level pattern for testability All existing heredoc behavior preserved 1:1: - GitLab suggestion:-0+0 syntax and <details> fallback format - Retry on 429/403-rate-limit/5xx/408 with exponential backoff + ±25% jitter - Retry-After header honoring, MAX_RETRY_DELAY cap - Proactive RateLimit-Remaining throttling (success path only) - Failure pacing: rate-limit-exhausted → SUCCESS_DELAY, other → FAILURE_DELAY - PRIVATE-TOKEN vs JOB-TOKEN auth selection - Inline → fallback → summary ordering - Parse failure → post stderr as error note - All 6 env vars (OCR_RETRY_BASE_DELAY, OCR_MAX_RETRIES, OCR_MAX_RETRY_DELAY, OCR_SUCCESS_DELAY, OCR_FAILURE_DELAY, OCR_RATE_LIMIT_THRESHOLD) 48 unit tests (stdlib unittest, no network, no real time.sleep): - Seam 1: publish() with Recorder fake poster — inline/fallback/summary flow, proactive throttling, failure pacing - Seam 2: make_poster() with mocked urlopen + _sleep — retry/backoff/jitter, Retry-After, delay cap, auth headers, is_rate_limit_exhausted classification - fetch_diff_refs() with mocked urlopen — success/failure/retry - build_config() defaults and env overrides - Dry-run poster — no HTTP calls Implements #534. * fix(examples): address code review findings on gitlab_ci post_review - Add missing-required check for CI_PROJECT_ID and CI_MERGE_REQUEST_IID in main(), matching gerrit_ci/gitflic_ci pattern. The heredoc used os.environ[...] (KeyError on missing); the extraction silently used env.get(..., "") which constructs a malformed API URL. Now fails fast with a clear error message. - Change transient_base_delay from int 2 to float 2.0 to match spec config-dict type annotation. - Add 5 end-to-end tests for main()'s auth-header env resolution: PRIVATE-TOKEN when GITLAB_API_TOKEN set, JOB-TOKEN when only CI_JOB_TOKEN set, PRIVATE-TOKEN wins when both set, missing CI vars fails fast, missing token fails fast. Addresses review findings: #3 (TP, medium), #4 (Edge), #5 (TP, low). * fix(examples): handle URLError in gitlab_ci post_review retry logic _api_request_with_retry only caught HTTPError, not URLError. Network-layer failures (DNS resolution failure, connection refused, connection reset) raised URLError which propagated uncaught, crashing the script and losing all pending review comments. The original heredoc had the same gap, but the gerrit_ci sibling already handles this correctly (lines 250-259: retry on connection errors, propagate timeouts). This fix follows the gerrit_ci pattern adapted to our return-dict contract: - Add 'except urllib.error.URLError' handler after HTTPError handler - Timeout (socket.timeout/TimeoutError): return failure dict, don't retry (ambiguous — server may have processed the request) - Connection errors (DNS, refused, reset): retry with transient_base_delay backoff + ±25% jitter, same as 5xx/408 handling - Exhaustion: return failure dict with is_rate_limit_exhausted=False 3 new tests: - test_retry_urlerror_then_success: ConnectionRefused → retry → success - test_urlerror_exhausts_retries: 4 ConnectionRefused → failure after 4 attempts - test_urlerror_timeout_not_retried: socket.timeout → immediate failure, no retry Found by OCR (open-code-review) AI code review. * fix(examples): handle non-UTF-8 HTTP error bodies in gitlab_ci post_review e.read().decode('utf-8') raises UnicodeDecodeError when the GitLab server returns a non-UTF-8 error body (e.g., an HTML error page in latin-1 from a misconfigured proxy or load balancer). This exception propagated uncaught, crashing the entire posting loop — no further inline comments, fallback notes, or summary notes would be posted. Both gerrt_ci (line 242: decode('utf-8', 'replace')) and gitflic_ci (line 344: decode('utf-8', 'replace')) siblings already handle this correctly. The original heredoc had the same gap. Fix: add errors='replace' to both decode() calls (success path line 248 + error path line 260). For valid UTF-8 input (the normal case), behavior is identical. The error body is only used for keyword matching and logging, both of which work fine with replacement characters (U+FFFD). 1 new test: - test_non_utf8_error_body_does_not_crash: HTTPError with invalid UTF-8 body → no crash, returns failure dict Found by OCR (open-code-review) AI code review on PR #539. |
||
|---|---|---|
| .claude/commands | ||
| .claude-plugin | ||
| .github | ||
| bin | ||
| cmd/opencodereview | ||
| examples | ||
| extensions/vscode | ||
| imgs | ||
| internal | ||
| npm | ||
| pages | ||
| plugins/open-code-review | ||
| scripts | ||
| skills | ||
| .gitignore | ||
| .npmignore | ||
| action.yml | ||
| ASSURANCE_CASE.md | ||
| CODE_OF_CONDUCT.md | ||
| CONTRIBUTING.ja-JP.md | ||
| CONTRIBUTING.ko-KR.md | ||
| CONTRIBUTING.md | ||
| CONTRIBUTING.ru-RU.md | ||
| CONTRIBUTING.zh-CN.md | ||
| go.mod | ||
| go.sum | ||
| GOVERNANCE.md | ||
| install.ps1 | ||
| install.sh | ||
| LICENSE | ||
| Makefile | ||
| package.json | ||
| README.ja-JP.md | ||
| README.ko-KR.md | ||
| README.md | ||
| README.ru-RU.md | ||
| README.zh-CN.md | ||
| ROADMAP.md | ||
| SECURITY.md | ||
English | 简体中文 | 日本語 | 한국어 | Русский
What is Open Code Review?
Open Code Review is an AI-powered code review CLI tool. It originated as Alibaba Group's internal official AI code review assistant — over the past two years, it has served tens of thousands of developers and identified millions of code defects. After thorough validation at massive scale, we incubated it into an open source project for the community. Simply configure a model endpoint to get started.
It reads Git diffs, sends changed files to a configurable LLM via an agent with tool-use capabilities, and generates structured review comments with line-level precision. The agent can read full file contents, search the codebase, inspect other changed files for context, and produce deep reviews — not just surface-level diff feedback. Beyond diff review, ocr scan reviews entire files for auditing unfamiliar codebases or directories that have no meaningful diff.
Visit the official website for more details.
Benchmark
Compared to general-purpose agents (Claude Code), Open Code Review achieves significantly higher Precision and F1 with the same underlying model, while consuming only ~1/9 of the tokens and completing reviews faster. Note that its Recall is lower than general-purpose agents — a deliberate trade-off favoring precision over noise.
A real-world code review benchmark built from 50 popular open-source repositories, 200 real Pull Requests, and 10 programming languages — cross-validated by 80+ senior engineers (1,505 annotated ground-truth issues).
| Metric | What it measures | Why it matters |
|---|---|---|
| F1 | Harmonic mean of precision and recall | Best single number for overall review quality |
| Precision | Proportion of reported issues that are real defects | Higher = fewer false alarms to triage |
| Recall | Proportion of real defects that are found | Higher = fewer issues slip through review |
| Avg Time | Wall-clock time per review | Matters for CI pipeline latency |
| Avg Token | Total tokens consumed per review | Directly impacts API cost |
Why Open Code Review?
The Problem with General-Purpose Agents
If you've used general-purpose agents like Claude Code with Skills for code review, you've likely encountered these pain points:
- Incomplete coverage — On larger changesets, agents tend to "cut corners," selectively reviewing only some files and missing others.
- Position drift — Reported issues frequently don't match the actual code location, with line numbers or file references drifting off target.
- Unstable quality — Natural-language-driven Skills are hard to debug, and review quality fluctuates significantly with minor prompt variations.
The root cause: a purely language-driven architecture lacks hard constraints on the review process.
Core Design: Deterministic Engineering × Agent Hybrid
Open Code Review's core philosophy is to combine deterministic engineering with an agent, each handling what it does best.
Deterministic Engineering — Hard Constraints
For review steps that must not go wrong, engineering logic — not the language model — guarantees correctness:
- Precise file selection — Determines exactly which files need review and which should be filtered, ensuring no important change is missed.
- Smart file bundling — Groups related files into a single review unit (e.g.,
message_en.propertiesandmessage_zh.propertiesare bundled together). Each bundle runs as a sub-agent with isolated context — a divide-and-conquer strategy that stays stable on very large changesets and naturally supports concurrent review. - Fine-grained rule matching — Matches review rules to each file's characteristics, keeping the model's attention sharply focused and eliminating information noise at the source. Compared to purely language-driven rule guidance, template-engine-based rule matching is more stable and predictable.
- External positioning and reflection modules — Independent comment-positioning and comment-reflection modules systematically improve both the location accuracy and content accuracy of AI feedback.
Agent — Dynamic Decision-Making
The agent's strengths are concentrated where they matter most — dynamic decisions and dynamic context retrieval:
- Scenario-tuned prompts — Prompt templates deeply optimized for code review, improving effectiveness while reducing token consumption.
- Scenario-tuned toolset — Distilled from deep analysis of tool-call traces in large-scale production data — including call frequency distributions, per-tool repetition rates, and the impact of new tools on the overall call chain — resulting in a purpose-built toolset that is more stable and predictable for code review than a generic agent toolkit.
How to Use
Prerequisites
- Git >= 2.41 — Open Code Review relies on Git for diff generation, code search, and repository operations.
CLI
Install
npm install -g @alibaba-group/open-code-review
After installation, the ocr command is available globally.
For other installation methods (install script, GitHub Release binary, from source), see Installation.
Quick Start
1. Configure LLM
You must configure an LLM before reviewing code, unless you use Delegation Mode.
ocr config provider # Select a built-in provider or add a custom one
ocr config model # Pick a model for the active provider
The interactive UI guides you through provider selection, API key entry, and model configuration, then automatically tests connectivity.
For CLI setup, environment variables, custom providers, and other advanced configuration, see Configuration.
2. Review
cd your-project
# Workspace mode — review all staged, unstaged, and untracked changes
ocr review
# Branch range — compare two refs
ocr review --from main --to feature-branch
# Single commit
ocr review --commit abc123
# Resume an interrupted range or commit review
ocr session list
ocr review --from main --to feature-branch --resume <session-id>
# Full-file scan — review whole files instead of a diff (no git history needed)
ocr scan # scan the entire repository
ocr scan --path internal/agent # scan a directory or specific files
# Delegation mode — let your AI coding agent perform the review itself
# OCR handles file selection and rule resolution; no LLM configuration needed
ocr delegate preview
ocr delegate rule src/main.go src/handler.go
Documentation
Full documentation lives at open-codereview.ai/docs:
- Quickstart — install and run your first review
- Installation — all platforms and package managers
- CLI Reference — every command and flag
- Review Rules — customize review rules with path filtering and targeting
- Configuration — config keys and environment variables
- MCP Server — extend the review agent with external tools
- Coding Agent Integrations — choose the platform you use
- Claude Code — install a plugin with review slash commands
- Codex — install a plugin with callable review skills
- Cursor — install a plugin with portable review skills
- OpenCode — install native review tools and slash commands
- Skill-compatible agents — install the portable agent skill
- Review Execution Modes — after integration, choose which LLM performs the review
- Default (OCR-managed) — OCR runs the review using its configured LLM
- Delegation Mode — your coding agent runs the review using its own LLM; no OCR API key required
- CI/CD Integration — GitHub Actions, GitLab CI, GitFlic CI, and Gerrit integration
- Session Viewer — browse and replay review sessions in browser
- Telemetry — OpenTelemetry integration for observability
- FAQ — common questions and troubleshooting
Contributing
This project exists thanks to all the people who contribute. See CONTRIBUTING.md for development setup, coding guidelines, and how to submit pull requests.
License
Apache-2.0 — Copyright 2026 Alibaba


