@@ -68,7 +68,8 @@ Three repositories are in scope. "Verification" means something different in eac
6868
6969== Current proof state (ochrance, canonical)
7070
71- The core is *clean*: all 24 modules carry `%default total`; zero
71+ The core is *clean*: all 19 `ochrance-core` modules carry `%default total` (the
72+ `src/abi/` tree adds the ABI modules separately); zero
7273`believe_me` / `assert_*` / `postulate` / holes / `partial` on any proof symbol.
7374
7475.Proven, machine-checked (axiom-free)
@@ -83,6 +84,11 @@ The core is *clean*: all 24 modules carry `%default total`; zero
8384| `verifyProofWith h root leaf prf = (root == reconstructWith h leaf prf)`.
8485| `reconstructAppendWith`, `powerTwoSucc`, `justInj`
8586| supporting lemmas.
87+ | `buildGetLeaf` (Stage 1.1)
88+ | constructor round-trip: `getLeafHash (buildMerkleTree hs) (finToNat i) = Just (index i hs)`.
89+ | `Ochrance.Util.VectLemmas` (×5)
90+ | reusable transport/append lemmas: `indexAppendLeft` / `indexAppendRight`,
91+ `indexReplace`, `finToNatReplace`, `splitAtConcat`.
8692| `roundtripManifest` + sub-codecs (`algoRT`, `modeRT`, `refsRT`, `mpolRT`, …)
8793| grammar invertibility: `decodeManifest (encodeManifest m) = Just m`.
8894| `SatisfiesMinimum` / `attestedSatisfiesLax`
@@ -99,15 +105,24 @@ design change or a model downshift mid-stage.
99105
100106=== Stage 1 — Merkle closure + crypto-binding interface [model: Opus]
101107
102- . `buildMerkleTree` correctness: `getLeafHash (buildMerkleTree hs) i = Just (index i hs)`,
103- and the root-fold law relating `rootHashWith h (buildMerkleTree hs)` to `hs`.
104- . *IO↔pure bridge*: prove `verifyProofIO` / `rootHashBytesIO` compute the
105- `…With (blake3 combiner)` spec modulo the `Either` allocation-failure plumbing —
106- connecting the proven theorem to the *production* crypto path.
107- . *D2*: introduce `CollisionResistant h` and `merkleBinding` (stub/interface).
108+ . *[DONE — 1.1]* `buildMerkleTree` ↔ `getLeafHash` round-trip:
109+ `getLeafHash (buildMerkleTree hs) (finToNat i) = Just (index i hs)`
110+ (`buildGetLeaf` in `Ochrance.Filesystem.MerkleBuild`, on the reusable
111+ `Ochrance.Util.VectLemmas` lemmas). Machine-checked, axiom-free, on `main`.
112+ . *[1.2] Root-fold law*: characterise `rootHashWith h (buildMerkleTree hs)` as a
113+ deterministic fold over `hs` — "the root is a function of the leaves". Pure;
114+ prerequisite of the binding argument.
115+ . *[1.3] IO↔pure bridge*: prove `verifyProofIO` / `rootHashBytesIO` compute the
116+ `…With (hashPairBlake3 …)` spec modulo the `Either` allocation-failure plumbing,
117+ against a typed combiner-equality hypothesis — connecting the proven theorem to
118+ the *production* crypto path. (The estate-wide spine; see "The IO↔pure bridge".)
119+ . *[1.4] D2*: introduce `CollisionResistant h` and state `merkleBinding`
120+ (typed hypothesis / interface; discharged in Stage 4).
108121+
109- WATCH-FOR: the `replace`-by-`powerTwoSucc` transport in `buildMerkleTree` may fight
110- the index lemma; if it forces a builder/API reshape, stop and surface the fork.
122+ RESOLVED (was WATCH-FOR): the `replace`-by-`powerTwoSucc` transport in
123+ `buildMerkleTree` was discharged *without* reshaping the builder — via the
124+ `indexReplace` / `finToNatReplace` / `splitAtConcat` transport-cancellation lemmas
125+ in `VectLemmas`. No API change was forced.
111126
112127=== Stage 2 — Verify + Validator soundness [model: Opus → Sonnet if mechanical]
113128
@@ -122,7 +137,16 @@ propositional-over-decidable (document the boundary; do *not* reach for
122137
123138=== Stage 3 — Repair correctness (L3, linear types) [model: Opus]
124139
125- . `verify (repair s) = Valid` — the meaty linear-type theorem.
140+ PRECONDITION (surfaced at Compaction 2): `repair` is currently a *stub* —
141+ `repairBlock` (`Repair.idr`) updates the hash map but does **not** read or write
142+ block data. Proving `verify (repair s) = Valid` against a no-op would be vacuous or
143+ false. DECISION (recommended): introduce a pure
144+ `repairPure : FSState -> Manifest -> FSState` that genuinely reconstructs the hash
145+ map, prove correctness over *that*, and make the IO `repair` a proven-equivalent
146+ shell (the IO↔pure pattern). Alternative: leave repair honestly-bounded until real
147+ block-I/O lands (defers the linear-type theorem).
148+
149+ . `verifyPure (repairPure s m) m = True` — the meaty (now well-founded) theorem.
126150. Repair idempotence as a *proof* (today only a property test).
127151. Harvest framework's mode-indexed Interface; state the `VerifiedSubsystem` law
128152 `verify (repair s m) m = Right …` and prove the FSState instance satisfies it.
@@ -140,6 +164,78 @@ possible signature changes to `Repair.idr`.
140164CLEAR = every intended theorem proven *or honestly bounded* (primitive walls
141165documented, never faked), disposed tracks handed off, PRs landed.
142166
167+ == The IO↔pure bridge (estate-wide spine)
168+
169+ The same device recurs at *every* IO boundary — Merkle (1.3), Verify (2.2),
170+ Repair (3), signatures (4 / bounded). The shape is always:
171+
172+ pure spec (proven) --[extensional-equality lemma]--> IO production path
173+ (modulo `Either`
174+ allocation-failure +
175+ a typed crypto hypothesis)
176+
177+ Treating this as *one* architectural pattern — not four ad-hoc stage items — is what
178+ lets the proven backdrop reach production code *without ever faking the FFI*. The
179+ typed crypto hypotheses (`CollisionResistant h`; `hashPairBlake3 a b` equals the
180+ spec combiner) are introduced in Stage 1.4 and discharged-or-assumed explicitly,
181+ never silently. It is also the mechanism that licenses optimisation (below).
182+
183+ == Build-with-proofs discipline
184+
185+ The invariant: *code never outstrips proofs*. Operationally —
186+
187+ . A correctness-claiming `public export` symbol lands only when (a) it carries its
188+ lemma in the same PR, or (b) it is explicitly `-- UNPROVEN:`-marked with a tracking
189+ issue, or (c) it is a documented honestly-bounded wall. No silent (d).
190+ . The `--total` CI build *is* the totality proof (already enforced) — a green build
191+ is the floor, not the ceiling.
192+ . *No proving stubs.* If an implementation is a placeholder (Repair today), make it
193+ real or model it purely *first* — never point a theorem at a no-op.
194+ . This ledger's proven-surface table is the source of truth; `README` / `TOPOLOGY`
195+ must not claim beyond it.
196+
197+ == Optimisation ledger (against the proven backdrop)
198+
199+ Governing principle: *the proven surface is exactly the code you may optimise* — the
200+ proof is the optimisation's regression contract. Keep the simple reference `R`
201+ (proven), introduce optimised `F`, discharge `F x = R x`, and every theorem about `R`
202+ transports to `F` by `rewrite`. Never optimise unproven code (nothing guards it).
203+
204+ [cols="1,2,2,1",options="header"]
205+ |===
206+ | Target | Optimisation | Guard | Status
207+
208+ | `buildMerkleTree`
209+ | bottom-up O(n) fold from the flat vector (vs. per-level `replace`/`splitAt`)
210+ | `buildFast hs = buildMerkleTree hs` ⇒ `buildGetLeaf` transports
211+ | unlocked now
212+
213+ | `getLeafHash`
214+ | thread a `Fin` index; drop Nat `minus`/`<`
215+ | `getLeafFast t i = getLeafHash t (finToNat i)`
216+ | unlocked now
217+
218+ | `generateProof` / `reconstruct`
219+ | difference-list / vector path (vs. List append per step)
220+ | `reconstructAppendWith` + `merkleCorrectWith`
221+ | unlocked now
222+
223+ | root combiner
224+ | real BLAKE3 in IO (vs. abstract `h`)
225+ | the Stage 1.3 bridge lemma
226+ | after 1.3
227+
228+ | A2ML production parser
229+ | any fast String parser
230+ | `roundtripManifest` + runtime `roundtripProperty` net
231+ | bounded (prim. wall)
232+
233+ | Repair (incremental / CoW)
234+ | touch only broken blocks
235+ | `verify (repair s) = Valid`
236+ | after Stage 3
237+ |===
238+
143239== Honestly-bounded items (NOT failures — boundaries by design)
144240
145241* *Production-pipeline round-trip* (`parse . lex . serialize = Right m`) cannot
0 commit comments