# 037 — The surface follows the track (2026-08-30)

**Goal:** stop the driver from being a one-track instrument. PLN, mid-set, three
ways in one hour: "i see still ROSE_ROUGE in title", "why dont i see the lcxl
colors evolve as i map buttons on the new track?", "im starting a new track,
probably this will be an opp to confirm you read current file well". One bug,
three faces — a driver that parsed its `.tidal` once, at launch, and never
looked again. It played sept1 correctly the whole time, because the v3→v2
translation is track-agnostic, and it labelled everything wrongly, because the
map was rose_rouge's. The sound was right and every light lied.

**What shipped** (`claude/lcxl3-surface`, `7c297a6..ac86478`):

- **Track-follow.** The bus already existed and nobody had read it: the Pulsar
  HUD publishes the loaded track to `~/.cache/parvagues/current-track` and
  appends every ctrl+enter to `eval-events.jsonl`. A different path is a track
  change (remap, relabel 32 targets, repaint, reset the lap clock); a changed
  mtime on the same path is a re-read, so mapping a control and saving lights
  the board in under a second. Verified live twice in the log while PLN worked.
- **Carry policy**, his spec: DJFs carry (they ARE the transition — "so i can do
  djf-and-fader-crossfaded-transitions"), effect knobs go to 0, faders are
  physical. Two he did not name carry too, because the sound would otherwise
  have taught us: the tempo knob (reset = the range floor = a 60→120 transition
  slamming back to 60 as the new track lands) and every button (emitting to a
  gate is the mutebomb).
- **Live tempo.** `# cps ((range 60 180 "^29")/60/4)` makes row-B knob 1 the
  clock. BPM now comes from the knob, and bar phase is integrated rather than
  read off the wall clock — the wall-clock form re-scales all of history the
  moment the tempo moves, which would make the countdown jump exactly
  mid-transition.
- **The move, served.** PLN: "start holding kick mute, move kick to the 120bpm
  position (i used the center notch, now ill rely on OLED), drop kick mute at
  end of a bar." So the screen became the notch — BPM not wire units, an arrow
  to the nearest landmark that vanishes when he is on it, and while a mute is
  held the bar countdown ("DROP kick / ~120 BPM >2") with the ring breathing at
  the beat to count it in. Plus software detents, since the encoder has no
  ridge.
- **The mute overlay** finally names the held SET ("MUTE x2 / kick+percs",
  "all") instead of the last finger down.
- **A probe instead of a fourth guess** (`lcxl3-probe-display.py`, Opus worker):
  the frozen lap clock and the 1-second DJF Hz share one unproven rule, the
  protocol has no display readback, so the instrument is PLN's eyes asked
  precise questions in order.

**Three findings that cost nothing but reading.** The v2 `lcxl-leds-watch`
service has been logging "no LCXL sequencer port" every 30 s since the v3 board
arrived — its name regex cannot match "LCXL3 1", so my prime suspect for the
paint-reset mystery never touched the surface at all, and that mystery is
reopened with no suspect. The Midi-Through→SuperCollider re-add is
`MIDIIn.connectAll`, re-running on sample reload, exactly as
`midi-autoconnect.sh`'s own header predicted. And the A1 label off-by-one that
sat on the board was never real: "d9 level [ard]" is correct — the grid puts
d9-d12 on row A and d1-d8 on the faders.

**Two traps worth the retelling.** The detent welded the knob to the first notch
it met, twice: the closest STEP to a landmark sits just below it, so stepping up
re-crosses the same landmark and snaps back — 24 consecutive clicks stuck at
114.8 BPM before the fix tracked *which* landmark holds you by identity. And a
rich commit message passed inline under zsh lost every backticked code
reference to command substitution, silently; the only hint was a stray "command
not found: resetCycles". Rich messages go through `-F` from now on.

**Answered at the desk, unbuilt on purpose:** PLN asked why rapid ctrl+enter
retriggers the kick "as if it was a once, not a d1". Because `resetCycles` shares
a blank-line block with the patterns, so every eval restarts cycle 0 — and
separately, every `dN` is a 1-cycle crossfade launch by definition
(`d1 = xfade 1 . (|< orbit 0)`). Both diagnosed, neither touched: it is his file
and his taste. The compose/perform mode that would make it a switch instead of a
shadowed `let` is now C-1 on the register.
