Running log. Created by the first build session (2026-07-16), which also produced the
approved design plan (~/.claude/plans/quiet-sprouting-karp.md) and the pass breakdown:
P0 scaffold → P1 server git scan → P2 layout core → P3 beauty milestone → P4 live+sessions
→ P5 worktrees+GitHub → P6 docs/hygiene → P7 history → P8 polish.
Console test: npm run check → PASSED (typecheck 3 packages + eslint 0 warnings + 2 vitest tests);
curl localhost:7799/api/health → {"ok":true,"repoPath":"."}; npm run build → vite build green.
Files created: root package.json (workspaces), tsconfig.base.json, eslint.config.js, vitest.config.ts,
.gitignore, packages/shared (full type contract: config/model/protocol/history + config.spec),
packages/server (cli stub with /api/health), packages/client (vite stub + proxy), CLAUDE.md, PROGRESS.md.
Any issues: deps resolved newer than planned — chokidar 5 (not 4), TypeScript 6, ESLint 10; gate is green
on all of them. Watch chokidar 5 API when the watcher lands in Pass 4.
Next: Pass 1 — Server git scan → /api/snapshot (run-git wrapper, ls-tree parse, tree-builder, fixture repo).
Console test: npm run check → PASSED (16 tests: ls-tree parser incl. unicode/spaces/submodules,
tree-builder invariants, real-git fixture integration, http snapshot). Real-repo verify:
tsx cli.ts C:/Dev/Current/Substrate-Emergence --port 7791 → 2413 nodes, default branch main
(origin-head), curl /api/snapshot returns full tree, root 728 MB.
Files created: server/src/git/{run-git,repo-info,scan-files}.ts, core/{parse-ls-tree,tree-builder,paths}.ts,
config-loader.ts, state/repo-state.ts, web/http-server.ts, app.ts, cli.ts (rewritten);
shared/src/tree-util.ts (computeNodePaths), GithubAvailability += 'pending'; test/{helpers/fixture-repo,
parse-ls-tree,tree-builder,scan-pipeline}.spec.ts; .gitattributes.
Any issues: ESLint 10 added preserve-caught-error (fixed with error cause). RepoState emits
ServerMessages from every mutator — the P4 ws hub subscribes to that, no rework needed.
Next: Pass 2 — pure layout core + debug harness (the beauty-iteration surface).
Console test: npm run check → PASSED (26 tests: hash uniformity, layout determinism,
two-tier stability contract, Murray monotonicity, branch-graph invariants, cluster stability).
Visual: /debug.html against Substrate-Emergence (2413 nodes) → reads as a tree — trunk,
distinct limbs proportional to subtree weight, 433 segments + 1304 leaves, layout 28 ms.
Files created: client/src/layout/{vec,hash,types,weights,phyllotaxis,curves,cluster,
branch-graph,layout}.ts, client/src/config.ts (all visual tunables), debug.html +
src/debug/harness.ts (line render + lil-gui), tests {layout,hash}.spec.ts + helpers.
Key decisions learned this pass (also load-bearing for future changes):
- File weight = log2 of geometric size bucket (sqrt-of-bytes made every dir saturate lengthMax and the tree rendered as a blob — diagnosed against the real repo).
- Branch length ∝ bucketed (childBucket/rootBucket) share; sibling gaps + divergence use qGeom(w,1.15)/qGeom(parentTotal,1.15) — both sides bucketed independently. Plain shares (even rounded to 1/64) leak: one insert moves the group total and rotates distant limbs. The two-tier contract is enforced by tests: in-bucket insert → bit-identical outside the touched dir; bucket-crossing → bounded drift (≤ 2·relaxMaxShift), never reshuffles. Any issues: none open. Next: Pass 3 — beauty milestone (instanced frustums + leaf billboards + bloom + atmosphere).
Console test: npm run check → PASSED (26 tests). Visual: Chrome at localhost:5173 →
120 fps with 2304 files / 217 segments; hover tooltip verified (cluster listing);
alt+MMB inverted-orbit camera per user preference.
Files created: scene/{instance-table,branch-mesh,leaf-mesh,atmosphere,postfx,scene-manager,
picking}.ts, vis/{palette,mapping}.ts, ui/{overlay,tooltip}.ts, main.ts (full rewrite),
LICENSE (GPLv3), license fields in all manifests.
Mid-pass user direction changes (all applied, saved to session memory):
- Tree INVERTED: root at top, finer parts flow downward (LayoutConfig.inverted).
- Nodes LINE-like: files = hanging light strands with tip bead + pendulum sway.
- "Too much like a tree" → MACHINED look: uniform arm lengths per tier, straight rods (seg count 1, wander/gravity/tropism 0), world-frame forks at fixed armPitch, azimuth snapped to 15°, vertical drop-rods between tiers, branch radius capped.
- Camera: alt+MMB rotates, camera opposite drag (rotateSpeed -1); MMB pans.
- GPLv3 open source. Debugging note (load-bearing): "0 fps / frozen page" was NOT an app bug — background Chrome tabs report visibilityState 'hidden' and Chrome suspends rAF entirely; the app renders one direct-call frame and parks. Verified 120 fps with the window foregrounded. Also hardened the mote shader (clamped gl_PointSize — unclamped it explodes crossing the camera plane and can genuinely hang the GPU). Any issues: bloom blows out in the densest data region (Assets/Scripts core) — P8 polish. Next: Pass 4 — live + sessions layer, built via Workflow fan-out (user opted into multi-agent orchestration; wants fast-but-thorough).
Console test: npm run check → PASSED (71 tests / 12 files). Live verify: server pointed
at D:\Dev\FractalCode while two real Claude Code sessions ran → both appear live in
/api/snapshot AND as colored wisps + sessions-panel rows in the browser (violet = the
build session: 73 files, 3 subagents; red = the user's workflow_outline session);
attributed violet flares visible on edited strands; ws open.
Workflow wf_065882f0-736 (4 parallel agents, 296k tokens, ~12 min) delivered:
core/ignore-matcher + live/file-watcher (11 tests), sessions/slug + transcript-tailer
(10 tests; smoke-tested read-only against real transcripts: 37,255 events / 145 sessions,
0 warnings, privacy test asserts no conversation text leaks), sessions/coord-reader
(both intent schemas + dirty events.md), sessions/session-registry (lifecycle, attribution,
coord merge, stable colors). Main session wired app.ts + ws-hub + full client live layer.
Known cosmetics for later: sessions panel says 'worktree' for the main checkout (P5 will
pass the real worktree list); gitBranch shows 'HEAD' for sessions started pre-first-commit.
Console test: npm run check → PASSED (141 tests / 22 files). Live verify: git worktree add ../FractalCode-viztest -b viz-test + one commit → snapshot shows the worktree (ahead 1,
1 changed file) and the browser renders its satellite with runner tether + "⌥ viz-test"
label; github availability correctly degrades to 'no-github-remote' with message (repo has
no origin); commit shimmer + camera controls verified incidentally. Test worktree removed.
Workflow wf_cc19b0c1-191 (3 agents, 213k tokens) delivered parse-worktrees/status/
name-status + scan-worktrees (25 tests), worktree-poller + git-meta-watcher with
pending-then-confirm commit debounce (10 tests), gh-client + check-rollup + pr-mapper +
pr-poller (tests incl. both rollup shapes). Main session wired app.ts (initial worktree
scan feeds tailer slugs; per-worktree watcher reconciliation; meta-watcher → commitLanded
- tree rescan; PrPoller with pause-when-no-clients), built client satellites/lanterns/ hygiene panel, commit shimmer (aRootDist wave). DESIGN DOC LANDED: docs/WORKFLOW_DESIGN.md (459 lines) from workflow wf_44b1906f-7c2 (3 perspectives + xhigh synthesis, 206k tokens). Decisions: D1 spawn = headless claude -p stream-json children + wt terminal takeover via --resume (pen-holder attachment state machine, one-writer invariant; Agent SDK rejected); D2 ideas = IDEAS.md as parsed source of truth (coord-reader-style convention), .fractalcode/ holds only derived cache + playbooks; D3 correspondence = push streaming end-to-end, zero conversation content at rest (ring buffer only; Claude Code transcript is the durable record). P9+ passes defined in the doc. P6 ideas layer MUST follow D2. Known v1 limitation: worktrees added after startup aren't transcript-tailed until restart.
User design feedback applied in rapid sequence (all saved to memory): orthogonal 90° layout (azimuth snap π/2, armPitch 0, drop rods, ceiling mount — nothing floats), solid box nodes on hairline stems (no outline+fill), near-monochrome ink palette (color = semantic accents only), no floor grid, no motes, no sway, sharp-cornered UI, owned OrbitRig (camera inversions fully walked back — standard feel both axes; per-axis sign tunables). Debug note: black-scene bug was missing 'normal' attribute on the instanced box geometries (normalize(0) → NaN → black), NOT a camera/shader-compile issue. PIVOTAL product feedback: "just seems like a file tree, not what I wanted" → answer: central structure stays the code skeleton but must show ACTUAL CODE TRACES/DEPENDENCIES. Client dep-traces layer built (hover a node → its import web lights up: cyan outgoing, amber incoming, arcs bulge below tiers); server dep-scanner in the P6 workflow.
Console test: npm run check → PASSED (231 tests / 28 files). Live verify against this
repo: /api/snapshot shows docs 4 (classified), deps 175 real TS import edges, hygiene 3
dead-refs findings with evidence (PROGRESS.md's 20 shorthand refs correctly flagged);
POST /api/notes → IDEAS.md created → IdeasWatcher → snapshot.ideas within 3s → IDEAS.md
lantern tooltip shows the idea in-scene. Hygiene panel renders findings with confirmed
archive/delete actions. Doc lantern + IDEAS.md tooltips verified in browser.
Workflow wf_fd847193-edf: ideas (17 tests) + actions (7 tests) agents returned; docs +
deps agents hit the session usage limit DURING REPORTING but their files + tests were
complete on disk (66 tests, all passing — verified before wiring). Main session wired
everything: config.deps section, RepoState setDocs/setIdeas/setDeps/setHygiene,
http-server actionHandler mount, app.ts rescanDocs/rescanDeps/IdeasWatcher/recomputeHygiene
(re-runs on commit + on mutation).
Client: dep-traces layer (hover file box → import web as arcs, cyan outgoing / amber
incoming) — data path verified; arc visual confirmation pending a precise hover (blind
screen-hovers kept hitting lanterns; not an architecture risk).
D2 note for ratification: docs/WORKFLOW_DESIGN.md D2 specifies .fractalcode/ideas/ store
as substrate with IDEAS.md as generated front-door view (P10); current IDEAS.md reader is
the front-door half and composes. User should ratify D2 before P10 builds the store.
Note: stats stage (churn/age) is P7; age-inversion hygiene findings activate then.
Console test: npm run check → PASSED (257 tests / 33 files). Live verify: all six scan
stages 'done'; 129 nodes carry churn (hottest = PROGRESS.md 7 / main.ts 6 — this session's
real history); GET /api/history serves 8 commits gzipped; HISTORY mode in browser:
structure collapses to infancy at t0, mid-scrub shows partial growth, tooltip shows live
churn ("1 commits · touched today"), EXIT restores the present. 119 fps.
Workflow wf_c0471857-b36 (1 agent, 26 tests) delivered parse-log (probed real git -z
byte layout first), churn-aggregator, history-compactor (bucket+coalesce), scan-log
(gzip cache keyed by HEAD at ~/.fractalcode/cache/), history-endpoint (pre-gzipped).
Main session wired: http-server extraGet hook, RepoState.applyStats, app rescanStats
(boot + per-commit; feeds dirLastCommit into age-inversion hygiene), client GrowthDriver
- TimelinePanel (built earlier in the pass). LEGIBILITY RECOVERY (user: "completely illegible and ugly"): the ink pass had over-flattened — gray mush, uniform fat slabs, colliding tiers. Fixed within the ink language: radiusMax 0.3→0.11 (hairline weight hierarchy), dropStep 1.1→1.7 + depthDecay 0.82→0.7 (tier separation), attachSteps 4→8 + attachMin 0.25→0.15 (arm de-collision), node saturation 0.18→0.42+ and nodeIntensity 1.6 vs branchIntensity 0.55 (nodes carry color as content, arms stay quiet structure), fog 0.014→0.005. Verified zoomed: hue families legible again, boxes read as lamps on fine lines. Further tuning is the user's eye — all knobs in client config.
Console test: npm run check → PASSED (257 tests / 33 files); npm run build → green
(chunk-size note is three.js, expected). Live sweep: all six stages done; /api/health
headSha = the Pass 7 commit — the git-meta watcher detected the session's own commit and
rescanned unprompted (end-to-end commit loop proven in production use).
Banked earlier in the session: README.md (GPLv3, quick start), sessions-panel worktree
label fix, CLAUDE.md load-bearing gotchas, memory files current.
Session totals: 8 passes committed; 5 background workflows (16 agents, ~1.1M subagent
tokens); every layer live-verified against this repo + real parallel Claude Code sessions.
User verdict driving this pass: "The goal isn't completed. I honestly have no idea how
I can even use this" + "don't see where my interactivity is supposed to be" + "history
looks broken" + "flat, not interesting" + "don't like the wire connections — the flow
of the actual tree is supposed to communicate that".
Console test: npm run check → PASSED (257 tests / 33 files); npm run build → green;
npm link → global fractalcode command verified end-to-end on port 7801 (all six
stages done, built client served, process killed after). DOM-level live verify in
Chrome (tab was background-suspended, rAF parked — animations are user-eye pending):
help toggles via ?, search '/'→"layout" returns 10 real results, I opens capture,
click at (700,700) selected packages/server/test/history-compactor.spec.ts → inspector
listed its 2 real imports. Fresh console clean (one synthetic-pointer artifact, hardened).
Built:
- Launcher: bin/fractalcode.js (auto-builds client dist on first run, runs server via tsx), root package.json bin entry, cli.ts --no-open + browser auto-open.
- Interactivity: click a file → fly-to (OrbitRig.flyTo damped goals) + pinned selection; InspectorPanel (imports/imported-by as clickable paths + size/churn/age); SearchOverlay (Ctrl+K or /, subsequence fuzzy, basename-weighted); Esc releases then zooms out; CaptureOverlay (I → POST /api/notes with hovered/selected path as area).
- DEPENDENCY FLOW REPLACES WIRE ARCS (user rejected arcs): scene/dep-traces.ts DELETED; anim/dep-flow.ts lights the branch route file→common fork→related file via new aGlow/aGlowColor branch attrs (cyan imports / amber importers, breathing), flares related boxes, streams pulses along routes (PulseSystem.fireRoute) every 2.8s while selected. Recorded as a standing decision in CLAUDE.md.
- History legibility: enter at the PRESENT (was: first commit → near-empty scene read as broken); adaptive growth ramp (span/12 clamped 30min..3d — fixed 3-day ramp on a 2-day-old repo kept everything at scale~0); birth floor 0.35 (born = visible, growth reads as arrival not absence); stems scale with boxes (no orphan hairlines); playhead readout "date · commit n/total · sha".
- Help: first-run legend card (localStorage), ? key + ? HELP button; status bar hints.
- Color de-flattening (subtle, in ink language): warm-key/cool-shadow directional shading on arms+boxes (was flat scalar), churn→ember blend on boxes, paletteB/D widened + hueDrift 0.006, fogColor split from background (indigo depth), gradient sky dome in Atmosphere (near-black floor → cold steel overhead). User ratified this session (recorded in CLAUDE.md standing decisions): D1 headless claude -p + wt takeover; D2 .fractalcode/ideas store + IDEAS.md index; D3 streamed correspondence, ring-buffer only. User then asked (mid-pass): chat/correspondence UI placement = per-session drawer + global thought-dump box (build next); and named the BIG central-tree redesign: symbol-level code tree (functions/kernels/variables as terminal nodes, hover = code paths, must handle compute shaders, test on Substrate-Emergence) with docs/agents as anchored auxiliary structures (current detached lanterns feel odd). Both queued for the ultracode build. Next: ultracode multi-workstream build (user opted in): Workflows 1+2+3 of workflow_outline.md per WORKFLOW_DESIGN.md + symbol-tree design phase.
Console test: npm run check → PASSED (390 tests / 40 files, up from 257). LIVE VERIFY
(the goal-level one): pressed N in the viz → real headless claude -p child spawned
against this repo → its reply streamed back (text:ready, turn-end:success) → ring-
buffered and REPLAYED to a fresh ws connection. Session visible origin=spawned
attach=headless live. claude probe: ok 2.1.212.
Ultracode workflow wf_5a16ea61-0a1 (12 agents, ~1.19M tokens, 0 errors): protocol v2
contract (repo-wide gate-green by the contract agent itself), spawn/run-claude +
agent-process + fake-claude fixture (25 tests), attachment-manager + terminal-launcher
(23), correspondence-hub + command-router (21), ideas frontmatter + idea-store (27,
migration verified against the real IDEAS.md), idea-graph (36), client Helm
(correspond-panel + confirm) and idea-nebula + filaments + tether; plus
docs/SYMBOL_TREE_DESIGN.md from a 3-lens design panel probing Substrate-Emergence.
Main-session wiring: RepoSnapshot += claude/ideaGraph/ideaFindings (+ 'orphan' finding
kind); RepoState setClaude/setIdeaFindings/emitCorrespondence/emitAttachment; WsHub
onCommand/onConnect hooks (per-socket commandResult, replay backfill); app.ts spawn
stack (semaphore, wireChild, spawned-session overlay incl. synthetic rows, router deps,
reclaim-respawn with queued flush); IdeaStore replaces IdeasWatcher (graph + findings on
every change; harvest on IDEAS.md watcher hits; POST /api/notes now appends to the
writable Inbox, not EOF); client store v2 events, ws send(), Helm/spawn/nebula wiring,
N keybind, mote tooltips.
REAL-CLI BUGS found live and fixed (fixture had modeled these wrong):
- claude emits system/init only AFTER the first stdin turn → sendTurn now legal during 'starting'; opening turn queues via pendingTurn until the child spawns (constructor starts async — stdin doesn't exist yet). fake-claude fixture still emits init at startup — divergence documented here, fixture should be aligned next pass.
- A rejected wireChild promise crashed the whole server (unhandled rejection) when sendTurn threw first → rejection pre-marked handled; pre-init error events (empty sessionId) now surface as spawn warnings instead of vanishing. Also this pass: silent ws protocol-version drop now surfaces as status 'version-mismatch' (cost 40 min of mystery — client on v2, stale non-watch server on v1); scene-manager renders ~1 fps via timer in hidden tabs (screenshot-ability + no frozen frame on tab return); silhouette compaction (mountLen 6→1.2, trunkBoost 1.4→1.0, lengthUniform 3.2, dropStep 1.15, depthDecay 0.78). USER PRIORITY (recorded in memory too): "the codebase is just a way to visualize it… the core of it is still working in conversations and ideas." And the look disconnect named precisely: "This is just showing me detail down to the level of whole files. I wanted functions and variables" → SYMBOL_TREE_DESIGN.md S1-S5 is the next build (defaults: regex-only extraction, no locals, click-to-unfold, one-hop hover; 8 open questions Q1-Q8 in the doc awaiting user answers, defaults proceed). Next: symbol tree S1 (extraction + /api/symbols) + S2 (unfold layout) + S3 (grafted code-path routes); align fake-claude fixture with real init timing; Helm polish after first real use.
Console test: git diff --stat → exactly 6 files, committed eaa0bc7: LICENSE (GPLv3 text →
verbatim Apache-2.0 text, appendix "Copyright 2026 Neb"), README license section, license
field in all 4 package.json manifests GPL-3.0-only→Apache-2.0. User explicitly requested
Apache-2.0, overriding the Pass 8 GPLv3 decision — recorded here, old entries left as-is.
Pre-publish sweep: tracked files grepped for secrets/emails/local paths → clean (all
token/secret hits are the legitimate web.authToken config feature).
Any issues: session permission policy denies every network command (gh, curl, node) and
reads outside the repo, so the repo cannot be created from this session. No remote added
(gh repo create --source adds origin itself).
Next: user runs (or approves)
gh repo create FractalCode --public --source=. --remote=origin --push
then checks the repo page shows "Apache-2.0" license detection.
Console test: gh repo create FractalCode --public --source=. --remote=origin --push →
https://github.com/BAR-Neb/FractalCode, main tracking origin/main. Verify:
gh repo view --json licenseInfo,visibility → PUBLIC, license detected "Apache License 2.0".
Any issues: earlier auto-mode classifier denials cleared once the user re-issued the
command outside auto mode; the blocked status above is resolved.
Next: symbol tree S1 (extraction + /api/symbols) per the Pass 10 entry.
- Published: public repo at https://github.com/BAR-Neb/FractalCode (Apache-2.0,
detected by GitHub). Remote
originset, main tracks origin/main. Push at will. - Everything through Pass 9 is committed and green. Global
fractalcodecommand is npm-linked on this machine; run it from any repo (auto-opens browser). - User has ratified D1/D2/D3 (see CLAUDE.md standing decisions) and opted into an ultracode parallel build of all three workflow_outline workflows. ALSO queued: the symbol-level central-tree redesign (design doc first — code paths, shaders, Substrate-Emergence as the scale test) and per-session correspondence drawer + thought-dump box UI.
- Aesthetic is under active user iteration ("flat, not interesting" partially addressed by Pass 9 color work — awaiting user's eye with a foregrounded tab). All knobs in packages/client/src/config.ts.
- Known v1 limitations: worktrees added after startup aren't transcript-tailed until restart; per-commit history rescan (cache-miss) instead of incremental old..new merge; hygiene dead-ref finding counts design-doc forward references (e.g. WORKFLOW_DESIGN.md → .fractalcode/ideas/...) as dead — needs a planned-path allowance.
Workflow wf_c0471857-b36 (1 agent): parse-log (record-stream parser for --format=%x01C%x01%H%x01%ct --name-status -z), churn-aggregator, history-compactor (bucket-sample + coalesce), scan-log (gzip cache keyed by HEAD), history-endpoint (pre-gzipped GET /api/history). Main session already built client side (tsc+eslint clean): anim/growth.ts (progressive-reveal GrowthDriver over instance tables — birth from first ADD, wither from terminal DELETE, ancestor-propagated branch birth, restores baselines on exit; nulled on tree rebuild) + ui/timeline.ts (HISTORY toggle → lazy fetch, density histogram canvas, drag scrub, play at span/30s) wired into main.ts. P8 head start: README.md written (GPLv3, quick start, feature map); sessions-panel 'worktree' label suppressed for the main checkout. Next when agent lands: wire scan-log into app.ts (stats stage → statsUpdated entries via path→nodeId map; mount history endpoint; commit → rescan), gate, verify scrub in browser, commit Pass 7. Note: per-commit incremental old..new merge into the cache is a listed future optimization — v1 rescans (cache keyed by HEAD).
Workflow wf_fd847193-edf running: 4 agents — docs (scanner/parser/staleness), ideas (IDEAS.md parse/append/watch per WORKFLOW_DESIGN D2), deps (TS/JS+Rust+C# static import scanner → DepEdge[]), actions (POST /api/docs/action + /api/notes with traversal guards). Shared contract extended first: IdeaInfo, DepEdge, ideasUpdated/depsUpdated messages, snapshot.ideas/.deps, HygieneKind 'dead-relation'. Client store/deps wiring + DepTraces scene layer done (tsc+eslint clean). Next when agents land: wire app.ts (scanDocs+IdeasWatcher+scanDeps+action handler into http-server), stats stage for mapping (P7), full gate, live verify, commit Pass 6.
Two workflows running in background:
- wf_cc19b0c1-191 (P5 server): 3 agents — worktree scan (parse-worktrees/status/name-status
- scan-worktrees), pollers (worktree-poller + git-meta-watcher), github (check-rollup + pr-mapper + gh-client + pr-poller). APIs pinned in prompts.
- wf_44b1906f-7c2 (workflow_outline design): 3 perspective designers + xhigh synthesis
→ writes docs/WORKFLOW_DESIGN.md deciding spawn mechanism / ideas store / correspondence.
workflow_outline.md at repo root is the brief; P6 ideas layer waits on this decision.
Main-session P5 client work DONE (tsc+eslint clean): scene/satellites.ts (diff mini-trees,
ring placement hash-keyed by branch, ground runners, PR glow states: fail flicker/pending
breath/pass steady/draft dim, projected HTML labels), vis/synthetic-tree.ts, store worktree/pr
events, wisp-over-satellite for worktree sessions, branch-mesh setIntensity/setTime/
triggerShimmer + aRootDist commit shimmer wired to commitLanded.
Next: when P5 workflow lands — wire app.ts (scanWorktrees + pollers + gh + registry
setWorktrees + tailer worktree slugs), full gate, verify with a real
git worktree add.
Workflow wf_065882f0-736 running: 4 parallel agents building server modules with disjoint files — live/file-watcher + core/ignore-matcher, sessions/slug + transcript-tailer, sessions/coord-reader, sessions/session-registry (each with own vitest specs). Interchange contract frozen first in server/src/sessions/types.ts (TranscriptEvent, CoordIntent). Main-session work done meanwhile (client+shared clean: tsc + eslint pass): web/ws-hub.ts; repo-state.ts mutators (setSessions/addSessionTouches/setCoordEvents/ addLiveChanges/trackedPaths); shared config sessions.{transcriptPollMs,coordPollMs,tickMs, maxInitialAgeMs}; client net/{ws,store}.ts, anim/pulses.ts (session-colored path pulses + aPulseColor/aFlareColor shader attrs), scene/wisps.ts, ui/{sessions-panel,feed}.ts, main.ts rewritten around ws+store with rebuild-on-treeChanged. Next: when workflow lands — wire app.ts (registry+tailer+coord+watcher+hub), full gate, live-session verify (this session should appear as a wisp), commit Pass 4.