-
feat(gig-log): record what was PLAYED, not what was looked at · 97b22c0b
#150, and the fix at the source of #148. gig-log recorded tab-focus events -- which file PLN was LOOKING at. Album track boundaries were then derived from those, and they were wrong, because a livecoder tabs around constantly while a pattern keeps running. Looking at a file is not playing it. An EVAL is the moment a pattern actually changes. That is the honest boundary. SIGNAL SOURCE `atom.commands.onDidDispatch` in the HUD package, filtered to `tidalcycles:eval*`. Confirmed ctrl+enter maps to `tidalcycles:eval-multi-line` in Pulsar's own keymap, and that MULTI_LINE sends exactly the blank-line-delimited paragraph around the cursor -- which is already this repo's block convention. onDidDispatch rides Atom's EXISTING command routing, so it adds no new per-keystroke listener: it cannot make the renderer burn worse. Rejected: GHCi stdout (no stable per-eval marker without changing the REPL protocol) and SuperDirt OSC sniffing (needs its own listener process -- closer to the observer-perturbs trap this rig has already been burned by). SHAPE New `k:"eval"` record {t, path, d}, where d is a best-effort list of dN streams found by a narrow regex: dN as the FIRST token of a line, inside the evaluated block only. Documented as best-effort rather than dressed up as complete. Transport is ~/.cache/parvagues/eval-events.jsonl, APPEND-only -- unlike current-track, which overwrites. An eval is an EVENT, in the same category as a MIDI note, never coalesced; current-track is STATE. Conflating the two is how the focus lens got mistaken for a play lens in the first place. `EvalTail` polls it once per tick with a byte-offset seek, buffers torn lines, and rebaselines if the file shrinks or is recreated -- the same pattern XrunReader already uses for node respawns. It never replays pre-session content. `track` events are UNTOUCHED. This adds a lens; it does not replace one. Boundary detection wants several (gap < orbit-flip < tempo), and focus is still the cheapest of them. BLAST RADIUS Folded into load()'s existing marks list exactly as `track` is, so cmd_report renders it for free and load()'s tuple signature does not change. The one real consumer, tools/take-segments.py, reads the JSONL itself and already ignores any `k` it does not recognise -- verified by reading it, not assumed. VALIDATION 111/111 python tests pass (91 pre-existing + 20 new), covering the pure normalizer, the tail's offset / torn-line / rebaseline behaviour, and a full write -> load round trip. NOT VERIFIED: whether the running gig-log.service picks this up without a restart. It was deliberately left alone -- PLN was performing.PLN (Algolia) authored97b22c0b
×