Libretto
Sessions
29 numbered sessions · 73 rows scheduled · 7 unnumbered H3 epics
H1 — the personal app
Exact session numbers. Ends when Dylan reads a whole book with Libretto and reaches for it again.
15 sessions · 53 items · session 1 next
-
Session 0
finished M + L + L + M + M + M + S + S- M4 Jev (TypeSafe AI) research + the two-mode decision M
Cut point: Report saved under docs/research; two-mode rule in ARCHITECTURE; JevTagger row in the plan.
- M5 Strategy research: soundtrack generators, arrangement, artists, competition, hardware, licensing L
Cut point: Brief saved with verified/refuted claims; decisions written into the plan rows below.
- M6 Roadmap site (this) — inventory, derivation, brief, session plan, paper theme L
Cut point: `npm run gate` green; both views render; every session card carries MODEL/EFFORT/ULTRACODE/ULTRA-REVIEW tags and a cut point.
- M7 Management dashboard at /admin (books & licences, stems, competition, research) M
Cut point: Four data-driven admin pages behind nginx basic auth.
- M8 libretto.tinkr.es live: Cloudflare A record, nginx block, certbot, deploy script with neighbour check M
Cut point: `curl -sI https://libretto.tinkr.es` = 200 from outside; /admin/ = 401 without password; neighbours unchanged.
- M9 /start and /end wired to the plan (digest script, brief-first briefing, inventory step, Sonnet cleanup agent) M
Cut point: `bash .claude/scripts/start-check.sh` prints "Session 1 next" in one call; /end moves rows + regenerates + redeploys.
- M10 Context hygiene: CLAUDE.md ≤ 6 KB, GOTCHAS.md, one-line memory index, ROADMAP.md as history S
Cut point: Before/after byte counts in BUILD_LOG; nothing lost (grep-able).
- M11 Standing rule: every question through the AskUserQuestion tool S
Cut point: One line in the global CLAUDE.md + a feedback memory.
- M4 Jev (TypeSafe AI) research + the two-mode decision M
-
Session 1
next up S + S + M + S- PL5 git-LFS decision + configuration (or audio masters kept out of the repo, documented) S
Cut point: A 300 MB WAV drop cannot produce a bad commit; the rule is in CLAUDE.md.
- PL6 OGG-in-app decision + one OGG seamless loop proven on SoLoud S
Cut point: Decision written (WAV master / OGG shipped or WAV only) with the APK-size numbers behind it.
- SN9 make_seamless_loop.py: downbeat-snap pre-pass (allin1) + concat mode for multi-take beds M
Cut point: 2-3 short takes stitch into one 60-120 s bed with loop points on downbeats; tests on synthetic takes.
- PL7 Fork drop check: upstream flutter_inappwebview_android + file_picker on AGP 9 S
Cut point: Either a fork is dropped, or FORK.md records why not and the next check date.
- PL5 git-LFS decision + configuration (or audio masters kept out of the repo, documented) S
-
Session 2
L + S + S- ST1 Generator shoot-out: Stable Audio 3 Small (local), Stable Audio 2.5 API, Eleven Music v2, ACE-Step — 7 roles each L
Cut point: Families ai_sa3 / ai_sa25 / ai_11m / ai_ace in stems.json, loop-prepped, selectable from the debug screen.
Waiting on:
SN9· make_seamless_loop.py: downbeat-snap pre-pass (allin1) + concat mode for multi-take beds - ST2 Key-adherence + cost report per generator (D minor held? USD per bed, minutes per bed) S
Cut point: docs/research/GENERATORS-<date>.md with a table; spend ≤ 30 USD.
- SN10 APK v5 with the four AI families S
Cut point: Release APK built and handed to Dylan.
- ST1 Generator shoot-out: Stable Audio 3 Small (local), Stable Audio 2.5 API, Eleven Music v2, ACE-Step — 7 roles each L
-
Session 3
M + M + S + M- SN11 CC0 family: Dylan's Freesound picks per role, loop-prepped, provenance in stems.json M
Cut point: 7 CC0 beds with Freesound ids + licence recorded.
Waiting on:
SN9· make_seamless_loop.py: downbeat-snap pre-pass (allin1) + concat mode for multi-take beds - SN12 Source-family A/B verdict on the S25 (CC0 vs best AI family) M
Cut point: A family is chosen and the reason written to memory + BUILD_LOG.
Waiting on:
ST1· Generator shoot-out: Stable Audio 3 Small (local), Stable Audio 2.5 API, Eleven Music v2, ACE-Step — 7 roles each - SN13 Mood-at-right-beats verdict, round 2 (80-cue timeline on real beds) S
Cut point: Dylan confirms changes land at story beats and moods are distinct, or a named fix list exists.
- SN14 Phase 1 exit: 45-60 min sustained read without loop fatigue M
Cut point: Dylan reads 45-60 min on the S25 and the score never pulls him out; Phase 1 declared closed.
- SN11 CC0 family: Dylan's Freesound picks per role, loop-prepped, provenance in stems.json M
-
Session 4
L + S- G1 Camera-gaze smoke test: MediaPipe iris → regression → coarse gaze → throwaway CameraGazePositionSource feeding ScoreConductor L
Cut point: Gaze drives a cue change end-to-end on video, on the S25 or a laptop webcam.
- G2 Gaze accuracy log + go/no-go note for the device concept S
Cut point: Measured error (cm / lines) at reading distance written to docs/research.
- G1 Camera-gaze smoke test: MediaPipe iris → regression → coarse gaze → throwaway CameraGazePositionSource feeding ScoreConductor L
-
Session 5
M + S + S + S + S + S- R7 Reader CFI-spine → timeline-slug mapping (lights up the chapter-anchored lookup) M
Cut point: Conductor takes the chapter path on the real Frankenstein EPUB; verified against its CFIs on device in the next sitting.
- R8 Font-size change debounce S
Cut point: Rapid font taps no longer race the async reflow.
- R9 Reading-speed smoother on the position source S
Cut point: A fast page-flip does not jump the mix.
- R10 Default ambient bed for device-opened (unscored) books S
Cut point: Opening a personal EPUB plays a calm bed instead of silence.
- R11 Small cleanups: `.single` → `.firstOrNull` in open-from-device; Phase-2 debug app bar off the scored screen S
Cut point: Both gone; analyze + tests green.
- SN15 APK v6 (reader polish + chosen family as default) S
Cut point: Release APK built and handed to Dylan.
- R7 Reader CFI-spine → timeline-slug mapping (lights up the chapter-anchored lookup) M
-
Session 6
M + M + S- SC4 preprocessor/ Python subproject: EPUB parse → paragraphs with chapter + char offsets M
Cut point: Frankenstein parses into a paragraph table whose offsets match the reader's chapter geometry.
Waiting on:
SN14· Phase 1 exit: 45-60 min sustained read without loop fatigue - SC5 ModelTagger interface + ClaudeTagger (Opus 4.8 default, Batch API + prompt caching) M
Cut point: One chapter tagged {mood, intensity, tempo, confidence} per paragraph; cost logged.
Waiting on:
SN14· Phase 1 exit: 45-60 min sustained read without loop fatigue - SC6 Strict schema validation of the generated cue JSON S
Cut point: Generated output passes the same validator the app loads with.
- SC4 preprocessor/ Python subproject: EPUB parse → paragraphs with chapter + char offsets M
-
Session 7
M + M + S- SC7 Smoothing + merge of paragraph tags into per-scene cues M
Cut point: Auto cue count and boundaries are in the same order of magnitude as the hand 80-cue timeline; diff reviewed.
Waiting on:
SC5· ModelTagger interface + ClaudeTagger (Opus 4.8 default, Batch API + prompt caching) - SC8 Stem + transition assignment and full-timeline validator M
Cut point: A complete auto Frankenstein score-timeline.json loads in-app and drives the mixer on the emulator.
- ST3 ScoreArrangement design (horizontal re-sequencing on SoLoud 4.1 scheduled play + loop points) for artist tracks S
Cut point: ARCHITECTURE section written: segments (allin1/Demucs) → per-mood loops + transitions; what stays hand-authored.
- SC7 Smoothing + merge of paragraph tags into per-scene cues M
-
Session 8
M + L- O1 JevTagger: second ModelTagger over TypeSafe Jev (Choice on the mood enum, Score for intensity) M
Cut point: Tags a golden chapter through the Jev API with calibrated confidence per paragraph.
Waiting on:
SC5· ModelTagger interface + ClaudeTagger (Opus 4.8 default, Batch API + prompt caching) - SC10 Model taste-test: Opus 4.8 vs Haiku 4.5 vs Jev on golden chapters — agreement, calibration, cost, latency L
Cut point: Default tagger chosen and written into PREPROCESSOR.md; best auto timeline listened to on device.
Waiting on:
SC8· Stem + transition assignment and full-timeline validator
- O1 JevTagger: second ModelTagger over TypeSafe Jev (Choice on the mood enum, Score for intensity) M
-
Session 9
M + M + S- P1 Two more public-domain books (Gutendex) scored end-to-end M
Cut point: Two new timelines generated, validated, packaged as assets.
Waiting on:
SC8· Stem + transition assignment and full-timeline validator - P2 Library screen: pick a book, resume position M
Cut point: Three scored books selectable; position restored per book.
- C1 Admin Books table fed from the same book manifest the app ships S
Cut point: One manifest, two readers (app + /admin/books).
- P1 Two more public-domain books (Gutendex) scored end-to-end M
-
Session 10
S + S + S + S + S- P3 Master volume + mood-intensity control S
Cut point: Both persist and apply live.
- P4 Sleep timer (fade out, stop) S
Cut point: Timer fades the mix and stops the engine.
- P5 Crossfade + hysteresis tuning knobs (debug) with sane defaults S
Cut point: Defaults chosen from the S3 verdict; knobs hidden behind the debug toggle.
- P6 Persisted comfort settings + first-run defaults S
Cut point: Font, theme, volume survive a restart; first run opens on a sensible page.
- SN16 APK v7 (library + polish) S
Cut point: Release APK built and handed to Dylan and the test group.
- P3 Master volume + mood-intensity control S
-
Session 11
S + L- CA1 Friends & family test group installs APK v7 S
Cut point: At least 3 people reading with Libretto and reporting.
Waiting on:
SN16· APK v7 (library + polish) - CA2 Two books driven to "100% approved" by Dylan and the test group L
Cut point: Fix list → fixes → re-approval; both books signed off.
- CA1 Friends & family test group installs APK v7 S
-
Session 12
L- P7 H1 exit: Dylan reads a whole book with Libretto and reaches for it again L
Cut point: Verdict recorded in VISION/BUILD_LOG; H1 declared done.
Waiting on:
SN14· Phase 1 exit: 45-60 min sustained read without loop fatigue
- P7 H1 exit: Dylan reads a whole book with Libretto and reaches for it again L
-
Session 13
M + L + M + S- CA3 Industrial-design brief for the H3 reader (form, display, camera/IR placement, audio) M
Cut point: One-page brief approved by Dylan.
Waiting on:
G2· Gaze accuracy log + go/no-go note for the device concept - CA4 3D render / mockup of the device L
Cut point: Render set (front, side, in-hand) approved by Dylan.
- CA5 Marketing media: stills + a short video of the app and the render M
Cut point: Media folder ready for a campaign page and social posts.
- CA6 Landing section on libretto.tinkr.es (public-facing, not the roadmap) S
Cut point: A visitor understands the product in 20 seconds.
- CA3 Industrial-design brief for the H3 reader (form, display, camera/IR placement, audio) M
-
Session 14
M + M + S- CA7 Campaign page draft + reward tiers M
Cut point: Kickstarter draft with tiers, goal 2-8k USD for one commissioned stem pack.
Waiting on:
CA4· 3D render / mockup of the device - CA8 Artist letters: author-recommended artists shortlist + outreach template M
Cut point: Five names with a one-page pitch each; rights reality (sync + master) explained in the letter.
- CA9 Campaign goal + timeline decision S
Cut point: Goal, launch window (H2 beta) and fallback written down.
- CA7 Campaign page draft + reward tiers M
H2 — the public app
Provisional numbers. Store, accounts, online mode, payments, the first commissioned soundtrack.
10 sessions · 16 items · session 101 next
-
Session 101
next up L- PL8 Scripted-content sandbox for user-supplied EPUBs L
Cut point: A hostile EPUB fixture cannot run script; user books still render.
- PL8 Scripted-content sandbox for user-supplied EPUBs L
-
Session 102
L- PL9 iOS platform: flutter create --platforms ios, signing, TestFlight build L
Cut point: A TestFlight build installs on an iPhone; WAV/OGG loops verified on iOS.
- PL9 iOS platform: flutter create --platforms ios, signing, TestFlight build L
-
Session 103
L + L- O2 Scoring service: the preprocessor as an authenticated, rate-limited VPS endpoint with a job queue L
Cut point: An EPUB posted to the endpoint returns a validated timeline; abuse limits proven.
Waiting on:
SC8· Stem + transition assignment and full-timeline validator - O3 Online mode: "score as you read" chapter-ahead tagging with offline fallback + app mode switch L
Cut point: An unscored EPUB gets a score while reading; airplane mode still reads with the default bed.
Waiting on:
O2· Scoring service: the preprocessor as an authenticated, rate-limited VPS endpoint with a job queue
- O2 Scoring service: the preprocessor as an authenticated, rate-limited VPS endpoint with a job queue L
-
Session 104
L- PU1 Accounts + sync (positions, library) L
Cut point: Sign in on two devices; position and library follow.
- PU1 Accounts + sync (positions, library) L
-
Session 105
M + M- PU2 Catalog + scored packs (public-domain seed library, downloadable timelines) M
Cut point: Catalog lists ≥ 10 scored public-domain books.
Waiting on:
P2· Library screen: pick a book, resume position - C2 Catalog content model: licence, source, provenance, timeline version per title M
Cut point: Every catalog title carries a machine-checked licence + source; Gutendex import script.
- PU2 Catalog + scored packs (public-domain seed library, downloadable timelines) M
-
Session 106
L- PU3 Payments + "score your own books" subscription (Play Billing / App Store / Stripe web) L
Cut point: A test purchase unlocks scoring; refunds + cancellation paths proven.
Waiting on:
O3· Online mode: "score as you read" chapter-ahead tagging with offline fallback + app mode switch ·PU1· Accounts + sync (positions, library)
- PU3 Payments + "score your own books" subscription (Play Billing / App Store / Stripe web) L
-
Session 107
M + S + M- PU4 Onboarding flow M
Cut point: A stranger reaches a scored page within 60 s of install.
- PU5 Store assets (icon, screenshots, listing copy) S
Cut point: Assets approved by Dylan.
- PU6 Privacy policy, terms, support channel M
Cut point: Published pages; support inbox answered.
- PU4 Onboarding flow M
-
Session 108
L + M- ST4 Composer commission #1 (work-for-hire): 8-10 roles, 60-120 s evolving beds, 24-bit/48k WAV, key/tempo sheet, stingers L
Cut point: Pack delivered and accepted; contract signed (WFH, derivative-work right explicit); 5-20k USD band.
Waiting on:
SN14· Phase 1 exit: 45-60 min sustained read without loop fatigue - ST5 Arrangement of the commissioned pack through the ScoreArrangement pipeline M
Cut point: Pack becomes a stems.json family and drives a whole book.
Waiting on:
ST3· ScoreArrangement design (horizontal re-sequencing on SoLoud 4.1 scheduled play + loop points) for artist tracks
- ST4 Composer commission #1 (work-for-hire): 8-10 roles, 60-120 s evolving beds, 24-bit/48k WAV, key/tempo sheet, stingers L
-
Session 109
M + S- C3 Licensing partner scoping: PublishDrive / Ingram CoreSource / Draft2Digital — deal shape, revenue share, DRM obligations M
Cut point: A written comparison and one opened conversation.
- C4 Soundstripe app-embedding licence quote (the one stock catalog built for apps) S
Cut point: Quote in hand; go/no-go against a commission.
- C3 Licensing partner scoping: PublishDrive / Ingram CoreSource / Draft2Digital — deal shape, revenue share, DRM obligations M
-
Session 110
M- PU7 Public beta + launch checklist M
Cut point: Play internal test → open beta; checklist all green.
Waiting on:
PL8· Scripted-content sandbox for user-supplied EPUBs ·PU1· Accounts + sync (positions, library)
- PU7 Public beta + launch checklist M
H2.5 — camera gaze
Provisional numbers. Phone-camera gaze drives the score; the gate before hardware money.
4 sessions · 4 items · session 201 next
-
Session 201
next up L- G3 Gaze + page-estimate fusion, calibration flow, confidence gating L
Cut point: Fused position beats the page estimate alone on a 20-minute read; falls back cleanly in bad light.
Waiting on:
G1· Camera-gaze smoke test: MediaPipe iris → regression → coarse gaze → throwaway CameraGazePositionSource feeding ScoreConductor
- G3 Gaze + page-estimate fusion, calibration flow, confidence gating L
-
Session 202
M- G4 On-device reading-behaviour heuristics (skim / re-read / pause) → intensity nudges M
Cut point: Nudges are audible, subtle, and computed entirely on-device.
Waiting on:
G3· Gaze + page-estimate fusion, calibration flow, confidence gating
- G4 On-device reading-behaviour heuristics (skim / re-read / pause) → intensity nudges M
-
Session 203
M- G5 H2.5 verdict sitting: does gaze → score feel magical? M
Cut point: Verdict written; H3 capital gate opened or closed.
Waiting on:
G4· On-device reading-behaviour heuristics (skim / re-read / pause) → intensity nudges
- G5 H2.5 verdict sitting: does gaze → score feel magical? M
-
Session 204
M- D1 Android e-ink reader as test device (Boox Go 7 / Palma 2, or Hisense A9 for a front camera) + APK on e-ink M
Cut point: Libretto reads on e-ink with acceptable refresh and audio out.
- D1 Android e-ink reader as test device (Boox Go 7 / Palma 2, or Hisense A9 for a front camera) + APK on e-ink M
H3 — epics
The eye-tracking device. Unnumbered on purpose: these stay XL until H2.5 proves the gaze thesis and they can be split into real sessions.
7 epics · no session numbers
- D2 OS decision: gaze on a coprocessor (embedded Linux) vs on the main SoC (Android/AOSP) XL Needs Dylan
Cut point: Decision memo with power, cost and vision-stack trade-offs; prototypes stay on Android until then.
Waiting on:
G5· H2.5 verdict sitting: does gaze → score feel magical? - D3 Device prototype: IR gaze module, display, audio, battery XL Needs Dylan
Cut point: A bench prototype reads a book with gaze-driven score.
Waiting on:
D2· OS decision: gaze on a coprocessor (embedded Linux) vs on the main SoC (Android/AOSP)More
Ground truth: Pupil Labs Core (~3.6k EUR) or Gazepoint GP3 HD (~2.7k USD). Consumer Tobii is not licensed for gaze data.
- D4 ODM RFQs (RK3566-class e-ink boards) + open-hardware references (Open Book Touch, Modos Flow) XL Needs Dylan
Cut point: Three quotes with MOQ and NRE; one reference board on the bench.
Waiting on:
D2· OS decision: gaze on a coprocessor (embedded Linux) vs on the main SoC (Android/AOSP) - D5 Word-level cue anchoring (gaze precision → cue timing on the dot) XL Needs Dylan
Cut point: Cues fire within one line of the intended word on the device.
Waiting on:
D3· Device prototype: IR gaze module, display, audio, battery - D6 On-device reflex classifier over gaze features (only if a local System-One / open-weight model exists) XL Needs Dylan
Cut point: A local model classifies reading state under 20 ms on the device; no frame leaves it.
Waiting on:
D3· Device prototype: IR gaze module, display, audio, batteryMore
Conditional epic from the Jev research: cloud reflex models are the wrong shape for this loop.
- D7 Funding (crowdfunding proceeds, loan, or investment) for a production run XL Needs Dylan
Cut point: Capital secured for the first run.
Waiting on:
CA10· Crowdfunding campaign launch ·D3· Device prototype: IR gaze module, display, audio, battery - D8 Manufacturing + fulfilment of the first run XL Needs Dylan
Cut point: Devices in backers' hands.
Waiting on:
D7· Funding (crowdfunding proceeds, loan, or investment) for a production run
The jump in the numbers is deliberate: H1 sessions run 1–99, H2 starts at 101 and H2.5 at 201, so a session number always says which horizon it belongs to and H1 can grow without renumbering anything downstream.