sync-human-watch-listen-20261110). Overwritten in place at https://minds.gamecult.org/aqua/sync-offgrid-ramp-playground/ . Earlier page: sync-perlines.2026-11-11. Follow-up to the Perlines v2 page. Same recorder (rec.cjs), headless Chromium with software GL, 640x360, ten hits per 12 s clip; the Playground recorder is pg-rec.cjs. Default profile (audio may lead 25 ms, lag 100 ms). Code: GameCult/AquaSynth tools/aqua-feel, SYNC.md.
New WAV clicks-offgrid.wav (hits at 1.013, 2.241, 3.127, 4.389, 5.306, 6.652, 7.519, 8.834, 9.707, 10.943 s; list). The first page's identical -15.9 ms on every hit was the grid, as suspected. Two takes per scene, step detector and ramp detector (section 2) on each:
| clip | onset shape | paired/audio onsets | median lag ms | spread ms | verdicts | files |
|---|---|---|---|---|---|---|
| Aurora disk take a | step | 8/10 | -5.0 | 29.3 | inside-window 5, borderline 3 | report json |
| Aurora disk take a | ramp | 10/10 | +42.5 | 26.4 | borderline 10 | report json |
| Aurora disk take b | step | 8/10 | +5.4 | 26.9 | inside-window 8 | report json |
| Aurora disk take b | ramp | 10/10 | +53.4 | 47.7 | borderline 10 | report json |
| Burning water take a | step | 10/10 | -0.1 | 63.5 | borderline 5, ambiguous-pairing 1, inside-window 4 | report json |
| Burning water take a | ramp | 10/10 | +32.8 | 76.1 | borderline 10 | report json |
| Burning water take b | step | 10/10 | +33.6 | 24.6 | inside-window 10 | report json |
| Burning water take b | ramp | 10/10 | +75.3 | 29.8 | borderline 10 | report json |
| Vector trails take a | step | 0/10 | - | - | - | report json |
| Vector trails take a | ramp | 10/10 | -7.6 | 80.2 | borderline 10 | report json |
| Vector trails take b | step | 0/10 | - | - | - | report json |
| Vector trails take b | ramp | 9/10 | +15.4 | 22.5 | borderline 8, ambiguous-pairing 1 | report json |
The real spread of the step detector on a software-rendered capture is 25 to 64 ms within one take (per-hit lag, min to max), and the median moves by up to 34 ms between two takes of the same scene (Burning water: -0.1 and +33.6 ms). So these clips cannot support a latency claim tighter than about +/-40 ms for the app, and cannot say which take is typical. Where the spread is small (24 to 29 ms) it is still the capture: frames arrive 17 to 50 ms apart. A real GPU is the missing control. Clips: Aurora take a, Burning water take a, Vector trails take a (other takes' reports are listed; their video is not kept).
--shape ramp, PR #34, open: a third Soul pass has not reported, not merged)On Vector trails the step detector pairs 0 of 10 hits in both takes; the ramp detector pairs 10 and 9 (see table). That is a recovered detection, not a recovered measurement:
audio-late-detectable, whatever the swell's shape.inside-window or audio-early-detectable, because a swell's start cannot be bounded from below by looking at it. Every ramp row above is therefore borderline (or ambiguous), which says "not shown late", not "fine". It also cannot say when anyone sees the swell begin or that this sound caused it; a bed that swells on its own makes false pairs.The Playground (static page, 808-kick, published build 6080f9b, served locally) answers a sound with one thing that moves: the <meter id="level"> output-peak bar, written by the page's own animation loop from an analyser. It has no video to screen-record in a headless browser, so this is not a picture-and-sound clip. Instead pg-rec.cjs records (a) every write the app makes to the meter value with its timestamp, (b) the app's audio output sample-accurately through an AudioWorklet tap placed at the destination, and (c) the Play-click times; the audio clock and the page clock are bridged with getOutputTimestamp(). Six Play presses 1.5 s apart, four takes. Files: wav, meter track, presses (first take as pg-kick.* and pgk-0), screenshot.
| take | paired/audio onsets | median lag ms | spread ms | verdicts | files |
|---|---|---|---|---|---|
| take 1 | 6/6 | +22.7 | 14.3 | inside-window 6 | report json |
| take 2 | 6/6 | +24.5 | 15.0 | inside-window 6 | report json |
| take 3 | 6/6 | +39.4 | 40.6 | inside-window 6 | report json |
| take 4 | 6/6 | +26.4 | 47.0 | inside-window 6 | report json |
Lag = audio onset minus meter onset; positive means the audio comes after the meter moves. In every take the meter moves 3 to 33 ms after the click and the sound lands 25 to 68 ms after the click, so the meter leads the sound by 4 to 56 ms (median across takes 23 to 39 ms) and all 24 pairs are inside-window by the default profile. That is a statement about the app's own meter and its audio graph, not about anything on screen. Whether a person perceives a meter 25 ms ahead of the sound as in sync is exactly the check that is still owed.
Where the limits show.
getOutputTimestamp() jitters: the clock offset's spread over a take was -0.1..+33 ms, -10..+8, -30..+10 and -20..+20 ms (takes 1 to 4). Per-hit lag spread (14 to 47 ms) follows it. Take 3 and 4 spreads (41, 47 ms) are mostly this. The audio tap also reported 0 to 2 dropped 128-sample blocks per take.ambiguous-pairing. These results use --min-gap-ms 600 --pair-window-ms 120 (hits are 1.5 s apart). Without that the tool would have said it could not judge.A person watches and listens to a clip the tool calls inside-window and one it calls late and says whether the verdict matches; the 25/100 ms windows are checked against the standards texts; a capture on a real GPU and display.