|
| 1 | += Ochránce — Proof Campaign Ledger |
| 2 | +:toc: macro |
| 3 | +:sectnums: |
| 4 | + |
| 5 | +// SPDX-License-Identifier: MPL-2.0 |
| 6 | +// SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell (hyperpolymath) |
| 7 | + |
| 8 | +This is the authoritative, dependency-sorted plan for driving the formal |
| 9 | +verification of the Ochránce estate to completion. It is the durable source of |
| 10 | +truth for the proof thread: it survives context compaction, so each working |
| 11 | +window starts from this file rather than from chat memory. |
| 12 | + |
| 13 | +toc::[] |
| 14 | + |
| 15 | +== Scope & estate map |
| 16 | + |
| 17 | +Three repositories are in scope. "Verification" means something different in each. |
| 18 | + |
| 19 | +[cols="1,2,2",options="header"] |
| 20 | +|=== |
| 21 | +| Repo | What "verified" means | This thread executes? |
| 22 | + |
| 23 | +| `ochrance` |
| 24 | +| Idris2 dependent-type proofs (the canonical core). |
| 25 | +| *Yes — primary focus.* |
| 26 | + |
| 27 | +| `ochrance-framework` |
| 28 | +| Architecture + docs. Its `ochrance-core` is a weaker, type-incompatible |
| 29 | + duplicate and is being *retired* (see Decision D1). |
| 30 | +| Docs/Interface harvest only — core is deleted, not proven. |
| 31 | + |
| 32 | +| `svalinn` |
| 33 | +| ReScript edge gateway → migrating to AffineScript + Ephapax. Type-safety and |
| 34 | + schema/property tests, not dependent types. |
| 35 | +| *No — disposed* to a delegated session (see Disposed Tracks). Specs tracked here. |
| 36 | +|=== |
| 37 | + |
| 38 | +== Decisions on record |
| 39 | + |
| 40 | +[cols="1,3",options="header"] |
| 41 | +|=== |
| 42 | +| ID | Decision |
| 43 | + |
| 44 | +| *D1 — Converge on ochrance* |
| 45 | +| `ochrance/ochrance-core` is the single source of proof truth. |
| 46 | + `ochrance-framework/ochrance-core` is retired. Its one genuinely better idea — |
| 47 | + the *mode-indexed, subsystem-parameterised* `VerifiedSubsystem` Interface |
| 48 | + (`VerificationProof mode SubState SubManifest`) — is harvested into ochrance. |
| 49 | + Framework keeps its real value: the docs (A2ML-SPEC, FFI-CONTRACT, THREAT-MODEL, |
| 50 | + WHITEPAPER, ROADMAP, L4-POLICIES) and architecture. |
| 51 | + |
| 52 | +| *D2 — Crypto binding as a typed interface* |
| 53 | +| The security half of the Merkle argument (collision resistance) is modelled as |
| 54 | + an Idris hypothesis `CollisionResistant h`, and the binding theorem is |
| 55 | + discharged against it — not left as prose. Stubbed in Stage 1, discharged in the |
| 56 | + final stage. |
| 57 | + |
| 58 | +| *D3 — svalinn: migrate before proving* |
| 59 | +| Prove where the language is final; migrate-then-prove where it is changing. |
| 60 | + svalinn migrates ReScript → *AffineScript* (gateway bulk; affine boundary |
| 61 | + decoders eliminate `Obj.magic`) + *Ephapax* linear tokens (surgical: JWT/JTI |
| 62 | + single-use & revocation, OAuth nonce/PKCE, session/container lifecycle). Its |
| 63 | + *specifications* are captured now (Disposed Tracks); its *proofs* come after |
| 64 | + migration. Proving the about-to-be-deleted ReScript is waste. |
| 65 | +|=== |
| 66 | + |
| 67 | +== Current proof state (ochrance, canonical) |
| 68 | + |
| 69 | +The core is *clean*: all 24 modules carry `%default total`; zero |
| 70 | +`believe_me` / `assert_*` / `postulate` / holes / `partial` on any proof symbol. |
| 71 | + |
| 72 | +.Proven, machine-checked (axiom-free) |
| 73 | +[cols="2,3",options="header"] |
| 74 | +|=== |
| 75 | +| Theorem | Statement (shape) |
| 76 | + |
| 77 | +| `merkleCorrect` / `merkleCorrectWith` |
| 78 | +| inclusion-proof soundness; generic over the hash combiner `h` (XOR & BLAKE3 are |
| 79 | + instances). `reconstructWith h leaf prf = rootHashWith h t`. |
| 80 | +| `verifyProofReconstructs(With)` |
| 81 | +| `verifyProofWith h root leaf prf = (root == reconstructWith h leaf prf)`. |
| 82 | +| `reconstructAppendWith`, `powerTwoSucc`, `justInj` |
| 83 | +| supporting lemmas. |
| 84 | +| `roundtripManifest` + sub-codecs (`algoRT`, `modeRT`, `refsRT`, `mpolRT`, …) |
| 85 | +| grammar invertibility: `decodeManifest (encodeManifest m) = Just m`. |
| 86 | +| `SatisfiesMinimum` / `attestedSatisfiesLax` |
| 87 | +| progressive-assurance threshold witness. |
| 88 | +| ABI `Handle` / `createHandle` |
| 89 | +| `So (ptr /= 0)` non-null invariant discharged via `choose`. |
| 90 | +|=== |
| 91 | + |
| 92 | +== The remaining proof program (dependency-sorted) |
| 93 | + |
| 94 | +Each stage is sized to roughly one context window; the thread compacts at each |
| 95 | +boundary with this file as the hand-off. *Watch-fors* are things that may force a |
| 96 | +design change or a model downshift mid-stage. |
| 97 | + |
| 98 | +=== Stage 1 — Merkle closure + crypto-binding interface [model: Opus] |
| 99 | + |
| 100 | +. `buildMerkleTree` correctness: `getLeafHash (buildMerkleTree hs) i = Just (index i hs)`, |
| 101 | + and the root-fold law relating `rootHashWith h (buildMerkleTree hs)` to `hs`. |
| 102 | +. *IO↔pure bridge*: prove `verifyProofIO` / `rootHashBytesIO` compute the |
| 103 | + `…With (blake3 combiner)` spec modulo the `Either` allocation-failure plumbing — |
| 104 | + connecting the proven theorem to the *production* crypto path. |
| 105 | +. *D2*: introduce `CollisionResistant h` and `merkleBinding` (stub/interface). |
| 106 | ++ |
| 107 | +WATCH-FOR: the `replace`-by-`powerTwoSucc` transport in `buildMerkleTree` may fight |
| 108 | +the index lemma; if it forces a builder/API reshape, stop and surface the fork. |
| 109 | + |
| 110 | +=== Stage 2 — Verify + Validator soundness [model: Opus → Sonnet if mechanical] |
| 111 | + |
| 112 | +. Validator: validated manifest ⇒ structural invariants hold. |
| 113 | +. `verifyState` agrees with the manifest, wired to `merkleCorrect`. |
| 114 | +. Hex codec: `hexStringToBytes (bytesToHex bs) = Just bs` and the length law. |
| 115 | ++ |
| 116 | +WATCH-FOR: `Verify` and `Hex` likely rest on primitive `String`/`Bits8` |
| 117 | +comparison — the *same wall* as the lexer round-trip. If so the honest theorem is |
| 118 | +propositional-over-decidable (document the boundary; do *not* reach for |
| 119 | +`believe_me`). This can shorten Stage 2 and justify a Sonnet downshift. |
| 120 | + |
| 121 | +=== Stage 3 — Repair correctness (L3, linear types) [model: Opus] |
| 122 | + |
| 123 | +. `verify (repair s) = Valid` — the meaty linear-type theorem. |
| 124 | +. Repair idempotence as a *proof* (today only a property test). |
| 125 | +. Harvest framework's mode-indexed Interface; state the `VerifiedSubsystem` law |
| 126 | + `verify (repair s m) m = Right …` and prove the FSState instance satisfies it. |
| 127 | ++ |
| 128 | +WATCH-FOR: may need proof witnesses threaded through the `1`-quantified API — |
| 129 | +possible signature changes to `Repair.idr`. |
| 130 | + |
| 131 | +=== Stage 4 — Completeness, binding discharge, write-up [model: Sonnet; Opus if binding is hard] |
| 132 | + |
| 133 | +. Merkle *completeness* (converse of soundness): in-range leaf ⇒ a proof exists. |
| 134 | +. *D2 discharge*: prove the binding argument against `CollisionResistant`. |
| 135 | +. Progressive monotonicity: the remaining `SatisfiesMinimum` cases (all `Refl`). |
| 136 | +. Final ledger pass; thesis-aligned summary (ICFP/PLDI/SOSP framing). |
| 137 | + |
| 138 | +CLEAR = every intended theorem proven *or honestly bounded* (primitive walls |
| 139 | +documented, never faked), disposed tracks handed off, PRs landed. |
| 140 | + |
| 141 | +== Honestly-bounded items (NOT failures — boundaries by design) |
| 142 | + |
| 143 | +* *Production-pipeline round-trip* (`parse . lex . serialize = Right m`) cannot |
| 144 | + carry a compile-time theorem: `pack`/`unpack`/`parseInteger` are primitives with |
| 145 | + no equational theory. The honest guarantee is `roundtripManifest` over a |
| 146 | + reference token codec, complemented by `roundtripProperty` at runtime. |
| 147 | +* *`root == root` Bool step* in `merkleCorrect`: the propositional digest equality |
| 148 | + is the strongest honest statement; discharging the residual primitive-`Bits8` |
| 149 | + `==` would need an unsafe reflexivity axiom. |
| 150 | + |
| 151 | +== Disposed tracks (handoff briefs) |
| 152 | + |
| 153 | +These are *not* this thread's work. Each is a brief for a delegated session, |
| 154 | +disposed at Compaction 1. Specs live here so nothing is lost. |
| 155 | + |
| 156 | +=== svalinn — migrate (AffineScript + Ephapax), then verify [model: Sonnet] |
| 157 | + |
| 158 | +PRECONDITION: language migration precedes proof (Decision D3). |
| 159 | + |
| 160 | +. *Migrate* ReScript → AffineScript (gateway, auth, policy, MCP, vörðr, compose). |
| 161 | + Affine boundary-decoders replace the *20+ `Obj.magic`* casts in security paths. |
| 162 | +. *Ephapax linear tokens* for exactly-once resources: JWT/JTI single-use + the |
| 163 | + revocation ledger (fixes the `hasRevocationList = false // TODO` hazard by |
| 164 | + construction), OAuth nonce/PKCE, session/container lifecycle. |
| 165 | +. *Unblock CI*: the 53 ReScript unit/security tests don't execute under Deno |
| 166 | + (`@rescript/core` resolution) — they vanish with the migration; ensure the |
| 167 | + AffineScript suite runs in CI. |
| 168 | +. *Specs to discharge after migration* (language-agnostic): policy determinism; |
| 169 | + `allow ∩ deny` composition + monotonicity; JWT single-use & revocation; |
| 170 | + no unchecked boundary casts; JSON-Schema conformance of all 9 gateway types. |
| 171 | +. *Planned SPARK properties* (`cerro-torre-integration.adoc §6.2`): attestation |
| 172 | + sig, key lookup, threshold sig, log inclusion, policy eval. |
| 173 | ++ |
| 174 | +DEPENDENCY: Ephapax has *3 Admitted* (Coq) — svalinn's linear guarantees inherit |
| 175 | +those holes until closed. Track upstream. |
| 176 | + |
| 177 | +=== ochrance-framework — retire core, harvest Interface, keep docs [model: Sonnet] |
| 178 | + |
| 179 | +. Delete `ochrance-framework/ochrance-core`; make the repo depend on / reference |
| 180 | + the canonical ochrance core. |
| 181 | +. Harvest the mode-indexed `VerifiedSubsystem` Interface into ochrance (Stage 3). |
| 182 | +. Fix the weak spots that should *not* be carried over: `decodeSnapshot` always |
| 183 | + returns `Nothing` (repair unreachable); `signatureValid : Bool` and |
| 184 | + `allPresent : Bool` are unguarded runtime flags; no totality gate in CI. |
| 185 | +. Keep and maintain the docs — they are the framework repo's real value. |
| 186 | + |
| 187 | +=== ochrance ABI / Zig FFI hardening [model: Sonnet/Haiku] |
| 188 | + |
| 189 | +. `blake3Hash` in `src/abi/Ochrance/ABI/Foreign.idr` is `covering` + a stub |
| 190 | + returning `replicate 32 0` — wire it to the real Zig `libochrance` BLAKE3. |
| 191 | +. ECHIDNA FFI is entirely stubbed (`echidnaProve` returns |
| 192 | + `Left "FFI not yet implemented"`). |
| 193 | + |
| 194 | +=== CI watch — PR #32 [model: Haiku/Sonnet] |
| 195 | + |
| 196 | +Keep PR #32 (combiner generalisation) shepherded to green; it is subscribed. |
| 197 | + |
| 198 | +== Model guidance (per the thread's operating model) |
| 199 | + |
| 200 | +[cols="1,3",options="header"] |
| 201 | +|=== |
| 202 | +| Model | Use |
| 203 | + |
| 204 | +| *Opus 4.8* |
| 205 | +| Proof *discovery* — "is this provable, what is the shape": Stages 1, 3, and any |
| 206 | + novel theorem or structural-wall reasoning. |
| 207 | +| *Sonnet 4.6* |
| 208 | +| Proof *mechanisation* (known shape), refactors, tests, and the disposed-track |
| 209 | + application work (svalinn AffineScript, framework, ABI). |
| 210 | +| *Haiku 4.5* |
| 211 | +| Grunt sweeps — suites, grep, SPDX/format, CI watch. |
| 212 | +|=== |
| 213 | + |
| 214 | +RULE: when a stage's remaining work is all mechanical, downshift this thread to |
| 215 | +Sonnet to conserve Opus budget; when a *research-grade wall* appears, pause for the |
| 216 | +design conversation rather than pushing proofs. |
0 commit comments