Repository navigation
Validate reopened optiflow receipts against the complete evidence contract #81
Description
Outcome
Make ReadOnlyReceipt::load enforce the complete versioned optiflow read-only receipt contract and refuse completed status without the required artifact evidence.
Audit evidence
Current audit, finding AUDIT-001, inspected flow af68afa5732a04c237df5fbeee6bc5e901a5c6fd.
The published schemas/optiflow-read-only-receipt-v1.schema.json and runtime loader disagree. An executed synthetic probe loaded a complete receipt containing scan/report/plan command names but empty artifact lists and null plan_sha256; it reported needs_recovery=false. Independent Draft 2020-12 validation rejected that receipt. Wrong environment text, an extra capability, an omitted required nullable key, and an unknown native-path property were also accepted at runtime despite schema rejection. A separately emitted receipt from the exact downloaded v0.1.1 Linux provider validates and reopens successfully.
These are editable local audit records, not signatures or authority grants. Keep that distinction.
Scope
- Reconcile typed runtime validation with the existing closed receipt schema.
- Require complete/partial records to retain the actual expected plan and command artifact proof; absence on both sides of an optional comparison must not count as matching proof.
- Reuse one bounded validation path for emitted and reopened evidence where appropriate.
- Add provider-independent synthetic schema/runtime parity fixtures to ordinary CI. The native receipt currently sits outside the 25-contract manifest; give it an explicit validation owner rather than silently assuming the existing validator covers it.
Acceptance criteria
- The valid emitted v0.1.1 receipt and valid scanning/reporting/planning/refused receipts retain their documented reopen/recovery behavior.
- Complete/partial receipts require present correlated plan identity and the required verified artifacts for each command; empty artifact proof and absent plan digest refuse.
- Required nullable keys, closed nested paths/capability keys, constants, enums, bounded shapes and digest forms agree with the versioned schema, with no silent field dropping.
- The five executed counterexamples above fail at the runtime boundary and against the schema; positive controls pass both.
- Changed artifact bytes, source/state path constraints and unsupported mutation/approval states remain refused under existing contracts.
- Focused tests and applicable existing Rust, contract and documentation checks pass; retained evidence distinguishes synthetic cases from native provider execution.
Dependencies and boundary
No open implementation prerequisite. The read-only adapter is already merged in #50. Coordinate with #34's later installed-provider qualification without making this local correctness repair wait for every provider release. Do not add source mutation, signature claims, automatic recovery, a new provider protocol, or unrelated refactoring.
Roadmap: #11
October 21, 2026 — completed in PR #84
Merged PR #84, implementation a6313bc542b121373a7f91e015fe7fe808e596b3, merge aadf053d48ce8826ee5b9ca4a134985f4e7910e3. All six acceptance criteria above are covered by the handoff and local validation receipt. The 84-case corpus passes; the unchanged baseline wrongly accepted 45 cases, including all five audit counterexamples and all nine omitted nullable keys. Focused Linux/Rust 1.85.0 checks and actual pinned v0.1.1 compatibility pass. Broader suite/moving-stable qualification remains #34; current-documentation reconciliation is next in #82. No release, mutation authority or full hosted-green claim is made.
Activity