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).
161 lines
6.7 KiB
Python
161 lines
6.7 KiB
Python
"""Seed a small arborist shard so dropping a hash visualizes something.
|
|
|
|
Usage:
|
|
|
|
arborist_viz_seed_demo data/demo_arborist.db
|
|
|
|
Ingests ~5 documents via ``arborist.embed.ingest_documents`` and prints
|
|
their ``document_root`` and a few sample ``leaf_hash`` values — the
|
|
operator copies one of these into the dashboard's hash input.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
import sys
|
|
import sqlite3
|
|
|
|
try:
|
|
from arborist.embed import open_store, ingest_documents, Document, Edge
|
|
except Exception as exc:
|
|
print("ERROR: arborist not importable: {0}".format(exc), file=sys.stderr)
|
|
print("Run `make arborist` first (installs ~/git/arborist into the venv).", file=sys.stderr)
|
|
sys.exit(1)
|
|
|
|
|
|
SAMPLE_DOCS = [
|
|
Document(
|
|
uri="https://unturf.com/software/arborist",
|
|
title="Arborist — content-addressed memory for ML agents",
|
|
source_type="demo_unturf",
|
|
content=(
|
|
"Arborist is a content-addressed, Merkle-committed, audit-chained store "
|
|
"for documents an ML agent has read. Every document is canonicalized, "
|
|
"chunked, and rooted; every chunk is content-addressable; every ingest "
|
|
"produces one append-only audit event. Identical content collapses to a "
|
|
"single document_root. Mesh peers re-derive and cross-verify roots. "
|
|
"Embedders (e.g. neopig) hand arborist Document objects and arborist "
|
|
"owns the SQLite — no raw SQL in the embedder's app."
|
|
),
|
|
edges=[Edge(edge_type="references", dst_uri="https://unturf.com/software/")],
|
|
extra={"demo": True, "ix": 1},
|
|
),
|
|
Document(
|
|
uri="https://unturf.com/let-us-define-a-permacomputer",
|
|
title="Let us define a permacomputer",
|
|
source_type="demo_unturf",
|
|
content=(
|
|
"A permacomputer is a regenerative compute substrate: free execution for "
|
|
"anyone, infrastructure that outlasts its builders, code that outlasts "
|
|
"its authors. Russell Ballestrini's manifesto frames compute as a "
|
|
"commons, not a rent extraction surface. Workstations are nodes, edges "
|
|
"are queues, every patch must confirm downstream capacity before it "
|
|
"ships. Three drivers, three million people — fix the dispatch, but "
|
|
"stage the drivers first."
|
|
),
|
|
extra={"demo": True, "ix": 2},
|
|
),
|
|
Document(
|
|
uri="https://undefect.com/moad/moad-2026-0001",
|
|
title="MOAD-0001 — The Sedimentary Defect (CWE-407)",
|
|
source_type="demo_undefect",
|
|
content=(
|
|
"list.contains() inside a loop yields O(N^2) behaviour where a hash set "
|
|
"would give O(1). The sedimentary defect: written before O(1) was "
|
|
"idiomatic, still ships today. Patches land at the Java, Python, Go, "
|
|
"and JS layers — six.js carries the JS dogfood: three.js r175 plus a "
|
|
"scene-level BVH that drops raycaster scans from O(N) to O(log N). "
|
|
"Every six.js deploy adds a data point that the patch is production-safe."
|
|
),
|
|
extra={"demo": True, "ix": 3},
|
|
),
|
|
Document(
|
|
uri="https://undefect.com/moad/moad-2026-0005",
|
|
title="MOAD-0005 — The Thundering Herd",
|
|
source_type="demo_undefect",
|
|
content=(
|
|
"Cache get + null check + compute + put with no synchronization invites "
|
|
"N concurrent recomputations on a cold miss — the thundering herd. The "
|
|
"fix is computeIfAbsent or singleflight: one computation per key, the "
|
|
"rest park on the same future. Coupled with MOAD-0001: fix the O(N^2) "
|
|
"bottleneck and you flood every downstream cache simultaneously unless "
|
|
"the herd discipline is in place first."
|
|
),
|
|
extra={"demo": True, "ix": 4},
|
|
),
|
|
Document(
|
|
uri="https://unturf.com/eight-forms-of-capital",
|
|
title="Eight Forms of Capital",
|
|
source_type="demo_unturf",
|
|
content=(
|
|
"Roland and Landua's eight capitals: living, material, financial, "
|
|
"intellectual, experiential, social, cultural, spiritual. Nurture "
|
|
"capitals cannot be bought, only grown. Transactional capitals "
|
|
"facilitate exchange — they are tools, not goals. Regenerative systems "
|
|
"reinvest surplus back into living capital. Platform tax is O(N^2) "
|
|
"friction at the exchange layer: it drains workaholic nodes to feed "
|
|
"gluttons that feel no pain."
|
|
),
|
|
extra={"demo": True, "ix": 5},
|
|
),
|
|
]
|
|
|
|
|
|
def main(argv=sys.argv):
|
|
if len(argv) < 2:
|
|
print("usage: arborist_viz_seed_demo <db_path>", file=sys.stderr)
|
|
sys.exit(1)
|
|
db_path = argv[1]
|
|
os.makedirs(os.path.dirname(db_path) or ".", exist_ok=True)
|
|
|
|
print("[seed] opening {0} ...".format(db_path))
|
|
conn = open_store(db_path)
|
|
|
|
print("[seed] ingesting {0} demo documents (sentence chunker for richer trees) ...".format(len(SAMPLE_DOCS)))
|
|
# SentenceChunker (sent-v1) splits on sentence boundaries — one leaf per
|
|
# sentence. This makes the 3D Merkle lattice visually meaningful even on
|
|
# short demo docs. TokenChunker default (tok-512-v1) collapses our
|
|
# paragraph-sized samples into a single leaf each.
|
|
stats = ingest_documents(conn, SAMPLE_DOCS, source_type="demo", chunker_name="sent-v1")
|
|
print("[seed] stats: {0}".format(stats))
|
|
|
|
print("")
|
|
print("=" * 64)
|
|
print(" demo arborist shard ready — paste any of these into VIZ:")
|
|
print("=" * 64)
|
|
cur = conn.execute(
|
|
"SELECT document_root, title, "
|
|
" (SELECT COUNT(*) FROM chunks WHERE chunks.document_root = documents.document_root) AS n_leaves "
|
|
"FROM documents ORDER BY ingest_ts"
|
|
)
|
|
for row in cur:
|
|
# Sample one leaf per doc as well.
|
|
leaf = conn.execute(
|
|
"SELECT leaf_hash, idx FROM chunks WHERE document_root = ? ORDER BY idx LIMIT 1",
|
|
(row[0],),
|
|
).fetchone()
|
|
print("")
|
|
print(" document_root: {0}".format(row[0]))
|
|
print(" title: {0}".format(row[1]))
|
|
print(" leaves: {0}".format(row[2]))
|
|
if leaf:
|
|
print(" sample leaf: {0} (leaf #{1})".format(leaf[0], leaf[1]))
|
|
|
|
# And a sample audit event.
|
|
ev = conn.execute("SELECT event_hash, event_type FROM audit_events ORDER BY seq LIMIT 1").fetchone()
|
|
if ev:
|
|
print("")
|
|
print(" sample audit_event: {0} ({1})".format(ev[0], ev[1]))
|
|
|
|
print("")
|
|
print("=" * 64)
|
|
print(" Boot the VIZ: ARBORIST_VIZ_SHARDS={0} make serve".format(db_path))
|
|
print(" Or just: make serve-demo")
|
|
print("=" * 64)
|
|
print("")
|
|
|
|
conn.close()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|