diff --git a/.next-version b/.next-version
index 8f0916f..4b9fcbe 100644
--- a/.next-version
+++ b/.next-version
@@ -1 +1 @@
-0.5.0
+0.5.1
diff --git a/.release-metadata.json b/.release-metadata.json
index 8c67dad..268681b 100644
--- a/.release-metadata.json
+++ b/.release-metadata.json
@@ -1,10 +1,8 @@
{
"issues": [
- 70,
- 71,
- 72,
- 73
+ 76,
+ 78
],
"schema_version": "ocr-toolkit.release-authorization/v1",
- "version": "0.4.7"
+ "version": "0.5.0"
}
diff --git a/.release-source-date-epoch b/.release-source-date-epoch
index 5582fbc..1912db3 100644
--- a/.release-source-date-epoch
+++ b/.release-source-date-epoch
@@ -1 +1 @@
-1786440757
+1786541273
diff --git a/.release-version b/.release-version
index f905682..8f0916f 100644
--- a/.release-version
+++ b/.release-version
@@ -1 +1 @@
-0.4.7
+0.5.0
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5b002d1..8c6f9b9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,19 @@
+## 0.5.0 - 2026-08-12
+
+### 🚀 Features
+
+- Add a bounded ecosystem-adapter layer plus framework and template evidence plugins for Jinja2, Go web frameworks, Symfony/PHP, and React/TypeScript, including unambiguous root components, applicability-aware Go replacements, include-graph completeness, fail-closed provider isolation, scoped coverage, and first-class redacted delta queries through the built-in evidence MCP. ([#77](https://github.com/xeonvs/open-code-review-toolkit/issues/77))
+- Target checksum-verified Open Code Review 1.9.2 after adjacent compatibility qualification. ([#78](https://github.com/xeonvs/open-code-review-toolkit/issues/78))
+
+### 🐛 Bug Fixes
+
+- Make stable release recovery idempotent across private draft Releases, already-published registry artifacts, and exact issue-receipt comment readback, while binding release notes, assets, and issue evidence to their validated file descriptors. ([#76](https://github.com/xeonvs/open-code-review-toolkit/issues/76))
+
+### 🧩 Rules
+
+- Make Jinja and Twig templates reviewable through explicit additive includes and template-specific rules in the synthetic GitLab rules pack. ([#77](https://github.com/xeonvs/open-code-review-toolkit/issues/77))
+
+
## 0.4.7 - 2026-08-11
### 🚀 Features
diff --git a/PLANS.md b/PLANS.md
index 5342c2a..3eba3e9 100644
--- a/PLANS.md
+++ b/PLANS.md
@@ -4,7 +4,7 @@ Use this file for active, blocked, or recently completed execution work. Update
## Active Plan: M2 ecosystem and framework coverage for 0.5.0
-Status: active; implementation and local validation complete; history and external delivery pending
+Status: active; release candidate locally validated; release PR and stable external delivery pending
Owner: Codex
Last Updated: 2026-08-12
Release Classification: release-required
@@ -20,10 +20,11 @@ public synthetic rules pack, expose framework/template state and deltas through
the existing read-only evidence MCP, repair issue #76 release recovery, and
qualify checksum-pinned OCR 1.9.2 through issue #78 before final validation.
The implementation, installed-artifact E2E, both owner-authorized local OCR
-review cycles, deterministic remediation, package reorganizations, and final
-local validation are complete in signed local checkpoints without intermediate
-pushes. Preserve that validated tree while consolidating unpublished history,
-then update feature PR #77 once before protected feature and stable delivery.
+review cycles, deterministic remediation, package reorganizations, protected
+feature merge, and TestPyPI development readback are complete. The final
+repository mutation for stable 0.5.0 is locally prepared and validated; complete
+its protected release PR, publication, immutable evidence, issue closure, and M2
+external reconciliation without another repository pull request.
### Decisions
@@ -31,6 +32,10 @@ then update feature PR #77 once before protected feature and stable delivery.
TestPyPI development verification, final release PR, stable registries,
provenance, annotated tag, immutable Release, receipt, supported-Python
installs, and completed closure of issues #76 and #78.
+- The release PR records M2 and external publication as pending because those
+ facts do not exist before merge. After its immutable receipt and independent
+ readback prove stable delivery, close the issues and active objective without
+ another repository mutation; the release receipt is the final status evidence.
- Use only anonymized technology selection conclusions from the private
inventory. Never persist private host, project, namespace, path, payload, or
identifying aggregate data; all public fixtures and examples are synthetic.
@@ -136,16 +141,90 @@ then update feature PR #77 once before protected feature and stable delivery.
supported-Python gates; reproduce the target-version artifacts; verify
hash-locked installs, installed MCP, template rules preview, and static
workflow boundaries; then recheck public OCR release and issue/PR state.
-15. [ ] Update feature PR #77 once with `--force-with-lease`, read back its exact
+15. [x] Update feature PR #77 once with `--force-with-lease`, read back its exact
head, finish checks and review threads, merge it, and independently verify
TestPyPI development delivery.
-16. [ ] Prepare the final release PR as the last repository mutation, archive
- completed 0.4.7 history, consume fragments 76, 77, and 78, and reconcile M2
- to implemented truth while leaving external publication pending.
-17. [ ] Complete stable 0.5.0 TestPyPI/PyPI, provenance/hash/tag/immutable
+16. [x] Prepare and locally validate the final release candidate as the last
+ repository mutation, archive completed 0.4.7 history, consume fragments 76,
+ 77, and 78, and reconcile M2 while leaving external publication pending.
+17. [ ] Push the release branch once, open the exact final release PR, read back
+ its head, required checks, and review threads, then squash-merge only after
+ every protected gate passes.
+18. [ ] Complete stable 0.5.0 TestPyPI/PyPI, provenance/hash/tag/immutable
Release/receipt/Python-install readback and close #76 and #78 as completed
without another repository PR.
+### Feature Merge And Development Publication Checkpoint
+
+- Feature PR #77 was updated once after local consolidation and read back at
+ exact reviewed head `a0a9e33ceda170c6339cbcc255b59d3a1538f74e` over stable
+ base `3caa50b4fc5026da79c7f2ceae1deef31715f814`. All exact-head hosted checks
+ passed, the thread-aware review inventory was empty, and the active `main`
+ ruleset required no approving review while enforcing resolved conversations,
+ signed linear history, and its complete check set.
+- The GitHub-verified squash merge
+ `a7d97ff0e0e128f833b1991e4e4af778b2e4fb8f` has the reviewed tree
+ `e79bda9bcdbf7d3c3e3c6ab8a98635834aecc524` and stable base as its only
+ parent. The remote feature branch was removed and `main` points to that merge.
+- TestPyPI development workflow `31601538539` completed for the exact merge and
+ published `0.5.0.dev47`. Fresh Simple API downloads are byte-identical to
+ Actions artifact `9143315192`: wheel SHA-256
+ `e9d8c2520f12efaa4c9ee1d7350bc946d33c1767daf0a86a8172a67d13996ec0` and
+ sdist SHA-256
+ `b2b6ac96edafeb69cc9cff4942512620cc16534a605435b3e31a17db9b9bf8f1`.
+- Independent Integrity reads bind both subjects to repository
+ `xeonvs/open-code-review-toolkit`, workflow `testpypi.yml`, and environment
+ `testpypi-public-disclosure`. Published wheel installs pass on Python 3.12
+ and 3.13 and the sdist on Python 3.14, including exact version, `pip check`,
+ isolated import, and restricted-`PATH` CLI smoke.
+- The release branch starts from that exact protected merge. It is the final
+ repository mutation for this lifecycle; stable registry, provenance,
+ attestation, tag, immutable Release, receipt, install, issue-closure, and M2
+ roadmap completion signals remain pending and are not claimed by this PR.
+
+### Release Preparation Validation Checkpoint
+
+- The release branch starts from protected feature merge
+ `a7d97ff0e0e128f833b1991e4e4af778b2e4fb8f`. Tracked authorization names
+ stable 0.5.0 and sorted issues #76 and #78; the next line is 0.5.1, and the
+ deterministic source epoch is exactly one second after the feature merge.
+ Towncrier consumed only the four release fragments, and generated notes contain
+ only the 0.5.0 section plus the exact `v0.4.7...v0.5.0` comparison.
+- The externally reconciled 0.4.7 plan moved intact into the release-tag archive;
+ its content is byte-identical to the protected feature-merge source, apart from
+ the structural separator before the next anchor. Every indexed archive link
+ resolves. Roadmap, strategy, README, and backlog reconciliation keeps M2 in
+ progress only until independently read-back stable delivery; BL-010 remains
+ conditional rather than blocking this release.
+- The final release-focused suite passes 100 tests. Complete tests pass on Python 3.12,
+ 3.13, and 3.14 with 676 tests plus 85 subtests per interpreter; routine format,
+ Ruff, strict mypy, Bandit, OCR-manifest, lock, workflow-YAML, ShellCheck, and
+ dependency-audit gates pass. The release audit found and fixed one unquoted
+ quality-environment export, added its contract regression, and audited every
+ tracked shell script for the same class.
+- Two source-date-epoch-controlled stable builds are byte-identical and pass
+ Twine plus closed archive inspection. Wheel SHA-256 is
+ `e3ffcdeb9052dc0dd57909ccb7867d546e11bd4e3bf8f43394896837cd3864d5`;
+ sdist SHA-256 is
+ `bda676aa0dde70ae73c49cf5a90dd85c46268b257f5f26afff212f6249b94153`.
+ Both carry 0.5.0, Python `>=3.12,<3.15`, zero runtime dependencies, the new
+ ecosystem/framework layout, and no removed flat modules. Hash-locked wheel
+ installs on Python 3.12 and 3.13 plus an sdist install on Python 3.14 pass
+ isolated import, hostile shadow, `pip check`, restricted `PATH`, and layout
+ probes.
+- The installed stable wheel passes the real stdio MCP protocol with the one
+ read-only `ocr_toolkit_evidence` tool, including root and named components,
+ framework facts, scoped coverage, deltas, Jinja2/Twig templates, and private
+ artifacts. Checksum-qualified PATH-effective OCR 1.9.2 selects ordinary,
+ Jinja, Twig, and extensionless conventional role-template files in JSON
+ preview without an LLM run or session artifact. Changed-content and complete
+ tracked-source privacy scans contain no private inventory marker or review
+ artifact, and the release diff passes Gitleaks plus `git diff --check`.
+- Stable registry bytes, provenance, GitHub attestations, annotated tag,
+ immutable Release and complete asset set, release receipt, published installs,
+ issue receipts/closure, and final M2 external completion remain post-merge
+ gates. This release preparation does not claim any of them.
+
### Issue #76 Checkpoint
- Stable delivery now retains a validated numeric GitHub Release ID from draft
@@ -523,423 +602,3 @@ then update feature PR #77 once before protected feature and stable delivery.
and rules fragments. Canonical OCR 1.9.2 qualification issue #78 is open and
already contains passing hosted checksum/contract evidence; issue #76 and #78
remain open until immutable stable delivery.
-
-## Recently Completed Plan: Harden GitLab suggestions and add SHA-bound approval for 0.4.7
-
-Status: completed; stable 0.4.7 externally delivered and independently read back
-Owner: Codex
-Last Updated: 2026-08-11
-Release Classification: release-required
-Target Stable Version: 0.4.7
-Tracking Issues: #70, #71, #72 (OCR 1.9.1), #73 (OCR 1.9.0)
-
-### Goal
-
-Ship issues #70 and #71 as toolkit 0.4.7: publish actionable GitLab
-suggestions only when they are proven to replace one contiguous range in the
-reviewed immutable head, and add conservative default-on automatic approval
-that is bound to the exact reviewed merge-request SHA. Preserve a successfully
-published advisory review when approval management is ineligible, stale, or
-fails, and complete the release only after immutable external evidence has been
-independently read back.
-
-### Decisions
-
-- Use one feature branch and one protected feature pull request, with separate
- signed implementation checkpoints for #70, #71, and release-lifecycle
- hardening. Keep both issues open until stable external delivery is verified.
-- Keep provider-neutral decisions in typed core objects and GitLab HTTP/state
- transitions behind the provider adapter. Add no runtime dependency, public
- evidence command, permanent OCR harness, telemetry expansion, or tunable
- approval-policy variables.
-- Make `OCR_AUTO_APPROVE` default on with the established boolean vocabulary.
- An invalid value disables approval for that run. Encode the initial policy in
- code and fail closed when authoritative completeness or typed finding
- metadata cannot be proven. Keep the transaction add-only: GitLab cannot bind
- unapproval to the reviewed SHA at mutation time, so ineligible or disabled
- later reviews preserve every existing approval.
-- After the release-lifecycle checkpoint, qualify the contiguous Open Code
- Review 1.9.0 and 1.9.1 chain from authoritative release/source evidence.
- Preserve a separate checksum/contract record and human impact conclusion for
- each release, with a separate qualification issue for each version. Classify
- every upstream item as a toolkit-consumed contract change, future-backlog
- impact, or explicit no impact; adapt only demonstrated contracts and
- atomically replace the local checksum-pinned OCR binary with 1.9.1 before
- full E2E.
-- After the complete feature implementation is committed, run exactly one real
- local OCR 1.9.1 review through `uv run ocr-ci review` over
- `origin/main..HEAD`. Require the built-in `ocr_toolkit_evidence` MCP receipt,
- do not post to GitLab, fix actionable findings, and then use deterministic
- validation and self-review rather than a second OCR run.
-- Do not run Codex Security. Existing repository CI security checks and the
- checksum-pinned local Gitleaks gate remain required.
-- Redesign the durable release lifecycle so the release PR is the final
- repository mutation without preclaiming external facts. Bind publication to
- the exact reviewed tree and emit an immutable machine-readable release
- receipt; close #70/#71 and both OCR qualification issues only after
- independent registry, provenance, tag, Release, receipt, hash, and
- supported-Python readback succeeds.
-
-### Work Queue
-
-1. [x] Implement typed contiguous-range suggestion validation, immutable-head
- proof, bounded omission reasons, documentation, complete regressions, review,
- and the #70 checkpoint commit.
-2. [x] Implement typed auto-approval configuration and policy, exact-SHA GitLab
- synchronization/write/readback, add-only provider semantics, documentation,
- complete regressions, review, and the #71 checkpoint commit. The original
- managed-unapproval design was removed after final OCR found that GitLab
- cannot provide the required mutation-time immutable guard.
-3. [x] Replace the redundant post-release closure-PR contract with exact-tree
- release authorization and deterministic `ocr-toolkit.release-receipt/v1`
- evidence; update durable rules, recovery behavior, tests, and the lifecycle
- checkpoint commit.
-4. [x] Inspect authoritative OCR 1.9.0 and 1.9.1 release notes and source
- changes, record separate consumed-contract/backlog/no-impact
- classifications and qualification issues, update compatibility records and
- the local checksum-pinned OCR 1.9.1 binary, and adapt the toolkit only where
- evidence requires it.
-5. [x] Reconcile this plan, roadmap table/diagram, backlog, and current-state
- documentation against the implemented code. Run focused tests, the synthetic
- GitLab E2E, Python 3.12 quality, Towncrier draft, workflow/document/privacy
- checks, and `git diff --check`.
-6. [x] Commit the complete feature tip and run one local toolkit-owned OCR review
- with private result/stderr artifacts, no GitLab posting, and verified nonzero
- built-in MCP use. Correct its findings, complete deterministic validation and
- final self-review, and do not run a second OCR or Codex Security review.
-7. [x] Run deterministic post-review validation and pinned local Gitleaks over
- the unpublished history, push the exact reviewed branch, open one feature PR,
- resolve every conversation, pass protected checks, and squash-merge.
-8. [x] Independently verify the exact TestPyPI development artifacts, hashes,
- provenance, and supported-Python installs before preparing `release/v0.4.7`.
-9. [ ] Prepare and validate the final release PR, consuming fragments 69, 70,
- 71, 72, and 73 and reconciling repository-side planning truth without
- claiming publication that has not happened.
-10. [ ] Merge the release PR only after exact-head protected checks. Verify stable
- TestPyPI/PyPI artifacts, provenance/attestations, annotated tag, immutable
- GitHub Release and release receipt, hashes, and Python 3.12-3.14 installs.
- Record receipts and close #70/#71 plus both OCR qualification issues without
- another repository PR.
-
-### Initial Evidence
-
-- Clean synchronized `main` is `bb8827148f13b17b209495788ac4f7b15573a168`;
- stable toolkit 0.4.6 is published and `.next-version` targets 0.4.7.
-- Issues #70 and #71 are open. Current suggestion handling proves exact no-op
- equality but does not prove changed `suggestion_code` applies to
- `existing_code` at the reviewed range; the toolkit has no approval-management
- transaction yet.
-- The effective local binary is Open Code Review 1.8.10 and the checkout's
- `uv run ocr-ci review` path owns evidence collection, compact bootstrap,
- mandatory `ocr_toolkit_evidence` composition, use verification, and the
- private receipt.
-- Current release guidance still requires a documentation-only closure PR and
- release authorization does not bind publication to the reviewed head tree and
- exact checks. Both are explicit scope of the lifecycle checkpoint.
-
-### Issue #70 Checkpoint
-
-- GitLab suggestion applicability is now a closed typed decision rather than a
- hidden mutation on the untrusted OCR comment. The renderer accepts only an
- already-proven replacement; impossible state/field combinations fail at the
- typed boundary.
-- Validation binds a safe repository-relative path and inclusive range to one
- bounded immutable head blob, normalizes CRLF/CR and one terminal newline, and
- requires exact `existing_code` agreement before a changed replacement becomes
- actionable. Existing exact no-op suppression remains available even for the
- older no-`existing_code` result shape.
-- Synthetic omission bridges across common comment syntaxes, diff-prefixed
- replacements, quick actions, unsafe fences, oversized values, stale source,
- and invalid ranges retain the finding but produce only a closed non-sensitive
- omission reason. Fallback notes never render an actionable suggestion fence.
-- Focused Ruff and strict mypy pass. The complete posting/suggestion regression
- set passes 123 tests, including valid one-line and multiline replacements,
- newline equivalence, missing/stale source, invalid/out-of-bounds ranges,
- omission variants, diff prefixes, no-op behavior, typed invariants, unsafe
- paths, and workflow-level proof that only the apply fence is withheld.
- Towncrier 0.4.7 draft and `git diff --check` pass.
-
-### Issue #71 Checkpoint
-
-- `OCR_AUTO_APPROVE` is a typed default-on setting using the shared
- true/false, 1/0, yes/no, and on/off vocabulary. Invalid values fail closed to
- disabled without logging their contents. The fixed policy consumes the full
- unsuppressed OCR finding set and requires a complete manifest, zero warnings,
- failures, waivers, budget stop, or omitted findings, no more than three exact
- `low` findings, and only style/documentation/maintainability categories.
-- Approval is a distinct post-publication transaction. The GitLab adapter reads
- bounded MR and full paginated diff-version state, selects the highest valid
- version ID, waits at most ten two-second intervals for merge/approval
- synchronization and a non-null patch ID, verifies the open current head, and
- submits only the reviewed 40-hex SHA. Approve and summary-update writes are
- attempted once and followed by bounded readback.
-- Approval is add-only. An already approved toolkit user is reported as skipped
- without a provider write; ineligible, partial, skipped, legacy, disabled, and
- ambiguous runs also make no approval write. The adapter exposes no unapprove
- operation or managed-approval receipt because GitLab cannot bind unapproval to
- the immutable reviewed SHA at mutation time. Project-owned reset and
- invalidation rules remain authoritative.
-- The published summary contains one bounded approval state. Eligible runs first
- publish a conservative failed-until-confirmed state, then update the uniquely
- marked owned summary once after provider readback. Failure never rolls back the
- advisory review; strict mode returns nonzero while advisory mode remains
- nonfatal. Existing GitLab rules, groups, Code Owners, protected branches, and
- reauthentication stay authoritative.
-- Self-review fixed version-order assumptions, different-SHA approval claims,
- and provisional-summary truth. The final OCR correction subsequently removed
- the unsafe managed-unapproval design and its receipt surface entirely. Ruff
- and strict mypy pass; 148 posting/approval/suggestion tests and 15 public
- documentation/integration contracts pass. Towncrier 0.4.7 draft includes the
- default-on write and opt-out, and `git diff --check` passes. Roadmap and future
- backlog statuses remain unchanged because neither issue completes an existing
- outcome milestone or activation trigger.
-
-### Release Lifecycle Checkpoint
-
-- The merged release PR is now the final repository mutation without claiming
- future delivery. Authorization executes from the protected reviewed base that
- predates the release candidate, treats candidate head and merge commits as
- bounded data, validates tracked metadata from the exact merge ref, proves
- squash-tree equivalence and parent identity, and requires every live strict
- `main` check context from its exact GitHub App on the reviewed head SHA.
-- Registry verification covers Python 3.12-3.14 and exact PyPI Integrity
- publisher/subject provenance. GitHub artifact attestations, annotated-tag
- target, exact Release metadata/assets, immutable status, and a deterministic
- `ocr-toolkit.release-receipt/v1` are verified before tracked issues close.
-- Recovery is non-destructive and exact: existing registry and draft Release
- bytes must match, an existing receipt remains canonical across workflow
- reruns, asset reads work through bounded authenticated API calls, and no path
- replaces an existing tag, receipt, or Release asset.
-- Issue closure is bounded and idempotent. Every tracked item is preflighted
- before publication; only an exact GitHub Actions-owned receipt marker is
- trusted, conflicting user markers fail closed, and an already-completed issue
- is accepted after final readback. Durable agent guidance, principles,
- pitfalls, release documentation, and execution-history rules now agree that
- no redundant post-release repository PR is required.
-- Self-review corrected timestamp semantics, arbitrary receipt artifact names,
- incomplete check-run binding, unbounded API/asset/comment reads, draft asset
- download behavior, destructive `--clobber` recovery, receipt regeneration on
- reruns, metadata checkout drift, standalone provenance imports, and ambiguous
- Release/issue state. The focused suite passes 53 tests; strict mypy, Ruff,
- ShellCheck, workflow YAML parsing, OCR manifest validation, Towncrier 0.4.7
- draft, and `git diff --check` pass. Full `scripts/quality.sh check` passes 608
- tests plus 81 subtests at 79.62% coverage. Roadmap and backlog statuses remain
- unchanged at this checkpoint because the lifecycle hardening changes process,
- not an outcome milestone or future-work activation trigger.
-
-### Final OCR Review And Correction Checkpoint
-
-- The only final local OCR review covered
- `bb8827148f13b17b209495788ac4f7b15573a168..fe88f8d78744847bc58b35129de5c9130cd46853`
- with official OCR 1.9.1. It completed all 23 selected items in 39 minutes 5
- seconds with zero failed or waived items, returned 16 findings, and made 68
- mandatory `ocr_toolkit_evidence` calls. The private toolkit receipt records
- the same 68 calls; result/stderr and `.review-context` artifacts retain owner-
- only permissions, `.review-context` is absent from the reviewed diff, and no
- GitLab posting command ran.
-- Thirteen findings exposed valid boundary defects or the same root-cause
- classes. Release authorization now executes from the protected pre-candidate
- base. The GitHub API helper has a closed endpoint grammar, redirect-safe
- bearer authentication, private same-directory temporary output, allowed-
- status validation, and atomic replacement. Minor/major OCR promotion requires
- chain-aware schema 2. Stable receipts reject unknown top-level and nested
- fields; malformed registry provenance URLs fail closed; unhashable finding
- categories degrade to not eligible; complete unified-diff replacements are
- rejected; and unused approval-receipt parsing was removed.
-- The two unapproval findings and the approval-without-durable-receipt finding
- shared one architectural cause: GitLab's unapprove endpoint cannot receive the
- reviewed SHA, so preflight and readback cannot close its destructive TOCTOU
- gap. Automatic approval is therefore add-only. All unapproval and managed-
- receipt runtime paths were removed instead of adding another compensating
- state machine.
-- Three suggestions were rejected after source and regression review. Python's
- `binascii.Error` is already a `ValueError`, so existing malformed-base64
- handling covers both flagged decode sites. A user-authored exact issue-receipt
- marker intentionally blocks closure as the documented anti-preemption,
- fail-closed contract; it is not trusted as a successful receipt.
-- Root-cause sibling audits covered URL parsers, release/security receipt
- loaders, bounded HTTP helpers, and destructive provider writes. Public
- approval/release/security documentation and `AGENTS.md`, project principles,
- and execution pitfalls now encode the corrected boundaries. A direct
- regression proves that schema-1 evidence cannot cross minor or major OCR
- boundaries. No second OCR review or Codex Security run will be performed.
-- The final post-correction gate runs from isolated Python 3.12.13 and passes
- formatting, Ruff, strict mypy, Bandit with zero medium/high findings, 623
- tests plus 85 subtests, and 79.09% coverage. OCR manifest validation,
- Towncrier 0.4.7 draft, changed-shell ShellCheck, workflow YAML parsing,
- changed-public-content privacy checks across 31 files, and `git diff --check`
- pass. Fresh `0.4.7.dev7` wheel and sdist pass Twine, canonical composition,
- centralized SCM-version, zero-runtime-dependency, and Python `>=3.12,<3.15`
- metadata checks. Separate Python 3.12 installs pass `pip check` and execute
- the installed CLI/import under restricted `PATH` from a hostile shadow-package
- working directory. Wheel SHA-256 is
- `0582f8b1ed7623cec55aaeef289bde7d9ccda9c1b9b856d30eacb95e57508ac6`;
- sdist SHA-256 is
- `4bdcfc1a302e1f7392623b2c651bf8d747e8228891b74f14257479e8ab93dee6`.
-- Final manual self-review removed the obsolete `ApprovalResult.managed` flag,
- confirmed every workflow-used GitHub endpoint is represented by the closed
- helper grammar, verified recovery binds the protected reviewed base, and
- found no roadmap, backlog, or narrative status tail. Exactly one worktree is
- present and all review/quality artifacts remain ignored and private.
-
-### OCR 1.9.0-1.9.1 Qualification Checkpoint
-
-- Canonical GitHub Actions run `31465539451` created separate open
- qualification issues #73 for 1.9.0 and #72 for 1.9.1. Local Python 3.12
- qualification independently downloaded all seven assets for each release,
- proved GitHub digests equal the upstream `sha256sum.txt`, executed the Linux
- amd64 version/help/JSON-preview/full-review/result/posting contracts, and
- reproduced both evidence files byte-for-byte from checkpoint `5acbf15`.
-- OCR 1.9.0 is compatible after required human review. Toolkit-consumed changes
- are JSON preview output, preview session-store isolation, additive private
- comment `thinking`, merge-base range semantics, and the Nim rules/allowlist
- expansion. The harness now proves JSON preview, no session-store creation,
- additive `thinking` preservation, and non-publication of that private field;
- source review confirms reasoning-content backfill and the documented range
- semantics. The Nim change receives a separate `🧩 Rules` entry.
-- OCR 1.9.0 per-file token limits and retry status codes are future profile or
- configuration inputs only and do not activate BL-016. Mistral and MiniMax
- providers, QCA delegation, the upstream GitLab example, Pages/viewer/CSP,
- scan and installation documentation, fork deployment, blog, package-manager,
- and other documentation fixes are not toolkit-owned contracts. They require
- no runtime, roadmap, or backlog activation.
-- OCR 1.9.1 is an adjacent automatic-safe patch whose source was still reviewed.
- Viewer comment filters and suggestion-panel layout, CodeQL workflow
- permissions, upstream contributor/retry documentation, and the Anthropic
- dynamic cache breakpoint do not change toolkit CLI, result, posting,
- configuration, or MCP contracts. The cache change is a future profile/quality
- input only and does not complete BL-016 or BL-017.
-- Both releases retain Go MCP SDK v1.6.1 and protocol revision `2025-11-25`, so
- the built-in MCP protocol matrix is unchanged. Both annotated upstream tags
- carry signatures that GitHub reports as `unknown_key`; compatibility does not
- misrepresent them as verified and instead relies on the double-source asset
- digest contract plus executed binary probes.
-- Human-reviewed promotion now accepts only an adjacent patch, next minor `.0`,
- or next major `.0.0`; every minor/major transition requires an explicit
- bounded conclusion. The automatic lane remains patch-only. Self-review also
- isolated Git initialization, preview, and full-review probes from operator
- OCR/Git configuration and bounded optional automatic-safe conclusions.
-- Manifest, preflight, public examples, documentation, tests, and Linux digest
- now target OCR 1.9.1. The PATH-effective Darwin arm64 binary is official OCR
- 1.9.1 with SHA-256
- `5cffe45ef006b80dcbe95e6711807261850108d6390ce708cdac0e72cb261d1d`;
- its isolated local contract probe passes. Focused validation passes 265 tests
- plus 27 subtests, Ruff, strict mypy, manifest validation, Towncrier 0.4.7
- draft, and `git diff --check`.
-- Backlog statuses, roadmap table/diagram, and strategy status remain unchanged.
- Nim is review-engine scope rather than an evidence pack; upstream `AGENTS.md`
- is contributor guidance rather than target-ref runtime guidance; token/cache
- changes do not supply the missing profile or telemetry policy contracts.
-- The complete isolated Python 3.12.13 quality gate passes formatting, Ruff,
- strict mypy, Bandit, 622 tests plus 81 subtests, and 79.61% coverage. A fresh
- authenticated discovery after promotion reports zero unseen stable OCR
- releases. The gate uses `.quality-logs/py312` and does not mutate the host
- `.venv` or tracked checkout.
-
-### Feature-tip Validation And E2E Checkpoint
-
-- The signed `4f3dd29` tree builds on Python 3.12.13 as
- `0.4.7.dev6+g4f3dd2994`. Twine accepts both distributions; the wheel SHA-256
- is `295c0e9fa52492aa9e99c7dd11ae0b3a2b2c6339f3e4991ea3009e29812ed358`
- and the sdist SHA-256 is
- `c679d9490f8cb1fb58f37bac4eba24dcad52fb745814121523c2841a15096c55`.
- Metadata derives the version from SCM, requires Python 3.12 through 3.14,
- declares no runtime dependencies, and both archives contain only their
- intended package/source surfaces.
-- Separate clean Python 3.12 wheel and hash-locked sdist installs pass
- `pip check`, import the same centralized version, and run the installed
- `ocr-ci --help` entry point under a restricted `PATH` from a repository that
- contains a hostile local `ocr_toolkit` shadow package. The installed artifact,
- rather than checkout code or the untrusted current directory, owns execution.
-- One ignored, one-off synthetic repository E2E uses the installed wheel and the
- official local OCR 1.9.1 binary without adding a permanent harness. A local
- deterministic gateway forces OCR to query `ocr_toolkit_evidence` before it
- emits one synthetic finding. OCR finishes with `status=complete` and one
- built-in evidence call; `_ocr_toolkit.mcp_usage` records the same count. The
- exact base/head snapshots match the reviewed commits, `.review-context` is
- absent from Git status and the reviewed diff, its directory is `0700`, all
- store/bootstrap/result/stderr artifacts are `0600`, and no GitLab posting
- command is invoked.
-- The complete posting/suggestion/approval/release/compatibility changed-surface
- suite passes 347 tests plus 73 subtests. The full gate executed directly from
- Python 3.12.13 passes 622 tests plus 81 subtests at 79.61% coverage; formatting,
- Ruff, strict mypy, Bandit, changed-shell ShellCheck, workflow YAML parsing,
- OCR manifest validation, Towncrier 0.4.7 draft, changed-public-content privacy,
- and `git diff --check` pass.
-- Read-only validation against current public service payloads confirms that
- PyPI Integrity v1 uses the publisher and in-toto subject shape enforced by the
- release verifier, GitHub exposes strict effective `main` checks with exact App
- integration IDs, and immutable Release state is available through the pinned
- API version. No registry, Release, issue, or GitLab state was changed.
-- Final reconciliation found no roadmap table/diagram, strategy, or backlog
- status transition: #70/#71 are release-scoped behavior rather than an outcome
- milestone, while OCR 1.9.0/1.9.1 inputs leave BL-008/009/010/015/016/017 at
- their documented triggers. Self-review corrected the release queue to consume
- all five fragments 69-73; every tracked issue remains open until stable 0.4.7
- delivery is proven by the immutable receipt and independent readback.
-
-### Feature Merge And Development Publication
-
-- Feature PR #74 was read back as exact head
- `2f63d250cb47ab3c7bcc174514949f7bb2d6e044` over base
- `bb8827148f13b17b209495788ac4f7b15573a168`, with zero comments, reviews, or
- review threads. All 13 exact-head required checks passed from their required
- App integration IDs before squash merge. The GitHub-verified merge
- `0534c54c7f00b5e391fd6a85d9fee41aaa6c1d70` has the reviewed head tree
- `9ff900ab33d3485cb4d6aadd0c88fe180e4a708b` and exact protected base as its
- only parent. The feature branch was deleted locally and remotely.
-- TestPyPI run `31478171014` completed successfully for that exact merge and
- published immutable `0.4.7.dev45`. Cache-bypassed PEP 691 reads, freshly
- downloaded registry bytes, and Actions artifact `9096110238` are
- byte-identical: wheel SHA-256
- `e7aa351d30ae6da865e249ec353ebef2c4a2ba6eb2365370df86aa247d0116c9`;
- sdist SHA-256
- `ed05585e4d8c3104641a2309e830fad1738043c2fa1343febe0ceff9e559e251`.
- The Actions archive digest is
- `91018933dff03e8ad97fe5e814ab06776a9d246198bab3c68ae32bc8fa7e5fb2`.
-- Independent PyPI Integrity reads bind both exact subjects to repository
- `xeonvs/open-code-review-toolkit`, workflow `testpypi.yml`, and environment
- `testpypi-public-disclosure`. Registry wheel installs pass on Python 3.12 and
- 3.13; the registry sdist installs on Python 3.14. All three pass `pip check`,
- exact runtime-version import, and restricted-`PATH` CLI smoke from a hostile
- shadow-package working directory.
-- The final release PR is the last repository mutation. It archives the complete
- externally reconciled 0.4.6 cycles under stable-tag anchors, consumes exactly
- fragments 69-73, records authorization metadata for issues 70-73, and lists
- stable registry, provenance, tag, immutable Release, receipt, install, and
- issue-closure checks as pending. Roadmap, strategy, and backlog statuses remain
- unchanged after another code-first reconciliation.
-
-### Release Preparation Review Checkpoint
-
-- The release branch starts from exact feature merge
- `0534c54c7f00b5e391fd6a85d9fee41aaa6c1d70`. Its tracked authorization
- metadata names stable 0.4.7 and the sorted issue set 70-73; stable and next
- version markers are 0.4.7 and 0.4.8, and deterministic epoch `1786440757` is
- exactly one second after the feature merge. Towncrier consumed only fragments
- 69-73, and the generated release notes end with the exact
- `v0.4.6...v0.4.7` comparison.
-- The previously retained 0.4.6 plans moved into the stable-tag archive without
- rewriting their plan text. Explicit anchors resolve from the execution-history
- index, and roadmap, strategy, README, and backlog review found no status or
- narrative change justified by this repository-only release preparation.
-- The release-focused suite passes 137 tests plus 15 subtests. The complete
- isolated Python 3.12 gate passes formatting, Ruff, strict mypy, Bandit with
- zero medium/high findings, 623 tests plus 85 subtests, and 79.09% coverage.
- OCR manifest validation, workflow YAML parsing, changed-shell ShellCheck,
- release-note extraction, metadata/archive checks, and `git diff --check`
- pass. `pip-audit --skip-editable` reports no known dependency vulnerabilities.
-- Two clean source-date-epoch-controlled stable builds are byte-identical and
- pass Twine, canonical archive composition, centralized SCM-version, zero
- runtime dependency, and Python `>=3.12,<3.15` metadata checks. Wheel SHA-256
- is `15c86588987fd441aebf7a43235571e2d14f789aa7a8e1f59cbd24ce113978b2`;
- sdist SHA-256 is
- `5ad2563c9cfc4e6fc9da95d425df44c5e53e62de05ddad462eeda0b41626ac6a`.
- Restricted-`PATH` hostile-shadow installs pass for the wheel on Python 3.12
- and 3.13 and the sdist on Python 3.14, including exact runtime version, CLI,
- and `pip check` readback.
-- Stable TestPyPI/PyPI bytes, Integrity provenance, GitHub attestations, the
- annotated tag, immutable Release and exact asset set, release receipt,
- published-artifact installs, and issue receipt/closure remain external
- post-merge gates. None is represented as complete in this release PR, and no
- later repository closure PR is planned.
diff --git a/ROADMAP.md b/ROADMAP.md
index 8808bcf..2d2ed3d 100644
--- a/ROADMAP.md
+++ b/ROADMAP.md
@@ -40,7 +40,7 @@ flowchart LR
- OCR compatibility and the established common evidence model now converge at compact-bootstrap/evidence-MCP integration.
- M3 threat modeling can proceed from the established generic composition boundary; provider examples wait for BL-011, while managed OAuth does not block static-header or stdio operation.
-- M2 repository implementation is in release validation; conditional future ecosystem packs do not block its closure. M4 can proceed independently from the stable evidence contracts it consumes.
+- M2 implementation, protected feature merge, and TestPyPI development verification are complete; only the final stable-delivery signal remains pending in the release lifecycle. Conditional future ecosystem packs do not block closure, and M4 can proceed independently from the stable evidence contracts it consumes.
- The M5 measurement-gap audit can begin from current lifecycle and result receipts; BL-016 is required only for later named-profile comparisons.
- Versioned documentation remains a separate MCP integration: the toolkit supplies package/version evidence but does not store documentation.
- Additional code-hosting adapters are not ecosystem collectors. They remain conditional because the near-term product is GitLab-first.
diff --git a/changelog.d/76.bugfix.md b/changelog.d/76.bugfix.md
deleted file mode 100644
index ebdc16c..0000000
--- a/changelog.d/76.bugfix.md
+++ /dev/null
@@ -1 +0,0 @@
-Make stable release recovery idempotent across private draft Releases, already-published registry artifacts, and exact issue-receipt comment readback, while binding release notes, assets, and issue evidence to their validated file descriptors.
diff --git a/changelog.d/77.feature.md b/changelog.d/77.feature.md
deleted file mode 100644
index 70516a1..0000000
--- a/changelog.d/77.feature.md
+++ /dev/null
@@ -1 +0,0 @@
-Add a bounded ecosystem-adapter layer plus framework and template evidence plugins for Jinja2, Go web frameworks, Symfony/PHP, and React/TypeScript, including unambiguous root components, applicability-aware Go replacements, include-graph completeness, fail-closed provider isolation, scoped coverage, and first-class redacted delta queries through the built-in evidence MCP.
diff --git a/changelog.d/77.rules.md b/changelog.d/77.rules.md
deleted file mode 100644
index 2b2314a..0000000
--- a/changelog.d/77.rules.md
+++ /dev/null
@@ -1 +0,0 @@
-Make Jinja and Twig templates reviewable through explicit additive includes and template-specific rules in the synthetic GitLab rules pack.
diff --git a/changelog.d/78.feature.md b/changelog.d/78.feature.md
deleted file mode 100644
index 362f26f..0000000
--- a/changelog.d/78.feature.md
+++ /dev/null
@@ -1 +0,0 @@
-Target checksum-verified Open Code Review 1.9.2 after adjacent compatibility qualification.
diff --git a/docs/engineering/execution_history/README.md b/docs/engineering/execution_history/README.md
index ff6bb09..9fa1099 100644
--- a/docs/engineering/execution_history/README.md
+++ b/docs/engineering/execution_history/README.md
@@ -6,6 +6,7 @@
| Stable tag | Primary archived plan | Related context in the same archive |
| --- | --- | --- |
+| `v0.4.7` | [GitLab review delivery and OCR 1.9.0-1.9.1 qualification](releases.md#plan-toolkit-0-4-7) | Exact-range suggestions, add-only SHA-bound approval, and the release lifecycle used by later stable delivery. |
| `v0.4.6` | [OCR 1.8.9-1.8.10 qualification and toolkit 0.4.6](releases.md#plan-toolkit-0-4-6) | The subsequent [0.4.6 lifecycle and backlog reconciliation](releases.md#plan-toolkit-0-4-6-reconciliation) records the process correction carried into later releases. |
| `v0.4.5` | [OCR 1.8.7-1.8.8 qualification and toolkit 0.4.5](releases.md#plan-toolkit-0-4-5) | Compatibility-chain automation and the toolchain update included in that release. |
| `v0.4.4` | [Evidence coverage and GitLab review health](releases.md#plan-toolkit-0-4-4) | Scoped completeness, failed-file coverage, and summary separation. |
diff --git a/docs/engineering/execution_history/releases.md b/docs/engineering/execution_history/releases.md
index a4f0ce4..e4e19c0 100644
--- a/docs/engineering/execution_history/releases.md
+++ b/docs/engineering/execution_history/releases.md
@@ -2,6 +2,428 @@
This archive preserves completed execution plans moved out of the active registry; the release index associates each plan with the stable tag or release cycle it supported. `PLANS.md` remains the source for active, blocked, and recently completed work; historical receipts here remain part of the audit trail.
+
+
+## Recently Completed Plan: Harden GitLab suggestions and add SHA-bound approval for 0.4.7
+
+Status: completed; stable 0.4.7 externally delivered and independently read back
+Owner: Codex
+Last Updated: 2026-08-11
+Release Classification: release-required
+Target Stable Version: 0.4.7
+Tracking Issues: #70, #71, #72 (OCR 1.9.1), #73 (OCR 1.9.0)
+
+### Goal
+
+Ship issues #70 and #71 as toolkit 0.4.7: publish actionable GitLab
+suggestions only when they are proven to replace one contiguous range in the
+reviewed immutable head, and add conservative default-on automatic approval
+that is bound to the exact reviewed merge-request SHA. Preserve a successfully
+published advisory review when approval management is ineligible, stale, or
+fails, and complete the release only after immutable external evidence has been
+independently read back.
+
+### Decisions
+
+- Use one feature branch and one protected feature pull request, with separate
+ signed implementation checkpoints for #70, #71, and release-lifecycle
+ hardening. Keep both issues open until stable external delivery is verified.
+- Keep provider-neutral decisions in typed core objects and GitLab HTTP/state
+ transitions behind the provider adapter. Add no runtime dependency, public
+ evidence command, permanent OCR harness, telemetry expansion, or tunable
+ approval-policy variables.
+- Make `OCR_AUTO_APPROVE` default on with the established boolean vocabulary.
+ An invalid value disables approval for that run. Encode the initial policy in
+ code and fail closed when authoritative completeness or typed finding
+ metadata cannot be proven. Keep the transaction add-only: GitLab cannot bind
+ unapproval to the reviewed SHA at mutation time, so ineligible or disabled
+ later reviews preserve every existing approval.
+- After the release-lifecycle checkpoint, qualify the contiguous Open Code
+ Review 1.9.0 and 1.9.1 chain from authoritative release/source evidence.
+ Preserve a separate checksum/contract record and human impact conclusion for
+ each release, with a separate qualification issue for each version. Classify
+ every upstream item as a toolkit-consumed contract change, future-backlog
+ impact, or explicit no impact; adapt only demonstrated contracts and
+ atomically replace the local checksum-pinned OCR binary with 1.9.1 before
+ full E2E.
+- After the complete feature implementation is committed, run exactly one real
+ local OCR 1.9.1 review through `uv run ocr-ci review` over
+ `origin/main..HEAD`. Require the built-in `ocr_toolkit_evidence` MCP receipt,
+ do not post to GitLab, fix actionable findings, and then use deterministic
+ validation and self-review rather than a second OCR run.
+- Do not run Codex Security. Existing repository CI security checks and the
+ checksum-pinned local Gitleaks gate remain required.
+- Redesign the durable release lifecycle so the release PR is the final
+ repository mutation without preclaiming external facts. Bind publication to
+ the exact reviewed tree and emit an immutable machine-readable release
+ receipt; close #70/#71 and both OCR qualification issues only after
+ independent registry, provenance, tag, Release, receipt, hash, and
+ supported-Python readback succeeds.
+
+### Work Queue
+
+1. [x] Implement typed contiguous-range suggestion validation, immutable-head
+ proof, bounded omission reasons, documentation, complete regressions, review,
+ and the #70 checkpoint commit.
+2. [x] Implement typed auto-approval configuration and policy, exact-SHA GitLab
+ synchronization/write/readback, add-only provider semantics, documentation,
+ complete regressions, review, and the #71 checkpoint commit. The original
+ managed-unapproval design was removed after final OCR found that GitLab
+ cannot provide the required mutation-time immutable guard.
+3. [x] Replace the redundant post-release closure-PR contract with exact-tree
+ release authorization and deterministic `ocr-toolkit.release-receipt/v1`
+ evidence; update durable rules, recovery behavior, tests, and the lifecycle
+ checkpoint commit.
+4. [x] Inspect authoritative OCR 1.9.0 and 1.9.1 release notes and source
+ changes, record separate consumed-contract/backlog/no-impact
+ classifications and qualification issues, update compatibility records and
+ the local checksum-pinned OCR 1.9.1 binary, and adapt the toolkit only where
+ evidence requires it.
+5. [x] Reconcile this plan, roadmap table/diagram, backlog, and current-state
+ documentation against the implemented code. Run focused tests, the synthetic
+ GitLab E2E, Python 3.12 quality, Towncrier draft, workflow/document/privacy
+ checks, and `git diff --check`.
+6. [x] Commit the complete feature tip and run one local toolkit-owned OCR review
+ with private result/stderr artifacts, no GitLab posting, and verified nonzero
+ built-in MCP use. Correct its findings, complete deterministic validation and
+ final self-review, and do not run a second OCR or Codex Security review.
+7. [x] Run deterministic post-review validation and pinned local Gitleaks over
+ the unpublished history, push the exact reviewed branch, open one feature PR,
+ resolve every conversation, pass protected checks, and squash-merge.
+8. [x] Independently verify the exact TestPyPI development artifacts, hashes,
+ provenance, and supported-Python installs before preparing `release/v0.4.7`.
+9. [ ] Prepare and validate the final release PR, consuming fragments 69, 70,
+ 71, 72, and 73 and reconciling repository-side planning truth without
+ claiming publication that has not happened.
+10. [ ] Merge the release PR only after exact-head protected checks. Verify stable
+ TestPyPI/PyPI artifacts, provenance/attestations, annotated tag, immutable
+ GitHub Release and release receipt, hashes, and Python 3.12-3.14 installs.
+ Record receipts and close #70/#71 plus both OCR qualification issues without
+ another repository PR.
+
+### Initial Evidence
+
+- Clean synchronized `main` is `bb8827148f13b17b209495788ac4f7b15573a168`;
+ stable toolkit 0.4.6 is published and `.next-version` targets 0.4.7.
+- Issues #70 and #71 are open. Current suggestion handling proves exact no-op
+ equality but does not prove changed `suggestion_code` applies to
+ `existing_code` at the reviewed range; the toolkit has no approval-management
+ transaction yet.
+- The effective local binary is Open Code Review 1.8.10 and the checkout's
+ `uv run ocr-ci review` path owns evidence collection, compact bootstrap,
+ mandatory `ocr_toolkit_evidence` composition, use verification, and the
+ private receipt.
+- Current release guidance still requires a documentation-only closure PR and
+ release authorization does not bind publication to the reviewed head tree and
+ exact checks. Both are explicit scope of the lifecycle checkpoint.
+
+### Issue #70 Checkpoint
+
+- GitLab suggestion applicability is now a closed typed decision rather than a
+ hidden mutation on the untrusted OCR comment. The renderer accepts only an
+ already-proven replacement; impossible state/field combinations fail at the
+ typed boundary.
+- Validation binds a safe repository-relative path and inclusive range to one
+ bounded immutable head blob, normalizes CRLF/CR and one terminal newline, and
+ requires exact `existing_code` agreement before a changed replacement becomes
+ actionable. Existing exact no-op suppression remains available even for the
+ older no-`existing_code` result shape.
+- Synthetic omission bridges across common comment syntaxes, diff-prefixed
+ replacements, quick actions, unsafe fences, oversized values, stale source,
+ and invalid ranges retain the finding but produce only a closed non-sensitive
+ omission reason. Fallback notes never render an actionable suggestion fence.
+- Focused Ruff and strict mypy pass. The complete posting/suggestion regression
+ set passes 123 tests, including valid one-line and multiline replacements,
+ newline equivalence, missing/stale source, invalid/out-of-bounds ranges,
+ omission variants, diff prefixes, no-op behavior, typed invariants, unsafe
+ paths, and workflow-level proof that only the apply fence is withheld.
+ Towncrier 0.4.7 draft and `git diff --check` pass.
+
+### Issue #71 Checkpoint
+
+- `OCR_AUTO_APPROVE` is a typed default-on setting using the shared
+ true/false, 1/0, yes/no, and on/off vocabulary. Invalid values fail closed to
+ disabled without logging their contents. The fixed policy consumes the full
+ unsuppressed OCR finding set and requires a complete manifest, zero warnings,
+ failures, waivers, budget stop, or omitted findings, no more than three exact
+ `low` findings, and only style/documentation/maintainability categories.
+- Approval is a distinct post-publication transaction. The GitLab adapter reads
+ bounded MR and full paginated diff-version state, selects the highest valid
+ version ID, waits at most ten two-second intervals for merge/approval
+ synchronization and a non-null patch ID, verifies the open current head, and
+ submits only the reviewed 40-hex SHA. Approve and summary-update writes are
+ attempted once and followed by bounded readback.
+- Approval is add-only. An already approved toolkit user is reported as skipped
+ without a provider write; ineligible, partial, skipped, legacy, disabled, and
+ ambiguous runs also make no approval write. The adapter exposes no unapprove
+ operation or managed-approval receipt because GitLab cannot bind unapproval to
+ the immutable reviewed SHA at mutation time. Project-owned reset and
+ invalidation rules remain authoritative.
+- The published summary contains one bounded approval state. Eligible runs first
+ publish a conservative failed-until-confirmed state, then update the uniquely
+ marked owned summary once after provider readback. Failure never rolls back the
+ advisory review; strict mode returns nonzero while advisory mode remains
+ nonfatal. Existing GitLab rules, groups, Code Owners, protected branches, and
+ reauthentication stay authoritative.
+- Self-review fixed version-order assumptions, different-SHA approval claims,
+ and provisional-summary truth. The final OCR correction subsequently removed
+ the unsafe managed-unapproval design and its receipt surface entirely. Ruff
+ and strict mypy pass; 148 posting/approval/suggestion tests and 15 public
+ documentation/integration contracts pass. Towncrier 0.4.7 draft includes the
+ default-on write and opt-out, and `git diff --check` passes. Roadmap and future
+ backlog statuses remain unchanged because neither issue completes an existing
+ outcome milestone or activation trigger.
+
+### Release Lifecycle Checkpoint
+
+- The merged release PR is now the final repository mutation without claiming
+ future delivery. Authorization executes from the protected reviewed base that
+ predates the release candidate, treats candidate head and merge commits as
+ bounded data, validates tracked metadata from the exact merge ref, proves
+ squash-tree equivalence and parent identity, and requires every live strict
+ `main` check context from its exact GitHub App on the reviewed head SHA.
+- Registry verification covers Python 3.12-3.14 and exact PyPI Integrity
+ publisher/subject provenance. GitHub artifact attestations, annotated-tag
+ target, exact Release metadata/assets, immutable status, and a deterministic
+ `ocr-toolkit.release-receipt/v1` are verified before tracked issues close.
+- Recovery is non-destructive and exact: existing registry and draft Release
+ bytes must match, an existing receipt remains canonical across workflow
+ reruns, asset reads work through bounded authenticated API calls, and no path
+ replaces an existing tag, receipt, or Release asset.
+- Issue closure is bounded and idempotent. Every tracked item is preflighted
+ before publication; only an exact GitHub Actions-owned receipt marker is
+ trusted, conflicting user markers fail closed, and an already-completed issue
+ is accepted after final readback. Durable agent guidance, principles,
+ pitfalls, release documentation, and execution-history rules now agree that
+ no redundant post-release repository PR is required.
+- Self-review corrected timestamp semantics, arbitrary receipt artifact names,
+ incomplete check-run binding, unbounded API/asset/comment reads, draft asset
+ download behavior, destructive `--clobber` recovery, receipt regeneration on
+ reruns, metadata checkout drift, standalone provenance imports, and ambiguous
+ Release/issue state. The focused suite passes 53 tests; strict mypy, Ruff,
+ ShellCheck, workflow YAML parsing, OCR manifest validation, Towncrier 0.4.7
+ draft, and `git diff --check` pass. Full `scripts/quality.sh check` passes 608
+ tests plus 81 subtests at 79.62% coverage. Roadmap and backlog statuses remain
+ unchanged at this checkpoint because the lifecycle hardening changes process,
+ not an outcome milestone or future-work activation trigger.
+
+### Final OCR Review And Correction Checkpoint
+
+- The only final local OCR review covered
+ `bb8827148f13b17b209495788ac4f7b15573a168..fe88f8d78744847bc58b35129de5c9130cd46853`
+ with official OCR 1.9.1. It completed all 23 selected items in 39 minutes 5
+ seconds with zero failed or waived items, returned 16 findings, and made 68
+ mandatory `ocr_toolkit_evidence` calls. The private toolkit receipt records
+ the same 68 calls; result/stderr and `.review-context` artifacts retain owner-
+ only permissions, `.review-context` is absent from the reviewed diff, and no
+ GitLab posting command ran.
+- Thirteen findings exposed valid boundary defects or the same root-cause
+ classes. Release authorization now executes from the protected pre-candidate
+ base. The GitHub API helper has a closed endpoint grammar, redirect-safe
+ bearer authentication, private same-directory temporary output, allowed-
+ status validation, and atomic replacement. Minor/major OCR promotion requires
+ chain-aware schema 2. Stable receipts reject unknown top-level and nested
+ fields; malformed registry provenance URLs fail closed; unhashable finding
+ categories degrade to not eligible; complete unified-diff replacements are
+ rejected; and unused approval-receipt parsing was removed.
+- The two unapproval findings and the approval-without-durable-receipt finding
+ shared one architectural cause: GitLab's unapprove endpoint cannot receive the
+ reviewed SHA, so preflight and readback cannot close its destructive TOCTOU
+ gap. Automatic approval is therefore add-only. All unapproval and managed-
+ receipt runtime paths were removed instead of adding another compensating
+ state machine.
+- Three suggestions were rejected after source and regression review. Python's
+ `binascii.Error` is already a `ValueError`, so existing malformed-base64
+ handling covers both flagged decode sites. A user-authored exact issue-receipt
+ marker intentionally blocks closure as the documented anti-preemption,
+ fail-closed contract; it is not trusted as a successful receipt.
+- Root-cause sibling audits covered URL parsers, release/security receipt
+ loaders, bounded HTTP helpers, and destructive provider writes. Public
+ approval/release/security documentation and `AGENTS.md`, project principles,
+ and execution pitfalls now encode the corrected boundaries. A direct
+ regression proves that schema-1 evidence cannot cross minor or major OCR
+ boundaries. No second OCR review or Codex Security run will be performed.
+- The final post-correction gate runs from isolated Python 3.12.13 and passes
+ formatting, Ruff, strict mypy, Bandit with zero medium/high findings, 623
+ tests plus 85 subtests, and 79.09% coverage. OCR manifest validation,
+ Towncrier 0.4.7 draft, changed-shell ShellCheck, workflow YAML parsing,
+ changed-public-content privacy checks across 31 files, and `git diff --check`
+ pass. Fresh `0.4.7.dev7` wheel and sdist pass Twine, canonical composition,
+ centralized SCM-version, zero-runtime-dependency, and Python `>=3.12,<3.15`
+ metadata checks. Separate Python 3.12 installs pass `pip check` and execute
+ the installed CLI/import under restricted `PATH` from a hostile shadow-package
+ working directory. Wheel SHA-256 is
+ `0582f8b1ed7623cec55aaeef289bde7d9ccda9c1b9b856d30eacb95e57508ac6`;
+ sdist SHA-256 is
+ `4bdcfc1a302e1f7392623b2c651bf8d747e8228891b74f14257479e8ab93dee6`.
+- Final manual self-review removed the obsolete `ApprovalResult.managed` flag,
+ confirmed every workflow-used GitHub endpoint is represented by the closed
+ helper grammar, verified recovery binds the protected reviewed base, and
+ found no roadmap, backlog, or narrative status tail. Exactly one worktree is
+ present and all review/quality artifacts remain ignored and private.
+
+### OCR 1.9.0-1.9.1 Qualification Checkpoint
+
+- Canonical GitHub Actions run `31465539451` created separate open
+ qualification issues #73 for 1.9.0 and #72 for 1.9.1. Local Python 3.12
+ qualification independently downloaded all seven assets for each release,
+ proved GitHub digests equal the upstream `sha256sum.txt`, executed the Linux
+ amd64 version/help/JSON-preview/full-review/result/posting contracts, and
+ reproduced both evidence files byte-for-byte from checkpoint `5acbf15`.
+- OCR 1.9.0 is compatible after required human review. Toolkit-consumed changes
+ are JSON preview output, preview session-store isolation, additive private
+ comment `thinking`, merge-base range semantics, and the Nim rules/allowlist
+ expansion. The harness now proves JSON preview, no session-store creation,
+ additive `thinking` preservation, and non-publication of that private field;
+ source review confirms reasoning-content backfill and the documented range
+ semantics. The Nim change receives a separate `🧩 Rules` entry.
+- OCR 1.9.0 per-file token limits and retry status codes are future profile or
+ configuration inputs only and do not activate BL-016. Mistral and MiniMax
+ providers, QCA delegation, the upstream GitLab example, Pages/viewer/CSP,
+ scan and installation documentation, fork deployment, blog, package-manager,
+ and other documentation fixes are not toolkit-owned contracts. They require
+ no runtime, roadmap, or backlog activation.
+- OCR 1.9.1 is an adjacent automatic-safe patch whose source was still reviewed.
+ Viewer comment filters and suggestion-panel layout, CodeQL workflow
+ permissions, upstream contributor/retry documentation, and the Anthropic
+ dynamic cache breakpoint do not change toolkit CLI, result, posting,
+ configuration, or MCP contracts. The cache change is a future profile/quality
+ input only and does not complete BL-016 or BL-017.
+- Both releases retain Go MCP SDK v1.6.1 and protocol revision `2025-11-25`, so
+ the built-in MCP protocol matrix is unchanged. Both annotated upstream tags
+ carry signatures that GitHub reports as `unknown_key`; compatibility does not
+ misrepresent them as verified and instead relies on the double-source asset
+ digest contract plus executed binary probes.
+- Human-reviewed promotion now accepts only an adjacent patch, next minor `.0`,
+ or next major `.0.0`; every minor/major transition requires an explicit
+ bounded conclusion. The automatic lane remains patch-only. Self-review also
+ isolated Git initialization, preview, and full-review probes from operator
+ OCR/Git configuration and bounded optional automatic-safe conclusions.
+- Manifest, preflight, public examples, documentation, tests, and Linux digest
+ now target OCR 1.9.1. The PATH-effective Darwin arm64 binary is official OCR
+ 1.9.1 with SHA-256
+ `5cffe45ef006b80dcbe95e6711807261850108d6390ce708cdac0e72cb261d1d`;
+ its isolated local contract probe passes. Focused validation passes 265 tests
+ plus 27 subtests, Ruff, strict mypy, manifest validation, Towncrier 0.4.7
+ draft, and `git diff --check`.
+- Backlog statuses, roadmap table/diagram, and strategy status remain unchanged.
+ Nim is review-engine scope rather than an evidence pack; upstream `AGENTS.md`
+ is contributor guidance rather than target-ref runtime guidance; token/cache
+ changes do not supply the missing profile or telemetry policy contracts.
+- The complete isolated Python 3.12.13 quality gate passes formatting, Ruff,
+ strict mypy, Bandit, 622 tests plus 81 subtests, and 79.61% coverage. A fresh
+ authenticated discovery after promotion reports zero unseen stable OCR
+ releases. The gate uses `.quality-logs/py312` and does not mutate the host
+ `.venv` or tracked checkout.
+
+### Feature-tip Validation And E2E Checkpoint
+
+- The signed `4f3dd29` tree builds on Python 3.12.13 as
+ `0.4.7.dev6+g4f3dd2994`. Twine accepts both distributions; the wheel SHA-256
+ is `295c0e9fa52492aa9e99c7dd11ae0b3a2b2c6339f3e4991ea3009e29812ed358`
+ and the sdist SHA-256 is
+ `c679d9490f8cb1fb58f37bac4eba24dcad52fb745814121523c2841a15096c55`.
+ Metadata derives the version from SCM, requires Python 3.12 through 3.14,
+ declares no runtime dependencies, and both archives contain only their
+ intended package/source surfaces.
+- Separate clean Python 3.12 wheel and hash-locked sdist installs pass
+ `pip check`, import the same centralized version, and run the installed
+ `ocr-ci --help` entry point under a restricted `PATH` from a repository that
+ contains a hostile local `ocr_toolkit` shadow package. The installed artifact,
+ rather than checkout code or the untrusted current directory, owns execution.
+- One ignored, one-off synthetic repository E2E uses the installed wheel and the
+ official local OCR 1.9.1 binary without adding a permanent harness. A local
+ deterministic gateway forces OCR to query `ocr_toolkit_evidence` before it
+ emits one synthetic finding. OCR finishes with `status=complete` and one
+ built-in evidence call; `_ocr_toolkit.mcp_usage` records the same count. The
+ exact base/head snapshots match the reviewed commits, `.review-context` is
+ absent from Git status and the reviewed diff, its directory is `0700`, all
+ store/bootstrap/result/stderr artifacts are `0600`, and no GitLab posting
+ command is invoked.
+- The complete posting/suggestion/approval/release/compatibility changed-surface
+ suite passes 347 tests plus 73 subtests. The full gate executed directly from
+ Python 3.12.13 passes 622 tests plus 81 subtests at 79.61% coverage; formatting,
+ Ruff, strict mypy, Bandit, changed-shell ShellCheck, workflow YAML parsing,
+ OCR manifest validation, Towncrier 0.4.7 draft, changed-public-content privacy,
+ and `git diff --check` pass.
+- Read-only validation against current public service payloads confirms that
+ PyPI Integrity v1 uses the publisher and in-toto subject shape enforced by the
+ release verifier, GitHub exposes strict effective `main` checks with exact App
+ integration IDs, and immutable Release state is available through the pinned
+ API version. No registry, Release, issue, or GitLab state was changed.
+- Final reconciliation found no roadmap table/diagram, strategy, or backlog
+ status transition: #70/#71 are release-scoped behavior rather than an outcome
+ milestone, while OCR 1.9.0/1.9.1 inputs leave BL-008/009/010/015/016/017 at
+ their documented triggers. Self-review corrected the release queue to consume
+ all five fragments 69-73; every tracked issue remains open until stable 0.4.7
+ delivery is proven by the immutable receipt and independent readback.
+
+### Feature Merge And Development Publication
+
+- Feature PR #74 was read back as exact head
+ `2f63d250cb47ab3c7bcc174514949f7bb2d6e044` over base
+ `bb8827148f13b17b209495788ac4f7b15573a168`, with zero comments, reviews, or
+ review threads. All 13 exact-head required checks passed from their required
+ App integration IDs before squash merge. The GitHub-verified merge
+ `0534c54c7f00b5e391fd6a85d9fee41aaa6c1d70` has the reviewed head tree
+ `9ff900ab33d3485cb4d6aadd0c88fe180e4a708b` and exact protected base as its
+ only parent. The feature branch was deleted locally and remotely.
+- TestPyPI run `31478171014` completed successfully for that exact merge and
+ published immutable `0.4.7.dev45`. Cache-bypassed PEP 691 reads, freshly
+ downloaded registry bytes, and Actions artifact `9096110238` are
+ byte-identical: wheel SHA-256
+ `e7aa351d30ae6da865e249ec353ebef2c4a2ba6eb2365370df86aa247d0116c9`;
+ sdist SHA-256
+ `ed05585e4d8c3104641a2309e830fad1738043c2fa1343febe0ceff9e559e251`.
+ The Actions archive digest is
+ `91018933dff03e8ad97fe5e814ab06776a9d246198bab3c68ae32bc8fa7e5fb2`.
+- Independent PyPI Integrity reads bind both exact subjects to repository
+ `xeonvs/open-code-review-toolkit`, workflow `testpypi.yml`, and environment
+ `testpypi-public-disclosure`. Registry wheel installs pass on Python 3.12 and
+ 3.13; the registry sdist installs on Python 3.14. All three pass `pip check`,
+ exact runtime-version import, and restricted-`PATH` CLI smoke from a hostile
+ shadow-package working directory.
+- The final release PR is the last repository mutation. It archives the complete
+ externally reconciled 0.4.6 cycles under stable-tag anchors, consumes exactly
+ fragments 69-73, records authorization metadata for issues 70-73, and lists
+ stable registry, provenance, tag, immutable Release, receipt, install, and
+ issue-closure checks as pending. Roadmap, strategy, and backlog statuses remain
+ unchanged after another code-first reconciliation.
+
+### Release Preparation Review Checkpoint
+
+- The release branch starts from exact feature merge
+ `0534c54c7f00b5e391fd6a85d9fee41aaa6c1d70`. Its tracked authorization
+ metadata names stable 0.4.7 and the sorted issue set 70-73; stable and next
+ version markers are 0.4.7 and 0.4.8, and deterministic epoch `1786440757` is
+ exactly one second after the feature merge. Towncrier consumed only fragments
+ 69-73, and the generated release notes end with the exact
+ `v0.4.6...v0.4.7` comparison.
+- The previously retained 0.4.6 plans moved into the stable-tag archive without
+ rewriting their plan text. Explicit anchors resolve from the execution-history
+ index, and roadmap, strategy, README, and backlog review found no status or
+ narrative change justified by this repository-only release preparation.
+- The release-focused suite passes 137 tests plus 15 subtests. The complete
+ isolated Python 3.12 gate passes formatting, Ruff, strict mypy, Bandit with
+ zero medium/high findings, 623 tests plus 85 subtests, and 79.09% coverage.
+ OCR manifest validation, workflow YAML parsing, changed-shell ShellCheck,
+ release-note extraction, metadata/archive checks, and `git diff --check`
+ pass. `pip-audit --skip-editable` reports no known dependency vulnerabilities.
+- Two clean source-date-epoch-controlled stable builds are byte-identical and
+ pass Twine, canonical archive composition, centralized SCM-version, zero
+ runtime dependency, and Python `>=3.12,<3.15` metadata checks. Wheel SHA-256
+ is `15c86588987fd441aebf7a43235571e2d14f789aa7a8e1f59cbd24ce113978b2`;
+ sdist SHA-256 is
+ `5ad2563c9cfc4e6fc9da95d425df44c5e53e62de05ddad462eeda0b41626ac6a`.
+ Restricted-`PATH` hostile-shadow installs pass for the wheel on Python 3.12
+ and 3.13 and the sdist on Python 3.14, including exact runtime version, CLI,
+ and `pip check` readback.
+- Stable TestPyPI/PyPI bytes, Integrity provenance, GitHub attestations, the
+ annotated tag, immutable Release and exact asset set, release receipt,
+ published-artifact installs, and issue receipt/closure remain external
+ post-merge gates. None is represented as complete in this release PR, and no
+ later repository closure PR is planned.
+
## Completed Plan: Reconcile 0.4.6 lifecycle, architecture, and backlog truth
diff --git a/scripts/quality.sh b/scripts/quality.sh
index 427cf18..a6ce9f9 100755
--- a/scripts/quality.sh
+++ b/scripts/quality.sh
@@ -6,7 +6,7 @@ log_dir=${OCR_TOOLKIT_LOG_DIR:-.quality-logs}
mkdir -p "$log_dir"
log_file="$log_dir/${mode}.log"
quality_environment=${OCR_TOOLKIT_QUALITY_ENVIRONMENT:-$log_dir/venv}
-export UV_PROJECT_ENVIRONMENT=$quality_environment
+export UV_PROJECT_ENVIRONMENT="$quality_environment"
# An interrupted editable install can leave dist-info without RECORD. uv then
# warns while trying an uninstall that cannot be complete. This environment is
diff --git a/tests/test_quality_script.py b/tests/test_quality_script.py
index b6fe0ce..cf729fe 100644
--- a/tests/test_quality_script.py
+++ b/tests/test_quality_script.py
@@ -13,7 +13,7 @@ def test_quality_script_uses_an_isolated_ignored_environment() -> None:
script = SCRIPT.read_text(encoding="utf-8")
assert "OCR_TOOLKIT_QUALITY_ENVIRONMENT:-$log_dir/venv" in script
- assert "export UV_PROJECT_ENVIRONMENT=$quality_environment" in script
+ assert 'export UV_PROJECT_ENVIRONMENT="$quality_environment"' in script
assert "open_code_review_toolkit-*.dist-info" in script
assert '[ ! -f "$metadata/RECORD" ]' in script
assert 'uv venv --clear "$quality_environment"' in script