arborist-viz/arborist_viz/routes.py
russell@unturf.com 60e8640d86
sessions: list / tree / FTS5 search views via arborist.read.SessionsView
Mounts the sessions shard (~/.arborist/sessions.db by default) as a
read-only data source alongside the corpus shards. Imports stay
behind the arborist.read seam — viz never touches the schema directly.

Wire:
- storage.py: get_sessions(path) — process-cached SessionsView,
  parallel structure to get_shards(paths). close_all() now closes
  both caches.
- __init__.py: ARBORIST_VIZ_SESSIONS_DB env (or arborist.sessions_db
  ini) → request.sessions request property. Defaults to
  ~/.arborist/sessions.db.
- routes.py: /sessions (list), /sessions/{sid} (tree),
  /sessions/find (FTS5 search) + matching /api/sessions/... JSON.
- views/sessions.py: HTML + JSON handlers.
- templates/sessions_{list,tree,find}.jinja2: minimal views — table
  for list, recursive tree macro for tree, table for find results.
- static/css/viz.css: cmd-table / cmd-tree / cmd-audit-* styles.

Endpoint summary:
  /sessions                   list every session
  /sessions/{sid}             one session's tree (synthetic root
                              collapsed, cross-session children show
                              [from <sid>] tag)
  /sessions/find?q=...&limit= FTS5 across all sessions
  /api/sessions                       JSON list
  /api/sessions/{sid}                 JSON tree
  /api/sessions/find?q=...            JSON search

Audit_mode is rendered as a colored chip (strict/hybrid/ungrounded/
canonical_projection); cited titles surface as inline pills. Privacy
contract from base.jinja2 inherits unchanged — sessions shard is
local-private per ticket #000069 §14.
2026-06-01 17:41:24 -04:00

72 lines
3.2 KiB
Python

"""Route declarations — ticket §13 (with WS→SSE translation per §3-corrected)."""
def includeme(config):
# static + meta
config.add_static_view("static", "static", cache_max_age=3600)
config.add_route("favicon", "/favicon.ico")
config.add_route("robots", "/robots.txt")
config.add_route("version", "/version")
config.add_route("home", "/")
config.add_route("dashboard_page", "/dashboard/{dashboard_id}")
config.add_route("proof_page", "/proof/{root_hash}")
config.add_route("audit_page", "/audit/{event_hash}")
# dashboards (saved layout metadata)
config.add_route("api_dashboards", "/api/dashboards")
config.add_route("api_dashboard", "/api/dashboards/{dashboard_id}")
# roots
config.add_route("api_roots", "/api/roots")
config.add_route("api_root", "/api/root/{root_hash}")
config.add_route("api_root_leaves", "/api/root/{root_hash}/leaves")
config.add_route("api_lattice", "/api/lattice/{root_hash}")
# hash resolver — drop-a-hash dispatcher
config.add_route("api_resolve", "/api/resolve/{hex_hash}")
# proofs
config.add_route("api_proof", "/api/proof/{root_hash}/{leaf_index}")
# claims + graveyard
config.add_route("api_claim", "/api/claim/{claim_id}")
config.add_route("api_claim_neighborhood", "/api/claim/{claim_id}/neighborhood")
config.add_route("api_graveyard_entry", "/api/graveyard/{claim_hash}")
# audit
config.add_route("api_audit_recent", "/api/audit/recent")
config.add_route("api_audit_by_root", "/api/audit/by-root/{root_hash}")
config.add_route("api_audit_event", "/api/audit/{event_hash}")
config.add_route("api_audit_chain", "/api/audit/chain/{event_hash}")
# run / cache / fork
config.add_route("api_run", "/api/run/{run_id}")
config.add_route("api_cache", "/api/cache/{cache_key}")
config.add_route("api_fork", "/api/fork/{fork_id}")
# traces (gated on arborist #000062 producing MechanisticWitnessRoot;
# Phase 0 returns 501 Not Implemented).
config.add_route("api_trace", "/api/trace/{trace_id}")
config.add_route("api_circuit", "/api/circuit/{circuit_id}")
# diff + snapshot
config.add_route("api_diff", "/api/diff/{root_a}/{root_b}")
config.add_route("api_graph_snapshot", "/api/graph/snapshot")
# sessions — Merkle conversation forest (single-shard, per-user
# journal at ~/.arborist/sessions.db). Read-only consumer of
# arborist.read.SessionsView.
config.add_route("sessions_list", "/sessions")
config.add_route("sessions_find", "/sessions/find")
config.add_route("sessions_tree", "/sessions/{sid}")
config.add_route("api_sessions_list", "/api/sessions")
config.add_route("api_sessions_find", "/api/sessions/find")
config.add_route("api_sessions_tree", "/api/sessions/{sid}")
# SSE — §3-corrected replaces WS routes with text/event-stream.
config.add_route("sse_audit_live", "/sse/audit/live")
config.add_route("sse_run", "/sse/run/{run_id}")
config.add_route("sse_root", "/sse/root/{root_hash}")
config.add_route("sse_claim", "/sse/claim/{claim_id}")
config.add_route("sse_dashboard", "/sse/dashboard/{dashboard_id}")
config.add_route("sse_mesh_live", "/sse/mesh/live")