docs(roadmap): sub-project 3 alteration-engine + player-core slice shipped

This commit is contained in:
Ben Stull
2026-06-05 18:09:54 -07:00
parent 86b52ab8af
commit 5403021e4a
+50 -19
View File
@@ -15,7 +15,7 @@ Design reference: [`specs/2026-06-04-human-experience-filter-design.md`](./super
|---|---------------------------------|---------------|----------|
| 1 | Catalog & Selection Core | ✅ Done | everything |
| 2 | Ingest & Tagging / Review tools | ✅ Done | a real library |
| 3 | Player Runtime (Pi) | ⏳ Next | the room runs |
| 3 | Player Runtime (Pi) | ⏳ In progress | the room runs |
| 4 | Arduino Firmware (control panel)| ◻ Not started | real knobs |
| 5 | ~~Procedural Side Walls~~ | ❌ Dropped | — (superseded) |
@@ -95,29 +95,60 @@ was `validate_catalog` + `index_by_id`.
---
## 3. Player Runtime (Pi) ⏳ (next)
## 3. Player Runtime (Pi) ⏳ (in progress)
**Goal:** the thing that makes the room run — read the controls, pick media, play
it across the single panoramic projector.
**Goal:** the thing that makes the room run — read the controls, **alter** the
neutral base footage toward the knob state, and play it across the single
panoramic projector. Per the machine-altered-perception revision the knobs no
longer *select* a pre-tagged clip; they drive an **alteration engine** (design
§4/§5) over a small neutral base library.
**Delivers (`player/`):**
**Slice 1 — alteration engine + player core (pure logic) ✅ Done.** Merged to
`main` (session 0006); 56 tests. The new `player/` package, with all I/O
(video/audio/serial) behind injected interfaces:
- Read the five control values from the Arduino over USB serial.
- Call `hef.selection.select()` on each change; loop the chosen 515 min segment
until the knobs move; **crossfade** on change.
- `None` mode → fade to black + silence.
- Drive the **single panoramic projector** spanning the three walls with the real
selected video (no primary/side split; no side-wall feed — sub-project 5 dropped).
- `player/controls.py``Controls`, the full panel state (7-way content dial +
4 experience knobs + volume + brightness); the serial-contract data shape
shared with sub-project 4.
- `player/content.py``resolve_content`, the §6 7-way dial → (audio source,
video on/off) table.
- `player/alteration.py``plan_alteration`, knob vector → `RenderPlan`
(mood `ColorGrade` with center=identity §5; Left `AnalyticalOverlay`; Right
`Restyle`), encoding the §4.2 layering rule (substrate vs overlay; Left & Right
stack).
- `player/state.py``Player`, the state machine that diffs successive controls
into transitions (`FADE_TO_BLACK`/`FADE_FROM_BLACK` on video on/off,
`CROSSFADE` on clip/restyle-variant swap, `LIVE_UPDATE` for the continuous
grade/overlay/level ops per §4.3, `NONE` when unchanged).
**Depends on:** sub-project 1 (`select`); a populated catalog from sub-project 2
to be meaningful, but can be developed against a hand-authored catalog and a
**keyboard/serial stand-in** before firmware exists.
**Done when:** given a catalog and a stream of control values, it plays the
correct segment, loops, crossfades, and goes dark on `None` — testable with the
serial input mocked.
**Hardware:** Raspberry Pi 5 (holds the drive + catalog).
Plan: [`2026-06-05-player-alteration-core.md`](./superpowers/plans/2026-06-05-player-alteration-core.md).
**Remaining slices (not started):**
- **Runtime renderer** — drive the single panoramic projector via mpv/ffmpeg;
GPU shaders for the luma-keyed mood grade + analytical-overlay compositing;
realize crossfade/fade timing and the 515 min loop. (Open decision: player
stack — mpv via IPC vs. ffmpeg vs. custom.)
- **Serial input** — real USB-serial reader on the Pi + the **3⇄4 framing
contract** with the firmware (the keyboard/serial stand-in already works via a
`Controls` stream).
- **White-noise generation** — runtime white/pink noise for that content position.
- **Offline v2v variant pipeline** — author the pre-baked Right restyle variants
(the only paid AI step, design §9) + the multilingual label/string tables + TTS.
- **Catalog model changes** — audio *source* + "neutral base" vs "altered
variant" flag (sub-project 2 territory, design §13).
**Depends on:** sub-project 1 (`Coordinate`); a neutral base library from
sub-project 2 to be meaningful, but developable against a hand-authored library
and a **keyboard/serial stand-in** before firmware exists.
**Done when:** given a base library and a stream of control values, it plays the
correct altered segment, loops, crossfades, and goes dark on `Off` — the
decision logic is covered (slice 1, serial mocked); the renderer realizes it.
**Hardware:** Raspberry Pi 5 (holds the drive + base library + variants).
**Open decisions:** player stack (mpv via IPC vs. ffmpeg vs. custom); whether the
player hard-restricts to `approved` records.
player hard-restricts to `approved` records (the `approved_only` flag is plumbed
but inert until backed by a real catalog); knob→strength calibration (the §3 vs
§4.2/§5 reconciliation — see the slice-1 plan / session 0006 transcript).
---