The repo is a small local runtime wrapped in a much larger product-memory system.
The runtime is real and shipped at v0.2.0; the brain is useful as history and intent,
but several of its status surfaces are now behind the code. For current truth, read the source and
tests first, then use the brain to recover why the choices were made.
Living brainstatic HTML · 13 agent commands · SessionStart + Stop hooks
+
Refine surfaceSand · Hands · Sling injected into any served HTML page
=
One artifactthe file on disk remains authoritative throughout
AI writing loop · Sandtoolbar → POST /turn → server snapshots → claude -p --resume → Claude's file tools edit disk → fs.watch → page-scoped SSE reload. Model stdout supplies status, streamed prose and edit cards; it never becomes the document.
Direct writing loop · Handsleaf data-cid contenteditable / sibling drag / delete → /write or /dom → lexical splice in edit.js → disk. No model call; one pre-edit snapshot powers direct undo.
| State | What the code actually supports |
| shipped | File/folder serving; toolbar injection; resumed on-page Claude conversation; streamed text/thinking/cost/edit cards; click scope; AI undo; text/move/delete direct edits + direct undo; Sling; brain scaffold/install/upgrade/rebuild/doctor/open; detached-link resolver; canvas; CI and tag-triggered npm release. |
| partial | waiting exists only as a reserved UI state; durable anchoring is still a prompt contract; direct manipulation is pointer-first; doctor checks structure but not publish privacy or source-package correctness. |
| not built | Screenshot paste, one-click refine presets, branch-and-compare, threaded annotations, a long-lived model process, Next/React-project editing, keyboard/touch reorder-delete, and stats. |
| verified now | npm test, shipped-script syntax checks, verify-publish (33 files · 222 KB), doctor, a fresh scaffold/install smoke test, and live HTTP checks for injection, SSE idle, and traversal rejection all passed. No live billable Claude turn was run. |
The brain is not current state today
Before this roadmap extension the plan derived to 39/45 tasks done (87%); it now also tracks the stabilization and provider releases. The cover still says Phase 1 is 50%, 3 open questions and 13 decisions; the ledgers contain 4 and 19. It still calls undo open and drag/delete “next,” although both ship. All 13 pages also carry data-pkg="sandpaper" while package.json is @nynb/sandpaper, so the resolver falsely treats a whole-repo serve as detached; doctor misses that mismatch. The live board this one demotes also says CI cannot publish, even though v0.2.0 did.
Trustworthy boundariesLoopback bind, lexical + symlink traversal guards, explicit .git denial, constrained Claude tool types, XSS-safe model Markdown, server-owned undo mapping, synchronous direct edits, and a package-content/secret envelope in CI.
Watch before extendingThe local server serves every non-.git file under its root — including dotfiles — and mutation routes have no Origin/auth check. The single-turn guard has a request-body race. A 409 turn rejection is dropped by the toolbar and can leave “Sending…” stuck. Current tests are pure/unit-level: no HTTP, watcher, multi-window, browser/a11y, setup, hook, or live-model coverage.
Small verified UI defects: .sp-del styles both deleted diff rows and the Hands delete button; brain search adds .hidden to timeline rows but CSS hides only .entry.hidden; and Pick can be enabled while Hands remains active. These are local fixes. The architectural choices to preserve are the disk invariant, the plumbing/intelligence split, and data-cid as the cross-layer address.
1Read firstREADME.md for the shipped product; then bin/cli.js → src/server.js → src/claude.js; then public/toolbar.js + src/edit.js; finally src/setup.js and the agent commands.
2Treat as historicalsandpaper.html and engg-spec.html are valuable P0 design records, not accurate build sheets. The wiki mirrors much of that snapshot.
3Highest-leverage follow-upRun a real brain sync: refresh digest/counts/map/wiki, resolve undo/Hands drift, mark screenshot honestly, refresh all source meta, and add tests around the HTTP/concurrency boundary before widening the feature set.