open-code-review-toolkit 0.9.0__tar.gz → 0.10.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/.gitignore +1 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/PKG-INFO +34 -12
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/README.md +33 -11
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/_version.py +2 -2
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/cli.py +19 -2
- open_code_review_toolkit-0.10.0/src/ocr_toolkit/common/filesystem.py +68 -0
- open_code_review_toolkit-0.10.0/src/ocr_toolkit/posting/comments.py +21 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/posting/formatting.py +46 -396
- open_code_review_toolkit-0.10.0/src/ocr_toolkit/posting/result.py +25 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/preflight.py +10 -3
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/provider_config.py +33 -0
- open_code_review_toolkit-0.10.0/src/ocr_toolkit/providers/local.py +164 -0
- open_code_review_toolkit-0.10.0/src/ocr_toolkit/providers/local_config.py +14 -0
- open_code_review_toolkit-0.10.0/src/ocr_toolkit/reporting/__init__.py +1 -0
- open_code_review_toolkit-0.10.0/src/ocr_toolkit/reporting/dlp.py +197 -0
- open_code_review_toolkit-0.10.0/src/ocr_toolkit/reporting/metadata.py +90 -0
- open_code_review_toolkit-0.10.0/src/ocr_toolkit/reporting/model.py +127 -0
- open_code_review_toolkit-0.10.0/src/ocr_toolkit/reporting/outcome.py +86 -0
- {open_code_review_toolkit-0.9.0/src/ocr_toolkit/posting → open_code_review_toolkit-0.10.0/src/ocr_toolkit/reporting}/result.py +2 -2
- open_code_review_toolkit-0.10.0/src/ocr_toolkit/reporting/sections.py +82 -0
- open_code_review_toolkit-0.9.0/src/ocr_toolkit/posting/comments.py → open_code_review_toolkit-0.10.0/src/ocr_toolkit/reporting/text.py +3 -3
- open_code_review_toolkit-0.10.0/src/ocr_toolkit/reporting/usage.py +224 -0
- open_code_review_toolkit-0.10.0/src/ocr_toolkit/review_debug.py +363 -0
- open_code_review_toolkit-0.10.0/src/ocr_toolkit/review_progress.py +126 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/review_receipt.py +4 -133
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/review_runner.py +498 -36
- open_code_review_toolkit-0.9.0/src/ocr_toolkit/common/filesystem.py +0 -19
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/LICENSE +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/pyproject.toml +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/__init__.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/common/__init__.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/common/git.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/common/language.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/common/markdown.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/common/redaction.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/config_writer.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/configure.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/context/__init__.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/context/adapters.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/context/broker.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/context/ci_outcomes.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/context/contracts.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/context/dlp.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/context/mcp.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/context/policy.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/context/recognizers.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/context/store.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/evidence/__init__.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/evidence/__main__.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/evidence/actions.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/evidence/artifacts.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/evidence/categorize.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/evidence/collect.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/evidence/collectors/__init__.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/evidence/collectors/graphs.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/evidence/collectors/orchestration.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/evidence/collectors/projections.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/evidence/collectors/registry.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/evidence/collectors/sources.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/evidence/coverage.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/evidence/ecosystems/__init__.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/evidence/ecosystems/ansible/__init__.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/evidence/ecosystems/ansible/requirements.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/evidence/ecosystems/ansible/topology.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/evidence/ecosystems/contracts.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/evidence/ecosystems/go.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/evidence/ecosystems/javascript.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/evidence/ecosystems/php.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/evidence/ecosystems/python.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/evidence/frameworks/__init__.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/evidence/frameworks/contracts.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/evidence/frameworks/detection.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/evidence/frameworks/providers/__init__.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/evidence/frameworks/providers/frontend.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/evidence/frameworks/providers/go.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/evidence/frameworks/providers/php.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/evidence/frameworks/providers/python.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/evidence/frameworks/registry.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/evidence/frameworks/schema.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/evidence/frameworks/templates.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/evidence/infrastructure.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/evidence/invocation.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/evidence/mcp.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/evidence/model.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/evidence/policy/__init__.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/evidence/policy/contracts.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/evidence/policy/decisions.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/evidence/policy/guidance.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/evidence/policy/registry.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/evidence/policy/schema.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/evidence/policy/scopes.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/evidence/project.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/evidence/repository.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/evidence/review_context.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/evidence/store/__init__.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/evidence/store/atomic.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/evidence/store/contracts.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/evidence/store/core.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/evidence/store/readback.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/evidence/store/values.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/mcp_config.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/ocr_result.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/posting/__init__.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/posting/__main__.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/posting/approval.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/posting/gitlab.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/posting/gitlab_approval.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/posting/markers.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/posting/payloads.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/posting/reconciliation.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/posting/settings.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/posting/snapshot.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/posting/suggestions.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/posting/transaction.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/posting/workflow.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/pre_execution.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/provider_failure.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/providers/__init__.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/providers/gitlab.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/providers/gitlab_ci.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/providers/gitlab_context.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/providers/gitlab_discussions.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/providers/gitlab_identity.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/providers/gitlab_remediation.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/py.typed +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/result_contract.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/result_usage.py +0 -0
- {open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/review_identity.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: open-code-review-toolkit
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.10.0
|
|
4
4
|
Summary: Unofficial GitLab CI integration layer for Open Code Review
|
|
5
5
|
Project-URL: Homepage, https://github.com/xeonvs/open-code-review-toolkit
|
|
6
6
|
Project-URL: Repository, https://github.com/xeonvs/open-code-review-toolkit
|
|
@@ -234,7 +234,7 @@ Description-Content-Type: text/markdown
|
|
|
234
234
|
[](https://securityscorecards.dev/viewer/?uri=github.com/xeonvs/open-code-review-toolkit)
|
|
235
235
|
[](https://github.com/xeonvs/open-code-review-toolkit/actions/workflows/codeql.yml)
|
|
236
236
|
|
|
237
|
-
Open Code Review Toolkit is an unofficial
|
|
237
|
+
Open Code Review Toolkit is an unofficial review control and integration layer for [Alibaba Open Code Review](https://github.com/alibaba/open-code-review), with GitLab CI and standalone local providers. It provides bounded repository evidence, a compact review bootstrap, a built-in read-only MCP server, environment-driven OCR configuration, preflight validation, local Markdown reports, and safe GitLab merge-request posting. It does **not** bundle or download the `ocr` binary.
|
|
238
238
|
|
|
239
239
|
> [!NOTE]
|
|
240
240
|
> The project is under active development; the public API, CLI, environment contract, and generated schemas may evolve before 1.0.
|
|
@@ -257,13 +257,12 @@ python -m venv .venv
|
|
|
257
257
|
python -m pip install open-code-review-toolkit
|
|
258
258
|
```
|
|
259
259
|
|
|
260
|
-
The toolkit does not bundle OCR.
|
|
261
|
-
[
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
`
|
|
265
|
-
|
|
266
|
-
the other platform hashes.
|
|
260
|
+
The toolkit does not bundle OCR. Use `recommended_version` in the
|
|
261
|
+
[compatibility manifest](compatibility/ocr-support.json) for this toolkit revision
|
|
262
|
+
to select the exact [upstream release](https://github.com/alibaba/open-code-review/releases).
|
|
263
|
+
Download its platform asset, verify it against that release entry's asset SHA-256,
|
|
264
|
+
and place the verified binary on `PATH`. Do not substitute the latest upstream
|
|
265
|
+
release or use another toolkit revision's manifest.
|
|
267
266
|
|
|
268
267
|
Verify the installation without contacting an LLM provider:
|
|
269
268
|
|
|
@@ -272,18 +271,41 @@ ocr --version
|
|
|
272
271
|
ocr-ci --help
|
|
273
272
|
```
|
|
274
273
|
|
|
275
|
-
`ocr --version` must report `
|
|
274
|
+
`ocr --version` must report the manifest's exact `recommended_version`; `ocr-ci --help` must exit
|
|
276
275
|
successfully. `ocr-ci preflight` is an operational configuration check, not the installation
|
|
277
276
|
smoke test.
|
|
278
277
|
|
|
279
278
|
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.
|
|
280
279
|
The [versioned compatibility policy](docs/compatibility.md) records tested assets and evidence and describes the conservative Dependabot-like qualification workflow for later upstream releases.
|
|
281
280
|
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`.
|
|
282
|
-
The
|
|
281
|
+
The toolkit 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.
|
|
283
282
|
|
|
284
283
|
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.
|
|
285
284
|
|
|
286
|
-
##
|
|
285
|
+
## Standalone local quick start
|
|
286
|
+
|
|
287
|
+
With the qualified OCR binary and LLM environment configured, review an immutable
|
|
288
|
+
commit without forge credentials:
|
|
289
|
+
|
|
290
|
+
```console
|
|
291
|
+
ocr-ci preflight --local
|
|
292
|
+
ocr-ci review --local --result review.json --stderr review.stderr --report review.md -- --commit HEAD
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
Local execution uses the same OCR, mandatory evidence MCP, validation and DLP
|
|
296
|
+
pipeline as CI. It publishes every admitted finding to a fresh private Markdown
|
|
297
|
+
file and the console, without GitLab acquisition, suppression, approval or a
|
|
298
|
+
fabricated publication receipt. See [local review](docs/local.md) for ranges,
|
|
299
|
+
failure behavior and optional private `--debug-dir` bundles.
|
|
300
|
+
|
|
301
|
+
Optional [reasoning and progress controls](docs/configuration.md#provider-endpoint-and-completion-cap-contract)
|
|
302
|
+
do not change review rounds or budgets. Reasoning is unset by default; explicit
|
|
303
|
+
`none` is a wire value whose support depends on the provider/model. Progress is
|
|
304
|
+
off by default and emits only bounded toolkit phases to an interactive terminal
|
|
305
|
+
or an explicitly nonblocking embedding stream; a conventional CI stderr pipe is
|
|
306
|
+
intentionally not used because it can block a review.
|
|
307
|
+
|
|
308
|
+
## How GitLab reviews evolve
|
|
287
309
|
|
|
288
310
|
On a successful rerun, the toolkit replaces untouched OCR-only notes instead of accumulating stale reviews. A human reply transfers that discussion to the team: the conversation is preserved and a matching finding is suppressed. Reply with `/ocr suppress` or `@<live-bot-username> suppress` to keep a discussion open without future repeats; use the corresponding `resolve` command to resolve it after the next successful posting transaction. For example, a bot named `mr.bot` accepts the exact reply `@mr.bot resolve`.
|
|
289
311
|
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
[](https://securityscorecards.dev/viewer/?uri=github.com/xeonvs/open-code-review-toolkit)
|
|
8
8
|
[](https://github.com/xeonvs/open-code-review-toolkit/actions/workflows/codeql.yml)
|
|
9
9
|
|
|
10
|
-
Open Code Review Toolkit is an unofficial
|
|
10
|
+
Open Code Review Toolkit is an unofficial review control and integration layer for [Alibaba Open Code Review](https://github.com/alibaba/open-code-review), with GitLab CI and standalone local providers. It provides bounded repository evidence, a compact review bootstrap, a built-in read-only MCP server, environment-driven OCR configuration, preflight validation, local Markdown reports, and safe GitLab merge-request posting. It does **not** bundle or download the `ocr` binary.
|
|
11
11
|
|
|
12
12
|
> [!NOTE]
|
|
13
13
|
> The project is under active development; the public API, CLI, environment contract, and generated schemas may evolve before 1.0.
|
|
@@ -30,13 +30,12 @@ python -m venv .venv
|
|
|
30
30
|
python -m pip install open-code-review-toolkit
|
|
31
31
|
```
|
|
32
32
|
|
|
33
|
-
The toolkit does not bundle OCR.
|
|
34
|
-
[
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
`
|
|
38
|
-
|
|
39
|
-
the other platform hashes.
|
|
33
|
+
The toolkit does not bundle OCR. Use `recommended_version` in the
|
|
34
|
+
[compatibility manifest](compatibility/ocr-support.json) for this toolkit revision
|
|
35
|
+
to select the exact [upstream release](https://github.com/alibaba/open-code-review/releases).
|
|
36
|
+
Download its platform asset, verify it against that release entry's asset SHA-256,
|
|
37
|
+
and place the verified binary on `PATH`. Do not substitute the latest upstream
|
|
38
|
+
release or use another toolkit revision's manifest.
|
|
40
39
|
|
|
41
40
|
Verify the installation without contacting an LLM provider:
|
|
42
41
|
|
|
@@ -45,18 +44,41 @@ ocr --version
|
|
|
45
44
|
ocr-ci --help
|
|
46
45
|
```
|
|
47
46
|
|
|
48
|
-
`ocr --version` must report `
|
|
47
|
+
`ocr --version` must report the manifest's exact `recommended_version`; `ocr-ci --help` must exit
|
|
49
48
|
successfully. `ocr-ci preflight` is an operational configuration check, not the installation
|
|
50
49
|
smoke test.
|
|
51
50
|
|
|
52
51
|
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.
|
|
53
52
|
The [versioned compatibility policy](docs/compatibility.md) records tested assets and evidence and describes the conservative Dependabot-like qualification workflow for later upstream releases.
|
|
54
53
|
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`.
|
|
55
|
-
The
|
|
54
|
+
The toolkit 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.
|
|
56
55
|
|
|
57
56
|
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.
|
|
58
57
|
|
|
59
|
-
##
|
|
58
|
+
## Standalone local quick start
|
|
59
|
+
|
|
60
|
+
With the qualified OCR binary and LLM environment configured, review an immutable
|
|
61
|
+
commit without forge credentials:
|
|
62
|
+
|
|
63
|
+
```console
|
|
64
|
+
ocr-ci preflight --local
|
|
65
|
+
ocr-ci review --local --result review.json --stderr review.stderr --report review.md -- --commit HEAD
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Local execution uses the same OCR, mandatory evidence MCP, validation and DLP
|
|
69
|
+
pipeline as CI. It publishes every admitted finding to a fresh private Markdown
|
|
70
|
+
file and the console, without GitLab acquisition, suppression, approval or a
|
|
71
|
+
fabricated publication receipt. See [local review](docs/local.md) for ranges,
|
|
72
|
+
failure behavior and optional private `--debug-dir` bundles.
|
|
73
|
+
|
|
74
|
+
Optional [reasoning and progress controls](docs/configuration.md#provider-endpoint-and-completion-cap-contract)
|
|
75
|
+
do not change review rounds or budgets. Reasoning is unset by default; explicit
|
|
76
|
+
`none` is a wire value whose support depends on the provider/model. Progress is
|
|
77
|
+
off by default and emits only bounded toolkit phases to an interactive terminal
|
|
78
|
+
or an explicitly nonblocking embedding stream; a conventional CI stderr pipe is
|
|
79
|
+
intentionally not used because it can block a review.
|
|
80
|
+
|
|
81
|
+
## How GitLab reviews evolve
|
|
60
82
|
|
|
61
83
|
On a successful rerun, the toolkit replaces untouched OCR-only notes instead of accumulating stale reviews. A human reply transfers that discussion to the team: the conversation is preserved and a matching finding is suppressed. Reply with `/ocr suppress` or `@<live-bot-username> suppress` to keep a discussion open without future repeats; use the corresponding `resolve` command to resolve it after the next successful posting transaction. For example, a bot named `mr.bot` accepts the exact reply `@mr.bot resolve`.
|
|
62
84
|
|
{open_code_review_toolkit-0.9.0 → open_code_review_toolkit-0.10.0}/src/ocr_toolkit/_version.py
RENAMED
|
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
|
|
|
18
18
|
commit_id: str | None
|
|
19
19
|
__commit_id__: str | None
|
|
20
20
|
|
|
21
|
-
__version__ = version = '0.
|
|
22
|
-
__version_tuple__ = version_tuple = (0,
|
|
21
|
+
__version__ = version = '0.10.0'
|
|
22
|
+
__version_tuple__ = version_tuple = (0, 10, 0)
|
|
23
23
|
|
|
24
24
|
__commit_id__ = commit_id = None
|
|
@@ -24,7 +24,12 @@ def build_parser() -> argparse.ArgumentParser:
|
|
|
24
24
|
version=f"%(prog)s {__version__}",
|
|
25
25
|
)
|
|
26
26
|
subparsers = parser.add_subparsers(dest="command", required=True)
|
|
27
|
-
subparsers.add_parser(
|
|
27
|
+
preflight_parser = subparsers.add_parser(
|
|
28
|
+
"preflight", help="Validate review prerequisites and configured access."
|
|
29
|
+
)
|
|
30
|
+
preflight_parser.add_argument(
|
|
31
|
+
"--local", action="store_true", help="Validate standalone local review prerequisites."
|
|
32
|
+
)
|
|
28
33
|
subparsers.add_parser("configure", help="Write the OCR runtime configuration.")
|
|
29
34
|
subparsers.add_parser("mcp-config", help="Write OCR MCP server configuration.")
|
|
30
35
|
review_parser = subparsers.add_parser(
|
|
@@ -32,6 +37,15 @@ def build_parser() -> argparse.ArgumentParser:
|
|
|
32
37
|
)
|
|
33
38
|
review_parser.add_argument("--result", required=True, help="OCR JSON output path.")
|
|
34
39
|
review_parser.add_argument("--stderr", required=True, help="Full OCR stderr artifact path.")
|
|
40
|
+
review_parser.add_argument(
|
|
41
|
+
"--local", action="store_true", help="Review immutable Git refs and publish local Markdown."
|
|
42
|
+
)
|
|
43
|
+
review_parser.add_argument(
|
|
44
|
+
"--report", help="Fresh local Markdown path (default: --result path plus .md)."
|
|
45
|
+
)
|
|
46
|
+
review_parser.add_argument(
|
|
47
|
+
"--debug-dir", help="Fresh private diagnostic bundle directory (requires --local)."
|
|
48
|
+
)
|
|
35
49
|
review_parser.add_argument(
|
|
36
50
|
"--preserve-private-artifacts",
|
|
37
51
|
action="store_true",
|
|
@@ -62,7 +76,7 @@ def main(argv: Sequence[str] | None = None) -> int:
|
|
|
62
76
|
|
|
63
77
|
args = build_parser().parse_args(argv)
|
|
64
78
|
if args.command == "preflight":
|
|
65
|
-
return preflight.main()
|
|
79
|
+
return preflight.main(local=True) if args.local else preflight.main()
|
|
66
80
|
if args.command == "configure":
|
|
67
81
|
return configure.main()
|
|
68
82
|
if args.command == "mcp-config":
|
|
@@ -75,6 +89,9 @@ def main(argv: Sequence[str] | None = None) -> int:
|
|
|
75
89
|
Path(args.stderr),
|
|
76
90
|
ocr_args,
|
|
77
91
|
preserve_private_artifacts=args.preserve_private_artifacts,
|
|
92
|
+
**({"local": True} if args.local else {}),
|
|
93
|
+
**({"report_path": Path(args.report)} if args.report is not None else {}),
|
|
94
|
+
**({"debug_dir": Path(args.debug_dir)} if args.debug_dir is not None else {}),
|
|
78
95
|
)
|
|
79
96
|
except review_runner.ReviewRunnerError as exc:
|
|
80
97
|
print(f"Cannot run Open Code Review: {exc}", file=sys.stderr)
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"""Small cross-platform filesystem durability helpers."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import errno
|
|
6
|
+
import os
|
|
7
|
+
import stat
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def fsync_directory(descriptor: int) -> None:
|
|
12
|
+
"""Persist a directory-entry change when the platform supports it."""
|
|
13
|
+
|
|
14
|
+
try:
|
|
15
|
+
os.fsync(descriptor)
|
|
16
|
+
except OSError as exc:
|
|
17
|
+
# Some supported filesystems reject directory fsync even though the
|
|
18
|
+
# atomic rename itself succeeded. Ignore only documented unsupported
|
|
19
|
+
# descriptor/filesystem cases; propagate genuine durability failures.
|
|
20
|
+
if exc.errno not in {errno.EINVAL, errno.ENOTSUP, errno.EBADF}:
|
|
21
|
+
raise
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def open_private_parent_directory(path: Path) -> tuple[int, str]:
|
|
25
|
+
"""Open a path's parent without following replaceable pathname components.
|
|
26
|
+
|
|
27
|
+
The returned descriptor pins the parent directory. Callers must use
|
|
28
|
+
descriptor-relative operations and close it themselves; returning an
|
|
29
|
+
absolute pathname would reintroduce the ancestor replacement race this
|
|
30
|
+
helper avoids.
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
absolute = path.absolute()
|
|
34
|
+
parts = [part for part in absolute.parts if part != os.path.sep]
|
|
35
|
+
if not parts:
|
|
36
|
+
raise ValueError("private output path must name a file or directory")
|
|
37
|
+
descriptor = os.open(os.path.sep, os.O_RDONLY | os.O_DIRECTORY)
|
|
38
|
+
try:
|
|
39
|
+
for component in parts[:-1]:
|
|
40
|
+
flags = os.O_RDONLY | os.O_DIRECTORY | os.O_NOFOLLOW
|
|
41
|
+
try:
|
|
42
|
+
child = os.open(component, flags, dir_fd=descriptor)
|
|
43
|
+
except FileNotFoundError:
|
|
44
|
+
try:
|
|
45
|
+
os.mkdir(component, mode=0o700, dir_fd=descriptor)
|
|
46
|
+
except FileExistsError:
|
|
47
|
+
pass
|
|
48
|
+
try:
|
|
49
|
+
child = os.open(component, flags, dir_fd=descriptor)
|
|
50
|
+
except OSError as exc:
|
|
51
|
+
raise ValueError("private output parent must not be a symlink") from exc
|
|
52
|
+
except OSError as exc:
|
|
53
|
+
raise ValueError("private output parent must not be a symlink") from exc
|
|
54
|
+
os.close(descriptor)
|
|
55
|
+
descriptor = child
|
|
56
|
+
parent = os.fstat(descriptor)
|
|
57
|
+
if not stat.S_ISDIR(parent.st_mode):
|
|
58
|
+
raise OSError("private output parent is not a directory")
|
|
59
|
+
return descriptor, parts[-1]
|
|
60
|
+
except BaseException:
|
|
61
|
+
os.close(descriptor)
|
|
62
|
+
raise
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def same_file_identity(left: os.stat_result, right: os.stat_result) -> bool:
|
|
66
|
+
"""Compare two pinned filesystem identities without following pathnames."""
|
|
67
|
+
|
|
68
|
+
return left.st_dev == right.st_dev and left.st_ino == right.st_ino
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"""Posting facade for shared report value normalization."""
|
|
2
|
+
|
|
3
|
+
from ocr_toolkit.reporting.text import (
|
|
4
|
+
clean_text,
|
|
5
|
+
code_text,
|
|
6
|
+
comment_line,
|
|
7
|
+
compact_control_text,
|
|
8
|
+
compact_escaped_text,
|
|
9
|
+
compact_text,
|
|
10
|
+
line_number,
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
__all__ = [
|
|
14
|
+
"clean_text",
|
|
15
|
+
"code_text",
|
|
16
|
+
"comment_line",
|
|
17
|
+
"compact_control_text",
|
|
18
|
+
"compact_escaped_text",
|
|
19
|
+
"compact_text",
|
|
20
|
+
"line_number",
|
|
21
|
+
]
|