Skip to content
Merged
18 changes: 15 additions & 3 deletions .github/workflows/ocr-compatibility.yml
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,9 @@ jobs:
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: "3.14"
- name: Qualify candidate
- id: qualify
name: Qualify candidate
continue-on-error: true
env:
CANDIDATE_TAG: ${{ matrix.tag }}
COMPARISON_VERSION: ${{ matrix.comparison_version }}
Expand All @@ -100,15 +102,21 @@ jobs:
--comparison-version "${COMPARISON_VERSION}" \
--tested-baseline-version "${TESTED_BASELINE_VERSION}" \
--output /tmp/ocr-compat/evidence.json \
--issue-body /tmp/ocr-compat/issue.md
--issue-body /tmp/ocr-compat/issue.md \
--status-output /tmp/ocr-compat/status.json
- name: Upsert qualification issue
if: ${{ !cancelled() }}
env:
GITHUB_TOKEN: ${{ github.token }}
REPOSITORY: ${{ github.repository }}
RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
run: |
input=(--status /tmp/ocr-compat/status.json)
if [ -f /tmp/ocr-compat/evidence.json ]; then
input=(--evidence /tmp/ocr-compat/evidence.json)
fi
PYTHONPATH=src python scripts/ocr_compat.py upsert-issue \
--evidence /tmp/ocr-compat/evidence.json \
"${input[@]}" \
--repository "${REPOSITORY}" \
--run-url "${RUN_URL}" \
--output-number /tmp/ocr-compat/issue-number.txt
Expand All @@ -117,11 +125,15 @@ jobs:
''|*[!0-9]*) echo "invalid qualification issue number: ${issue}" >&2; exit 1 ;;
esac
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
if: ${{ always() && !cancelled() }}
with:
name: ocr-compatibility-${{ matrix.tag }}
path: /tmp/ocr-compat/
if-no-files-found: error
retention-days: 7
- name: Preserve qualification failure
if: steps.qualify.outcome == 'failure'
run: exit 1

aggregate:
name: assess-complete-chain
Expand Down
507 changes: 506 additions & 1 deletion PLANS.md

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ ocr-ci --help
The exact recommended OCR release and its verified asset checksums live in the [versioned compatibility manifest](compatibility/ocr-support.json). CI should pin that release and checksum before execution.
The [versioned compatibility policy](docs/compatibility.md) records tested assets and evidence and describes the conservative Dependabot-like qualification workflow for later upstream releases.
Review output defaults to English. `OCR_REVIEW_LANGUAGE` accepts another explicit language name when a project needs localized review output; for example, `OCR_REVIEW_LANGUAGE=Russian`.
The current OCR 1.10.0 integration defaults `OCR_REVIEW_EFFORT` to `medium` for two review rounds. `low` and `high` are explicit one- and three-round alternatives; see the [configuration reference](docs/configuration.md#review-effort) for cost, budget, and precedence boundaries.

Stable distributions are published to [PyPI](https://pypi.org/project/open-code-review-toolkit/) and mirrored as checksum-listed, provenance-attested assets in the corresponding [GitHub Release](https://github.com/xeonvs/open-code-review-toolkit/releases). Development snapshots are published only to TestPyPI.

Expand Down
4 changes: 2 additions & 2 deletions ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ flowchart LR
| M3 External MCP hardening | Established | Qualify and document the safe-use envelope and residual limits of the shipped generic external-MCP composition boundary. | Existing external MCP and built-in composition plus BL-011 real-OCR qualification. | Canonical security and configuration guidance records the direct-composition trust boundaries, tool-name allowlist limits, server-owned object authorization, shared plan/main exposure, response/session persistence, failure degradation, and receipt non-claims observed with checksum-verified OCR and a real synthetic stdio peer. Managed OAuth remains conditional. |
| M4 Policy and project guidance | Established | Supply relevant target-branch decisions and guidance without allowing self-whitelisting. | Evidence scoping and target/source snapshots. | Stable delivery independently proves backward-compatible structured decisions, bounded target-derived guidance, one read-only MCP lifecycle, and closure of the tracked release work. |
| M5 Bounded review-context enrichment | Established | Extend invocation evidence with bounded forge discussions, verified remediation history, and optional external records through one provider-neutral, capability-constrained context lifecycle, without a second review engine. | Established M1, M3, and M4 boundaries plus the v0.7.0 BL-023 delivery. | v0.7.0 establishes bounded discussion/reference acquisition. The v0.8.0 release tree adds policy-v2 remediation selection, context-store v2 and fixed MCP projection, live bot-root/mention identity, DLP isolation, comment-only remediation, and provider-neutral reuse boundaries. The owner waived the separate enriched OCR+LLM qualification, so no receipt proves model-time `context_list`/`context_get`, still-present/evidence-resolved scenarios, or receipt-level raw-data leakage inspection. Protected release publication and independent external readback remain mandatory delivery evidence but do not replace that absent qualification. |
| M6 Profiles and quality measurement | Planned / conditional | Audit current OCR telemetry and result-derived review signals; add model-profile aliases only after demonstrated operational need. | Established receipt-v5 result, discussion, coverage, posting, normalized token, and reconciled MCP/evidence-use signals; a demonstrated alias need and owner-approved matrix are required only for profile implementation. | The audit either proves current bounded reporting sufficient or isolates a separately scoped provider-neutral gap; any later model profiles remain independent from explicit coverage and budget controls. |
| M6 Profiles and quality measurement | Established / conditional | Keep the completed review-signal ownership audit current; add model-profile aliases only after demonstrated operational need. | The BL-017 audit establishes OCR/provider telemetry and toolkit lifecycle-signal ownership; a demonstrated alias need and owner-approved matrix are required only for profile implementation. | The audit concludes `no-new-layer`; any later model profiles remain conditional and independent from explicit coverage and budget controls. |
| M7 Later and conditional work | Conditional | Activate routing, more ecosystems, fuzzing, configuration, forge adapters, or governance work only from demonstrated need. | Milestone-specific activation signals and stable preceding contracts. | Each item meets its own trigger and ships as a coherent validated slice without weakening core invariants. |

## Ordering notes
Expand All @@ -46,7 +46,7 @@ flowchart LR
- M2 is established through independently verified stable delivery of its framework plugins, template rules, scoped evidence, deltas, and built-in MCP projection. Conditional future ecosystem packs remain in M7 and do not reopen M2.
- M4 is established through independently verified v0.6.0 artifacts and later protected-target identity improvements. M5 consumes but does not reopen its policy boundary.
- M5's foundation is established by the v0.7.0 BL-023 release content; the v0.8.0 release tree completes its remediation/provider-neutral extension under an explicit owner waiver for the separate enriched OCR+LLM receipt. The waiver is a permanent evidence limitation, not a successful qualification: model-time `context_list`/`context_get`, still-present/evidence-resolved scenarios, and receipt-level raw-data leakage inspection remain unproven. Direct provider-specific MCP enforcement is not a second M5 path: external records stay behind the broker, while generic direct MCP retains the established M3 operator boundary. Its dependency graph is exactly `M1 -> M5`, `M3 -> M5`, and `M4 -> M5`; it is not a gate for M6 or M7. The protected release workflow, immutable receipt, and independent registry/GitHub readback remain mandatory external delivery closure and do not erase the waiver.
- The M6 measurement-gap audit can begin from receipt v5, privacy-safe normalized token buckets, and reconciled MCP/evidence-action counts delivered in v0.7.1. BL-017 may inventory M5 receipts if they exist, but M5 does not create a second telemetry implementation or exporter. BL-016 remains parked because OCR already exposes direct run-level selection.
- The completed M6 BL-017 audit maps receipt v5, privacy-safe normalized token buckets, reconciled MCP/evidence-action counts, and OCR 1.10.0 grouping/round telemetry to their existing owners and concludes `no-new-layer`. M5 does not create a second telemetry implementation or exporter. BL-016 remains parked because OCR already exposes direct run-level selection; BL-018 remains conditional.
- Versioned documentation remains a separate MCP integration: the toolkit supplies package/version evidence but does not store documentation.
- Additional code-hosting adapters remain conditional and GitLab-first M5 does not depend on them.
- Historical roadmap names, release plans, changelog entries, closed issues/PRs, and receipts retain their original identities. BL-022 is historical and is not reused.
Expand Down
1 change: 1 addition & 0 deletions changelog.d/135.bugfix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
**Fixed:** Reject caller-owned OCR `--output`, `--output=...`, `-o`, and attached short forms before preview so the new upstream output flag cannot bypass the toolkit-owned result descriptor, atomic validation, DLP, cleanup, or posting handoff. Also make successful compatibility promotion report a caller-supplied relative manifest path without crashing after the update was written.
4 changes: 4 additions & 0 deletions changelog.d/135.feature.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Expose OCR 1.10.0 review depth and grouping with explicit operator ownership.

- **Added:** `OCR_REVIEW_EFFORT` is a closed `low|medium|high` setting written to OCR's root `effort` key. Its exact default is `medium`, selecting up to two review rounds; `low` selects one and `high` selects three. A caller-supplied OCR `--effort` remains the per-run override, and merge-request text cannot select it.
- **Changed:** OCR may semantically group related changed files and filter findings per group before additional rounds. Group labels, path-derived keys, membership, and round diagnostics remain untrusted private result data and cannot change findings, severity, fingerprints, lifecycle commands, receipt v5, toolkit telemetry, posting, or automatic approval.
6 changes: 6 additions & 0 deletions changelog.d/135.maintenance.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Qualify and promote the next OCR runtime without losing predecessor or deployment context.

- **OCR 1.9.10 — inherited predecessor:** Toolkit 0.8.0 and 0.8.1 used exact OCR 1.9.10, whose unset OpenAI completion cap was observed as `max_completion_tokens=58888`. Its checksum-pinned evidence remains unchanged; toolkit 0.8.2 does not require installing or requalifying it.
- **OCR 1.10.0 — changed target:** Toolkit 0.8.2 preflight and the GitLab example now require checksum-verified OCR 1.10.0. Qualification covers semantic file grouping, path-aware comments, group filtering, one/two/three review rounds, partial-budget reporting, tool/token accounting, the new `--output` flag, private git diagnostics, and the new inherited OpenAI completion cap `max_completion_tokens=16384`. Linux amd64 SHA-256 is `f8f99ea071bed77dbcaa15fdd2083287bb8ae408d5928b3943ebe0788d191b6b`.
- **Telemetry:** OCR remains authoritative for provider, request, latency, cost, grouping, round, and tool telemetry. OCR 1.10.0 group spans can contain sorted changed paths and model-produced labels; the toolkit defaults OCR telemetry off, does not ingest those values, and adds no exporter or approval/routing signal.
- **Deployment/Migration:** Deploy toolkit 0.8.2 directly with OCR 1.10.0; do not install OCR 1.9.10 as an intermediate step. Unset `OCR_LLM_MAX_COMPLETION_TOKENS` inherits `16384`; set an explicit value such as `4096` when a gateway-specific invariant is required. Caller `--output`/`-o` remains unsupported because `ocr-ci review --result` owns the private result lifecycle.
1 change: 1 addition & 0 deletions changelog.d/136.bugfix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
**Fixed:** A failed OCR compatibility qualification now still updates the canonical version issue and uploads a bounded `ocr-toolkit.compatibility-status/v1` artifact before the job returns red. Public coordination receives only closed phase, reason, version, and run identity; raw exceptions remain in the private job log, and aggregate promotion stays blocked.
1 change: 1 addition & 0 deletions changelog.d/137.maintenance.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
**Changed:** Complete the BL-017 review-signal ownership audit with a `no-new-layer` result. OCR retains provider/review telemetry ownership; toolkit receipt, context, DLP, posting, and approval projections retain deterministic lifecycle ownership. No exporter, automatic routing, developer scoring, or duplicate group/round metric schema is added.
132 changes: 132 additions & 0 deletions compatibility/evidence/ocr-1.10.0.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
{
"assets": [
{
"name": "opencodereview-darwin-amd64",
"sha256": "6936af725318aa67bebe4486dad6fcd4fdcf7e38dccdf8415fefcd0300651a86",
"size": 57592192
},
{
"name": "opencodereview-darwin-arm64",
"sha256": "c8f51b17c2be193ca178ecce6b5bcc1e38a5614629fbe81c6e1c95af5ede12e4",
"size": 54644290
},
{
"name": "opencodereview-linux-amd64",
"sha256": "f8f99ea071bed77dbcaa15fdd2083287bb8ae408d5928b3943ebe0788d191b6b",
"size": 55849122
},
{
"name": "opencodereview-linux-arm64",
"sha256": "15f6ec310103caf103aad48bb81bd1e10b1489353d4dc9a4423724d7fbe1edf8",
"size": 52625570
},
{
"name": "opencodereview-windows-amd64.exe",
"sha256": "c355d6c5966dc7d06922c45ca8772c95ee2c781247e120520951979863249601",
"size": 57309184
},
{
"name": "opencodereview-windows-arm64.exe",
"sha256": "09f09d7f63211c47100f340dc51ddc2856fd386fdf3f4f7daab6751103658900",
"size": 53292032
},
{
"name": "sha256sum.txt",
"sha256": "8ecdf209dd79446488dd35bab858e6b3902ebda7e82279b7a4ba3b9e5775829e",
"size": 572
}
],
"classification": "human-review-required",
"classification_reasons": [
"candidate is not a newer patch in the tested major/minor line",
"release notes contain a material or ambiguous compatibility signal"
],
"comparison_version": "1.9.10",
"contracts": {
"comment_thinking_probe": {
"additive_field_preserved": true,
"posting_exposes_thinking": false,
"result": "passed"
},
"completion_cap_probe": {
"explicit": 4096,
"inherited": 16384,
"result": "passed",
"wire_field": "max_completion_tokens"
},
"optional_capabilities": [
"llm_result_identity",
"per_run_model_override",
"per_run_provider_override",
"review_effort",
"semantic_grouping"
],
"preview_probe": {
"format": "json",
"path": "example.py",
"result": "passed",
"session_store_created": false
},
"required_review_flags": [
"--audience",
"--background-file",
"--effort",
"--format",
"--from",
"--max-tokens-budget",
"--preview",
"--rule",
"--to"
],
"result_contract_probe": {
"additive_fields_allowed": true,
"comment_fields": [
"category",
"content",
"end_line",
"existing_code",
"path",
"severity",
"start_line",
"thinking"
],
"manifest_schema": "ocr.run-manifest/v1",
"normalized_outcome": "clean",
"result": "passed"
},
"review_budget_probe": {
"budget": 30000,
"completed": 2,
"failed_budget": 1,
"partial_findings_preserved": true,
"result": "passed",
"selected": 3
},
"semantic_grouping_probe": {
"default_effort": "medium",
"filter_requests": 1,
"grouping_requests": 1,
"main_requests": 3,
"result": "passed",
"review_rounds": 2
},
"target_rule_selection_probe": {
"format": "json",
"from_to_unchanged": true,
"path": "synthetic-template.ocrfixture",
"result": "passed",
"source_exclusion": "unsupported_ext",
"target_selected": true
},
"version_probe": "passed"
},
"published_at": "2026-08-25T05:45:43Z",
"release_changes": "## 🚀 Features\n\n- feat(agent): group semantically related files for multi-file review (#808)\n- feat(cli): add --output flag to write review/scan results to a file (#852)\n\n## 🐛 Bug Fixes\n\n- fix(diff): surface git's own message when a diff command fails (#1039)\n\n**Full Changelog**: https://github.com/alibaba/open-code-review/compare/v1.9.10...v1.10.0",
"release_notes_sha256": "8d0f599600b34b30163d834878518758fa18e41be6f06851f131a2543e9a15cc",
"result": "compatible",
"schema_version": 2,
"tag": "v1.10.0",
"tested_baseline_version": "1.9.10",
"upstream_repository": "alibaba/open-code-review",
"version": "1.10.0"
}
57 changes: 55 additions & 2 deletions compatibility/ocr-support.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"monitoring_floor": "1.9.10",
"recommended_version": "1.9.10",
"monitoring_floor": "1.10.0",
"recommended_version": "1.10.0",
"releases": [
{
"assets": [
Expand Down Expand Up @@ -1134,6 +1134,59 @@
"release_url": "https://github.com/alibaba/open-code-review/releases/tag/v1.9.10",
"status": "tested",
"version": "1.9.10"
},
{
"assets": [
{
"name": "opencodereview-darwin-amd64",
"sha256": "6936af725318aa67bebe4486dad6fcd4fdcf7e38dccdf8415fefcd0300651a86",
"size": 57592192
},
{
"name": "opencodereview-darwin-arm64",
"sha256": "c8f51b17c2be193ca178ecce6b5bcc1e38a5614629fbe81c6e1c95af5ede12e4",
"size": 54644290
},
{
"name": "opencodereview-linux-amd64",
"sha256": "f8f99ea071bed77dbcaa15fdd2083287bb8ae408d5928b3943ebe0788d191b6b",
"size": 55849122
},
{
"name": "opencodereview-linux-arm64",
"sha256": "15f6ec310103caf103aad48bb81bd1e10b1489353d4dc9a4423724d7fbe1edf8",
"size": 52625570
},
{
"name": "opencodereview-windows-amd64.exe",
"sha256": "c355d6c5966dc7d06922c45ca8772c95ee2c781247e120520951979863249601",
"size": 57309184
},
{
"name": "opencodereview-windows-arm64.exe",
"sha256": "09f09d7f63211c47100f340dc51ddc2856fd386fdf3f4f7daab6751103658900",
"size": 53292032
},
{
"name": "sha256sum.txt",
"sha256": "8ecdf209dd79446488dd35bab858e6b3902ebda7e82279b7a4ba3b9e5775829e",
"size": 572
}
],
"capabilities": [
"llm_result_identity",
"per_run_model_override",
"per_run_provider_override",
"review_effort",
"semantic_grouping"
],
"evidence": "compatibility/evidence/ocr-1.10.0.json",
"evidence_sha256": "50f9668b68dbcc4dc83f379a55e81aa58bc7188d1be88d44abb32a509361e761",
"human_conclusion": "Reviewed OCR 1.9.10...1.10.0 source and hosted Linux wire evidence: semantic grouping, path-aware comments, default medium two-round review, private additive group metadata, output-file capability, git diagnostics, and the 16384 completion cap are compatible with toolkit boundaries; toolkit retains exclusive result-path ownership and explicit 4096 cap support.",
"published_at": "2026-08-25T05:45:43Z",
"release_url": "https://github.com/alibaba/open-code-review/releases/tag/v1.10.0",
"status": "tested",
"version": "1.10.0"
}
],
"schema_version": 1,
Expand Down
Loading
Loading