record-player 0.2.0

Shared Bitneedle transport, record physics, and acoustic scratch engine
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
# Playback and Scratch Engine Refactor Plan

Status: automated engine and browser implementation is complete as of
2026-07-20. The original phases below remain as the implementation record from
checkpoint `5eccda9` (`Checkpoint audio preview and capture support`). Hardware
measurements and the blind DJ protocol remain outstanding. No perceptual claim
is made.

Current automated evidence:

- `cargo test --workspace`: 108 tests (103 `record-player`, 5 `player-wasm`).
- Rust gate conformance traverses one learned stroke for Transform, Flare, Crab
  and Orbit. Click values 1, 4 and 8 produce exactly that many pulses or notches.
  At `8x`, the de-click envelope stays within its analytical fastest-attack
  adjacent-sample bound on sine and transient fixtures. Stable Stab closed/open
  RMS ratios remain below `1e-6` and above `0.999`.
- `node --test test/*.test.mjs`: 80 tests. Canvas tests check audio-owned phase
  at half-speed forward, full-speed reverse and rest, plus all eight preset and
  click-count selections through independent mouse and touch gestures. The
  click control remains absent and non-interactive for techniques that ignore it.
- The default tonearm now consumes decoded programme-gap anchors through the
  Rust monotone calibration. Its inverse projects the pointer onto physical arm
  length and recovers groove radius before seeking. Release WASM pinned a test
  gap to `0.421..0.429` and mapped its midpoint into the matching PCM interval.
- The canvas is the only bundled scratch surface. The permanently hidden legacy
  platter and its separate single-turn, event-rate-dependent differentiator
  were removed, so every bundled gesture uses the canonical tracker.
- `npm run build`: both browser WASM packages build in release mode.
- The current 2026-07-20 Chrome 150 integration run passed. It reached empty-deck
  motor phase, automatic needle drop, all direct preset controls and every
  radial click value through API, mouse, touch and keyboard paths. It verified
  per-preset click memory and hid the control for non-click techniques. Chrome
  reported zero underruns over `9.02 s`.
- `npm run bench:worklet`: three release-WASM runs measured p95 at `1.47%`
  normal and `8.10–8.14%` for alternating `±8×` crab/8. Fresh six-second
  stereo PCM window p95 was `2.90–3.08%` against a `2.667 ms` quantum.
- The rate-adaptive sinc keeps eight output-domain frames of bounded support
  instead of collapsing a fixed 24-source-tap kernel at high speed. Spectral
  sweeps at `±2×`, `±4×` and `±8×` keep passband RMS within `0.012` and
  stopband RMS below `0.003`, with exact forward/reverse symmetry. A recurrence
  matches the direct sinc calculation within `1e-11` while avoiding per-tap
  trigonometry. Release WASM measured `1.52%` normal, `6.60%` reversing Crab/8
  and `3.28%` fresh-window p95 against the audio quantum.
- Signed Rust mechanics traces apply identical limits in both directions. The
  motor reaches `0.55..0.70×` after 300 ms and more than `0.94×` after one
  second. A firm 50 ms grab reduces rate below 20% of steady speed. The motor
  catches above `0.75×` within 100 ms of release. A free throw retains more
  than `0.55×` after 200 ms, while a powered brake falls below `0.05×` after
  400 ms. Forward and reverse results agree within `1e-10`.
- Two current high-contention benchmark attempts exceeded the fresh-window
  threshold. The threshold was not relaxed. A later rerun passed with normal
  p95 `0.0573 ms`, reversing Crab/8 p95 `0.2599 ms`, and fresh-window maximum
  `0.3707 ms` against the `2.667 ms` quantum after gate v5.
- The post-calibration release run measured p95 `1.49%` normal, `8.70%` for
  alternating `±8×` crab/8 and `2.90%` for a fresh six-second window. Replay
  hashes remained unchanged, confirming that presentation calibration does not
  enter the audio renderer.
- The release-WASM harness requires identical output SHA-256 and gate traces
  when 2,176 live frames separate two runs of the same take. It verifies
  preset, click and manual-fader events at four exact sub-quantum offsets. A
  variable-grip take hashes to `0d44547b...`; its full-grip control hashes to
  `d3bf7be0...` and must differ. The harness also proves that a version-4 replay
  selects the historical Rust gate behavior and restores live version 5.
- The release-WASM harness also proves live scratch release policy in the next
  128-frame quantum. Explicit `resumePlayback: false` and a grab that began
  while paused produce exact silence and stop programme DSP immediately. A grab
  that began during playback resumes, while a lifted powered platter keeps
  rotating silently. Chrome captured all 12 post-release packets as silence,
  spanning 5,760 contiguous frames.
- The release-WASM progressive fixture stops at contiguous decoded coverage,
  requests the next bank, and holds the exact rendered source frame through four
  waiting quanta. New availability activates the requested bank without a
  position reset. Rust fades program audio out and back in over 6 ms. The first
  resumed-sample difference is less than `0.02`. The fixture does not expose
  zero-filled PCM or return at full level. The current release run measured
  `1.47%` normal, `6.40%` reversing Crab/8 and `2.94%` fresh-window p95 against
  the audio quantum.
- The release-WASM bounded-window fixture configures a five-minute stereo
  source. The worklet and Rust retain 6.59 MiB of PCM instead of a 109.86 MiB
  full Float32 record. Transport initialization and distant bank swaps do not
  grow Rust memory beyond the first 2.25 MiB window allocation. The worklet
  rejects a window that exceeds its configured frame budget before Rust can
  allocate it. The generated Rust API has no legacy full-record set or append
  methods. Rendered forward and reverse rates above `` each request and
  activate a bank 48,000 source frames in the direction of travel.
- `npm run test:browser`: Chrome 150 loaded real release WASM at 48 kHz.
  It exercised all eight gates in both directions and captured rendered audio.
  It recorded, replayed and restored an engine-version-5 take with more than
  400 events. The take retained begin/motion grip values `0.25`, `0.35` and
  `0.85`; public grip returned to zero on release.
  Scratch begin also retained `-1.4×` reverse intent and a `0.37` grab impulse
  after the Rust-core round trip instead of replacing them with zeros.
  Pointer input timestamps now project onto one bounded integer output frame
  carried through the worklet message, Rust command protocol and capture. A
  deliberately delayed browser marker must record within 512 frames of its
  independently calculated intent offset while applied-frame telemetry remains
  separate.
  Pointer cancellation follows the same safe physical release, remains distinct
  in the normalized take, and immediately frees canvas record ownership.
  It kept a trusted record touch active while a second touch moved XFADE. The
  API, trusted mouse, trusted touch and trusted keyboard paths each selected
  all eight presets and all eight click counts while XFADE remained at `0.37`.
  Transform restored its stored click count. Chirp disabled and hid CLICKS.
  The embed exposed both canvas selectors and its collapsed advanced dropdown
  in the initial viewport.
- The current browser run measured less than `5.44 ms` maximum pointer-to-apply
  latency in this synthetic trace. It reported `5.33 ms` base latency and `32 ms`
  output latency. These are headless host results, not hardware population data.
- The post-frontier-fix Chrome run reported zero underruns over `9.019 s`. Its
  sampled Web Audio callback p95 was `5.02%`, and its maximum was `6.12%` of the
  callback budget.
- Three independent browser runs sampled Chrome's Web Audio render capacity by
  phase. The worst maximum was `13.33%`, and the worst run-level p95 was
  `10.65%`. A later build-and-test invocation produced a `62.66%` callback
  sample, still below the full callback deadline. The harness enforces p95
  below `50%` and every sampled callback below `100%`. Capture timestamps stayed
  monotonic, cumulative timeline error stayed within `3.18 ms` over about
  `12.7 s`, and steady playback had no silent packet.
- The public state normalizes current `AudioContext.playbackStats` and legacy
  `playoutStats`. Three current Chrome runs observed `12.05–13.05 s` with zero
  underrun events and zero underrun duration. Target hardware must repeat this
  result.
- `npm run validation:template` creates the versioned DJ-study data shape.
  `npm run validation:analyze -- <file>` applies the pinned preflight, ABX and
  live-control acceptance rules. Unit tests cover passing and failing studies.
- `/dj-validation.html` embeds the real player and collects build-bound hardware,
  loopback, audio-block, participant, trial, routine and artifact evidence. It
  refuses release measurements from a dirty or mismatched build. Its bounded
  pointer probe records emitted pointer types, cadence, coalesced samples,
  pressure range, contact geometry, multi-touch and cancellation evidence. The
  schema-four session cannot start a block until that target-device profile
  passes; touch is explicitly full-contact grip and requires two pointers.
- `/dj-abx.html` runs participant-bound blind packages without condition labels.
  The coordinator tool verifies matched WAV captures, gives every A/B/X file a
  unique opaque identity, binds the package to the clean candidate build and
  keeps decoding in a private post-freeze step. Audio-data hashes prevent reuse
  across participants even when WAV metadata changes.
- The public acoustic-loopback probe emits a bounded diagnostic sweep and uses
  AudioWorklet frame tags for input correlation. Chrome passed a three-probe
  software loopback. Target hardware must supply the physical result.
- Physical output-device xrun measurements, physical controller runs and the
  human protocol in `DJ_VALIDATION_PROTOCOL.md` remain outstanding.

Grip now crosses the complete Phase 1 protocol. Explicit `0..1` API grip and
pen pressure reach Rust slipmat coupling, public state and deterministic
capture/replay. Missing historical values, mouse input and finger touch default
to full grip. iPhone Haptic Touch is not treated as force input; any
intent-derived touch grip needs target-device measurements before tuning.
Initial hand rate and grab impulse now cross the same ordered Rust protocol.
Historical begin events default to `0×`, the canonical `0.22` grab and full
grip, so the asynchronous core response cannot overwrite a newer live intent.

## Objective and proof standard

The player must use one continuous, audio-authoritative vinyl transport for normal
playback, braking, hand grabs, reverse motion, cue holds, releases, lead-in and
run-out. Scratch assistance must infer the user's motion rather than replaying a
wall-clock animation, and it must never prevent a DJ from operating the physical
record and manual crossfader with separate pointers.

"A DJ cannot tell" is a human perceptual claim, so automated checks alone cannot
prove it. This implementation will provide deterministic mechanical, spectral,
latency and browser evidence plus a repeatable blind comparison protocol. The
claim remains unproven until that protocol is run with experienced DJs.

## Audit baseline

Before implementation, the following checks pass:

- `cargo test --workspace`: 19 tests (14 player, 5 decoder facade).
- `node --test test/*.test.mjs`: 1 test.
- `npm run build`: both browser WASM packages build.

The passing suite does not cover production gesture handling, audio-thread
windowing, seam continuity, presets, replay clocks, multiple pointers or browser
latency.

## Architectural decisions

1. The Rust `ScratchAcousticDsp` remains the only programme-audio renderer and
   owns the final per-sample packet/mixer output gain. The browser `GainNode`
   remains unity and exists only for routing and capture. There
   will be no second scratch buffer-source path.
   More generally, per-sample and state-critical engine behavior belongs in Rust
   by default. JavaScript retains browser scheduling, pointer input and bounded
   buffer coordination only where moving the boundary would add measured work or
   latency; performance measurements, not language preference, decide exceptions.
2. Source positions use source frames. Performance timing uses AudioContext/output
   frames. Names and schemas must say which clock they use.
3. Pointer geometry and coalesced event collection live in the UI layer. Physical
   rate mapping, platter mechanics, de-clicking and assisted gate generation live
   in the audio engine.
4. Crossfader ownership follows the selected mode:

   - `baby`: `deck gain = channel gain × manual crossfader curve`.
   - automatic presets: `deck gain = channel gain × technique gate`.

   The Rust gate is the real audible XFADE in every automatic preset. Direct
   manual XFADE input selects `baby` and transfers ownership to the manual
   curve. Public state retains both the stored manual value and effective gate.
5. Preset phase advances from rendered groove travel in the confirmed stroke
   direction. It freezes while held still and resets after a hysteretic reversal.
   Residual outgoing motion must not advance the new stroke. Phase must not depend
   on `requestAnimationFrame`, pointer frequency or main-thread load.
6. Worklet memory is bounded by double-buffered PCM windows. Decoding and Int16 to
   Float32 conversion stay off the audio thread. A non-shared fallback may copy a
   bounded window, but may not restore full-record worklet allocations.
7. Published records enter a physical run-out/deadwax by default. Conventional
   authoring-preview audio may opt into a clean end explicitly.
8. The sharp `0.08` fader cut is shared by the Rust mixer and replay DSP, named in
   schema metadata and regression-tested. A public curve-tuning API is deferred
   until blind DJ evidence justifies the extra variability; the reference app's
   `0.22` width remains a documented different tuning, not silent parity.

## Phase 1 — clocks, ownership and state transitions

- Add an explicit source sample-rate update to the Rust player engine when a source
  is initialised; remove the fixed-48 kHz assumption from begin/end conversions.
- Track pointer target position and audio-rendered position separately in the host.
  Never overwrite one with the other.
- Make scratch begin/move/end/cancel an ordered protocol with explicit:
  `sourcePositionFrames`, `outputFrame`, `handContact`, `resumePlayback`, needle
  state, grip strength and release/handoff policy.
- Preserve a lifted needle during a hand grab. The record may turn visually, but
  the cartridge remains muted and the groove readhead does not falsely advance.
- Make `resumePlayback: false` stop programme playback in both core and worklet.
- Carry contact impulses through `HostCommand` translation instead of dropping
  them, and use rendered position for release/capture.
- Update the motor target whenever RPM changes while the motor is on, including
  run-out and non-programme states.

Acceptance evidence:

- Transition-table tests cover motor on/off × playing/paused × needle up/down ×
  scratch begin/end/cancel.
- 44.1, 48 and 96 kHz sources release to the same source frame (within one frame).
- `resumePlayback: false` produces silence and a stopped state in the next quantum.

## Phase 2 — bounded, continuous PCM delivery

- Reconnect `pcm-window-worker.js` and the two shared 6-second banks.
- Keep full Int16 programme storage outside the AudioWorklet; keep only the active
  Float32 window in Rust.
- Route progressive segments through the worker, merge written ranges, and expose
  contiguous availability to the worklet.
- Repair every contiguous chunk seam in the authoritative worker/source copy before
  a window becomes visible to Rust. Do not repair an unused JavaScript mirror.
- Consume `ScratchAcousticDsp.takeWindowRequest()` and project refills in both
  directions at high speed.
- Clamp seeking/scratching to decoded coverage, enter an explicit bounded buffering
  state at the frontier, and resume without resetting motor or spring state.
- Remove allocation/conversion loops from the render quantum.

Acceptance evidence:

- A five-minute stereo source keeps worklet + Rust PCM below the configured window
  budget rather than allocating full-record Float32 copies.
- A deliberately discontinuous chunk fixture crosses the repaired seam with a
  bounded first difference in forward and reverse playback.
- Slow progressive decode pauses at the availability frontier and resumes from the
  same rendered frame without a zero-filled excursion.
- High-speed forward/reverse traces request and activate the correct projected bank.

## Phase 3 — canonical high-resolution gesture input

- Replace both raw DOM/canvas differentiators with one pure gesture tracker.
- Consume `getCoalescedEvents()` sequentially and use incremental unwrapped angles,
  a 4 ms differentiation floor, multi-turn accumulation and a time-aware adaptive
  velocity filter (fast reversal response, approximately 35 ms steady smoothing).
- Apply a Schmitt direction state so sub-deadzone jitter cannot flip preset intent.
- Emit contact impulse only for a real grab, reversal or high acceleration; remove
  the current event-rate-dependent `abs(rate)/3` impulse on every move.
- Treat stylus-up motion and pointer cancellation explicitly.
- Replace the canvas's one global gesture slot with a pointer map, allowing one hand
  on the record while another moves XFADE/CH/PITCH.
- Wire programme-gap stylus calibration into the default canvas tonearm mapping.

Acceptance evidence:

- Equivalent gestures sampled at 30/60/120/240 Hz and with coalesced samples produce
  equivalent position/rate traces within declared tolerances.
- Tests cover ±π wrap, multiple turns, duplicate timestamps, reversal, dwell,
  cancellation, near-spindle movement and lifted-needle movement.
- A browser test holds the record with pointer A and moves/releases the fader with
  pointer B without losing either gesture.

## Phase 4 — audio-rate intent-aware scratch presets

- Add versioned presets: Baby, Stab, Chirp, Transform, Flare, Crab, Orbit and Drum.
- Preserve the reference starting constants (5.2/9.5/6.4/18/7.2/12 Hz, transform
  duty 0.48, crab duty 0.38, click range 1–8), but interpret them as initial groove-
  travel spans rather than an unconditional wall-clock oscillator.
- Implement the gate as a Rust audio-rate state machine using filtered target rate,
  rendered rate, velocity confidence, acceleration, dwell, direction hysteresis,
  distance since reversal and a learned stroke span.
- Gate algorithm 4 applies click count only to Transform, Flare, Crab and Orbit.
  Each preset keeps its own setting. Versioned replay retains the version 1–3
  global phase multiplier for historical takes.
- Gate algorithm 5 buffers candidate-direction rendered travel during onset and
  reversal confirmation. It commits that distance only after intent is confirmed,
  so fast patterns do not land late and false reversals cannot spend a stroke.
  Tests cover 8× travel, rejected jitter and 44.1/48/96 kHz invariance.
- Technique behavior:
  - Baby: assisted gate open; manual fader only.
  - Stab: forward stroke audible, return and hold cut.
  - Chirp: open at forward onset, close by speed-adjusted travel, reopen on return.
  - Transform: travel-locked repeated open/closed chops.
  - Flare: open phrase with click-count closed notches.
  - Crab: velocity-scaled rapid open pulses.
  - Orbit: symmetric notches reset for each direction.
  - Drum: acceleration/onset transient with travel/time close and retrigger guard.
- Filter Drum intent on the audio clock before differentiation. This prevents a
  small held-target step from becoming a sample-rate-dependent false attack.
- Require Drum onset and reversal attacks to exceed the minimum motion rate.
- Apply velocity-dependent 0.35–4 ms attack/release envelopes to prevent digital
  discontinuities while retaining a sharp professional cut.
- Return the technique gate to open on hand release so motor playback cannot remain
  accidentally muted.
- Expose effective gate, direction and rate telemetry without putting UI work on the
  render thread.

Acceptance evidence:

- Truth-table and trace tests cover rest/forward/reverse/reversal for every preset.
- Click values 1/4/8 create the expected pulses/notches over a learned stroke.
- Doubling travel velocity doubles temporal chop frequency while identical travel
  produces the same pattern; holding still freezes phase.
- A confirmed intent reversal resets phase before the rendered spring crosses
  zero. The new phase waits for rendered motion in the confirmed direction.
- Gate timing is invariant at 44.1/48/96 kHz and across 128-frame boundaries.
- Closed/open RMS and maximum adjacent-sample discontinuity are bounded on sine and
  transient fixtures.

## Phase 5 — platter and stylus fidelity beyond reference parity

- Apply the reference deadzone and Gaussian ±1× lock in the actual DSP command path,
  not in unused code.
- Shorten/tune hand ownership for deliberate DJ grabs and cover it with quantitative
  response tests; retain motor spin-up/brake constants unless evidence contradicts
  them.
- Model an unpowered hand throw separately from an explicit motor brake, preserving
  signed platter momentum with bearing-friction decay.
- Configure revolution-locked wow from native RPM (1.8 s at 33⅓, 1.333… s at 45).
- Add a rate-adaptive band-limited interpolation/anti-alias path for high-speed
  forward and reverse motion, with a smooth transition from the low-latency path.
- Preserve the speed- and source-curvature cartridge model as the adjustable
  `stylusTracingLimit` (default `0.72`). This is the physical stylus-tracing model,
  not a programme mastering limiter, and must never be mislabeled as one.
- Add a separate stereo-linked `highFrequencyAccelerationLimit` (conservative
  default `0.35`, exact bypass at `0`) for mastering protection. Split programme
  into a complementary base plus approximately 5.2 kHz upper residual, detect
  discrete upper-band acceleration and rapid direction changes, and apply a soft
  knee with very fast attack and transparent release to the upper residual only.
  Do not attenuate lows/mids, foley, needle-surface audio or surface-only renders.
- Drive canvas rotation from worklet effective rate during spin-up, pitch slew,
  braking and release rather than from an instantaneous nominal RPM flag.
- Keep lead-in surface rendering isolated from programme sampling and complete its
  timed transition on the audio clock. Restore record deadwax/locked-groove behavior;
  make clean preview ending a load option.
- Resolve one immutable needle-cue landing `50–140 ms` before the visual aim
  during active programme playback. Use it for both the immediate worklet update
  and the queued core seek. Keep paused and lifted-needle seeks exact.

Acceptance evidence:

- Quantitative traces cover grab latency, motor catch, powered brake and unpowered
  throw in both directions.
- 33⅓/45 wow completes one phase per physical revolution.
- Spectral tests show bounded alias energy for representative 2×/4×/8× sweeps and
  forward/reverse symmetry.
- Stylus-tracing tests retain curvature × squared-velocity behavior, while separate
  programme-limiter tests prove exact bypass, low-frequency preservation, benign
  high-frequency brightness, harsh/sibilant acceleration reduction without
  full-band collapse, bounded stereo linking and transparent release.
- Visual rotation stays within a declared angular tolerance of integrated rendered
  effective rate through start and stop.
- Lead-in cannot advance/leak programme PCM; published records enter run-out while
  preview sources can request a clean end.
- Chrome observes no transient exact-target seek before an active-playback cue
  reaches its physical landing.

## Phase 6 — deterministic capture and replay

- Introduce performance schema v2 with separate `sourceSampleRate` and
  `outputSampleRate`, preset/gate algorithm version, preset/click state, manual
  fader state, motor/needle state and canonical source-frame motion events.
- Record preset, click and manual fader changes as output-frame-timestamped events.
- Scale schema-v1 timestamps during import/replay and default them to Baby/manual.
- Apply replay events inside the worklet at exact sub-quantum frame offsets.
- Snapshot and restore motor, playing, needle, effects, preset/gate and final
  output-gain state in Rust on completion and cancellation; keep host/core
  public state untouched throughout replay.
- Store a stable replay seed and initial platter angle. Initialize replay-only
  mechanics, wow/flutter, noise, filters, limiter and gate state in Rust so a
  take never inherits mutable live DSP phase.
- Validate/migrate IndexedDB records instead of blindly accepting arbitrary shapes.

Acceptance evidence:

- Replaying the same performance twice yields the same gate trace and output hash.
- Mid-gesture preset/click/fader events apply on their exact requested frame.
- Schema-v1 import remains playable with documented defaults.
- Completion and cancellation restore all pre-replay state.

## Phase 7 — public controls, UI, documentation and measurement

- Add public preset/click APIs, fixed fader-curve metadata, distinct stylus-tracing
  and programme acceleration-limit controls, state subscription fields and
  postMessage bridge messages. Public fader-curve tuning remains deliberately
  deferred pending human validation.
- Add real preset and click controls to the canvas plus accessible fallback HTML;
  reflect (but do not drive) audio-owned gate/direction telemetry.
- Publish AudioContext `baseLatency`/`outputLatency` and measured pointer-command-
  apply latency so device-specific problems are observable.
- Correct stale acoustic/windowing documentation and record each intentional
  reference divergence.
- Add a blind DJ validation protocol using matched source material, calibrated
  output level, hidden real/digital conditions, baby/stab/chirp/flare/transform
  tasks, latency ratings and ABX-style identification results.

Acceptance evidence:

- Keyboard, pointer, touch and programmatic control paths select all presets and
  click counts without overwriting the stored manual-fader value. Automatic
  presets drive the effective XFADE from the Rust gate.
- API and README examples match runtime state and schema.
- Headless browser smoke tests report no page/worklet errors and exercise synthetic
  audio loading, normal playback, window replacement, multi-pointer control,
  every preset, capture and replay. The test samples Web Audio callback use by
  phase and checks capture timeline continuity in a dedicated worker.
- The final audit maps every item above to a passing command, trace, browser result
  or explicitly outstanding human validation result.

## Completion boundary

The checkpoint preserves the pre-refactor work. Implementation was committed in
reviewable clock, mechanics, limiter, replay and browser slices. Automated
acceptance is complete for the native, JavaScript, release-WASM and Chrome
harnesses listed above. The remaining deployment claim requires device-xrun and
acoustic latency evidence on target hardware plus the pre-registered DJ
protocol. Those results must be attached here. They cannot be inferred from
automated tests.