Skip to content

proof(merkle): Stage 1.2 — root-fold law (root of buildMerkleTree = foldRoot over leaves)#49

Merged
hyperpolymath merged 1 commit into
mainfrom
claude/dazzling-noether-hkgAV
Jun 18, 2026
Merged

proof(merkle): Stage 1.2 — root-fold law (root of buildMerkleTree = foldRoot over leaves)#49
hyperpolymath merged 1 commit into
mainfrom
claude/dazzling-noether-hkgAV

Conversation

@hyperpolymath

Copy link
Copy Markdown
Owner

Summary

Stage 1.2 of the proof campaign (see docs/PROOFS.adoc). Proves the Merkle root is a deterministic, representation-independent fold over the leaf vector:

rootHashWith h (buildMerkleTree hs) = foldRoot h hs — generic over the combiner h (XOR and BLAKE3 alike).

What landed (ochrance-core/Ochrance/Filesystem/MerkleBuild.idr)

  • foldRoot — the leaf-only spec of the root (singleton → element; a 2^(S k) vector splits at 2^k and combines its two sub-folds with h, the same split buildMerkleTree uses).
  • rootFoldSplit — the inductive step stated on the already-split halves, so the rootHashWith-of-Node reduction is clean and decoupled from the with abstraction (mirrors Stage 1.1's buildGetLeafSplit; the IH is a higher-order argument). This was the one wrinkle: a naive rewrite under with fails because buildMerkleTree's internal case is left as a stuck let — the split-lemma sidesteps it.
  • rootFoldLaw — the theorem; base Refl, step via rootFoldSplit applied to the IH.

Why it matters

Pairs with buildGetLeaf (Stage 1.1) to fully characterise buildMerkleTree — both its leaves (getLeafHash) and its root (rootHashWith) are pinned to the leaf vector. Hands the Stage-4 binding argument a leaf-only handle on the root ("the root is a function of the leaves").

Verification

  • Machine-checked, axiom-free, total — clean from-scratch idris2 --build ochrance.ipkg under --total, 19/19, exit 0. No believe_me/assert_*/postulate/holes.
  • docs/PROOFS.adoc updated: Stage 1.2 marked DONE; rootFoldLaw/foldRoot added to the proven surface.

Next: Stage 1.3 (the IO↔pure bridge — the estate-wide spine).

🤖 Generated with Claude Code

https://claude.ai/code/session_011z2t8zAxfcCNLJzU7YdpBQ


Generated by Claude Code

…oldRoot over leaves)

Prove the Merkle root is a deterministic, representation-independent fold over the
leaf vector: rootHashWith h (buildMerkleTree hs) = foldRoot h hs, generic over the
combiner h (XOR and BLAKE3 alike).

- foldRoot: the leaf-only spec of the root (singleton -> element; a 2^(S k) vector
  splits at 2^k and combines its two sub-folds with h, the same split
  buildMerkleTree uses).
- rootFoldSplit: the inductive step on the already-split halves, so the
  rootHashWith-of-Node reduction is clean and decoupled from the `with` abstraction
  (mirrors buildGetLeafSplit; the IH is a higher-order argument).
- rootFoldLaw: the theorem; base Refl, step via rootFoldSplit applied to the IH.

Pairs with buildGetLeaf to fully characterise buildMerkleTree (leaves + root) and
hands the Stage-4 binding argument a leaf-only handle on the root.

Machine-checked, axiom-free, total (clean --total build, 19/19). PROOFS.adoc marks
Stage 1.2 DONE and adds rootFoldLaw/foldRoot to the proven surface.

https://claude.ai/code/session_011z2t8zAxfcCNLJzU7YdpBQ
@hyperpolymath
hyperpolymath marked this pull request as ready for review June 18, 2026 00:11
@hyperpolymath
hyperpolymath merged commit db0f830 into main Jun 18, 2026
19 checks passed
@hyperpolymath
hyperpolymath deleted the claude/dazzling-noether-hkgAV branch June 18, 2026 00:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants