arborist-viz/arborist_viz/views/proofs.py
russell@unturf.com 0cd96ab1d7
Initial commit: arborist VIZ — Merkle command center
Pyramid web app for inspecting arborist Merkle trees over sharded SQLite:
document roots, inclusion proofs, an interactive 3D Merkle lattice
(six.js / WebGL with graceful fallback), audit-chain linkage, and a live
SSE event stream.

Generated artifacts (env/, vendored static/six/ bundles, demo databases)
are gitignored and rebuilt via the Makefile (venv, six, init-db, serve).
2026-05-28 09:22:59 -04:00

51 lines
1.8 KiB
Python

"""Merkle inclusion proof endpoint (ticket §6.1, §13).
Hard rule (DoD #10): inclusion is integrity, not semantic truth.
Server-side proof computation lives behind ``arborist.read.Shards.proof``.
"""
from __future__ import annotations
from pyramid.response import Response
from pyramid.view import view_config
def _json(body, status=200) -> Response:
return Response(json_body=body, status=status)
@view_config(route_name="api_proof", request_method="GET")
def get_proof(request):
if request.shards is None:
return _json(
{"error": "no_shard", "note": "configure arborist.shards"}, status=503
)
root_hash = request.matchdict["root_hash"]
try:
leaf_index = int(request.matchdict["leaf_index"])
except ValueError:
return _json({"error": "leaf_index must be an integer"}, status=400)
try:
p = request.shards.proof(root_hash, leaf_index)
if p is None:
# Fall through to a context root's inclusion proof — same
# builder, sorted source document_roots as leaves.
p = request.shards.context_proof(root_hash, leaf_index)
except IndexError as exc:
return _json({"error": str(exc)}, status=400)
if p is None:
return _json({"error": "not_found", "root_hash": root_hash, "leaf_index": leaf_index}, status=404)
return _json({
"root_hash": p.document_root,
"leaf_index": p.leaf_index,
"leaf_hash": p.leaf_hash,
"sibling_hashes": p.sibling_hashes,
"left_right_flags": p.left_right_flags,
"computed_root": p.computed_root,
"expected_root": p.expected_root,
"passed": p.passed,
"domain_separator": "leaf=0x00 / node=0x03",
"shard": p.shard_path,
"raw_proof": p.raw,
"source_roots": [p.document_root],
})