Owns: RRABBIT/m2/, RRABBIT/test/, RRABBIT/docs/ Must not touch: anything outside RRABBIT/. Root *.md belongs to lane F; the site to lane E.
## ⚠️ CHECK FOR A COLLISION BEFORE YOU START
m2/was being actively worked by another session on 2026-08-15 (tracks, reel, replay). Rungit -C RRABBIT log --oneline -3andgit -C RRABBIT status --short. - Newest commit is `a4ea112` and the tree is clean → the lane is free. - Anything newer, or modified files inm2/→ another session is live. Stop and ask Travis. Two agents inm2/is not a merge conflict, it is one overwriting the other.
RRABBIT/docs/TRACKS_HANDOFF.md — the authoritative rung table. Written by the session that
built tracks/reel/replay.
RRABBIT/docs/RUNBOOK.md — the port map and the probes that settle arguments.
PUBLISH_PATH.md §0a — what was built on 2026-08-15 and what deliberately was not.
RRABBIT/m2/publish.js and m2/trackstore.js — both pure, both tested, neither wired in.
DRIVE, TRACK and REPLAY are `live_local`. Three rungs stand.
`publish.js` seals a track into a content-addressed bundle. *The address is the hash of the
bundle and the guard is inside the bundle*, so a tampered track fails either on id mismatch or on a derived-vs-stated comparison. 33 tests.
`trackstore.js` puts and fetches bundles, and never trusts the store — every read
re-derives the hash. Two adapters (memoryAdapter, httpAdapter), logic in neither. 34 tests.
The machine-A-publishes / machine-B-refuses demo exists as a test (test/trackstore.mjs §5).
Whole suite: 507 tests, 0 failures, eight files.
There is no publish verb, no button, nothing in the UI. The reel (gear R) is where a track is managed, so it is where "publish this one" belongs. Seal → show the id → offer the bytes.
Design constraint: the shell must keep working with no network. Publishing is an action a user takes, never something that happens on a timer or on save.
ops.replaycheck() answers may this run here. Handing the steps to the seam is the remaining piece, and it is small on purpose — ops.replay is already a for loop over apply, deliberately not a second code path. Do not add a second one here. A fetched track's steps go through the same apply every local replay uses, or the §9 claim in OP_VOCABULARY_DRAFT.md is false.
Order is fixed: store.get (verifies) → check (roads, before anything moves) → ops.replay.
Measured 2026-08-15: tracks.js permits ~212.9 MB (999 tracks × REC_MAX 4096), the real localStorage quota is 5,187,584 bytes (4.95 MB) — a 43× gap, so only ~23 full tracks fit. save() wraps setItem in try {} catch {}, right for private-browsing mode and wrong for `QuotaExceededError`, which it swallows too. The shell keeps running, stops persisting, and loses the drive on the next reload with nothing said.
workspaces.js and layout.js have the same bare-catch pattern — check them too.
Direction (not a ruling): probe once at load with a tiny key to tell private-mode from quota; surface the quota case via #status, which already un-hides itself when written; and consider whether the caps should be bounded by the real store rather than by numbers 43× above it.
4.95 MB is one Chrome. The guest runs a Firefox kiosk, which was never measured. Measure it before hard-coding a threshold.
node test/publish.mjs && node test/trackstore.mjs && node test/ops.mjs green, plus the rest of
test/.
A track published from the reel and replayed on a second profile or machine — and a refusal
demonstrated when a road is missing. The refusal is the interesting half.
Quota exhaustion produces a visible message, proven by filling it rather than by reading code.
`REC_MAX`/`MAX` do not protect you — they are 43× larger than the store.
Measure the EFFECT before the INPUT. A control that "does not respond" cost four rounds when
#transport { display: flex } from an id selector beat [hidden]. It was told to hide 55 times.
A stopped instrument reads as a measurement. A frozen counter looked like evidence about
handlers. Put a heartbeat on anything you intend to trust.
The dev host may not run the 3D shell — other sessions hold the WebGL context pool. The
FreeBSD guest is the test environment; the deploy loop is in TRACKS_HANDOFF.md §1.
`agent-browser click` takes a selector, not coordinates. click 1120 737 matches nothing,
exits 0, and dispatches no event. A coordinate click is mouse move → mouse down → mouse up, and you should arm a capture listener to prove the event arrived.
studbook §10.5 — the `track-` prefix. It is provisional. Anything published before the ruling
may need re-sealing under a different id. Wire it; do not publish anything you would miss.
Whether the reel is the right home for publish, or whether it wants its own scene.