# Neon playback proof could pass without proving playback

Date: 2026-05-24

Target: LilArcade Neon Step Sequencer

## Catch

The playback-sync proof pack profile could pass after clicking Play even when the captured browser contract still reported `isPlaying: false` and `trainer.currentStep: 0`.

That was not an app playback failure. A direct browser sanity check showed the app changed the button to `Stop` and advanced the trainer playhead. The weak layer was the proof profile.

## Before

`before-weak-proof.json` passed with 7 setup actions:

- clicked `button.drum-play`
- did not wait for visible `Stop`
- captured post-action `isPlaying: false`
- captured post-action trainer `currentStep: 0`
- still reported the profile as passed

## After

`after-hardened-proof.json` passed with 10 setup actions:

- clicked `button.drum-play`
- waited for `button.drum-play` text `Stop`
- captured post-action `isPlaying: true`
- captured post-action `currentStep: 2`
- captured `movedForward: true`

## Fix

Riddle Proof packs `0.4.8` hardens the Neon playback-sync profile by:

- normalizing the nested trainer fields exposed by the live Neon app contract
- waiting for the visible `Stop` state after Play
- asserting post-action playback is running
- asserting the trainer playhead advanced
- adding static regression coverage in the proof-pack test suite

LilArcade then consumed the published pack and synced its local `.riddle-proof/profiles/neon-playback-sync.json` profile from it.

## Does Not Prove

- long-running transport timing
- audio output quality
- song-wide playback correctness
- human taste or mix preference
