
Local AI Code Review with OpenCodeReview, OpenCode, and Qwen3.6-35B-A3B
Run a high-precision AI reviewer against every Git diff without sending source code to a cloud model: OpenCodeReview supplies the deterministic review workflow, OpenCode provides the developer-facing agent environment, and a local Qwen3.6-35B-A3B server supplies inference through an OpenAI-compatible API.
That combination matters because a capable local model alone is not a dependable code-review system. A useful reviewer needs repeatable file selection, repository-aware context retrieval, project-specific rules, line-level findings, noise filtering, and evidence you can measure. OpenCodeReview (OCR) supplies that specialized layer; OpenCode fits it into the normal coding loop; and the self-hosted model keeps the code path under your control.
This article builds a practical workflow around this local network endpoint: http://192.168.0.88:8000/v1 with the model: qwen3.6-35b-a3b
The endpoint reports a 262,144-token context limit and supports low, medium, and high reasoning effort. The examples assume an OpenAI-compatible /v1/models and /v1/chat/completions interface.
The architecture
The system has three distinct responsibilities:
View PlantUML source code
@startuml
skinparam componentStyle rectangle
package "Developer workstation / CI runner" {
component "Git repository" as Git
component "OpenCode\n(interactive coding, debugging,\nand applying fixes)" as OpenCode
component "OpenCodeReview (ocr)\n(deterministic scope + rules\n+ agentic review pipeline)" as OCR
}
package "Local inference server" {
component "http://192.168.0.88:8000/v1\nqwen3.6-35b-a3b\n262K context, reasoning: low / medium / high" as Model
}
Git --> OpenCode
Git --> OCR
OpenCode --> Model : OpenAI-compatible HTTP
OCR --> Model : OpenAI-compatible HTTP
@enduml
The roles should not be conflated:
| Layer | Responsibility | Why it exists |
|---|---|---|
| OpenCode | Interactive developer workflow | Helps implement, investigate, test, and fix code |
| OpenCodeReview | Review-specific orchestration | Creates a controlled, repository-aware review process rather than a generic prompt |
| Qwen3.6-35B-A3B | Inference backend | Interprets code and rules, calls review tools, and produces findings |
| Git and CI | Source-of-truth and automation boundary | Defines the diff under review and preserves artifacts |
OCR's value is the deterministic shell around an LLM. It can choose the files to inspect, attach path-specific rules, group related files, provide bounded repository tools, position comments on real lines, and filter findings after the main review pass. That reduces the usual failure modes of unrestricted AI review: skipped files, excessive context, vague advice, misplaced comments, and a flood of low-confidence findings.
Why run it locally
A local reviewer changes both data handling and operations.
- Source code, diffs, and repository context stay on the network path you operate.
- Costs shift from per-token cloud billing to hardware, power, and model-serving capacity.
- The same endpoint can serve OpenCode, OCR, evaluation harnesses, and selected CI jobs.
- You can inspect requests, latency, token usage, queueing, and failure modes directly.
- Model behavior and review rules can be benchmarked against your own Java/Spring, TypeScript, infrastructure, or monorepo changes.
The trade-off is that you become responsible for endpoint availability, authentication, GPU capacity, context allocation, upgrades, logs, rate limits, and safety boundaries. A local model is not automatically cheaper or better; it becomes compelling when privacy, utilization, predictable workload, and control are more valuable than outsourcing operations.
For code review, another advantage is repeatability. Use low temperature, a fixed model version, a pinned OCR version, and versioned rules. Then you can investigate why a finding appeared, compare model configurations, and detect a regression after a server upgrade.
Prerequisites
Before configuring OCR, validate the complete path from the review machine to the model server.
Required components
- Git repository with a meaningful local diff or a branch range to review.
- Git 2.41 or later, as required by OCR for its Git-based review workflow.
- Node.js and npm to install the OCR CLI.
- A reachable OpenAI-compatible server at
http://192.168.0.88:8000/v1. - The model ID
qwen3.6-35b-a3bexposed by/v1/models. - OpenCode installed if you want the interactive fix-and-review loop or delegation workflow.
- A local network and access policy appropriate for source-code traffic.
Keep the endpoint private
The endpoint in this article uses plain HTTP on a private RFC1918 address. That can be reasonable on a trusted, isolated LAN, but do not expose it directly to an untrusted network.
For access across hosts, VPNs, or network segments, place the server behind an authenticated TLS reverse proxy and restrict it with firewall rules or an allowlist. Treat source code, prompts, tool results, and server logs as sensitive engineering data. Also ensure that forked pull requests cannot cause an untrusted CI job to access internal model credentials or a privileged LAN endpoint.
Verify the model server first
Do not debug OCR, OpenCode, tool calling, and the model server simultaneously. Start by proving that the endpoint works as a plain OpenAI-compatible API.
Set environment variables on the workstation or CI runner:
export OCR_BASE_URL="http://192.168.0.88:8000/v1"
export OCR_MODEL="qwen3.6-35b-a3b"
export OCR_API_KEY="local-dev-token"
If the server does not validate bearer tokens, the value can be a non-secret placeholder. Still use an environment variable rather than hard-coding it into shell history, repository configuration, or CI YAML.
Check model discovery
curl -fsS \
-H "Authorization: Bearer ${OCR_API_KEY}" \
"${OCR_BASE_URL}/models" | jq .
The essential result is that the response contains the configured ID:
{
"object": "list",
"data": [
{
"id": "qwen3.6-35b-a3b",
"object": "model",
"max_model_len": 262144,
"context_length": 262144,
"supported_reasoning_efforts": ["high", "medium", "low"],
"default_reasoning_effort": "medium"
}
]
}
The metadata tells you what the server advertises. It does not, by itself, prove that the server has allocated enough KV cache to accept that context in production. Validate large-context behavior later with actual usage.prompt_tokens from successful responses.
Run a minimal completion
curl -fsS "${OCR_BASE_URL}/chat/completions" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${OCR_API_KEY}" \
-d '{
"model": "'"${OCR_MODEL}"'",
"messages": [
{
"role": "user",
"content": "Reply with exactly: local endpoint is ready"
}
],
"temperature": 0,
"max_tokens": 32
}' | jq .
Record three things from the response:
- The model ID actually used.
finish_reason, which should normally bestopfor this request.usagevalues, if the server returns them.
A completion that ends with finish_reason: "length" is especially important with reasoning-capable models. The model may consume its output budget in hidden or explicit reasoning before emitting a usable final answer. That is a tuning issue, not necessarily a review-quality failure.
Test structured tool calls
OCR uses an agentic workflow. A model that can answer chat messages may still fail at machine-readable function calls. Test that explicitly before the first real review.
curl -fsS "${OCR_BASE_URL}/chat/completions" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${OCR_API_KEY}" \
-d '{
"model": "'"${OCR_MODEL}"'",
"temperature": 0,
"max_tokens": 256,
"messages": [
{
"role": "user",
"content": "You need more repository context. Call file_read for README.md."
}
],
"tools": [
{
"type": "function",
"function": {
"name": "file_read",
"description": "Read a text file from a repository",
"parameters": {
"type": "object",
"properties": {
"path": {"type": "string"}
},
"required": ["path"]
}
}
}
],
"tool_choice": "auto"
}' | jq .
A successful result contains a structured tool_calls entry with a function name and JSON arguments. A natural-language sentence such as “I would call file_read” is not sufficient: the client must be able to parse and execute the call.
Your serving engine may use a model-specific chat template, tool-call parser, or reasoning parser. If this test fails, inspect the server's documentation and logs before trying OCR. The required fix may be server-side rather than an OCR configuration change.
Install and configure OpenCodeReview
Install the CLI globally:
npm install -g @alibaba-group/open-code-review
ocr --version
Use the interactive setup rather than guessing a provider configuration schema that may change across releases:
ocr config provider
ocr config model
During the setup, choose the custom or OpenAI-compatible provider option, then enter:
Base URL: http://192.168.0.88:8000/v1
Model: qwen3.6-35b-a3b
API key: ${OCR_API_KEY} or the required local token
Use the connection test offered by the installed CLI. Save a redacted copy of the resulting configuration only after it has been generated successfully in your environment. This is safer than publishing a hand-written JSON or YAML snippet for a configuration format that may differ between OCR versions.
Start with a conservative profile
For the first review, optimize for observability rather than throughput:
| Parameter | Suggested starting point | Reason |
|---|---|---|
| Reasoning effort | medium | A sensible quality/latency baseline for repository analysis |
| Temperature | 0 or near 0 | Helps make reruns comparable |
| Scope | One small diff | Separates provider problems from large-PR complexity |
| Parallelism | 1 | Avoids GPU contention during initial diagnosis |
| Output | JSON plus interactive viewer | Enables later classification and comparison |
| Merge policy | Advisory only | Do not block merges before measuring precision locally |
| Rules | One or two focused project rules | Keeps the experiment interpretable |
The exact parameter names and locations vary between OCR versions and provider integrations. Treat these as operating variables to record, not as universal CLI flags. Capture the exact command, model-server settings, OCR version, model ID, and rule revision in every benchmark run.
The first real review
Use a small, realistic change rather than an artificial one-line null-pointer example. A good first candidate is a Java/Spring change that touches a controller, service, client, configuration, migration, and test.
For example:
feat: add POST /orders/{id}/cancel
Changed files:
- OrderController.java
- OrderService.java
- OrderRepository.java
- OrderClient.java
- application.yml
- V42__add_order_cancellation.sql
- OrderServiceTest.java
Seed a few review-worthy issues deliberately while learning the workflow:
- A synchronous external call inside a long-lived database transaction.
- Retry behavior for a mutating action without idempotency protection.
- Logging an entire request payload containing email addresses or phone numbers.
- A database migration that is unsafe during rolling deployment.
- A collection loop that can introduce an N+1 query.
Inspect the change before invoking the model:
git status --short
git diff --stat
git diff --check
Then run a workspace review:
ocr review
For a branch-level review, compare the change explicitly:
ocr review --from origin/main --to HEAD
Persist a machine-readable artifact:
mkdir -p .artifacts
ocr review \
--from origin/main \
--to HEAD \
--format json \
--output .artifacts/ocr-review.json
The goal of the first run is not to prove that the model is excellent. It is to answer operational questions:
- Can OCR enumerate the intended files?
- Does the local model make valid tool calls?
- Does it retrieve cross-file context when needed?
- Are comments attached to useful lines?
- Does it identify the deliberately seeded problems?
- Does it emit false positives, generic style advice, duplicates, or malformed output?
- How long does the review take, and what does the local server report for token usage?
Classify each output manually. A small review log is more valuable than an impressionistic “it looks good.”
| Finding | Expected issue? | Verdict | Reason |
|---|---|---|---|
HTTP call is performed inside @Transactional | Yes | True positive | Network latency may unnecessarily hold database resources and locks |
| Full customer payload is logged | Yes | True positive | Violates a PII/logging policy |
| Method name should be shorter | No | Ignore | Generic style feedback is not an actionable production defect |
| Missing null check | No | False positive | The value is guaranteed by validation and the established contract |
Add rules that know your project
The highest-value improvement is usually not a larger model. It is better review criteria.
Generic LLM review is good at proposing possibilities. Project rules tell the reviewer which possibilities matter in this codebase and which comments should be suppressed. Keep rules versioned with the repository, review them like production code, and test them against known-good and known-bad changes.
A focused rule should:
- Apply to a narrow class of files or a clear path pattern.
- State observable correctness or operational properties.
- Include domain invariants where relevant.
- Exclude low-value categories such as formatting and generic naming opinions.
- Avoid duplicating compiler, formatter, and mature static-analysis checks.
- Use examples when a policy is subtle or organization-specific.
A Java/Spring service rule
The following is the content of a useful project rule. Put it into the actual OCR rule mechanism supported by your installed version rather than assuming a fixed directory or file syntax.
Scope: src/main/java/**/*Service.java
Review only correctness and production risks:
- Verify that external network calls are not made inside long-lived database transactions unless explicitly justified.
- Check mutating operations for idempotency when a client, job, or message consumer can retry them.
- Flag logging of credentials, tokens, phone numbers, email addresses, or full request payloads.
- Confirm authorization is performed before tenant-scoped data is accessed or modified.
- Flag changed collection-processing code that can introduce an obvious N+1 query pattern.
- Check that exceptions are mapped to the application's public error contract.
- Ignore naming, formatting, boilerplate documentation, and generic style comments.
A practical starter ruleset can be organized around code responsibilities:
| Area | Typical paths | Review focus |
|---|---|---|
| Service layer | **/*Service.java, **/*Facade.java | Transactions, idempotency, authorization, exception mapping |
| Persistence | **/*Repository.java, **/entity/** | N+1, pagination, locking, parameterization, migration compatibility |
| Web/API | **/*Controller.java, **/api/** | Validation, authorization, error contract, compatibility |
| Integrations | **/client/**, **/integration/** | Timeouts, retries, circuit breaking, secrets, retry safety |
| Configuration | application*.yml, Dockerfile, **/*.tf | Secrets, unsafe defaults, management exposure, resource limits |
| Database changes | db/migration/** | Rolling-deploy safety, indexes, nullable transitions, data migration risks |
Do not begin with a 200-item checklist. Start with the defects your team repeatedly finds after review or after release. A short rule that produces five high-confidence findings per month is more useful than an encyclopedic rule that creates fifty arguments.
Two ways to combine OCR and OpenCode
OCR and OpenCode can work together in two different operating modes.
Mode 1: OCR manages the review
In this mode, OpenCode is used to implement and fix changes, while OCR independently calls the local Qwen endpoint for review.
1. Implement a change with OpenCode.
2. Run tests, formatter, static analysis, and git diff checks.
3. Run ocr review against the local Qwen endpoint.
4. Triage findings in terminal output, JSON, or the session viewer.
5. Use OpenCode to investigate and implement confirmed fixes.
6. Run tests again.
7. Re-run OCR and record what changed.
This is the recommended first setup because responsibilities stay separate. The coding agent is not the only system evaluating its own output, and the exact same ocr review command can later run in CI.
Mode 2: OCR delegation through OpenCode
OCR also supports a delegation approach in which it provides deterministic file selection and rule resolution while an existing coding-agent environment executes the review. This can make the developer experience more seamless when OpenCode is already the central interactive agent.
Use it after the managed mode is stable. Otherwise, a failure can originate in at least four places at once: the OCR integration, the OpenCode adapter, the provider configuration, or the local model's tool-call behavior.
Before enabling delegation, validate the exact commands and plugin syntax for the versions you run. A safe diagnostic sequence is conceptually:
1. Preview which files OCR will delegate.
2. Inspect which rules OCR resolves for a selected file.
3. Trigger a review from OpenCode.
4. Compare its findings with the same diff reviewed by OCR-managed mode.
Use the real command names displayed by your installed OCR/OpenCode integration rather than copying undocumented pseudo-commands into automation.
Which mode to choose
| Criterion | OCR-managed mode | Delegated through OpenCode |
|---|---|---|
| Who calls the model | OCR | OpenCode |
| Provider configuration | Dedicated OCR configuration | Reuses OpenCode's provider setup |
| Cost and usage attribution | Usually easier to isolate | Can blend with interactive-agent usage |
| CI reproducibility | Straightforward | Depends on integration maturity and environment |
| Developer experience | Separate review command | More native to an agent-centric workflow |
| Best first experiment | Yes | After validating managed mode |
Benchmark the workflow, not the demo
A model that finds an obvious planted bug in one diff is not yet ready for a production merge gate. Evaluate it on historical work from your own repositories.
Choose 20 to 30 merged pull requests that contain useful signal:
- Bugs discovered in later fixes or incident follow-ups.
- Human review findings that were accepted and fixed.
- Security or reliability corrections.
- Migration and API-compatibility changes.
- A representative spread of small changes and multi-file changes.
Do not give the reviewer access to later human comments or future fixes. Pin the evaluation inputs: repository commit, base commit, OCR version, model-server version, model ID, rules revision, reasoning configuration, and output budget.
Measure quality and operations separately
For review quality:
For operations, record a separate set of metrics:
| Metric | How to measure it | Why it matters |
|---|---|---|
| Confirmed finding rate | True positives divided by total findings | Indicates whether developers will trust the reviewer |
| Noise per PR | False positives per reviewed pull request | Measures triage burden directly |
| Recall of known defects | Found known defects divided by total known defects | Shows blind spots |
| Median and P95 review time | Client-side wall-clock duration | Determines developer and CI usability |
| Prompt and completion tokens | Model-server usage or logs | Supports capacity and cost planning |
| Tokens per true positive | Tokens divided by confirmed findings | Ties infrastructure cost to review value |
| Tool-call validity | Invalid or unparsable calls per run | Detects compatibility problems early |
| Repeatability | Finding overlap across repeated runs | Reveals sampling or serving instability |
| GPU queueing and KV pressure | Server metrics | Helps tune concurrency and context limits |
Run at least three local configurations:
| Experiment | Reasoning effort | Use |
|---|---|---|
| E1 | low | Fast, low-cost baseline |
| E2 | medium | Default candidate for ordinary PR review |
| E3 | high | High-risk changes or offline repository scans |
Avoid claiming that one setting is universally best. A Java/Spring service review, an IaC policy review, and a long multi-module refactor may need different latency and reasoning budgets.
Long context: useful, but not an excuse to dump the repository
A 262K-token model window is valuable for code review because it can retain instructions, related implementations, tests, migration files, logs, and earlier agent observations together. It does not mean that feeding the full repository to every review is efficient or reliable.
Use retrieval plus large context:
- Let deterministic scope selection identify changed and related files.
- Provide repository instructions and path-specific rules early.
- Let the agent read callers, callees, tests, and neighboring diffs only when evidence requires it.
- Preserve enough prior context to avoid repeated rediscovery.
- Reserve the largest context budgets for cross-cutting changes, audits, and complex incidents.
The crucial operational distinction is between a model capability and a deployed capability. A /v1/models response may advertise 262144, while the running server has insufficient KV cache for a request of that size. Validate the deployment with successful requests and the server's usage.prompt_tokens, not metadata alone.
When you test near the context limit, use the model's own tokenizer or server-side accounting. A generic tokenizer can underestimate or overestimate the actual token count. Leave enough headroom for system messages, tool schemas, model output, and any reasoning tokens.
CI rollout: advisory first
A practical first CI job should create artifacts and annotations, not block merges.
ocr review \
--from "$BASE_SHA" \
--to "$HEAD_SHA" \
--format json \
--output ocr-review.json
The surrounding pipeline should:
- Store the JSON review output as an artifact.
- Optionally turn selected findings into pull-request annotations or a summary comment.
- Capture OCR exit status, server errors, timeout events, and model finish reasons.
- Enforce a bounded timeout and a clear retry policy.
- Treat local inference unavailability as a warning during the pilot, not as a failed build.
- Exclude secret-bearing paths and generated/vendor files.
- Prevent untrusted fork jobs from reaching the internal model endpoint.
- Preserve enough telemetry to link a finding to an OCR version, model version, rule version, and commit range.
Only move to enforcement after you have enough local evidence. A cautious policy is:
| Finding category | Early policy |
|---|---|
| Confirmed high-confidence secret exposure | Candidate for blocking after validation |
| Confirmed injection, auth bypass, or unsafe deserialization | Candidate for blocking after validation |
| Transaction, retry, logging, and API-contract risks | Advisory by default |
| Style, naming, documentation | Do not emit or always advisory |
| Model/server failures | Never silently pretend the review passed |
The difference between a useful assistant and an ignored PR bot is usually precision. A blocking gate with even a modest false-positive rate creates bypass behavior, while a reliable advisory bot earns trust and supplies the data needed to decide what can safely become policy.
Capacity planning for the local server
The local endpoint is a shared resource once both interactive agents and CI start using it. Capacity depends on more than the model name:
- Diff size and number of touched files.
- Number of related file bundles.
- Tool-call depth and repository exploration.
- Full-file reads and search-result volume.
- Reflection or post-processing passes.
- Reasoning effort and output token limits.
- Context length and KV-cache allocation.
- Concurrent reviews and interactive coding requests.
- GPU memory, expert-cache behavior for MoE serving, system RAM, PCIe topology, and batching policy.
Track at least:
- Time to first token.
- Prompt prefill throughput.
- Decode throughput.
- End-to-end review duration.
- Queue wait time.
- Active sequences and request concurrency.
- GPU memory and utilization.
- KV-cache utilization or eviction pressure.
- Error rate, connection resets, and malformed tool calls.
Start with one concurrent review. Increase concurrency only after measuring whether aggregate throughput improves. More simultaneous agent trajectories can reduce performance if they create cache pressure, lengthen queues, or force the server to work with less favorable batching.
A repeatable developer loop
The daily loop can remain simple:
View PlantUML source code
@startuml
start
:Edit with OpenCode;
:Run tests, formatter, static analysis,\nand git diff --check;
:Run ocr review against the\nlocal Qwen endpoint;
:Triage: accept, reject,\nor defer each finding;
:Use OpenCode to investigate\nand apply confirmed fixes;
:Re-test and re-run OCR;
stop
@enduml
The important discipline is to treat review findings as hypotheses backed by code references, not as automatically correct patches. The reviewer should make a specific claim, point to an affected line, and explain a plausible failure mode. The developer still validates behavior against tests, contracts, production constraints, and domain knowledge.
Limitations
This workflow is intentionally not a replacement for the rest of an engineering quality system.
- OCR can miss real defects; high precision is not the same as complete recall.
- A local model can be weaker than a frontier hosted model on difficult architectural reasoning, unfamiliar frameworks, or novel security issues.
- Rules can become stale, overbroad, or contradictory if they are not owned and tested.
- Line-level comments can still be wrong even when the high-level concern is valid.
- Long context has latency and memory costs; retrieval quality still matters.
- Tool calling requires compatibility across the model, chat template, serving engine, and client.
- Review automation does not replace unit, integration, contract, and end-to-end tests; SAST; dependency and secret scanning; runtime observability; or human architecture review.
The correct goal is not “fully automated approval.” It is a trustworthy automated first pass that catches recurring defects early, provides structured evidence, and leaves developers more time for the decisions that require real system and domain context.
Final checklist
Before calling the workflow production-ready, verify all of the following:
-
/v1/modelsexposesqwen3.6-35b-a3b. - Basic chat completions work from the machine that runs OCR.
- The model emits parseable structured tool calls.
- OCR connects successfully through its configured custom/OpenAI-compatible provider.
- A small real diff produces structured, line-level findings.
- Project rules are versioned and limited to high-value checks.
- Results are retained as JSON artifacts.
- Historical PRs have been used to measure precision, recall, latency, and repeatability.
- The local server's actual context capability has been verified with real server-side token usage.
- CI starts in advisory mode with timeouts, logging, and failure visibility.
- Endpoint access is restricted to trusted workloads and paths containing secrets are excluded.
- Blocking policy is limited to categories that have demonstrated high precision in your own repository.
Conclusion
The useful unit of local AI code review is not a model endpoint and not a clever prompt. It is a controlled system: deterministic review scope, repository-aware agent context, explicit rules, structured outputs, measurable quality, and a local model server that you can observe and operate.
OpenCodeReview provides the review discipline. OpenCode supplies the interactive implementation and remediation loop. Qwen3.6-35B-A3B at http://192.168.0.88:8000/v1 provides a private, OpenAI-compatible inference backend with enough context for substantial multi-file investigation.
Start with one small diff, one focused project rule, and advisory-only output. Then benchmark against historical pull requests, tune reasoning and concurrency from measured evidence, and introduce CI enforcement only where the local data shows the reviewer is consistently right.
Resources
- Open code review GitHub repository: https://github.com/alibaba/open-code-review
Published on 9/12/2026