Lace Jukebox

Jukebox is a shared music app built from portable Lace records. A room is the user-facing shared queue; Jukebox is the corresponding schema key. Rooms, media, immutable queue edits, playlists, and song requests can converge between participating Laces. The Node CLI and browser use the same JavaScript records, views, policies, and actions.

A waypoint is an admission and convergence point. It is not room authority and has no app mutation commands.

The base frontend entry is //u//jukebox//index.html; the packaged HTTP compatibility host serves //u//jukebox/http//index.html.

Authority boundaries

A hosting statement addresses a waypoint steward but is marked by the room steward. Hosting is active only while that room steward has active registration at the waypoint and the statement exact-links the unique room descriptor.

Registration, hosting, and capability state are keyed by their documented subject. Greatest TAI is current. Two distinct records at greatest TAI conflict and produce no current state; a later statement resolves the conflict. Active: false revokes, and a later true grants again.

A room’s Jukebox value is a portable domain key, not record identity. Two distinct valid room descriptors with one key are an unresolved conflict; neither is listed or projected, and hosting cannot choose a winner.

Queue and playback

Queue edits are immutable operations reduced in ascending TAI, then ascending record hash. Append adds at the tail, Prepend at the head, Move moves the first matching track to the tail, and Remove removes its first occurrence.

The only durable shared playback action is Skip. An actor with skip capability names the queue head it observed. The reducer removes that track only while it remains the head, so concurrent duplicate Skips remove it once. Play, pause, restart, media position, and seek remain local browser state. Queue reordering is CLI-only.

An active player keeps one open exact-room sync session to its current waypoint and advances when the reduced queue head changes. Jukebox has no polling, retry, fallback, multi-waypoint fan-out, or shared clock.

Media, requests, and exposure

Search metadata is separate from byte manifests so metadata search does not fetch media chunks. Blob chunks converge only through selected byte-backed library items. Votes do not exist; users can save playlists and create portable song requests, resolvers may link a library item, and only the requester may accept a resolution.

Local storage intentionally retains checked Jukebox record families more broadly than the validated room view. Storage does not grant capability. The waypoint may likewise retain a registered actor’s records even when room authority keeps them out of the projection.

Public read mode exposes selected records to peer-origin rules. Registered read mode additionally requires transport PeerConfidential(peer_key) proof and current waypoint registration. Jukebox records therefore contain public or registered-audience data, not secrets. Revocation, conflict, or view exclusion does not retract bytes already copied.

Packaged host

Build and run the browser and ILTP waypoint together in one Deno process:

npm --prefix incubator/jukebox run host

The host listens on port 8847 by default, stores records under .lace-data/jukebox/host, and serves the browser from the HTTP URL it prints. Pass host options after --, for example -- --listen ws:0.0.0.0:9000/interlace.

CLI usage

The CLI opens one filesystem Lace and one mode-0600 By-secret credential:

npm --prefix incubator/jukebox run cli -- --store /tmp/jukebox setup
npm --prefix incubator/jukebox run cli -- --store /tmp/jukebox \
  sync --waypoint ws:127.0.0.1:8847/interlace --steward V.EXAMPLE.H3
npm --prefix incubator/jukebox run cli -- --store /tmp/jukebox request list
npm --prefix incubator/jukebox run cli -- --store /tmp/jukebox \
  steward registrations

Run npm --prefix incubator/jukebox run cli -- help for room, capability, hosting, library, queue, playlist, request, and waypoint commands.

The browser prefers OPFS, then falls back to localStorage or temporary memory when durable browser storage is unavailable. It prominently reports either fallback; localStorage may be too small for large media. It uses one current waypoint address and steward. Bootstrap provides the default; an invite or explicit sync setting may replace it. Replacing a waypoint closes the current room session first.

Validation

npm --prefix incubator/jukebox run check
npm --prefix incubator/jukebox test
cargo run -q -p lace-cli -- check \
  incubator/jukebox/waypoint-steward-policy.datalog \
  incubator/jukebox/policy.interlang
git diff --check -- incubator/jukebox