Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01K6897PWcUEwHiqZMcVnNF6
2.7 KiB
2.7 KiB
Handoff notes
For whoever picks this up: what is solid, what is held together with care, and what a refactor should and should not do. Read ARCHITECTURE.md first.
Where the seams are
index.htmlis ~1,900 lines in one script. It grew feature by feature in one long session. The sections are commented and ordered sensibly, but state is one globalstateobject and functions reach into each other freely.- brain.js overrides page functions by assignment (
djPrompt = …,openStation = …,makeJob = …,react = …) so it can be loaded after the page. A refactor should turn these into explicit hooks. - Playback has three overlapping mechanisms layered over time: the ordinary
playJob/advancepath, the synchronousendedswap (swapNow) for locked screens, and the crackle hold withpendingJob. They work together (the harness proves the paths) but they should be one small state machine:idle → cooking → holding → playing → ended. - The crackle exists twice: as the side element (room tone) and as the player's own source (the hold). That is deliberate (iOS needs the hold in the same element) but easy to misread.
db.all()is used in many places wheredb.getor a filtered index would do; it loads every blob.- Several things are computed from the sheet in more than one place (section-at-time, mmss, kind chips).
Known rough edges
- iOS volume sliders are inert (platform); the welcome/ident may fall back to Venice if Runware times out on a spoken-tag render (now avoided: spoken breaks are TTS).
- The mashup reference uses OfflineAudioContext; untested headlessly.
- The quota is per-person-per-day only; KV free tier caps total writes at ~1,000/day.
- Share links made before the render seed was included re-roll the song.
KEEP_UNKEPT = 40unkept tracks roll off; nothing warns.- Light theme: a few hard-coded colours may remain in rarely-seen sheets.
What a refactor should keep
- Every invariant in ARCHITECTURE.md › Playback invariants, and the harness green before and after.
- The sheet as the unit (everything derives from
spec), covers as a pure function of it. - One static page, no build step, no framework, no keys in the page.
- STORAGE.md's contract (chai's DB adapter targets it).
What's next (agreed directions, not started)
- Text embeddings for every sheet, audio embeddings (Gemini Embedding 2) for kept/reacted tracks; the taste map
laid out in embedding space; segment-level vectors with the timed reactions (
spec.hits). - Free tier = shared allowance on the worker (the key box is parked); pro = longer tracks, XL renders, sync.
- Room-tone picker (vinyl / rain / tape / brown / drone in key).
- Butterchurn (Milkdrop) as a fourth look.
- Taste file export/import.