11# tallyman-notebooks
22
33Spike for the Tallyman London 2026 talk * "The Future of Notebooks in a Claude Code World"* .
4- The plan and proposal live in ` plan.md ` / ` proposal.md ` . This README covers the V0 spike only.
4+ The proposal lives in ` proposal.md ` . This README covers the V0 spike only.
55For the system architecture — subsystem map, on-disk layout, data-flow paths, and an
66index of all the docs — start with [ docs/architecture.md] ( docs/architecture.md ) .
77
88## V0 scope
99
1010End-to-end: a Claude Code MCP tool that compiles a xorq expression, materializes
11- a parquet to a content-hashed catalog entry on disk, and pushes a live update
11+ a result to a content-hashed catalog entry on disk, and pushes a live update
1212to a browser companion via SSE.
1313
1414What's working:
1515
16- - ** MCP tools: **
16+ - ** MCP tools** (FastMCP over stdio):
1717 - Catalog: ` catalog_run ` , ` catalog_load_parquet ` , ` catalog_create ` ,
1818 ` catalog_revise ` , ` catalog_alias ` , ` catalog_rename ` , ` catalog_unalias ` ,
19- ` catalog_list ` , ` catalog_diff ` .
19+ ` catalog_list ` , ` catalog_diff ` , ` catalog_chart ` , ` catalog_recalc ` , plus the
20+ summary-stat / post-processing / display-klass authoring tools.
2021 - Notebook: ` notebook_reorder ` , ` notebook_remove ` , ` notebook_edit_markdown ` .
21- - ** Companion** (FastAPI on ` :7860 ` ):
22- - ` /catalog ` , ` /catalog/<hash> ` or ` /catalog/<alias> ` — entry list and detail
23- with V_n chips, forensic history, and a link to internal lineage.
24- - ` /notebook ` — curated narrative: cells anchored on aliases, vertical layout,
25- inline markdown editor, ↑/↓ reorder, × remove.
26- - ` /lineage ` and ` /lineage/<hash> ` — catalog DAG (cross-entry parents derived
27- from ` tracked_expr_from_alias ` ) and per-entry internal expression DAG. Pure SVG, no
28- Cytoscape dep.
29- - ` /diff/<alias>[/<va>/<vb>] ` — version diff with code diff, schema diff,
30- per-column stats, key-joined side-by-side, and head() side-by-side.
31- - ` /errors/<id> ` — build-failure detail.
32- - ` /api/{entries,aliases,errors,notebook,lineage,catalog_dag} ` — JSON.
33- - ` /api/sse ` — live updates (` new_entry ` , ` build_failed ` , ` alias_changed ` ,
34- ` notebook_changed ` ).
22+ - Project: ` project_list ` , ` project_new ` , ` project_switch ` .
23+
24+ See [ docs/architecture.md] ( docs/architecture.md ) for the full tool surface.
25+ - ** Companion** (FastAPI on ` :7860 ` ) — serves the React SPA
26+ (` packages/app/dist ` ) as a catch-all and exposes a JSON API + SSE under
27+ ` /{project}/api/* ` :
28+ - SPA tabs: ** Catalog** (entry list + detail with V_n chips and forensic
29+ history), ** Notebook** (curated narrative anchored on aliases, drag-reorder,
30+ inline markdown editor, × remove), ** Diff** (code diff, schema diff,
31+ per-column stats, key-joined side-by-side, head() side-by-side), ** Cache**
32+ (per-entry cache footprint), and ** Log** (linear, filterable activity view).
33+ - JSON: `/{project}/api/{entries,entry/<hash >,aliases,notebook,errors,log,
34+ data/<hash >,diff_data/...,disk_usage,result_cache,staleness}`, plus the
35+ mutation routes (` PATCH notebook ` , ` PUT code/<alias> ` ,
36+ ` PUT markdown/<cell_id> ` , ` POST reset ` , ` POST recalc ` ,
37+ ` POST promote_diff/... ` ).
38+ - ` /{project}/api/sse ` — live updates (` new_entry ` , ` build_failed ` ,
39+ ` alias_changed ` , ` notebook_changed ` , ` recalc ` , ` summary_stat_changed ` ).
40+ - ` /internal/notify ` — the MCP server's notification hook; fans out to SSE.
3541- ** Buckaroo subprocess** — ` tallyman run ` spawns ` python -m buckaroo.server `
3642 on ` :8700 ` (falls back to a random port if busy), watches for the
3743 ` BUCKAROO_PORT=... ` handshake, and lazily creates per-entry sessions on
3844 first view by POSTing the entry's ` xorq_build/ ` dir to Buckaroo's
3945 ` /load_expr ` endpoint (PR 776) — sort/search push down to the xorq
40- backend rather than paging over a materialised parquet. The build dir
41- is expanded into a tmp copy first so ` ${TALLYMAN_PROJECT_ROOT} `
42- placeholders are resolved before xorq's loader sees them. Sessions are
43- persisted under ` catalog/buckaroo_sessions.json ` and invalidated by
44- start-time when Buckaroo restarts; tmp dirs are cleaned on
45- ` BuckarooManager.stop() ` . Tear-down rides along with the companion .
46- Disable with ` --no-buckaroo ` .
46+ backend rather than paging over a materialised parquet. The build dir is
47+ expanded into a stable per-entry path ( ` .xorq_build_expanded/ ` , gated by a
48+ ` .complete ` marker) so ` ${TALLYMAN_PROJECT_ROOT} ` placeholders are resolved
49+ before xorq's loader sees them. Sessions are persisted in a global
50+ ` ~/.tallyman-notebooks/buckaroo_sessions.json ` (keyed by content hash, shared
51+ across projects) and invalidated by start-time when Buckaroo restarts .
52+ Tear-down rides along with the companion. Disable with ` --no-buckaroo ` .
4753- ** Build artifacts are portable.** xorq's absolute filesystem paths are
4854 rewritten to ` ${TALLYMAN_PROJECT_ROOT} ` on write and expanded back on load.
4955- ** ` tallyman serve <project_dir> ` ** — read-only companion against a project
5056 directory that may live anywhere on disk. Mutation routes return 403.
5157
52- What's NOT yet implemented (see ` TICKETS.md ` for the full punchlist) :
58+ What's NOT yet implemented:
5359
54- 1 . SortableJS drag-reorder for the notebook (current ↑/↓ buttons are the
55- accessibility fallback; drag is the headline UX).
56- 2 . Column-level lineage (xorq has the data; current view is op-level only).
57- 3 . ` tallyman pack ` / ` tallyman replay ` (today's hand-off is ` cp -r ` / ` tar ` ).
58- 4 . ML training pipeline (storyboard beats 7-8).
60+ 1 . Column-level lineage (xorq has the data; there is no lineage view today).
61+ 2 . ML training pipeline (storyboard beats 7-8).
5962
6063## Running the spike
6164
65+ Build the React companion UI once. The FastAPI server serves its ` dist/ ` ; Node +
66+ pnpm are install-time prerequisites and the build artifact is not committed:
67+
6268``` sh
63- uv sync
64- uv run tallyman init spike # creates ~/.tallyman/projects/spike/ + fixture
65- uv run tallyman run --project spike # edit-mode companion on http://127.0.0.1:7860
69+ cd packages/app && pnpm install && pnpm build # writes packages/app/dist/
6670```
6771
68- The companion's dataframe embed is a Vite React library in ` packages/embed/ `
69- that builds into ` src/tallyman_companion/static/buckaroo-embed.{js,css} ` . The
70- build artifact is ** not** committed — Node + pnpm are install-time
71- prerequisites:
72+ Then start the stack:
7273
7374``` sh
74- cd packages/embed && pnpm install && pnpm build # one-time per checkout
75- # or, for active embed development:
76- cd packages/embed && pnpm dev # vite build --watch
75+ uv sync
76+ uv run tallyman init spike # creates ~/.tallyman-notebooks/projects/spike/ + fixture
77+ uv run tallyman run --project spike # edit-mode companion on http://127.0.0.1:7860
7778```
7879
79- Bump ` buckaroo-js-core ` in ` packages/embed/package.json ` to match the
80- Python ` buckaroo ` pin in ` pyproject.toml ` and rebuild whenever either
81- side moves.
82-
8380In another terminal, launch Claude Code from this directory; it picks up
8481` .mcp.json ` and exposes the ` tallyman ` MCP server.
8582
@@ -98,10 +95,10 @@ forensic history.
9895
9996### Serving a project as an artifact
10097
101- Once you've authored a project, hand it off:
98+ Once you've authored a project, pack it and hand it off:
10299
103100``` sh
104- tar czf my-project.tgz -C ~ /.tallyman/projects spike
101+ uv run tallyman pack spike -o my-project.tgz # portable .tgz, ${TALLYMAN_PROJECT_ROOT} preserved
105102# colleague extracts somewhere
106103tar xzf my-project.tgz -C ~ /projects/
107104uv run tallyman serve ~ /projects/spike
@@ -129,6 +126,6 @@ affordances. Mutation routes return 403.
129126## Tests
130127
131128``` sh
132- uv run pytest # 76 tests, ~5s
133- uv run pytest tests/test_portable .py # the portability proof
129+ uv run pytest # full suite
130+ uv run pytest tests/test_pack .py # the pack / portability proof
134131```
0 commit comments