# Ticket #000069 — Arborist VIZ / Merkle Command Center

**Status:** open · awaiting go/no-go
**Opened:** 2026-05-27
**Scope:** Tableau-inspired, Palantir-style browser dashboard for inspecting
Merkle roots, proofs, claims, audit trails, run-DAGs, claim graveyard,
3D state geometry, and optional circuit/activation traces produced by
arborist. Read-only consumer of arborist's content-addressed state.
**Audience:** product/UX, Dav1d de-novo review, downstream integrators
(neopig, undefect.com).
**Hard constraint:**

1. **Use unturf's existing stack — not invent a new one** (fox
   2026-05-27). Backend: **Pyramid** (Python) + Jinja2 + SQLAlchemy,
   matching `~/git/remarkbox` / `~/git/make_post_sell` /
   `~/git/unhomeschool.com` idioms. Streaming: **SSE**
   (`text/event-stream`) via Pyramid streaming response. Frontend:
   **vanilla JS** + **six.js** (= `~/git/six.js`, fox's vendored
   three.js) for 3D widgets. **NO React, NO Next.js, NO Node**
   toolchain, NO NATS JetStream, NO PostgreSQL/ClickHouse/Redis
   bring-up unless a measured need surfaces. VIZ lives in a
   **sibling repo** `~/git/arborist-viz` (Pyramid Python, optional
   `[viz]` extra), matching the `arborist-zk-bench` /
   `arborist-world` pattern; arborist proper stays
   `python3.12 + venv + sqlite3`. See **§3-corrected** below for the
   pinned stack; original §3 is preserved as superseded design log.
2. The dashboard projects state, never asserts it. Merkle roots and
   audit events remain source-of-truth in arborist shards; every
   widget exposes the query + source roots it derived from
   (§19.3 of the proposal body).
3. **Soft signals never enter the proof path** (CLAUDE.md "soft hash
   vs hard hash" convention). The activation/circuit-trace layer
   (§11, §6.10) MAY render attribution weights, but it inherits
   #000049's cage verbatim: hash-pinned, governance-hashed,
   demotion-only-if-it-ever-feeds-`audit_mode`, never causal without
   intervention/ablation evidence. `audit_mode` is unaffected by
   anything VIZ displays.
4. **Private-leaf default-deny** (proposal §14). Commitments, hashes,
   redacted evidence maps, selective-disclosure objects only — raw
   chunks/prompts/traces require explicit authorization. No
   widget bypasses this gate.

---

## Filing notes (2026-05-27)

This ticket files the proposal text verbatim from
`/home/fox/Downloads/TICKET_0000VIZ_Arborist_VIZ__Merkle_Command_Center.txt`,
wrapped in the arborist ticket header above. Three structural decisions
were flagged at file time and stand as open items for the next review:

**(F-1) Repo home + stack — CORRECTED 2026-05-27.** Proposal §3
specifies Next.js + React + TypeScript + Node + Fastify + NATS
JetStream + PostgreSQL + ClickHouse + Redis. fox rejected that stack
2026-05-27: *"we will want to use the frameworks that unturf already
uses (not react) three.js (six.js) pyramid python prefered with SSE
see https://www.unturf.com/software/"*. Pinned stack lives in
**§3-corrected** below. The repo home is still a sibling — `~/git/arborist-viz`
(Pyramid Python app, not in-tree) — but now matches `remarkbox` /
`make_post_sell` / `unhomeschool.com` idioms instead of standing up a
parallel TypeScript world. Arborist's in-tree contribution is still
just the **read-API spec + Python read-API impl** (proposal §13: HTTP
routes + SSE endpoints, both Pyramid-flavored); the only code that
might land in `arborist/` itself is `arborist/viz_api/` (an optional
Pyramid view package) or, more likely, nothing in-tree at all (the
sibling repo imports `arborist` as a library via `arborist.embed`,
per `docs/embedding.md`).

**(F-2) Scope split.** Proposal §17 lists eight implementation phases.
Don't-proliferate (CLAUDE.md) says default to extending one ticket; the
Dav1d-audience rule says split when a sub-piece needs an independent
audience. Recommended cut:

| Sub-ticket | Phases | Audience |
|---|---|---|
| #000069 (this) | §17 phases 0–3: schema, dashboard shell, proof/root widgets, claim/audit/run widgets | core product + Dav1d (the foundational layer) |
| sibling A | §17 phase 4: NATS → WebSocket streaming | infra/ops review |
| sibling B | §17 phase 5: 3D Merkle lattice (R3F + Three.js) | UX + GPU/perf review |
| sibling C | §17 phase 6: massive-graph widgets (Cosmograph) | scale review |
| sibling D | §17 phase 7: circuit/activation trace widgets | gated on #000062 producing a `MechanisticWitnessRoot`; mechanistic-interp review |
| sibling E | §17 phase 8: embeddable web-components NPM package | API/integration review |

If fox prefers a single ticket carrying all phases, leave as-is and
spawn sub-tickets only when a phase's review surface diverges from the
others. **Default this ticket scope to phases 0–3 unless told otherwise.**

**(F-3) Upstream prereqs.** Two arborist tickets are upstream of VIZ
phases and need explicit cross-references for the de-novo review:

- **#000062 Mechanistic Witness (scaffold-only, awaiting go/no-go)** —
  produces `MechanisticWitnessRoot` over (model, capture policy,
  neurons/features, intervention deltas). VIZ §6.10 (Circuit Trace
  Widget) + §11 (full circuit/activation tracing layer) are
  **consumers** of this root. Phase D of this ticket cannot start
  until #000062 lands a witness producer. VIZ §11's hard rule
  ("never causal unless intervention or ablation evidence exists")
  must remain word-identical to #000062's four guardrails so the cage
  is consistent across producer + display layer.
- **#000059 Admission discipline / claim-graveyard** — VIZ §6.9 (Claim
  Graveyard Widget) is one UI projection of #000059's bounded-ingestion
  graveyard. Bounded-ingestion hard constraint (fox 2026-05-20)
  applies: the graveyard widget MUST display the recurring-error
  surface, never queries-ever, and must not encourage operators to
  treat the graveyard as a transcript store.

The proposal body below stands as the design draft. Phases, widget
catalog, schemas, and APIs are the design log; the four hard
constraints above and the three filing notes are the arborist-specific
gates the design must pass before any phase 0 work lands.

---

## §3-corrected — Pinned unturf-native stack (2026-05-27)

fox 2026-05-27: *"we will want to use the frameworks that unturf
already uses (not react) three.js (six.js) pyramid python prefered
with SSE — see https://www.unturf.com/software/"*. This section
supersedes the original §3 (preserved unchanged below as the
superseded draft / design log).

### Backend (sibling repo `~/git/arborist-viz`)

```text
Python 3.10+
Pyramid                — web framework (matches remarkbox / make_post_sell)
pyramid_jinja2         — Jinja2 server-rendered templates
pyramid_tm             — transaction manager
pyramid_retry          — retry on conflict
SQLAlchemy             — dashboard metadata (saved layouts / filter presets)
                         (read-only access to arborist shards goes through
                          `arborist.embed` / direct sqlite3, NOT SQLAlchemy)
alembic                — schema migrations for the dashboard metadata DB
waitress               — production WSGI server (Pyramid default)
arborist               — imported as a Python library for read-only
                         provenance access; arborist shards stay the
                         source of truth
```

### Storage

```text
arborist SQLite shards — provenance source of truth (read-only)
SQLite for dashboard
  metadata             — saved layouts, filter presets, user prefs
                         (NOT PostgreSQL — keeps unturf's
                          "python3.12 + venv + sqlite3" floor)
```

Pyramid's standard SQLAlchemy-on-PostgreSQL idiom (the remarkbox
pattern) is the obvious *escape hatch* when dashboard metadata
outgrows SQLite — but VIZ v1 ships SQLite-only by default. Promoting
to PostgreSQL requires a measured need (multi-user concurrent edits,
team sharing, hosted SaaS deployment), not a v1 default.

### Streaming

```text
SSE (Server-Sent Events) over HTTP — text/event-stream
Pyramid streaming response (`generator → Response.app_iter`)
arborist audit chain → SSE event stream
  (audit-event hash, root commitments, claim status changes,
   falsifier acceptance, cache invalidation — same subjects
   as the original §9 NATS subject list, but flat HTTP)
```

**Why SSE over WebSockets+NATS JetStream:**

- SSE is one-directional (server → browser), which is exactly what a
  read-only dashboard needs. No client→server channel = smaller
  attack surface, no auth complexity for the streaming side.
- Pyramid serves SSE natively via a streaming view (no extra
  gateway, no `uWebSockets.js`, no Node runtime).
- Auto-reconnect is built into the browser `EventSource` API; no
  client library needed.
- NATS JetStream is a queue-broker for many-producer many-consumer
  fan-out. Arborist is a single producer; the audit chain already
  carries sequence + content-addressed event hashes. A queue
  broker adds an extra durability layer we don't need.
- The CLAUDE.md "stdout buffering" rule applies: SSE streams must
  flush per-event, never line-buffer. Pyramid's `app_iter` pattern
  flushes naturally; `gunicorn` workers (if ever used in place of
  waitress) need `--worker-class gevent` or equivalent.

### Frontend

```text
vanilla JavaScript     — NO React, NO Next.js, NO TypeScript build step
                         (Jinja2 server-rendered HTML is the default;
                          JS sprinkles only where genuinely needed)
six.js                 — fox's patched three.js fork for 3D Merkle
                         lattice, 3D proof-pulse, root-diff explosion,
                         temporal playback (proposal §6.11). See
                         "six.js sourcing" subsection below — this is
                         a CWE-407-patched fork (MOAD-0001 dogfood),
                         not vanilla three.js.
EventSource (browser   — SSE client (no JS dep)
   built-in)
<canvas> + six.js      — graph rendering for large claim/falsifier graphs
                         (replaces the Cosmograph / cosmos.gl
                          recommendation; if a 100K+ node graph ever
                          needs WebGL force-directed layout, evaluate a
                          vanilla-JS lib then — sigma.js / d3-force —
                          NOT a React-coupled one)
HTML <details>/<table> — virtualized tables happen at the server
                         (Pyramid view paginates), not via TanStack
                         Table. Default to Jinja2 pagination; only
                         add client-side virtualization when a real
                         100K-row need surfaces.
SVG + vanilla layout   — run-DAG / pipeline widgets (proposal §6.5);
                         replaces React Flow. Either server-render
                         SVG from Jinja2 + a dagre-python port, or
                         emit Graphviz `.dot` and render server-side
                         (matches the existing `docs/diagrams/*.dot`
                          pattern under `make docs`).
```

**No build step by default.** A Pyramid+Jinja2+vanilla-JS dashboard
needs no webpack / no Vite / no `npm install`. Six.js loads as a
single `<script>` from `static/`. This matches remarkbox-theme-meta /
remarkbox-theme-chaostheory deployment idiom.

### six.js sourcing (fox 2026-05-27 — "vendored with a patch")

six.js is **not vanilla three.js** — it's a published fork with
fox's CWE-407 patches applied. Two artifacts to know about:

```text
Source repo:
  ~/git/six.js
  remote: ssh://git@git.unturf.com:2222/gumyum/six.js.git
  base:   three.js r175 (upstream commit 8b169b0)
  commits:
    363b9ff  six.js: three.js r175 (8b169b0) + CWE-407 patches
    4e74c8a  cwe-407: ObjectBVH — O(N) raycaster scan → O(log N)
             via scene-level BVH

Pre-built bundles (operational vendor source):
  ~/git/cupPCB/cdn/six/
    six-global.js          six.webgpu.js          six.webgpu.min.js
    six.tsl.js             six.tsl.min.js
    six.core.min.js        six.webgpu.nodes.js    six.webgpu.nodes.min.js
    (paired with the unpatched three.module.js / three.core.js /
     three.tsl.js / three.webgpu.js bundles for side-by-side A/B)
```

**Vendor from cupPCB, not the source repo.** Build artifacts shouldn't
be regenerated per-consumer. `arborist-viz/static/` copies the bundles
out of `~/git/cupPCB/cdn/six/` (or, ideally, references the
publicly-served CDN URL on cupPCB.com if that becomes available
post-deploy). The source repo is for patch maintenance, not for
direct inclusion.

**Why this is load-bearing, not incidental.** Per
`~/git/CLAUDE.md`, gumyum's engine strategy is *"Redot merges our
CWE-407 patches → switch to Redot; Redot ignores → hard fork Redot
as gumyum-engine, maintain patched fork for gumyum games. gumyum
games = dogfood proof our patches are production-safe."* six.js
follows the same pattern at the JS layer: three.js fork with the
same CWE-407 (MOAD-0001 sedimentary-defect) patches that
`~/git/java-topology` carries at the Java layer and that gumyum's
engine work would carry at the C++/godot layer.

Using six.js in arborist-viz is **third-instance dogfood** of fox's
CWE-407 patches — a permacomputer infrastructure piece running on
fox-patched three.js, a permacomputer game studio running on
fox-patched gumyum-engine, and the upstream undefect.com disclosures
that produced the patches all reinforcing one another. VIZ doesn't
*need* the BVH speedup to render dashboards — but every six.js
deploy adds a small data point that the patch is production-safe.

**Patch-tracking discipline.** When upstream three.js advances (r175
→ r176 → r177 → …), the six.js maintainer (fox) rebases `363b9ff`
+ `4e74c8a` forward; arborist-viz pulls the new bundles from
`cupPCB/cdn/six/` and verifies its 3D widgets still render. The
ticket assumes six.js stays the canonical 3D layer for the lifetime
of VIZ; if upstream three.js ever merges the BVH patch and six.js
collapses back to vanilla three.js, the `arborist-viz/static/`
import path stays `six.*.js` (the bundle names are stable; what
they wrap underneath is fox's concern, not VIZ's).

### What's deliberately dropped (vs original §3)

| Original §3 recommendation | Dropped because |
|---|---|
| Next.js / React 19 / TypeScript | fox: not React; unturf is server-rendered Pyramid + Jinja2 |
| Node.js / Fastify | not in unturf stack |
| React Flow | replace with server-rendered SVG or Graphviz `.dot` |
| Cosmograph / cosmos.gl | vanilla `<canvas>` + six.js; large-graph WebGL only if a measured need surfaces |
| React Three Fiber | direct six.js; declarative wrapper not needed without React |
| TanStack Table / Virtual | server-side pagination; virtualize only on measured need |
| Zustand | server-side dashboard state in Pyramid sessions |
| NATS JetStream | SSE streams directly from arborist audit chain |
| MessagePack / Protobuf | JSON over SSE (`data:` lines); revisit only if bandwidth measurably hurts |
| Apache Arrow snapshots | JSON or compact CSV snapshots; revisit on measured need |
| Web Workers + WebCrypto | browser-side proof verification stays a v1 *non*-goal — Pyramid view computes the proof, returns PASS/FAIL + receipt; client-side verification is a phase-N add-on only if a third-party-verification use case actually surfaces (auditing a hosted arborist instance you don't control) |
| PostgreSQL | SQLite for dashboard metadata; PostgreSQL only on measured need |
| ClickHouse | arborist shards already content-address audit events; query them directly |
| Redis | Pyramid sessions; revisit only if multi-server presence needed |
| S3 / R2 / MinIO for blob storage | arborist `#000061` cold-pack tier already covers blob distribution; no new storage tier |

The original §3 stack would deliver every spec'd capability — but at
the cost of operating two completely different toolchains (Python for
arborist, TypeScript+Node for VIZ) and bringing up four new
infrastructure components (NATS, PostgreSQL, ClickHouse, Redis). The
unturf-native stack delivers the same v1 capabilities (dashboard
composition, root/proof/claim/audit/run widgets, SSE live updates,
3D Merkle lattice, root diff) with one toolchain and zero new
infrastructure dependencies beyond Pyramid+SQLite+six.js — every
piece of which is already production-deployed under
`remarkbox.com` / `makepostsell.com`. Scale-up paths to the heavier
stack remain available case-by-case (Pyramid → SQLAlchemy on
PostgreSQL is one config flag; large-graph rendering can adopt
sigma.js or a WebGL force-layout lib without rewriting the rest of
the dashboard).

### What stays unchanged from the original proposal

```text
§4  dashboard interaction model
§5  ticket goals (1-5)
§6  widget catalog (12 widgets, just rendered with the new stack)
§7  layout system (DashboardConfig / WidgetSpec — Python dataclasses
    now, not TypeScript types, but the same shape)
§8  data model (VizNode / VizEdge / GraphPatch)
§9  real-time architecture (subjects unchanged; transport changes
    from NATS+WebSocket to direct SSE)
§10 3D rendering architecture (uses six.js directly)
§11 circuit/activation tracing layer (consumes #000062's
    MechanisticWitnessRoot; rendering via six.js + Jinja2)
§12 query layer (Pyramid view receives the JSON, compiles to SQL
    against arborist shards)
§13 API specification (HTTP routes unchanged; WebSocket routes
    become SSE routes — `WS /ws/audit/live` becomes
    `GET /sse/audit/live`)
§14 security / privacy / governance (unchanged)
§15 performance targets (browser-side proof verify dropped from v1;
    other targets unchanged — server-side SSE patch latency targets
    apply directly)
§16 test plan (unchanged — same tests, different test harness:
    pytest + Pyramid `TestApp` instead of Vitest)
§17 implementation phases (unchanged in structure; phase 4
    "real-time streaming" reads "SSE" not "NATS → WebSocket")
§18 definition of done (unchanged, modulo browser-side proof
    verification dropped from v1)
§19 best-practice constraints (unchanged)
```

### Phase 0 deliverables — concrete starting point

```text
~/git/arborist-viz/
├── setup.py / setup.cfg          # Pyramid scaffold (matches remarkbox)
├── development.ini / production.ini
├── arborist_viz/
│   ├── __init__.py               # Pyramid `main()` factory
│   ├── routes.py                 # `add_route('audit_sse', '/sse/audit/live')` etc.
│   ├── views/
│   │   ├── dashboards.py         # GET/POST/PUT /api/dashboards
│   │   ├── roots.py              # GET /api/root/<hash>
│   │   ├── proofs.py             # GET /api/proof/<root>/<leaf_index>
│   │   ├── claims.py             # GET /api/claim/<id>[/neighborhood]
│   │   ├── audit.py              # GET /api/audit/<hash> + chain
│   │   └── sse.py                # SSE endpoints (audit/live, run/<id>, …)
│   ├── models/                   # SQLAlchemy: dashboards, widgets, layouts
│   ├── templates/                # Jinja2 (root_explorer.jinja2,
│   │                              # claim_warrant.jinja2, run_dag.jinja2, …)
│   ├── static/
│   │   ├── six/                  # vendored from ~/git/cupPCB/cdn/six/
│   │   │   ├── six-global.js     # global (non-module) build for
│   │   │   │                      # legacy <script src> tags
│   │   │   ├── six.webgpu.min.js # WebGPU renderer (preferred)
│   │   │   ├── six.core.min.js   # CPU / WebGL fallback
│   │   │   └── six.tsl.min.js    # three shading language addons
│   │   ├── viz/                  # vanilla JS dashboard composition,
│   │   │                          # widget instantiation, SSE client
│   │   └── css/
│   ├── scripts/alembic/          # metadata schema migrations
│   └── tests/
└── README.rst
```

---

## Tableau-Inspired, Browser-Based, Real-Time Dashboard for Merkle Hash Tracing, Auditability, 3D Tree Visualization, Circuit/Activation Tracing, and Interpretability Geometry

**Status:** Proposed
**Priority:** High
**Type:** Visualization / Audit / Dashboard Builder / Interpretability / Real-Time Streaming
**Target form:** lightweight browser-based dashboard, configurable on the fly, embeddable as widgets, scalable to large proof/claim graphs, with optional 3D accelerated views.
**Canonical name:** **Arborist VIZ**
**Alternate product names:** Merkle Command Center, Merklepedia, Arborist Explorer, ProofOps Dashboard.

---

## 1. Design inspiration and correction

The previous ticket correctly specified a proof-first Merkle explorer. This revised ticket changes the product target:

```text
Old target:
  fixed explorer pages for roots, claims, audit events, run DAGs, and traces.

New target:
  configurable Tableau/Palantir-style dashboard system where users can compose,
  filter, animate, save, replay, and stream proof/audit/interp views on the fly.
```

The `palantir-for-family-trips` reference is useful for the **command-center UX**: dense dashboard, timeline playback, route/map surfaces, mission overlays, logistics panels, and large-screen operational styling. The repo describes itself as a “Palantir-ish dashboard,” tracks multi-party movement, simulates route/timeline playback, organizes logistics into views, and uses a dark command-center dashboard style. It is built with React 19, Vite, Google Maps JavaScript API, Lucide icons, and Framer Motion, with browser-local state and desktop/large-screen optimization. ([GitHub][1])

For Arborist, the equivalent is not a trip command center. It is:

```text
A command center for verifiable AI state.
```

Core product statement:

```text
Arborist VIZ is a configurable browser dashboard for inspecting what an AI system
claimed, why it was admitted, what Merkle roots commit to it, which evidence and
falsifiers exist, how the audit trail evolved, and which circuit/activation traces
were associated with the output.
```

---

## 2. Product thesis

```text
Neuronpedia makes model features inspectable.

Arborist VIZ makes verifiable AI state transitions inspectable.

Tableau makes data dashboards configurable.

Arborist VIZ combines both:
  configurable dashboards
+ Merkle-root audit trails
+ proof replay
+ claim/falsifier graphs
+ 3D temporal geometry
+ optional circuit/activation tracing.
```

The unit of inspection is:

```text
hash-rooted epistemic object
```

not just a document, node, chart, or feature.

Primary objects:

```text
document_root
leaf_hash
proof_path
claim_id
evidence_id
falsifier_id
graveyard_entry
audit_event_hash
cache_key
run_id
fork_id
benchmark_root
peer_root
activation_trace_id
circuit_id
intervention_id
```

---

## 3. Final architecture choice

### Recommended architecture

```text
Frontend:
  Next.js + React + TypeScript
  Dashboard grid/layout engine
  React Flow for run-DAG / pipeline widgets
  Cosmograph / cosmos.gl for massive graph widgets
  React Three Fiber + Three.js for 3D Merkle/circuit/time widgets
  TanStack Table + Virtual for audit/claim/leaf tables
  Zustand for local dashboard state
  Web Workers + WebCrypto for local proof verification
  Apache Arrow snapshots for large graph/table loads
  MessagePack/Protobuf for live patch streams

Backend:
  Node.js + TypeScript
  Fastify HTTP API
  uWebSockets.js or ws streaming gateway
  NATS JetStream event bus
  PostgreSQL for metadata, saved dashboards, layout configs, auth
  Arborist SQLite shards as provenance source of truth
  ClickHouse for high-volume audit/telemetry/time-series analytics
  S3/R2/MinIO for graph snapshots, proof packs, activation traces
  Redis for ephemeral cache, cursor state, presence, and rate limits
```

### Why this stack

Cosmograph is the preferred large-graph layer because its documentation states that it uses GPU parallel processing for force-directed layouts over hundreds of thousands or millions of nodes, with `cosmos.gl` as the GPU-accelerated force graph engine. ([Cosmograph][2]) React Three Fiber is the correct 3D layer because it is a React renderer for Three.js, letting scenes be built declaratively with reusable components that react to state. ([Poimandres Documentation][3]) React Flow is the correct run-DAG/pipeline layer because it is a customizable React component for node-based editors and interactive diagrams. ([React Flow][4])

The important implementation rule:

```text
Use the right renderer for each visualization.

Tables:
  TanStack Table / Virtual

Pipelines:
  React Flow

Massive graphs:
  Cosmograph / cosmos.gl

3D Merkle/circuit/temporal scenes:
  React Three Fiber / Three.js

Dashboard composition:
  custom layout grid + draggable/resizable panels
```

Do not force every visualization into 3D. Do not force every visualization into a graph.

---

## 4. Dashboard style: Tableau-inspired but proof-native

The dashboard should be configurable like a BI tool:

```text
drag panels
resize panels
dock/undock views
save dashboard layouts
apply global filters
bind widgets to selected objects
stream live updates
scrub time
switch between table / graph / DAG / 3D / map-like layouts
export proof packs
```

But unlike Tableau, every displayed metric must trace back to Merkle/audit state.

### Dashboard primitives

```text
Data source:
  Arborist shard
  proof pack
  audit stream
  activation trace file
  peer mesh snapshot

Dimension:
  root type
  claim status
  warrant level
  verifier policy
  model profile
  audit actor
  time window
  source root
  peer ID
  layer/head/feature ID

Measure:
  claim count
  failed count
  stale count
  proof verification rate
  falsifier acceptance rate
  cache invalidation count
  latency
  state drift
  audit-chain breaks
  activation magnitude
  attribution weight

Filter:
  time
  root
  claim family
  status
  warrant
  source
  peer
  model
  verifier policy
  circuit ID

Action:
  verify proof
  replay run
  diff roots
  quarantine claim
  open graveyard
  animate proof path
  inspect circuit trace
```

### Dashboard interaction model

```text
Click a root:
  all widgets filter to that root.

Click a claim:
  evidence table, claim graph, run-DAG, audit timeline, and trace view update.

Click an audit event:
  root diff, state transition, and rollback panel update.

Click an activation feature:
  linked token spans, output spans, claims, and evidence panels update.

Click a falsifier:
  claim graveyard, impacted descendants, and proof replay update.
```

---

## 5. Ticket goals

### Goal 1 — Configurable dashboard builder

Users must be able to build dashboards on the fly:

```text
add widget
select data source
select dimensions/measures
select filters
save layout
share read-only layout
export dashboard config JSON
```

Example dashboard configs:

```text
Audit Operations View
Claim Graveyard View
Merkle Root Proof View
Run-DAG Debug View
ForkScore Upgrade View
Circuit-to-Claim Attribution View
Peer Mesh Consensus View
State Drift View
```

### Goal 2 — Merkle root and proof tracing

Users must be able to inspect:

```text
root hash
leaf hash
canonical bytes hash
left/right sibling path
computed root
expected root
proof verification result
domain separator
canonicalization version
chunking version
schema version
verifier policy hash
```

### Goal 3 — Audit trail and time playback

Users must be able to replay:

```text
audit event chain
claim admission
state transition
falsification event
cache invalidation
source drift
rollback
fork upgrade
```

### Goal 4 — 3D state geometry and temporal tracing

Users must be able to see selected subgraphs as:

```text
3D Merkle lattice
3D proof-path pulse
3D state-transition flow
3D circuit-to-claim path
3D root diff explosion
3D temporal replay
```

### Goal 5 — Interpretability/circuit/activation adapter

Users must be able to attach and inspect:

```text
model ID
model profile hash
prompt hash
token span
layer
module
head/neuron/feature ID
activation value
tensor hash
trace root
output span
linked claim IDs
causal status
intervention evidence
```

No activation trace should be labeled causal unless intervention evidence exists.

---

## 6. Dashboard widget catalog

### 6.1 Merkle Proof Widget

**Purpose:** verify one proof path.

Fields:

```text
root_hash
leaf_index
leaf_hash
canonical_bytes_hash
proof_path
sibling_hashes
left_right_flags
computed_root
expected_root
PASS / FAIL
```

Views:

```text
compact proof card
step-by-step proof ladder
3D proof pulse
copy proof JSON
```

### 6.2 Root Explorer Widget

**Purpose:** inspect a Merkle root.

Fields:

```text
root_hash
root_type
leaf_count
hash_algorithm
domain_separator
canonicalization_version
schema_version
chunking_version
verifier_policy_hash
created_at
status counts
```

Views:

```text
root summary
leaf histogram
tree preview
root diff launcher
audit linkage
```

### 6.3 Claim Warrant Widget

**Purpose:** inspect one claim’s warrant status.

Fields:

```text
claim_id
canonical_claim
evidence_ids
source_roots
warrant_level
falsification_state
verifier_policy_hash
parent_claims
child_claims
counterclaims
```

Warrant ladder:

```text
UNGROUNDED
POINTER_LINKED
ANCHOR_WARRANTED
EVIDENCE_WARRANTED
FORMALLY_PROVED
FAILED
STALE
QUARANTINED
SPECULATIVE
SELF_PROVENANCE_QUARANTINED
```

### 6.4 Claim Graph Widget

**Purpose:** show local claim/evidence/falsifier neighborhood.

Engine:

```text
React Flow for small graphs
Cosmograph for large graphs
```

Edges:

```text
supports
contradicts
depends_on
falsifies
derived_from
stale_due_to
quarantined_by
```

### 6.5 Run-DAG Widget

**Purpose:** replay one model/run pipeline.

Nodes:

```text
Question
Preflight
Retrieval
EvidenceMap
AnswerDraft
ClaimExtraction
Verifier
FalsifierSearch
CacheWrite
AuditAppend
StateAdmission
```

Use React Flow.

### 6.6 Audit Timeline Widget

**Purpose:** time playback of state changes.

Modes:

```text
linear event chain
branch/fork view
state transition cards
rollback checkpoints
```

### 6.7 Cache-Key Widget

**Purpose:** explain cache hit/miss.

Cache dimensions:

```text
source_root
question_hash
model_profile_hash
conversation_hash
governance_policy_hash
schema_version
canonicalization_version
chunking_version
verifier_policy_hash
```

Output:

```text
cache hit / miss
changed dimension
reason for invalidation
stale warning
policy mismatch
verifier mismatch
```

### 6.8 Root Diff Widget

**Purpose:** compare root A and root B.

Outputs:

```text
added leaves
removed leaves
changed claims
new falsifiers
stale claims
failed claims
cache invalidations
benchmark deltas
activation trace changes
```

### 6.9 Claim Graveyard Widget

**Purpose:** inspect negative memory.

Fields:

```text
failed_claim_hash
failure_class
falsifier_ids
defeating_evidence_ids
affected_descendants
created_at
reopen_conditions
appeal_status
```

Failure classes:

```text
false
stale
poisoned
unsupported
self_confirming
policy_blocked
benchmark_regression
canonicalization_failed
```

### 6.10 Circuit Trace Widget

**Purpose:** inspect activation/circuit evidence linked to claims.

Fields:

```text
trace_id
model_id
model_profile_hash
prompt_hash
token_span
layer
module
head_id
neuron_id
feature_id
activation_value
activation_rank
tensor_hash
trace_root
linked_claim_ids
causal_status
```

Causal labels:

```text
CORRELATIONAL_TRACE
ATTRIBUTION_ESTIMATE
INTERVENTION_SUPPORTED
ABLATION_SUPPORTED
CAUSALLY_UNDERDETERMINED
```

### 6.11 3D Merkle Lattice Widget

**Purpose:** animated 3D state/proof visualization.

Layers:

```text
source roots
leaves/chunks
claims
evidence maps
falsifiers/graveyard
audit events
benchmark/fork roots
activation/circuit traces
```

Animations:

```text
proof path pulse
root diff explosion
temporal audit playback
claim admission flow
falsifier propagation
activation-to-claim trace
```

### 6.12 Mesh / Peer Widget

**Purpose:** inspect distributed roots and peer divergence.

Fields:

```text
peer_id
peer_root
shared roots
divergent roots
challenge windows
validator status
replay status
trust score
```

---

## 7. Layout system

Use a configurable dashboard schema.

```ts
type DashboardConfig = {
  id: string;
  title: string;
  description?: string;
  version: "dashboard-v1";
  globalFilters: FilterSpec[];
  dataSources: DataSourceSpec[];
  layout: PanelLayout[];
  widgets: WidgetSpec[];
  interactions: InteractionSpec[];
};
```

Panel layout:

```ts
type PanelLayout = {
  panelId: string;
  x: number;
  y: number;
  w: number;
  h: number;
  minW?: number;
  minH?: number;
  dock?: "left" | "right" | "bottom" | "floating" | "main";
};
```

Widget spec:

```ts
type WidgetSpec = {
  widgetId: string;
  type:
    | "merkle-proof"
    | "root-explorer"
    | "claim-warrant"
    | "claim-graph"
    | "run-dag"
    | "audit-timeline"
    | "cache-key"
    | "root-diff"
    | "claim-graveyard"
    | "circuit-trace"
    | "merkle-lattice-3d"
    | "mesh-peer";

  title: string;
  dataSourceId: string;
  query: QuerySpec;
  view: ViewSpec;
  interactions?: InteractionSpec[];
};
```

This is the Tableau-like part: the user can configure widgets rather than being locked into static pages.

---

## 8. Data model

### 8.1 Unified object node

```ts
type VizNode = {
  id: string;
  kind:
    | "document_root"
    | "leaf"
    | "chunk"
    | "claim"
    | "evidence"
    | "falsifier"
    | "graveyard_entry"
    | "audit_event"
    | "cache_key"
    | "run"
    | "fork"
    | "benchmark"
    | "peer"
    | "activation"
    | "circuit"
    | "feature"
    | "intervention";

  hash?: string;
  label?: string;

  status:
    | "live"
    | "failed"
    | "stale"
    | "quarantined"
    | "speculative"
    | "underdetermined"
    | "self_provenance_quarantined"
    | "formally_proved";

  warrant?:
    | "UNGROUNDED"
    | "POINTER_LINKED"
    | "ANCHOR_WARRANTED"
    | "EVIDENCE_WARRANTED"
    | "FORMALLY_PROVED";

  time?: string;
  roots?: Record<string, string>;
  metrics?: Record<string, number>;
  metadata: Record<string, unknown>;
};
```

### 8.2 Unified object edge

```ts
type VizEdge = {
  id: string;
  source: string;
  target: string;
  kind:
    | "contains"
    | "supports"
    | "contradicts"
    | "depends_on"
    | "derived_from"
    | "falsifies"
    | "committed_in"
    | "verified_by"
    | "replayed_by"
    | "served_by_cache"
    | "invalidated_by"
    | "descends_from"
    | "activates"
    | "attributed_to"
    | "causally_affects"
    | "patched_by"
    | "ablated_by";

  weight?: number;
  confidence?: number;
  timestamp?: string;
  metadata?: Record<string, unknown>;
};
```

### 8.3 Graph patch

```ts
type GraphPatch = {
  seq: number;
  eventHash: string;
  rootHash?: string;
  timestamp: string;
  patches: Array<
    | ["node.upsert", string, Partial<VizNode>]
    | ["node.status", string, VizNode["status"]]
    | ["edge.upsert", string, Partial<VizEdge>]
    | ["edge.delete", string]
    | ["metric.update", string, string, number]
  >;
};
```

---

## 9. Real-time architecture

### Event bus

Use NATS JetStream.

Subjects:

```text
arborist.audit.appended
arborist.root.committed
arborist.claim.created
arborist.claim.status_changed
arborist.falsifier.accepted
arborist.graveyard.inserted
arborist.cache.invalidated
arborist.fork.scored
arborist.benchmark.completed
arborist.trace.created
arborist.activation.recorded
arborist.circuit.detected
arborist.intervention.completed
arborist.peer.root_seen
```

### Streaming model

```text
Initial load:
  Arrow snapshot / compressed JSON snapshot

Live updates:
  MessagePack or Protobuf graph patches

Failure handling:
  sequence gap → request replay
  replay unavailable → reload snapshot
  duplicate patch → idempotent no-op
  out-of-order patch → buffer until sequence resolves
```

### Browser channels

```text
/ws/dashboard/:dashboardId
/ws/audit/live
/ws/root/:rootHash
/ws/run/:runId
/ws/claim/:claimId
/ws/fork/:forkId
/ws/trace/:traceId
/ws/mesh/live
/ws/graph/:view
```

---

## 10. 3D rendering architecture

### Use 3D for selected state, not everything

3D should be used for:

```text
selected root
selected claim neighborhood
selected proof path
selected root diff
selected fork upgrade
selected activation-to-claim trace
selected audit time window
```

Do not attempt to put the entire global proof mesh into one 3D view.

### Implementation rules

```text
Use InstancedMesh for nodes.
Use packed attributes for node type, status, layer, selection, proof depth.
Use GPU color-picking for selection.
Use LOD clustering for large scenes.
Use requestAnimationFrame only for active animation.
Pause render loop when static if possible.
Run layout/calculation in Web Workers.
```

### 3D layers

```text
Layer 0:
  source roots

Layer 1:
  leaves / chunks

Layer 2:
  claims

Layer 3:
  evidence maps

Layer 4:
  falsifiers / graveyard

Layer 5:
  audit events

Layer 6:
  benchmark / fork roots

Layer 7:
  activation / circuit traces

Layer 8:
  peer/mesh roots
```

### Animation modes

```text
Proof pulse:
  leaf → sibling path → root

Claim admission:
  draft → evidence → verifier → live state

Falsifier propagation:
  falsifier → claim → descendants → graveyard

Root diff explosion:
  root A and root B split, changed nodes glow

Audit playback:
  events stream through time axis

Circuit attribution:
  activation feature → token span → output span → claim
```

---

## 11. Circuit and activation tracing layer

### Purpose

This layer links mechanistic/interp objects to epistemic objects.

```text
prompt/input
→ model activation trace
→ feature/circuit
→ output span
→ claim object
→ evidence/warrant
→ state admission decision
```

### Minimal activation trace schema

```ts
type ActivationTrace = {
  traceId: string;
  runId: string;
  modelId: string;
  modelProfileHash: string;
  promptHash: string;
  tokenSpan: [number, number];

  hookpoints: Array<{
    layer: number;
    module: "attention" | "mlp" | "residual" | "embedding" | "logits";
    headId?: number;
    neuronId?: number;
    featureId?: string;
    activationValue: number;
    activationRank?: number;
    tensorHash?: string;
  }>;

  outputSpan?: [number, number];
  linkedClaimIds: string[];
  traceRoot: string;

  causalStatus:
    | "CORRELATIONAL_TRACE"
    | "ATTRIBUTION_ESTIMATE"
    | "INTERVENTION_SUPPORTED"
    | "ABLATION_SUPPORTED"
    | "CAUSALLY_UNDERDETERMINED";
};
```

### Circuit trace schema

```ts
type CircuitTrace = {
  circuitId: string;
  modelId: string;
  traceIds: string[];

  nodes: Array<{
    id: string;
    layer: number;
    module: string;
    featureId?: string;
    activationSummary: number;
  }>;

  edges: Array<{
    source: string;
    target: string;
    attributionWeight: number;
    method:
      | "activation_patching"
      | "integrated_gradients"
      | "logit_lens"
      | "sae"
      | "manual";
  }>;

  causalStatus:
    | "correlational"
    | "intervention_supported"
    | "ablation_supported"
    | "underdetermined";

  linkedClaimIds: string[];
};
```

Hard UI rule:

```text
Never show “causal” unless intervention or ablation evidence exists.
```

---

## 12. Query layer

The dashboard needs a simple query grammar.

Example:

```json
{
  "select": ["claim_id", "status", "warrant", "source_root", "created_at"],
  "from": "claims",
  "where": {
    "status": ["live", "stale", "quarantined"],
    "verifier_policy_hash": "vp_abc",
    "created_at": { "gte": "2026-05-01" }
  },
  "join": ["evidence", "audit_events"],
  "limit": 1000
}
```

Graph query:

```json
{
  "graph": "claim_neighborhood",
  "root": "claim:abc",
  "depth": 2,
  "edgeKinds": ["supports", "contradicts", "falsifies"],
  "includeStatuses": ["live", "failed", "stale", "quarantined"]
}
```

Dashboard filters compile down to these queries.

---

## 13. API specification

### HTTP APIs

```text
GET /api/dashboards
POST /api/dashboards
GET /api/dashboards/:id
PUT /api/dashboards/:id

GET /api/root/:rootHash
GET /api/root/:rootHash/leaves
GET /api/proof/:rootHash/:leafIndex

GET /api/claim/:claimId
GET /api/claim/:claimId/neighborhood
GET /api/graveyard/:claimHash

GET /api/audit/:eventHash
GET /api/audit/chain/:eventHash

GET /api/run/:runId
GET /api/cache/:cacheKey
GET /api/fork/:forkId

GET /api/trace/:traceId
GET /api/circuit/:circuitId

GET /api/diff/:rootA/:rootB
GET /api/graph/snapshot
```

### WebSocket APIs

```text
WS /ws/dashboard/:dashboardId
WS /ws/audit/live
WS /ws/run/:runId
WS /ws/root/:rootHash
WS /ws/claim/:claimId
WS /ws/trace/:traceId
WS /ws/mesh/live
```

---

## 14. Security, privacy, and governance

### Default privacy rule

```text
Private leaves are not sent to public dashboards by default.
```

Expose:

```text
commitments
hashes
redacted evidence maps
selective disclosure objects
proof summaries
```

Do not expose:

```text
private raw chunks
sensitive prompt text
private model traces
confidential source documents
```

unless explicitly authorized.

### Required policy fields

Every dashboard must show or have access to:

```text
governance_policy_hash
verifier_policy_hash
schema_version
canonicalization_version
chunking_version
model_profile_hash
```

### Audit mode

In audit mode, failed/stale/quarantined objects remain visible.

```text
do not delete failure
do not hide stale state
do not suppress contradictions
```

This is essential for reproducibility.

---

## 15. Performance targets

### v1 targets

```text
10k graph objects:
  smooth interaction on modern laptop

100k graph objects:
  interactive with clustering and filtering

1M graph objects:
  supported through snapshot + massive graph engine + server-side clustering,
  not full 3D rendering

Proof verification:
  browser-side inclusion proof under 50 ms for ordinary proof paths

Streaming:
  dashboard patch latency under 250 ms on local/dev deployment
  under 1 s over ordinary remote deployment

Tables:
  virtualized 100k+ rows
```

### Rendering policy

```text
3D:
  selected neighborhoods and cinematic analysis

Cosmograph:
  large claim/source/falsifier/peer graphs

Tables:
  audit logs, claims, leaves, traces

React Flow:
  DAGs, pipelines, step-by-step proof flows
```

---

## 16. Test plan

### 16.1 Dashboard tests

```text
create dashboard
add widget
resize widget
save layout
reload layout
apply global filter
cross-filter by selecting claim/root/event
export config
import config
```

### 16.2 Merkle proof tests

```text
valid proof passes
wrong leaf fails
wrong sibling order fails
wrong domain separator fails
wrong canonical bytes fail
wrong root fails
```

### 16.3 Audit tests

```text
valid chain passes
missing previous hash fails
modified event body fails
out-of-order event detected
rollback root resolves
```

### 16.4 Streaming tests

```text
snapshot loads
patch sequence applies
sequence gap triggers replay
duplicate patch is idempotent
out-of-order patch buffers or rejects
snapshot reload restores consistency
```

### 16.5 3D tests

```text
proof path animates correctly
root diff highlights changed objects
claim admission flow matches audit events
animation stops when paused
large scenes use LOD/clustering
```

### 16.6 Circuit/interp tests

```text
trace attaches to run
trace root verifies
linked claim IDs resolve
correlational trace not mislabeled causal
intervention-supported trace requires intervention object
```

---

## 17. Implementation phases

### Phase 0 — dashboard schema and proof format

Deliver:

```text
DashboardConfig
WidgetSpec
VizNode
VizEdge
GraphPatch
ProofPath
AuditEvent
ActivationTrace
CircuitTrace
```

### Phase 1 — configurable dashboard shell

Deliver:

```text
drag/resizable panels
global filters
saved layouts
theme system
widget registry
static JSON data source
```

### Phase 2 — proof and root widgets

Deliver:

```text
Root Explorer
Leaf Proof Widget
browser-side proof verification
copy/export proof JSON
```

### Phase 3 — claim/audit/run widgets

Deliver:

```text
Claim Warrant Widget
Audit Timeline
Run-DAG Widget
Cache-Key Widget
Claim Graveyard Widget
```

### Phase 4 — real-time streaming

Deliver:

```text
NATS → gateway → WebSocket
snapshot + patch protocol
live audit stream
live claim status updates
dashboard cross-filtering with live data
```

### Phase 5 — 3D Merkle lattice

Deliver:

```text
React Three Fiber widget
InstancedMesh rendering
proof-path pulse
root diff explosion
temporal playback
```

### Phase 6 — massive graph widgets

Deliver:

```text
Cosmograph claim graph
source-to-claim graph
falsifier graph
peer mesh graph
server-side clustering
```

### Phase 7 — circuit/activation tracing

Deliver:

```text
Activation Trace Widget
Circuit Graph Widget
token-span to claim-span linkage
trace-root verification
causal status labels
intervention object support
```

### Phase 8 — embeddable widgets

Deliver:

```text
<arborist-proof-card>
<arborist-claim-card>
<arborist-root-viewer>
<arborist-run-dag>
<arborist-trace-viewer>
```

NPM package:

```text
@arborist/viz
```

---

## 18. Definition of done

Ticket #000069 is complete when:

```text
1. A user can create a custom dashboard from widgets.
2. A user can save, reload, export, and import dashboard layouts.
3. A user can inspect a root, leaf, claim, audit event, run, cache key, and graveyard entry.
4. A user can verify a Merkle proof locally in the browser.
5. A user can stream live audit/claim/falsifier events into the dashboard.
6. A user can replay a run-DAG.
7. A user can animate a selected proof path in 3D.
8. A user can diff two roots or fork states.
9. A user can inspect an activation/circuit trace linked to claims.
10. The UI never presents Merkle inclusion as semantic truth.
11. The UI never presents activation correlation as causal proof.
12. Private data remains commitment-first and reveal-on-demand.
```

(Scope-cut caveat from filing note F-2: if this ticket is reduced to
phases 0–3, items 5/7/9 above migrate to sibling tickets A / B / D
respectively and stay out of this ticket's DoD.)

---

## 19. Best-practice constraints

```text
1. Arborist/audit roots remain source of truth.
2. Dashboard projections are derived and reproducible.
3. All widgets expose their data query and source roots.
4. Every proof widget supports local verification.
5. Every claim widget shows warrant and falsification state.
6. Every trace widget shows causal-status label.
7. Every cache widget includes verifier_policy_hash.
8. Every 3D animation maps to real audit/graph data.
9. Failed/stale/quarantined objects are visible in audit mode.
10. Raw private content is not sent to the browser unless authorized.
```

---

## 20. Final regenerated ticket summary

```text
Ticket #000069:

Build Arborist VIZ, a Tableau-inspired, Palantir-style configurable browser
dashboard for Merkle-AGI auditability.

It should support drag-and-drop dashboard composition, live streaming updates,
Merkle proof verification, root/claim/audit/run visualization, 3D proof and
temporal state animations, claim graveyard inspection, circuit/activation trace
linkage, and scalable graph exploration.

The system must be proof-first, real-time capable, lightweight in browser mode,
scalable through snapshots + patch streams, and safe by design:
Merkle proof is integrity, not truth;
activation trace is correlation unless intervention-backed;
private data is commitment-first.
```

Final one-line product definition:

```text
A configurable proof-native dashboard for seeing what an AI system is allowed
to believe, why, from what evidence, under which verifier policy, through which
Merkle root, over which audit trail, and with which optional circuit traces.
```

[1]: https://github.com/andrewjiang/palantir-for-family-trips "GitHub - andrewjiang/palantir-for-family-trips: A Palantir-ish dashboard for family trip planning."
[2]: https://cosmograph.app/docs-general/concept/?utm_source=chatgpt.com "The Concept of Cosmograph"
[3]: https://r3f.docs.pmnd.rs/?utm_source=chatgpt.com "React Three Fiber: Introduction"
[4]: https://reactflow.dev/?utm_source=chatgpt.com "React Flow: Node-Based UIs in React"
