open-code-review-toolkit 0.2.0__tar.gz → 0.3.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.2.0 → open_code_review_toolkit-0.3.0}/PKG-INFO +11 -2
- {open_code_review_toolkit-0.2.0 → open_code_review_toolkit-0.3.0}/README.md +10 -1
- {open_code_review_toolkit-0.2.0 → open_code_review_toolkit-0.3.0}/pyproject.toml +7 -13
- {open_code_review_toolkit-0.2.0 → open_code_review_toolkit-0.3.0}/src/ocr_toolkit/_version.py +2 -2
- {open_code_review_toolkit-0.2.0 → open_code_review_toolkit-0.3.0}/src/ocr_toolkit/cli.py +10 -2
- {open_code_review_toolkit-0.2.0 → open_code_review_toolkit-0.3.0}/src/ocr_toolkit/context/manifests.py +27 -15
- {open_code_review_toolkit-0.2.0 → open_code_review_toolkit-0.3.0}/src/ocr_toolkit/context/repo.py +4 -2
- {open_code_review_toolkit-0.2.0 → open_code_review_toolkit-0.3.0}/src/ocr_toolkit/posting/gitlab.py +14 -10
- {open_code_review_toolkit-0.2.0 → open_code_review_toolkit-0.3.0}/src/ocr_toolkit/posting/markers.py +6 -4
- {open_code_review_toolkit-0.2.0 → open_code_review_toolkit-0.3.0}/src/ocr_toolkit/posting/workflow.py +5 -4
- {open_code_review_toolkit-0.2.0 → open_code_review_toolkit-0.3.0}/src/ocr_toolkit/preflight.py +1 -1
- open_code_review_toolkit-0.2.0/CHANGELOG.md +0 -50
- open_code_review_toolkit-0.2.0/CONTRIBUTING.md +0 -14
- open_code_review_toolkit-0.2.0/SECURITY.md +0 -13
- open_code_review_toolkit-0.2.0/changelog.d/README.md +0 -3
- open_code_review_toolkit-0.2.0/docs/codex/AGENT_EXECUTION_PITFALLS.md +0 -44
- open_code_review_toolkit-0.2.0/docs/codex/TASKS_BACKLOG.md +0 -87
- open_code_review_toolkit-0.2.0/docs/configuration.md +0 -67
- open_code_review_toolkit-0.2.0/docs/development.md +0 -19
- open_code_review_toolkit-0.2.0/docs/engineering/project_principles.md +0 -30
- open_code_review_toolkit-0.2.0/docs/gitlab.md +0 -31
- open_code_review_toolkit-0.2.0/docs/operations.md +0 -83
- open_code_review_toolkit-0.2.0/docs/release.md +0 -49
- open_code_review_toolkit-0.2.0/docs/security.md +0 -29
- open_code_review_toolkit-0.2.0/examples/gitlab/ocr-review.gitlab-ci.yml +0 -84
- open_code_review_toolkit-0.2.0/examples/gitlab/rules.json +0 -33
- open_code_review_toolkit-0.2.0/tests/__init__.py +0 -1
- open_code_review_toolkit-0.2.0/tests/support.py +0 -85
- open_code_review_toolkit-0.2.0/tests/test_cli.py +0 -39
- open_code_review_toolkit-0.2.0/tests/test_common_helpers.py +0 -391
- open_code_review_toolkit-0.2.0/tests/test_context_helpers.py +0 -1946
- open_code_review_toolkit-0.2.0/tests/test_install_local_artifact.py +0 -67
- open_code_review_toolkit-0.2.0/tests/test_operations_docs.py +0 -58
- open_code_review_toolkit-0.2.0/tests/test_posting_helpers.py +0 -1757
- open_code_review_toolkit-0.2.0/tests/test_quality_script.py +0 -12
- open_code_review_toolkit-0.2.0/tests/test_release_authorization.py +0 -107
- open_code_review_toolkit-0.2.0/tests/test_release_notes.py +0 -46
- open_code_review_toolkit-0.2.0/tests/test_release_process_docs.py +0 -30
- open_code_review_toolkit-0.2.0/tests/test_runtime_helpers.py +0 -880
- open_code_review_toolkit-0.2.0/tests/test_testpypi_preview.py +0 -238
- {open_code_review_toolkit-0.2.0 → open_code_review_toolkit-0.3.0}/.gitignore +0 -0
- {open_code_review_toolkit-0.2.0 → open_code_review_toolkit-0.3.0}/LICENSE +0 -0
- {open_code_review_toolkit-0.2.0 → open_code_review_toolkit-0.3.0}/src/ocr_toolkit/__init__.py +0 -0
- {open_code_review_toolkit-0.2.0 → open_code_review_toolkit-0.3.0}/src/ocr_toolkit/common/__init__.py +0 -0
- {open_code_review_toolkit-0.2.0 → open_code_review_toolkit-0.3.0}/src/ocr_toolkit/common/language.py +0 -0
- {open_code_review_toolkit-0.2.0 → open_code_review_toolkit-0.3.0}/src/ocr_toolkit/common/markdown.py +0 -0
- {open_code_review_toolkit-0.2.0 → open_code_review_toolkit-0.3.0}/src/ocr_toolkit/common/redaction.py +0 -0
- {open_code_review_toolkit-0.2.0 → open_code_review_toolkit-0.3.0}/src/ocr_toolkit/config_writer.py +0 -0
- {open_code_review_toolkit-0.2.0 → open_code_review_toolkit-0.3.0}/src/ocr_toolkit/configure.py +0 -0
- {open_code_review_toolkit-0.2.0 → open_code_review_toolkit-0.3.0}/src/ocr_toolkit/context/__init__.py +0 -0
- {open_code_review_toolkit-0.2.0 → open_code_review_toolkit-0.3.0}/src/ocr_toolkit/context/__main__.py +0 -0
- {open_code_review_toolkit-0.2.0 → open_code_review_toolkit-0.3.0}/src/ocr_toolkit/context/ansible.py +0 -0
- {open_code_review_toolkit-0.2.0 → open_code_review_toolkit-0.3.0}/src/ocr_toolkit/context/categorize.py +0 -0
- {open_code_review_toolkit-0.2.0 → open_code_review_toolkit-0.3.0}/src/ocr_toolkit/context/instructions.py +0 -0
- {open_code_review_toolkit-0.2.0 → open_code_review_toolkit-0.3.0}/src/ocr_toolkit/context/planner.py +0 -0
- {open_code_review_toolkit-0.2.0 → open_code_review_toolkit-0.3.0}/src/ocr_toolkit/context/render.py +0 -0
- {open_code_review_toolkit-0.2.0 → open_code_review_toolkit-0.3.0}/src/ocr_toolkit/context/settings.py +0 -0
- {open_code_review_toolkit-0.2.0 → open_code_review_toolkit-0.3.0}/src/ocr_toolkit/mcp_config.py +0 -0
- {open_code_review_toolkit-0.2.0 → open_code_review_toolkit-0.3.0}/src/ocr_toolkit/posting/__init__.py +0 -0
- {open_code_review_toolkit-0.2.0 → open_code_review_toolkit-0.3.0}/src/ocr_toolkit/posting/__main__.py +0 -0
- {open_code_review_toolkit-0.2.0 → open_code_review_toolkit-0.3.0}/src/ocr_toolkit/posting/comments.py +0 -0
- {open_code_review_toolkit-0.2.0 → open_code_review_toolkit-0.3.0}/src/ocr_toolkit/posting/formatting.py +0 -0
- {open_code_review_toolkit-0.2.0 → open_code_review_toolkit-0.3.0}/src/ocr_toolkit/posting/payloads.py +0 -0
- {open_code_review_toolkit-0.2.0 → open_code_review_toolkit-0.3.0}/src/ocr_toolkit/posting/result.py +0 -0
- {open_code_review_toolkit-0.2.0 → open_code_review_toolkit-0.3.0}/src/ocr_toolkit/posting/settings.py +0 -0
- {open_code_review_toolkit-0.2.0 → open_code_review_toolkit-0.3.0}/src/ocr_toolkit/posting/snapshot.py +0 -0
- {open_code_review_toolkit-0.2.0 → open_code_review_toolkit-0.3.0}/src/ocr_toolkit/py.typed +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.3.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
|
|
@@ -243,7 +243,8 @@ ocr --version
|
|
|
243
243
|
ocr-ci --help
|
|
244
244
|
```
|
|
245
245
|
|
|
246
|
-
The current compatibility target is OCR `1.7.
|
|
246
|
+
The current compatibility target is OCR `1.7.17`. CI should pin the release and verify its published checksum before execution.
|
|
247
|
+
The [versioned compatibility policy](docs/compatibility.md) records tested assets and evidence and describes the conservative Dependabot-like qualification workflow for later upstream releases.
|
|
247
248
|
Review output defaults to English. Set `OCR_REVIEW_LANGUAGE=Russian` to use Russian consistently in both OCR configuration and generated review context.
|
|
248
249
|
|
|
249
250
|
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.
|
|
@@ -256,6 +257,14 @@ Suppression uses both the GitLab diff position and a stable finding fingerprint,
|
|
|
256
257
|
|
|
257
258
|
Project-wide accepted tradeoffs can be recorded separately in `.opencodereview/accepted-decisions.md`; the context generator supplies them to OCR only when the current merge request is not changing that file. See [Accepted project decisions](docs/configuration.md#accepted-project-decisions) for the entry format, inline marker convention, security boundary, and limitations.
|
|
258
259
|
|
|
260
|
+
## Project development
|
|
261
|
+
|
|
262
|
+
The project is evolving from bounded background generation toward a shared Repository Evidence Engine: one deterministic evidence model will support both a compact OCR bootstrap and a built-in read-only MCP server. Development is ordered by outcomes and dependencies rather than speculative dates.
|
|
263
|
+
|
|
264
|
+
- [Toolkit strategy](docs/engineering/toolkit_strategy.md) - durable product boundaries, architecture, invariants, and non-goals.
|
|
265
|
+
- [Roadmap](ROADMAP.md) - milestone status, dependencies, outcomes, and completion signals.
|
|
266
|
+
- [Backlog](docs/codex/TASKS_BACKLOG.md) - inactive implementation-ready work; active execution remains in `PLANS.md`.
|
|
267
|
+
|
|
259
268
|
## GitLab CI quick start
|
|
260
269
|
|
|
261
270
|
1. Configure protected/masked `GITLAB_API_TOKEN` and LLM variables in GitLab.
|
|
@@ -15,7 +15,8 @@ ocr --version
|
|
|
15
15
|
ocr-ci --help
|
|
16
16
|
```
|
|
17
17
|
|
|
18
|
-
The current compatibility target is OCR `1.7.
|
|
18
|
+
The current compatibility target is OCR `1.7.17`. CI should pin the release and verify its published checksum before execution.
|
|
19
|
+
The [versioned compatibility policy](docs/compatibility.md) records tested assets and evidence and describes the conservative Dependabot-like qualification workflow for later upstream releases.
|
|
19
20
|
Review output defaults to English. Set `OCR_REVIEW_LANGUAGE=Russian` to use Russian consistently in both OCR configuration and generated review context.
|
|
20
21
|
|
|
21
22
|
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.
|
|
@@ -28,6 +29,14 @@ Suppression uses both the GitLab diff position and a stable finding fingerprint,
|
|
|
28
29
|
|
|
29
30
|
Project-wide accepted tradeoffs can be recorded separately in `.opencodereview/accepted-decisions.md`; the context generator supplies them to OCR only when the current merge request is not changing that file. See [Accepted project decisions](docs/configuration.md#accepted-project-decisions) for the entry format, inline marker convention, security boundary, and limitations.
|
|
30
31
|
|
|
32
|
+
## Project development
|
|
33
|
+
|
|
34
|
+
The project is evolving from bounded background generation toward a shared Repository Evidence Engine: one deterministic evidence model will support both a compact OCR bootstrap and a built-in read-only MCP server. Development is ordered by outcomes and dependencies rather than speculative dates.
|
|
35
|
+
|
|
36
|
+
- [Toolkit strategy](docs/engineering/toolkit_strategy.md) - durable product boundaries, architecture, invariants, and non-goals.
|
|
37
|
+
- [Roadmap](ROADMAP.md) - milestone status, dependencies, outcomes, and completion signals.
|
|
38
|
+
- [Backlog](docs/codex/TASKS_BACKLOG.md) - inactive implementation-ready work; active execution remains in `PLANS.md`.
|
|
39
|
+
|
|
31
40
|
## GitLab CI quick start
|
|
32
41
|
|
|
33
42
|
1. Configure protected/masked `GITLAB_API_TOKEN` and LLM variables in GitLab.
|
|
@@ -38,6 +38,7 @@ ocr-ci = "ocr_toolkit.cli:main"
|
|
|
38
38
|
|
|
39
39
|
[dependency-groups]
|
|
40
40
|
dev = [
|
|
41
|
+
"bandit==1.9.4",
|
|
41
42
|
"build>=1.2.2",
|
|
42
43
|
"coverage[toml]>=7.6",
|
|
43
44
|
"hatch-vcs>=0.4",
|
|
@@ -60,19 +61,7 @@ version-file = "src/ocr_toolkit/_version.py"
|
|
|
60
61
|
packages = ["src/ocr_toolkit"]
|
|
61
62
|
|
|
62
63
|
[tool.hatch.build.targets.sdist]
|
|
63
|
-
include = [
|
|
64
|
-
"/src",
|
|
65
|
-
"/tests",
|
|
66
|
-
"/examples",
|
|
67
|
-
"/docs",
|
|
68
|
-
"/changelog.d",
|
|
69
|
-
"/README.md",
|
|
70
|
-
"/CONTRIBUTING.md",
|
|
71
|
-
"/SECURITY.md",
|
|
72
|
-
"/LICENSE",
|
|
73
|
-
"/CHANGELOG.md",
|
|
74
|
-
"/pyproject.toml",
|
|
75
|
-
]
|
|
64
|
+
only-include = ["src", "README.md", "LICENSE", "pyproject.toml"]
|
|
76
65
|
|
|
77
66
|
[tool.hatch.version.raw-options]
|
|
78
67
|
fallback_version = "0.3.0.dev0"
|
|
@@ -101,6 +90,11 @@ exclude = ["src/ocr_toolkit/_version.py"]
|
|
|
101
90
|
warn_unreachable = false
|
|
102
91
|
disable_error_code = ["arg-type", "assignment", "import-not-found", "index", "name-defined", "no-any-return", "no-redef", "union-attr", "unused-ignore", "var-annotated"]
|
|
103
92
|
|
|
93
|
+
[tool.bandit]
|
|
94
|
+
exclude_dirs = ["tests"]
|
|
95
|
+
severity = "medium"
|
|
96
|
+
confidence = "medium"
|
|
97
|
+
|
|
104
98
|
[tool.pytest.ini_options]
|
|
105
99
|
addopts = "--strict-config --strict-markers"
|
|
106
100
|
testpaths = ["tests"]
|
{open_code_review_toolkit-0.2.0 → open_code_review_toolkit-0.3.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.3.0'
|
|
22
|
+
__version_tuple__ = version_tuple = (0, 3, 0)
|
|
23
23
|
|
|
24
24
|
__commit_id__ = commit_id = None
|
|
@@ -33,9 +33,17 @@ def build_parser() -> argparse.ArgumentParser:
|
|
|
33
33
|
|
|
34
34
|
post_parser = subparsers.add_parser("post", help="Publish an OCR result artifact to GitLab.")
|
|
35
35
|
post_parser.add_argument(
|
|
36
|
-
|
|
36
|
+
# The public GitLab example writes this fixed path inside an isolated CI job.
|
|
37
|
+
"--result",
|
|
38
|
+
default="/tmp/ocr-result.json", # nosec B108
|
|
39
|
+
help="OCR JSON result path.",
|
|
40
|
+
)
|
|
41
|
+
post_parser.add_argument(
|
|
42
|
+
# The file contains only the current job's OCR stderr and is never shared.
|
|
43
|
+
"--stderr",
|
|
44
|
+
default="/tmp/ocr-stderr.log", # nosec B108
|
|
45
|
+
help="OCR stderr log path.",
|
|
37
46
|
)
|
|
38
|
-
post_parser.add_argument("--stderr", default="/tmp/ocr-stderr.log", help="OCR stderr log path.")
|
|
39
47
|
return parser
|
|
40
48
|
|
|
41
49
|
|
|
@@ -196,9 +196,9 @@ def parse_pyproject(path: Path) -> dict[str, Any]:
|
|
|
196
196
|
|
|
197
197
|
try:
|
|
198
198
|
try:
|
|
199
|
-
import tomllib
|
|
199
|
+
import tomllib # type: ignore[import-untyped]
|
|
200
200
|
except ModuleNotFoundError:
|
|
201
|
-
import tomli as tomllib
|
|
201
|
+
import tomli as tomllib
|
|
202
202
|
|
|
203
203
|
data = tomllib.loads(text)
|
|
204
204
|
except ModuleNotFoundError:
|
|
@@ -209,9 +209,12 @@ def parse_pyproject(path: Path) -> dict[str, Any]:
|
|
|
209
209
|
if not isinstance(data, dict):
|
|
210
210
|
return {"present": True, "parse_error": JSON_OBJECT_PARSE_ERROR}
|
|
211
211
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
212
|
+
raw_project = data.get("project")
|
|
213
|
+
raw_tool = data.get("tool")
|
|
214
|
+
project: dict[Any, Any] = raw_project if isinstance(raw_project, dict) else {}
|
|
215
|
+
tool: dict[Any, Any] = raw_tool if isinstance(raw_tool, dict) else {}
|
|
216
|
+
raw_poetry = tool.get("poetry")
|
|
217
|
+
poetry: dict[Any, Any] = raw_poetry if isinstance(raw_poetry, dict) else {}
|
|
215
218
|
|
|
216
219
|
dependencies: list[str] = []
|
|
217
220
|
if isinstance(project.get("dependencies"), list):
|
|
@@ -233,12 +236,14 @@ def parse_pyproject(path: Path) -> dict[str, Any]:
|
|
|
233
236
|
f"group.{group_name}: {redact_url_userinfo(str(dep))}" for dep in group_deps
|
|
234
237
|
)
|
|
235
238
|
|
|
236
|
-
|
|
239
|
+
raw_poetry_deps = poetry.get("dependencies")
|
|
240
|
+
poetry_deps: dict[Any, Any] = raw_poetry_deps if isinstance(raw_poetry_deps, dict) else {}
|
|
237
241
|
for name, version in poetry_deps.items():
|
|
238
242
|
if str(name).lower() != "python":
|
|
239
243
|
dependencies.append(f"{name}: {redact_url_userinfo(str(version))}")
|
|
240
244
|
|
|
241
|
-
|
|
245
|
+
raw_poetry_groups = poetry.get("group")
|
|
246
|
+
poetry_groups: dict[Any, Any] = raw_poetry_groups if isinstance(raw_poetry_groups, dict) else {}
|
|
242
247
|
for group_name, group_value in poetry_groups.items():
|
|
243
248
|
if not isinstance(group_value, dict):
|
|
244
249
|
continue
|
|
@@ -354,10 +359,14 @@ def parse_composer_json(path: Path) -> dict[str, Any]:
|
|
|
354
359
|
if not isinstance(data, dict):
|
|
355
360
|
return {"present": True, "parse_error": JSON_OBJECT_PARSE_ERROR}
|
|
356
361
|
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
362
|
+
raw_require = data.get("require")
|
|
363
|
+
raw_require_dev = data.get("require-dev")
|
|
364
|
+
raw_config = data.get("config")
|
|
365
|
+
require: dict[Any, Any] = raw_require if isinstance(raw_require, dict) else {}
|
|
366
|
+
require_dev: dict[Any, Any] = raw_require_dev if isinstance(raw_require_dev, dict) else {}
|
|
367
|
+
config: dict[Any, Any] = raw_config if isinstance(raw_config, dict) else {}
|
|
368
|
+
raw_platform = config.get("platform")
|
|
369
|
+
platform: dict[Any, Any] = raw_platform if isinstance(raw_platform, dict) else {}
|
|
361
370
|
|
|
362
371
|
platform_items, platform_omitted = limited_manifest_items(
|
|
363
372
|
[f"{name}: {version}" for name, version in platform.items()]
|
|
@@ -433,10 +442,13 @@ def parse_package_json(path: Path) -> dict[str, Any]:
|
|
|
433
442
|
if not isinstance(data, dict):
|
|
434
443
|
return {"present": True, "parse_error": JSON_OBJECT_PARSE_ERROR}
|
|
435
444
|
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
445
|
+
raw_engines = data.get("engines")
|
|
446
|
+
raw_dependencies = data.get("dependencies")
|
|
447
|
+
raw_dev_dependencies = data.get("devDependencies")
|
|
448
|
+
engines: dict[Any, Any] = raw_engines if isinstance(raw_engines, dict) else {}
|
|
449
|
+
dependencies: dict[Any, Any] = raw_dependencies if isinstance(raw_dependencies, dict) else {}
|
|
450
|
+
dev_dependencies: dict[Any, Any] = (
|
|
451
|
+
raw_dev_dependencies if isinstance(raw_dev_dependencies, dict) else {}
|
|
440
452
|
)
|
|
441
453
|
|
|
442
454
|
engines_items, engines_omitted = limited_manifest_items(
|
{open_code_review_toolkit-0.2.0 → open_code_review_toolkit-0.3.0}/src/ocr_toolkit/context/repo.py
RENAMED
|
@@ -162,11 +162,13 @@ def resolve_output_path(value: str) -> Path | None:
|
|
|
162
162
|
requested = Path(value)
|
|
163
163
|
logical_output = requested if requested.is_absolute() else root_lexical / requested
|
|
164
164
|
logical_output = logical_output.absolute()
|
|
165
|
-
|
|
165
|
+
# tempfile supplies the platform temp root; containment and symlink checks follow.
|
|
166
|
+
temp_lexical = Path(tempfile.gettempdir()).absolute() # nosec B108
|
|
166
167
|
allowed_roots = [(root_lexical, root), (root, root)]
|
|
167
168
|
temp_resolved = temp_lexical.resolve()
|
|
168
169
|
allowed_roots.extend([(temp_lexical, temp_resolved), (temp_resolved, temp_resolved)])
|
|
169
|
-
|
|
170
|
+
# POSIX /tmp may be a distinct lexical alias (for example, /private/tmp).
|
|
171
|
+
tmp_path = Path("/tmp") # nosec B108
|
|
170
172
|
if tmp_path.exists():
|
|
171
173
|
tmp_lexical = tmp_path.absolute()
|
|
172
174
|
tmp_resolved = tmp_path.resolve()
|
{open_code_review_toolkit-0.2.0 → open_code_review_toolkit-0.3.0}/src/ocr_toolkit/posting/gitlab.py
RENAMED
|
@@ -125,7 +125,7 @@ def _open_gitlab_request(request: urllib.request.Request) -> Any:
|
|
|
125
125
|
def _read_limited_response(response: Any) -> bytes:
|
|
126
126
|
"""Read a GitLab response body and fail when it exceeds the success budget."""
|
|
127
127
|
|
|
128
|
-
body = response.read(MAX_API_RESPONSE_BODY_BYTES)
|
|
128
|
+
body: bytes = response.read(MAX_API_RESPONSE_BODY_BYTES)
|
|
129
129
|
if len(body) >= MAX_API_RESPONSE_BODY_BYTES and response.read(1):
|
|
130
130
|
raise GitLabResponseTooLarge(f"GitLab response exceeds {MAX_API_RESPONSE_BODY_BYTES} bytes")
|
|
131
131
|
return body
|
|
@@ -323,11 +323,13 @@ def fetch_current_user_id(server_url: str, api_token: str, auth_header: str) ->
|
|
|
323
323
|
return None
|
|
324
324
|
|
|
325
325
|
raw_user_id = result.get("id")
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
326
|
+
if isinstance(raw_user_id, (str, int, float)) and not isinstance(raw_user_id, bool):
|
|
327
|
+
try:
|
|
328
|
+
return int(raw_user_id)
|
|
329
|
+
except ValueError:
|
|
330
|
+
pass
|
|
331
|
+
print_user_id_failure_banner("GET /user response has no valid id field")
|
|
332
|
+
return None
|
|
331
333
|
|
|
332
334
|
|
|
333
335
|
def load_gitlab_config() -> GitLabConfig | None:
|
|
@@ -481,10 +483,12 @@ def draft_note_id(value: Any) -> int | None:
|
|
|
481
483
|
if isinstance(raw_id, bool):
|
|
482
484
|
return None
|
|
483
485
|
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
486
|
+
if isinstance(raw_id, (str, int, float)) and not isinstance(raw_id, bool):
|
|
487
|
+
try:
|
|
488
|
+
return int(raw_id)
|
|
489
|
+
except ValueError:
|
|
490
|
+
pass
|
|
491
|
+
return None
|
|
488
492
|
|
|
489
493
|
|
|
490
494
|
def created_draft_note(response: Any, context: str) -> DraftNoteCreation | None:
|
{open_code_review_toolkit-0.2.0 → open_code_review_toolkit-0.3.0}/src/ocr_toolkit/posting/markers.py
RENAMED
|
@@ -240,10 +240,12 @@ def author_id_from_note(note: dict[str, Any]) -> int | None:
|
|
|
240
240
|
if isinstance(author, dict):
|
|
241
241
|
raw_author_id = author.get("id")
|
|
242
242
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
243
|
+
if isinstance(raw_author_id, (str, int, float)) and not isinstance(raw_author_id, bool):
|
|
244
|
+
try:
|
|
245
|
+
return int(raw_author_id)
|
|
246
|
+
except ValueError:
|
|
247
|
+
pass
|
|
248
|
+
return None
|
|
247
249
|
|
|
248
250
|
|
|
249
251
|
def is_diff_note(note: dict[str, Any]) -> bool:
|
|
@@ -131,7 +131,7 @@ def changed_new_lines(
|
|
|
131
131
|
timeout=15,
|
|
132
132
|
)
|
|
133
133
|
except (OSError, subprocess.SubprocessError):
|
|
134
|
-
lines = set()
|
|
134
|
+
lines: set[int] = set()
|
|
135
135
|
if cache is not None:
|
|
136
136
|
cache[cache_key] = lines
|
|
137
137
|
return lines
|
|
@@ -217,7 +217,7 @@ def head_file_lines(
|
|
|
217
217
|
size_result.returncode != 0
|
|
218
218
|
or int(size_result.stdout.strip() or "0") > MAX_REMAP_FILE_BYTES
|
|
219
219
|
):
|
|
220
|
-
lines = []
|
|
220
|
+
lines: list[tuple[int, str]] = []
|
|
221
221
|
if cache is not None:
|
|
222
222
|
cache[cache_key] = lines
|
|
223
223
|
return lines
|
|
@@ -827,8 +827,9 @@ def main(argv: list[str] | None = None) -> int:
|
|
|
827
827
|
"""CLI entrypoint."""
|
|
828
828
|
|
|
829
829
|
args = argv if argv is not None else sys.argv[1:]
|
|
830
|
-
|
|
831
|
-
|
|
830
|
+
# Defaults are per-job files in the isolated CI container; callers can override both.
|
|
831
|
+
result_path = Path(args[0]) if len(args) >= 1 else Path("/tmp/ocr-result.json") # nosec B108
|
|
832
|
+
stderr_path = Path(args[1]) if len(args) >= 2 else Path("/tmp/ocr-stderr.log") # nosec B108
|
|
832
833
|
|
|
833
834
|
config = load_gitlab_config()
|
|
834
835
|
if config is None:
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
## 0.2.0 - 2026-07-21
|
|
2
|
-
|
|
3
|
-
### Features
|
|
4
|
-
|
|
5
|
-
- Target Open Code Review 1.7.14 in preflight validation and the checksum-pinned GitLab CI example. ([#11](https://github.com/xeonvs/open-code-review-toolkit/issues/11))
|
|
6
|
-
- Replace the ambiguous `/ocr keep` and `/ocr skip` discussion replies with `/ocr resolve` and `/ocr suppress`, preserve human-owned deduplication, and document the complete GitLab review lifecycle for developers and CI operators. ([#8](https://github.com/xeonvs/open-code-review-toolkit/issues/8))
|
|
7
|
-
|
|
8
|
-
### Bug fixes
|
|
9
|
-
|
|
10
|
-
- Allow stable release verification to coexist with previously published development builds of the same base version on TestPyPI. ([#10](https://github.com/xeonvs/open-code-review-toolkit/issues/10))
|
|
11
|
-
- Treat ordinary merged pull requests as a successful no-op in the production release workflow while keeping release-branch authorization fail-closed. ([#7](https://github.com/xeonvs/open-code-review-toolkit/issues/7))
|
|
12
|
-
|
|
13
|
-
### Security
|
|
14
|
-
|
|
15
|
-
- Mark every source-distribution smoke install as hash-required while retaining the no-dependency boundary, and document the single-maintainer security posture and Scorecard triage policy. ([#6](https://github.com/xeonvs/open-code-review-toolkit/issues/6))
|
|
16
|
-
|
|
17
|
-
### Documentation
|
|
18
|
-
|
|
19
|
-
- Reduce the routine Ubuntu CI matrix to the supported Python 3.10 and 3.14 endpoints, matching the macOS matrix. ([#10](https://github.com/xeonvs/open-code-review-toolkit/issues/10))
|
|
20
|
-
- Document accepted project decisions, their optional `ocr-accept` marker convention, and the guard that prevents a merge request from whitelisting its own findings. ([#11](https://github.com/xeonvs/open-code-review-toolkit/issues/11))
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
## 0.1.0 - 2026-07-20
|
|
24
|
-
|
|
25
|
-
### Features
|
|
26
|
-
|
|
27
|
-
- Publish one deterministic, checksum-verified TestPyPI development build after every merge into `main`, with bounded registry downloads and idempotent reruns. ([#4](https://github.com/xeonvs/open-code-review-toolkit/pull/4))
|
|
28
|
-
- Target Open Code Review 1.7.13 in preflight validation and the pinned GitLab CI example. ([#4](https://github.com/xeonvs/open-code-review-toolkit/pull/4))
|
|
29
|
-
- Support and continuously test Python 3.14 while retaining Python 3.10-3.13 compatibility. ([#4](https://github.com/xeonvs/open-code-review-toolkit/pull/4))
|
|
30
|
-
- Publish reproducible 0.1.0 distributions to TestPyPI and PyPI with exact hash verification, provenance attestations, and immutable GitHub Release assets.
|
|
31
|
-
- Introduce the standalone `ocr-ci` toolkit with safe context generation, GitLab posting, runtime configuration, MCP configuration, and preflight checks.
|
|
32
|
-
|
|
33
|
-
### Bug fixes
|
|
34
|
-
|
|
35
|
-
- Bind production release smoke tests to the exact reviewed wheel and sdist hashes, with bounded HTTPS downloads from TestPyPI and PyPI. ([#4](https://github.com/xeonvs/open-code-review-toolkit/pull/4))
|
|
36
|
-
- Use `OCR_REVIEW_LANGUAGE` as the single safe language setting for OCR configuration and generated review context, with English as the default and Russian as an explicit option. ([#4](https://github.com/xeonvs/open-code-review-toolkit/pull/4))
|
|
37
|
-
- Preserve bounded context and version discovery with a 7,950-character ceiling, improve provider billing classification, and prevent cross-file remapping of findings that already name a path. ([#3](https://github.com/xeonvs/open-code-review-toolkit/pull/3))
|
|
38
|
-
|
|
39
|
-
### Security
|
|
40
|
-
|
|
41
|
-
- Require secure credential endpoints, block unsafe GitLab redirects, redact secret-shaped environment values, and reduce GitHub Actions credential persistence and permissions. ([#3](https://github.com/xeonvs/open-code-review-toolkit/pull/3))
|
|
42
|
-
|
|
43
|
-
### Documentation
|
|
44
|
-
|
|
45
|
-
- Document the checksum-verified TestPyPI prerelease path used before the public stable release. ([#2](https://github.com/xeonvs/open-code-review-toolkit/pull/2))
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
# Changelog
|
|
49
|
-
|
|
50
|
-
Changes for each release are assembled from `changelog.d/` by Towncrier.
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
# Contributing
|
|
2
|
-
|
|
3
|
-
Thank you for improving Open Code Review Toolkit. Keep changes focused, add regression tests for behavior changes, and use synthetic examples only.
|
|
4
|
-
|
|
5
|
-
1. Create a branch from `main`.
|
|
6
|
-
2. Install the locked development environment with `uv sync --frozen`.
|
|
7
|
-
3. Update `PLANS.md` for substantial work.
|
|
8
|
-
4. Add a Towncrier fragment for user-visible changes.
|
|
9
|
-
5. Run the checks in [docs/development.md](docs/development.md).
|
|
10
|
-
6. Open a pull request; protected `main` accepts changes only through green pull requests.
|
|
11
|
-
|
|
12
|
-
Every non-release merge publishes a `0.2.0.devN` development build to TestPyPI. Stable releases use a repository-owned `release/vX.Y.Z` branch and an exact `Release vX.Y.Z` pull-request title; merging that reviewed PR authorizes the automated TestPyPI, PyPI, and GitHub Release chain.
|
|
13
|
-
|
|
14
|
-
Do not include real credentials, provider payloads, internal hosts, or private repository details. Security reports should follow [SECURITY.md](SECURITY.md), not public issues.
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
# Security Policy
|
|
2
|
-
|
|
3
|
-
## Supported versions
|
|
4
|
-
|
|
5
|
-
Before 1.0, only the newest published release receives security fixes.
|
|
6
|
-
|
|
7
|
-
## Reporting a vulnerability
|
|
8
|
-
|
|
9
|
-
Use [GitHub private vulnerability reporting](https://github.com/xeonvs/open-code-review-toolkit/security/advisories/new) for this repository. Do not open a public issue or attach live credentials, proprietary source, or production provider responses. Include a minimal synthetic reproducer, impact, affected version, and suggested mitigation when available.
|
|
10
|
-
|
|
11
|
-
Maintainers will acknowledge a report within five business days, privately validate severity and affected versions, and coordinate disclosure only after a fix or documented mitigation is available. Critical fixes are released as soon as practical; reporters receive status updates at least every ten business days while investigation remains open.
|
|
12
|
-
|
|
13
|
-
The runtime trust model and deployment guidance are documented in [docs/security.md](docs/security.md).
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
# Agent Execution Pitfalls
|
|
2
|
-
|
|
3
|
-
## Closing a public-contract change after only the feature merge
|
|
4
|
-
|
|
5
|
-
**Failure mode:** A feature changes a public command or integration contract, its pull request merges, and a TestPyPI `.devN` build succeeds. The plan is then marked completed even though stable PyPI users still receive the old behavior.
|
|
6
|
-
|
|
7
|
-
**Why it happens:** Implementation, preview publication, and stable delivery are treated as separate mental tasks even when the user asked for one outcome. SCM-derived versions also make the source tree appear ready for the next version without proving that a stable tag or package exists.
|
|
8
|
-
|
|
9
|
-
**Required prevention:**
|
|
10
|
-
|
|
11
|
-
1. Classify the work at plan start and write the target stable version into `PLANS.md`.
|
|
12
|
-
2. Treat feature merge and TestPyPI `.devN` verification as intermediate receipts.
|
|
13
|
-
3. When release is required, prepare the version/changelog release PR immediately after the development build is verified.
|
|
14
|
-
4. Keep the objective active until the release workflow publishes and independent readback confirms PyPI, TestPyPI, the signed tag, immutable GitHub Release, hashes, attestations, and supported-Python installs.
|
|
15
|
-
5. If publication is intentionally deferred, record who deferred it, why, and the exact command or PR needed to resume.
|
|
16
|
-
|
|
17
|
-
**Closure question:** "Can a user installing from production PyPI obtain the promised behavior now?" If not, the stable-release objective is not complete.
|
|
18
|
-
|
|
19
|
-
This note records recurring execution mistake patterns discovered during real work. Record generalized lessons, not one-off complaints.
|
|
20
|
-
|
|
21
|
-
## Planning And Context Discipline
|
|
22
|
-
|
|
23
|
-
- Do not leave durable scope, source boundaries, or resume state only in chat; keep the active plan current.
|
|
24
|
-
- Do not treat a local working specification as publishable documentation; translate its public requirements and keep private audit criteria outside tracked files.
|
|
25
|
-
- Do not silently reduce extraction scope because the source is large; split it into coherent, validated subsystem slices.
|
|
26
|
-
- Do not commit completed work while the active plan still says `planned` or `in_progress`.
|
|
27
|
-
|
|
28
|
-
## Source And Privacy Boundaries
|
|
29
|
-
|
|
30
|
-
- Inventory tracked source explicitly and avoid broad copy commands that could include ignored or untracked files.
|
|
31
|
-
- Do not turn one-time private marker criteria into a tracked denylist or test fixture.
|
|
32
|
-
- Do not use real provider payloads, hosts, repositories, or credentials in public fixtures.
|
|
33
|
-
|
|
34
|
-
## Tooling And Validation Hygiene
|
|
35
|
-
|
|
36
|
-
- Prefer the narrowest reproducer before broad reruns.
|
|
37
|
-
- Verify both UTF-8 byte limits and Python character limits when changing note formatting.
|
|
38
|
-
- Treat tests, lint, typing, artifact checks, install smoke, privacy scans, and source-integrity checks as distinct gates.
|
|
39
|
-
- Pin third-party Actions by full commit SHA and keep readable version comments beside the pin.
|
|
40
|
-
|
|
41
|
-
## Learning Loop
|
|
42
|
-
|
|
43
|
-
- Promote a repeated stable lesson into `docs/engineering/project_principles.md`.
|
|
44
|
-
- Record actionable future work in `docs/codex/TASKS_BACKLOG.md` only when it has an activation trigger and next safe action.
|
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
# Tasks Backlog
|
|
2
|
-
|
|
3
|
-
This file tracks future work that is not active. Active extraction work is owned by `PLANS.md`.
|
|
4
|
-
|
|
5
|
-
## Backlog Item: Native fuzzing campaign
|
|
6
|
-
|
|
7
|
-
Status: parked
|
|
8
|
-
Priority: medium
|
|
9
|
-
|
|
10
|
-
### Activation Trigger
|
|
11
|
-
|
|
12
|
-
- A supported Python fuzzing backend is selected with reproducible local execution, bounded CI resources, and corpus ownership.
|
|
13
|
-
|
|
14
|
-
### Goal
|
|
15
|
-
|
|
16
|
-
Fuzz the untrusted-input boundaries with meaningful targets for result normalization, context rendering, GitLab payload parsing, and registry metadata validation. Integrate a public fuzzing service only after the targets demonstrate useful coverage and stable crash minimization.
|
|
17
|
-
|
|
18
|
-
### Next Safe Action
|
|
19
|
-
|
|
20
|
-
1. Compare Atheris with property-based alternatives across Python 3.10-3.14 and design a small synthetic seed corpus without adding a runtime dependency.
|
|
21
|
-
|
|
22
|
-
### Exit Criteria
|
|
23
|
-
|
|
24
|
-
- Native targets run locally and in bounded CI, retain minimized synthetic regressions, publish no repository or provider secrets, and are recognized by the selected fuzzing service.
|
|
25
|
-
|
|
26
|
-
## Backlog Item: OpenSSF Best Practices registration
|
|
27
|
-
|
|
28
|
-
Status: owner action
|
|
29
|
-
Priority: low
|
|
30
|
-
|
|
31
|
-
### Activation Trigger
|
|
32
|
-
|
|
33
|
-
- The owner is ready to authenticate at `bestpractices.dev` and attest every passing-level criterion truthfully.
|
|
34
|
-
|
|
35
|
-
### Goal
|
|
36
|
-
|
|
37
|
-
Register the public repository for an OpenSSF Best Practices badge without guessing owner-only governance or project-usage answers.
|
|
38
|
-
|
|
39
|
-
### Next Safe Action
|
|
40
|
-
|
|
41
|
-
1. Complete the passing-level questionnaire with evidence links to the public repository and leave unsupported criteria unmet.
|
|
42
|
-
|
|
43
|
-
### Exit Criteria
|
|
44
|
-
|
|
45
|
-
- The public badge record exists, all answers have current evidence, and the README displays only the earned status.
|
|
46
|
-
|
|
47
|
-
## Backlog Item: Additional provider adapters
|
|
48
|
-
|
|
49
|
-
Status: parked
|
|
50
|
-
Priority: low
|
|
51
|
-
|
|
52
|
-
### Activation Trigger
|
|
53
|
-
|
|
54
|
-
- A provider-neutral core has shipped and a concrete provider integration has an owner and testable API contract.
|
|
55
|
-
|
|
56
|
-
### Goal
|
|
57
|
-
|
|
58
|
-
Add another code-hosting adapter without weakening the provider-neutral core or GitLab behavior.
|
|
59
|
-
|
|
60
|
-
### Next Safe Action
|
|
61
|
-
|
|
62
|
-
1. Write an adapter contract proposal based on the shipped GitLab boundary and validate it against synthetic fixtures.
|
|
63
|
-
|
|
64
|
-
### Exit Criteria
|
|
65
|
-
|
|
66
|
-
- The new adapter has isolated tests, documentation, and no provider-specific leakage into core modules.
|
|
67
|
-
|
|
68
|
-
## Backlog Item: File-based user configuration
|
|
69
|
-
|
|
70
|
-
Status: parked
|
|
71
|
-
Priority: low
|
|
72
|
-
|
|
73
|
-
### Activation Trigger
|
|
74
|
-
|
|
75
|
-
- Environment-only configuration becomes a demonstrated usability constraint after v0.1.
|
|
76
|
-
|
|
77
|
-
### Goal
|
|
78
|
-
|
|
79
|
-
Evaluate a versioned user configuration file without silently changing environment precedence or secret handling.
|
|
80
|
-
|
|
81
|
-
### Next Safe Action
|
|
82
|
-
|
|
83
|
-
1. Draft a schema and threat model; do not implement until compatibility and migration behavior are agreed.
|
|
84
|
-
|
|
85
|
-
### Exit Criteria
|
|
86
|
-
|
|
87
|
-
- Schema, precedence, migration, secret handling, and validation behavior are documented and tested.
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
# Environment configuration
|
|
2
|
-
|
|
3
|
-
Open Code Review Toolkit uses environment variables only in v0.1. Empty values are generally treated as absent. Exact defaults and safety caps are enforced by the runtime modules.
|
|
4
|
-
|
|
5
|
-
## OCR and LLM
|
|
6
|
-
|
|
7
|
-
| Variable | Purpose |
|
|
8
|
-
| --- | --- |
|
|
9
|
-
| `OCR_LLM_URL` | OpenAI-compatible chat or responses endpoint. |
|
|
10
|
-
| `OCR_LLM_MODEL` | Exact model identifier passed to OCR. |
|
|
11
|
-
| `OCR_REVIEW_LANGUAGE` | Single review language used by OCR config and generated context. Defaults to `English`; set `Russian` for Russian review output. |
|
|
12
|
-
| `OCR_LLM_TOKEN` | LLM credential. Never written into generated context. |
|
|
13
|
-
| `OCR_LLM_AUTH_HEADER` | Optional authorization header name; defaults to `Authorization`. |
|
|
14
|
-
| `OCR_LLM_EXTRA_HEADERS` | Optional JSON object of additional string headers. |
|
|
15
|
-
| `OCR_LLM_SUPPORTS_FUNCTION_CALLING` | Boolean capability flag. |
|
|
16
|
-
| `OCR_LLM_SUPPORTS_REASONING` | Boolean capability flag. |
|
|
17
|
-
| `OCR_LLM_MAX_TOKENS` | Optional positive completion-token limit. |
|
|
18
|
-
| `OCR_LLM_VALIDATE_MODEL` | `true`, `false`, or `auto`; defaults to `false`. |
|
|
19
|
-
| `OCR_LLM_MODELS_URL` | Explicit `/models` metadata URL. |
|
|
20
|
-
| `OCR_LLM_ALLOWED_MODELS` | Optional comma-separated offline allowlist for `auto` validation. |
|
|
21
|
-
| `OCR_CONFIG_PATH` | Override the OCR JSON config path. |
|
|
22
|
-
|
|
23
|
-
## MCP
|
|
24
|
-
|
|
25
|
-
| Variable | Purpose |
|
|
26
|
-
| --- | --- |
|
|
27
|
-
| `OCR_MCP_SERVERS_JSON` | JSON object mapping server names to command, arguments, environment, and optional tool allowlists. |
|
|
28
|
-
| `OCR_MCP_REPLACE` | Replace configured MCP servers when true; otherwise merge by server name. |
|
|
29
|
-
|
|
30
|
-
MCP commands run as child processes of OCR. Treat their executable, arguments, environment, output, and tool access as privileged configuration.
|
|
31
|
-
|
|
32
|
-
## GitLab CI inputs
|
|
33
|
-
|
|
34
|
-
Posting requires `GITLAB_API_TOKEN`, `CI_SERVER_URL`, `CI_PROJECT_ID`, and `CI_MERGE_REQUEST_IID`. Inline discussions additionally use GitLab diff refs and merge-request source/base SHA variables. `CI_COMMIT_SHA` remains distinct from the merge-request source SHA and is never assumed to identify the reviewed branch head.
|
|
35
|
-
|
|
36
|
-
## Posting controls
|
|
37
|
-
|
|
38
|
-
`OCR_POST_MODE`, `OCR_STRICT_POSTING`, `OCR_EXIT_CODE`, `OCR_MAX_POST_COMMENTS`, `OCR_MAX_RESULT_BYTES`, and `OCR_POST_ERROR_DETAILS` control write behavior and bounded error reporting. Invalid numeric or boolean values fail closed or fall back to conservative defaults as documented in command output. Human replies to bot-created discussions prevent automated ownership actions on that discussion.
|
|
39
|
-
|
|
40
|
-
## Context controls
|
|
41
|
-
|
|
42
|
-
The `OCR_CONTEXT_*` family bounds files, bytes, changed paths, instructions, manifest content, dependency output, and generated background size. `OCR_BACKGROUND_MAX_CHARS` defaults to and is capped at `7950`; `OCR_BACKGROUND_MAX_BYTES` independently enforces the UTF-8 byte budget. The default output is `.review-context/dependencies.md`. The generator rejects symlink escapes and prunes common vendor/build directories.
|
|
43
|
-
|
|
44
|
-
### Accepted project decisions
|
|
45
|
-
|
|
46
|
-
Use `.opencodereview/accepted-decisions.md` for a reviewed, project-wide decision that OCR would otherwise report repeatedly. Each entry should have a stable slug, a concise rationale, an explicit scope, and an inline marker that ties the decision to the relevant code or configuration:
|
|
47
|
-
|
|
48
|
-
```markdown
|
|
49
|
-
## generated-client-timeout
|
|
50
|
-
|
|
51
|
-
The generated client keeps the provider's 90-second timeout so regenerated
|
|
52
|
-
code remains reproducible. Do not report that timeout in `src/client/generated.py`.
|
|
53
|
-
|
|
54
|
-
Look for `# ocr-accept: generated-client-timeout` at the configured value.
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
```python
|
|
58
|
-
REQUEST_TIMEOUT = 90 # ocr-accept: generated-client-timeout
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
`ocr-accept` is a human-readable convention, not a source-code parser or blanket linter suppression. The complete, byte-bounded Markdown file is sanitized, redacted, and included under `Accepted project decisions` in the generated review background; OCR is instructed not to raise matching findings. Keep the rationale narrow and name the affected paths or behavior so unrelated findings remain reviewable.
|
|
62
|
-
|
|
63
|
-
The decision file must already exist on the target branch and pass normal review. If the current merge request changes `.opencodereview/accepted-decisions.md`, or changed-file discovery fails, the toolkit omits all accepted decisions for that run to prevent self-whitelisting. A decision reduces repeated model findings but is not a deterministic static-analysis exemption: reviewers should still use `/ocr suppress` or `/ocr resolve` for a concrete GitLab discussion, and should update or remove stale decisions when the underlying tradeoff changes.
|
|
64
|
-
|
|
65
|
-
Use the default `OCR_POST_MODE=draft` for normal CI so all current notes are created as drafts before they are published and replaceable notes from the previous run are removed. Draft publication is sequential rather than atomic; the previous review is preserved unless every current draft publishes. Set `OCR_STRICT_POSTING=true` when the review job is a required merge gate; keep the default `false` only for advisory pipelines where GitLab posting availability must not block the pipeline. Reviewer commands and the complete repeated-run contract are documented in [GitLab review operations](operations.md).
|
|
66
|
-
|
|
67
|
-
Run `ocr-ci --help` and each subcommand's help for command arguments. Secret values are redacted from operational error text.
|