@riddledc/riddle-proof-packs 0.2.2 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/README.md +13 -0
  2. package/dist/index.cjs +1176 -6
  3. package/dist/index.js +1176 -6
  4. package/package.json +1 -1
  5. package/packs/audio-mix/README.md +30 -0
  6. package/packs/audio-mix/authoring-guide.md +35 -0
  7. package/packs/audio-mix/human-review-rubric.md +31 -0
  8. package/packs/audio-mix/metrics-schema.json +30 -0
  9. package/packs/audio-mix/profile.template.json +130 -0
  10. package/packs/audio-mix/ratchet-method.md +26 -0
  11. package/packs/neon-step-sequencer/README.md +49 -0
  12. package/packs/neon-step-sequencer/case-study/findings.md +113 -0
  13. package/packs/neon-step-sequencer/case-study/ratchet-card.md +40 -0
  14. package/packs/neon-step-sequencer/case-study/ratchet-log.md +235 -0
  15. package/packs/neon-step-sequencer/case-study/reusable-lessons.md +31 -0
  16. package/packs/neon-step-sequencer/examples/README.md +22 -0
  17. package/packs/neon-step-sequencer/examples/run-001-fast-mix-health/profile-result.json +5010 -0
  18. package/packs/neon-step-sequencer/examples/run-001-fast-mix-health/summary.md +37 -0
  19. package/packs/neon-step-sequencer/examples/run-002-mix-change/profile-result.json +6816 -0
  20. package/packs/neon-step-sequencer/examples/run-002-mix-change/summary.md +37 -0
  21. package/packs/neon-step-sequencer/examples/run-003-full-matrix/profile-result.json +18490 -0
  22. package/packs/neon-step-sequencer/examples/run-003-full-matrix/summary.md +33 -0
  23. package/packs/neon-step-sequencer/examples/run-004-ratchet-loop-mix-level-search/profile-result.json +7003 -0
  24. package/packs/neon-step-sequencer/examples/run-004-ratchet-loop-mix-level-search/summary.md +39 -0
  25. package/packs/neon-step-sequencer/profile.template.json +75 -0
  26. package/packs/neon-step-sequencer/profiles/explore-songs-and-mixes.json +112 -0
  27. package/packs/neon-step-sequencer/profiles/fast-mix-health.json +181 -0
  28. package/packs/neon-step-sequencer/profiles/full-mix-health-matrix.json +154 -0
  29. package/packs/neon-step-sequencer/profiles/mix-change-before-after.json +202 -0
  30. package/packs/neon-step-sequencer/profiles/mobile-trainer-layout.json +109 -0
  31. package/packs/neon-step-sequencer/profiles/playback-sync.json +126 -0
  32. package/packs/neon-step-sequencer/profiles/ratchet-loop-mix-level-search.json +137 -0
  33. package/packs/neon-step-sequencer/profiles/source-readiness.json +114 -0
@@ -0,0 +1,202 @@
1
+ {
2
+ "version": "riddle-proof.profile.v1",
3
+ "name": "neon-step-sequencer-mix-change-before-after",
4
+ "target": {
5
+ "route": "/games/drum-sequencer?song=monkberry-moon-delight-tab&mix=profile&view=trainer&instrument=bass",
6
+ "viewports": [
7
+ {
8
+ "name": "desktop",
9
+ "width": 1440,
10
+ "height": 1000
11
+ }
12
+ ],
13
+ "timeout_sec": 300,
14
+ "wait_for_selector": ".drum-sequencer h1",
15
+ "setup_actions": [
16
+ {
17
+ "type": "window_eval",
18
+ "label": "install-neon-mix-change-proof",
19
+ "timeout_ms": 10000,
20
+ "store_return_to": "__neonProof.install",
21
+ "script": "window.__neonProofApi=()=>window.__NEON_MIX_PROOF__||window.__RIDDLE_SEQUENCER_PROOF__; window.__neonProofRead=()=>{const api=window.__neonProofApi(); const diagnostic=api?.captureDiagnostic?.(); return api?.getState?.()||api?.getSummary?.()||diagnostic?.state||null;}; window.__neonProofRender=async(options={})=>{const api=window.__neonProofApi(); return await (api?.renderOfflineMetrics?.(options)||{ok:false,error:'missing renderOfflineMetrics'});}; window.__neonProofSetMixer=async(track,value)=>{const api=window.__neonProofApi(); if(api?.setMixerLevelForProof){return await api.setMixerLevelForProof(track,value);} const selector='.instrument-lane-'+track+' .instrument-lane-slider input[type=\"range\"]'; const input=document.querySelector(selector); if(!input) return {ok:false,track,value,error:'missing slider'}; const setter=Object.getOwnPropertyDescriptor(HTMLInputElement.prototype,'value')?.set; if(setter) setter.call(input,String(value)); else input.value=String(value); input.dispatchEvent(new Event('input',{bubbles:true})); input.dispatchEvent(new Event('change',{bubbles:true})); return {ok:true,track,value:Number(input.value)};}; return {available:Boolean(window.__neonProofApi())};"
22
+ },
23
+ {
24
+ "type": "assert_window_value",
25
+ "path": "__neonProof.install.available",
26
+ "expected_value": true,
27
+ "timeout_ms": 10000
28
+ },
29
+ {
30
+ "type": "window_call",
31
+ "label": "render-pre-action-metrics",
32
+ "path": "__neonProofRender",
33
+ "args": [
34
+ {
35
+ "bars": 1,
36
+ "seed": "neon-mix-change-pre-action",
37
+ "monitorProfile": "smallSpeaker"
38
+ }
39
+ ],
40
+ "store_return_to": "__neonProof.preAction",
41
+ "capture_return": true,
42
+ "timeout_ms": 120000,
43
+ "return_summary_fields": [
44
+ {
45
+ "path": "ok"
46
+ },
47
+ {
48
+ "path": "mixHealth.peak"
49
+ },
50
+ {
51
+ "path": "mixHealth.rms"
52
+ }
53
+ ]
54
+ },
55
+ {
56
+ "type": "window_call",
57
+ "label": "apply-bass-focus-change",
58
+ "path": "__neonProofSetMixer",
59
+ "args": [
60
+ "bass",
61
+ 1.35
62
+ ],
63
+ "store_return_to": "__neonProof.mixEdit",
64
+ "capture_return": true,
65
+ "timeout_ms": 10000,
66
+ "return_summary_fields": [
67
+ {
68
+ "path": "ok"
69
+ },
70
+ {
71
+ "path": "track"
72
+ },
73
+ {
74
+ "path": "value"
75
+ }
76
+ ]
77
+ },
78
+ {
79
+ "type": "wait",
80
+ "ms": 400
81
+ },
82
+ {
83
+ "type": "window_call",
84
+ "label": "render-post-action-metrics",
85
+ "path": "__neonProofRender",
86
+ "args": [
87
+ {
88
+ "bars": 1,
89
+ "seed": "neon-mix-change-post-action",
90
+ "monitorProfile": "smallSpeaker"
91
+ }
92
+ ],
93
+ "store_return_to": "__neonProof.postAction",
94
+ "capture_return": true,
95
+ "timeout_ms": 120000,
96
+ "return_summary_fields": [
97
+ {
98
+ "path": "ok"
99
+ },
100
+ {
101
+ "path": "mixHealth.peak"
102
+ },
103
+ {
104
+ "path": "mixHealth.rms"
105
+ }
106
+ ]
107
+ },
108
+ {
109
+ "type": "window_eval",
110
+ "label": "classify-mix-change",
111
+ "timeout_ms": 10000,
112
+ "store_return_to": "__neonProof.mixChange",
113
+ "script": "const pre=window.__neonProof?.preAction||{}; const post=window.__neonProof?.postAction||{}; const edit=window.__neonProof?.mixEdit||{}; const preRms=Number(pre.mixHealth?.rms||0); const postRms=Number(post.mixHealth?.rms||0); const peak=Number(post.mixHealth?.peak||0); const metricMoved=Math.abs(postRms-preRms)>0.00001||Math.abs(Number(post.mixHealth?.peak||0)-Number(pre.mixHealth?.peak||0))>0.00001; const out={ok:Boolean(pre.ok&&post.ok&&edit.ok&&metricMoved&&peak<0.98),levelChanged:Boolean(edit.ok),metricMoved,preRms,postRms,postPeak:peak}; window.__neonProof.mixChange=out; return out;",
114
+ "return_summary_fields": [
115
+ {
116
+ "path": "ok"
117
+ },
118
+ {
119
+ "path": "levelChanged"
120
+ },
121
+ {
122
+ "path": "metricMoved"
123
+ },
124
+ {
125
+ "path": "postPeak"
126
+ }
127
+ ]
128
+ },
129
+ {
130
+ "type": "assert_window_value",
131
+ "path": "__neonProof.mixChange.levelChanged",
132
+ "expected_value": true,
133
+ "timeout_ms": 10000
134
+ },
135
+ {
136
+ "type": "assert_window_value",
137
+ "path": "__neonProof.mixChange.metricMoved",
138
+ "expected_value": true,
139
+ "timeout_ms": 10000
140
+ },
141
+ {
142
+ "type": "assert_window_number",
143
+ "path": "__neonProof.mixChange.postPeak",
144
+ "max_value": 0.98,
145
+ "timeout_ms": 10000
146
+ },
147
+ {
148
+ "type": "screenshot",
149
+ "label": "neon-mix-change-post-action",
150
+ "mode": "viewport"
151
+ }
152
+ ]
153
+ },
154
+ "checks": [
155
+ {
156
+ "type": "route_loaded",
157
+ "expected_path": "/games/drum-sequencer"
158
+ },
159
+ {
160
+ "type": "selector_visible",
161
+ "selector": ".drum-sequencer h1"
162
+ },
163
+ {
164
+ "type": "no_horizontal_overflow",
165
+ "max_overflow_px": 1
166
+ },
167
+ {
168
+ "type": "no_fatal_console_errors"
169
+ }
170
+ ],
171
+ "artifacts": [
172
+ "screenshot",
173
+ "console",
174
+ "dom_summary",
175
+ "proof_json"
176
+ ],
177
+ "baseline_policy": "invariant_only",
178
+ "failure_policy": {
179
+ "environment_blocked": "neutral",
180
+ "proof_insufficient": "review",
181
+ "product_regression": "fail",
182
+ "needs_human_review": "review"
183
+ },
184
+ "metadata": {
185
+ "pack_id": "neon_step_sequencer",
186
+ "pack_public_name": "Neon Step Sequencer Pack",
187
+ "evidence_role_pattern": "interaction_snapshots",
188
+ "purpose": "Interaction proof that a pre-action/post-action mix edit changes objective audio metrics without clipping.",
189
+ "required_receipts": [
190
+ "pre-action offline render metrics",
191
+ "visible/user-like bass mix change",
192
+ "post-action offline render metrics",
193
+ "metric movement classification",
194
+ "post-action clipping guardrail"
195
+ ],
196
+ "does_not_prove": [
197
+ "that the change sounds better",
198
+ "that every mix control affects every render window",
199
+ "cross-device control reachability"
200
+ ]
201
+ }
202
+ }
@@ -0,0 +1,109 @@
1
+ {
2
+ "version": "riddle-proof.profile.v1",
3
+ "name": "neon-step-sequencer-mobile-trainer-layout",
4
+ "target": {
5
+ "route": "/games/drum-sequencer?song=monkberry-moon-delight-tab&mix=profile&view=trainer&instrument=bass",
6
+ "viewports": [
7
+ {
8
+ "name": "phone",
9
+ "width": 390,
10
+ "height": 844
11
+ },
12
+ {
13
+ "name": "ipad-mini",
14
+ "width": 768,
15
+ "height": 1024
16
+ }
17
+ ],
18
+ "timeout_sec": 180,
19
+ "wait_for_selector": ".drum-sequencer h1",
20
+ "setup_actions": [
21
+ {
22
+ "type": "window_eval",
23
+ "label": "capture-mobile-trainer-state",
24
+ "timeout_ms": 10000,
25
+ "store_return_to": "__neonProof.mobile",
26
+ "script": "const api=window.__NEON_MIX_PROOF__||window.__RIDDLE_SEQUENCER_PROOF__; const state=api?.getState?.()||api?.getSummary?.()||{}; const trainer=document.querySelector('.instrument-trainer')||document.querySelector('[class*=trainer]'); const mix=document.querySelector('.mix-board')||document.querySelector('[class*=mix]'); const out={available:Boolean(api),route:state.route||location.pathname,selectedSong:state.selectedSong||null,trainerVisible:Boolean(trainer),mixVisible:Boolean(mix),scrollWidth:document.documentElement.scrollWidth,clientWidth:document.documentElement.clientWidth}; window.__neonProof={...(window.__neonProof||{}),mobile:out}; return out;",
27
+ "return_summary_fields": [
28
+ {
29
+ "path": "available"
30
+ },
31
+ {
32
+ "path": "trainerVisible"
33
+ },
34
+ {
35
+ "path": "mixVisible"
36
+ },
37
+ {
38
+ "path": "scrollWidth"
39
+ },
40
+ {
41
+ "path": "clientWidth"
42
+ }
43
+ ]
44
+ },
45
+ {
46
+ "type": "assert_window_value",
47
+ "path": "__neonProof.mobile.available",
48
+ "expected_value": true,
49
+ "timeout_ms": 10000
50
+ },
51
+ {
52
+ "type": "assert_window_value",
53
+ "path": "__neonProof.mobile.trainerVisible",
54
+ "expected_value": true,
55
+ "timeout_ms": 10000
56
+ },
57
+ {
58
+ "type": "screenshot",
59
+ "label": "neon-mobile-trainer-layout",
60
+ "mode": "viewport"
61
+ }
62
+ ]
63
+ },
64
+ "checks": [
65
+ {
66
+ "type": "route_loaded",
67
+ "expected_path": "/games/drum-sequencer"
68
+ },
69
+ {
70
+ "type": "selector_visible",
71
+ "selector": ".drum-sequencer h1"
72
+ },
73
+ {
74
+ "type": "no_mobile_horizontal_overflow"
75
+ },
76
+ {
77
+ "type": "no_fatal_console_errors"
78
+ }
79
+ ],
80
+ "artifacts": [
81
+ "screenshot",
82
+ "console",
83
+ "dom_summary",
84
+ "proof_json"
85
+ ],
86
+ "baseline_policy": "invariant_only",
87
+ "failure_policy": {
88
+ "environment_blocked": "neutral",
89
+ "proof_insufficient": "review",
90
+ "product_regression": "fail"
91
+ },
92
+ "metadata": {
93
+ "pack_id": "neon_step_sequencer",
94
+ "pack_public_name": "Neon Step Sequencer Pack",
95
+ "evidence_role_pattern": "current_target",
96
+ "purpose": "Phone/tablet current-target audit for trainer reachability and overflow.",
97
+ "required_receipts": [
98
+ "mobile trainer state is readable",
99
+ "trainer surface is visible",
100
+ "viewport screenshot is captured",
101
+ "mobile overflow is clean"
102
+ ],
103
+ "does_not_prove": [
104
+ "all mixer controls are comfortable to use",
105
+ "audio output quality",
106
+ "desktop layout"
107
+ ]
108
+ }
109
+ }
@@ -0,0 +1,126 @@
1
+ {
2
+ "version": "riddle-proof.profile.v1",
3
+ "name": "neon-step-sequencer-playback-sync",
4
+ "target": {
5
+ "route": "/games/drum-sequencer?song=monkberry-moon-delight-tab&mix=profile&view=trainer&instrument=bass",
6
+ "viewports": [
7
+ {
8
+ "name": "desktop",
9
+ "width": 1440,
10
+ "height": 1000
11
+ }
12
+ ],
13
+ "timeout_sec": 180,
14
+ "wait_for_selector": ".drum-sequencer h1",
15
+ "setup_actions": [
16
+ {
17
+ "type": "window_eval",
18
+ "label": "capture-pre-playback-state",
19
+ "timeout_ms": 10000,
20
+ "store_return_to": "__neonProof.prePlayback",
21
+ "script": "const api=window.__NEON_MIX_PROOF__||window.__RIDDLE_SEQUENCER_PROOF__; const state=api?.getPlaybackState?.()||api?.getSummary?.()?.trainer||null; window.__neonProof={...(window.__neonProof||{}),prePlayback:{available:Boolean(api),state}}; return window.__neonProof.prePlayback;",
22
+ "return_summary_fields": [
23
+ {
24
+ "path": "available"
25
+ },
26
+ {
27
+ "path": "state.selectedInstrument"
28
+ },
29
+ {
30
+ "path": "state.currentStep"
31
+ }
32
+ ]
33
+ },
34
+ {
35
+ "type": "assert_window_value",
36
+ "path": "__neonProof.prePlayback.available",
37
+ "expected_value": true,
38
+ "timeout_ms": 10000
39
+ },
40
+ {
41
+ "type": "click",
42
+ "selector": "button.drum-play",
43
+ "timeout_ms": 10000
44
+ },
45
+ {
46
+ "type": "wait",
47
+ "ms": 900
48
+ },
49
+ {
50
+ "type": "window_eval",
51
+ "label": "capture-post-playback-state",
52
+ "timeout_ms": 10000,
53
+ "store_return_to": "__neonProof.postPlayback",
54
+ "script": "const api=window.__NEON_MIX_PROOF__||window.__RIDDLE_SEQUENCER_PROOF__; const state=api?.getPlaybackState?.()||api?.getSummary?.()?.trainer||null; const summary=api?.getState?.()||api?.getSummary?.()||{}; const out={available:Boolean(api),isPlaying:Boolean(summary.isPlaying),state}; window.__neonProof={...(window.__neonProof||{}),postPlayback:out}; return out;",
55
+ "return_summary_fields": [
56
+ {
57
+ "path": "isPlaying"
58
+ },
59
+ {
60
+ "path": "state.currentStep"
61
+ },
62
+ {
63
+ "path": "state.selectedInstrument"
64
+ }
65
+ ]
66
+ },
67
+ {
68
+ "type": "assert_window_value",
69
+ "path": "__neonProof.postPlayback.available",
70
+ "expected_value": true,
71
+ "timeout_ms": 10000
72
+ },
73
+ {
74
+ "type": "screenshot",
75
+ "label": "neon-playback-sync",
76
+ "mode": "viewport"
77
+ }
78
+ ]
79
+ },
80
+ "checks": [
81
+ {
82
+ "type": "route_loaded",
83
+ "expected_path": "/games/drum-sequencer"
84
+ },
85
+ {
86
+ "type": "selector_visible",
87
+ "selector": ".drum-sequencer h1"
88
+ },
89
+ {
90
+ "type": "selector_visible",
91
+ "selector": "button.drum-play"
92
+ },
93
+ {
94
+ "type": "no_fatal_console_errors"
95
+ }
96
+ ],
97
+ "artifacts": [
98
+ "screenshot",
99
+ "console",
100
+ "dom_summary",
101
+ "proof_json"
102
+ ],
103
+ "baseline_policy": "invariant_only",
104
+ "failure_policy": {
105
+ "environment_blocked": "neutral",
106
+ "proof_insufficient": "review",
107
+ "product_regression": "fail"
108
+ },
109
+ "metadata": {
110
+ "pack_id": "neon_step_sequencer",
111
+ "pack_public_name": "Neon Step Sequencer Pack",
112
+ "evidence_role_pattern": "interaction_snapshots",
113
+ "purpose": "Interaction proof that visible playback state and proof-contract playback state can be captured together.",
114
+ "required_receipts": [
115
+ "pre-action playback state",
116
+ "play button interaction",
117
+ "post-action playback state",
118
+ "screenshot after interaction"
119
+ ],
120
+ "does_not_prove": [
121
+ "long-running transport timing",
122
+ "audio output quality",
123
+ "song-wide playback correctness"
124
+ ]
125
+ }
126
+ }
@@ -0,0 +1,137 @@
1
+ {
2
+ "version": "riddle-proof.profile.v1",
3
+ "name": "neon-step-sequencer-ratchet-loop-mix-level-search",
4
+ "target": {
5
+ "route": "/games/drum-sequencer?song=monkberry-moon-delight-tab&mix=profile&view=trainer&instrument=bass",
6
+ "viewports": [
7
+ {
8
+ "name": "desktop",
9
+ "width": 1440,
10
+ "height": 1000
11
+ }
12
+ ],
13
+ "timeout_sec": 360,
14
+ "wait_for_selector": ".drum-sequencer h1",
15
+ "setup_actions": [
16
+ {
17
+ "type": "window_eval",
18
+ "label": "capture-neon-contract",
19
+ "timeout_ms": 10000,
20
+ "store_return_to": "__neonMixProof.contract",
21
+ "script": "const contract=window.__NEON_MIX_PROOF__; const diagnostic=contract?.captureDiagnostic?.(); window.__neonMixProof={...(window.__neonMixProof||{}),contract:{available:Boolean(contract),diagnostic}}; return window.__neonMixProof.contract;",
22
+ "return_summary_fields": [
23
+ {
24
+ "path": "available"
25
+ },
26
+ {
27
+ "path": "diagnostic.selectedSong.selectedSong"
28
+ }
29
+ ]
30
+ },
31
+ {
32
+ "type": "assert_window_value",
33
+ "path": "__neonMixProof.contract.available",
34
+ "expected_value": true,
35
+ "timeout_ms": 10000
36
+ },
37
+ {
38
+ "type": "window_call",
39
+ "label": "run-ratchet-loop-mix-level-search",
40
+ "path": "__NEON_MIX_PROOF__.runRatchetLoop",
41
+ "args": [
42
+ {
43
+ "strategy": "mix-level-search",
44
+ "focusTracks": [
45
+ "bass",
46
+ "chord",
47
+ "guitar",
48
+ "rhythmSynth"
49
+ ],
50
+ "maxIterations": 6,
51
+ "monitorProfile": "smallSpeaker",
52
+ "restore": true,
53
+ "applyBest": false,
54
+ "minImprovement": 0.1
55
+ }
56
+ ],
57
+ "store_return_to": "__neonMixProof.ratchetLoop",
58
+ "capture_return": true,
59
+ "timeout_ms": 240000,
60
+ "return_summary_fields": [
61
+ {
62
+ "path": "ok"
63
+ },
64
+ {
65
+ "path": "status"
66
+ },
67
+ {
68
+ "path": "strategy"
69
+ },
70
+ {
71
+ "path": "improvement"
72
+ },
73
+ {
74
+ "path": "best.candidate.track"
75
+ }
76
+ ]
77
+ },
78
+ {
79
+ "type": "assert_window_value",
80
+ "path": "__neonMixProof.ratchetLoop.ok",
81
+ "expected_value": true,
82
+ "timeout_ms": 10000
83
+ },
84
+ {
85
+ "type": "screenshot",
86
+ "label": "neon-ratchet-loop-mix-level-search",
87
+ "mode": "viewport"
88
+ }
89
+ ]
90
+ },
91
+ "checks": [
92
+ {
93
+ "type": "route_loaded",
94
+ "expected_path": "/games/drum-sequencer"
95
+ },
96
+ {
97
+ "type": "selector_visible",
98
+ "selector": ".drum-sequencer h1"
99
+ },
100
+ {
101
+ "type": "no_horizontal_overflow"
102
+ },
103
+ {
104
+ "type": "no_fatal_console_errors"
105
+ }
106
+ ],
107
+ "artifacts": [
108
+ "screenshot",
109
+ "console",
110
+ "dom_summary",
111
+ "proof_json"
112
+ ],
113
+ "baseline_policy": "invariant_only",
114
+ "failure_policy": {
115
+ "environment_blocked": "neutral",
116
+ "proof_insufficient": "review",
117
+ "needs_human_review": "review",
118
+ "product_regression": "fail"
119
+ },
120
+ "metadata": {
121
+ "pack_id": "neon_step_sequencer",
122
+ "pack_public_name": "Neon Step Sequencer Pack",
123
+ "evidence_role_pattern": "interaction_snapshots",
124
+ "purpose": "Run a bounded automated ratchet loop using the Neon mix-level-search strategy.",
125
+ "required_receipts": [
126
+ "ratchet loop returns ok",
127
+ "baseline proof-window summary is captured",
128
+ "candidate attempts are captured",
129
+ "best candidate or human-review status is captured"
130
+ ],
131
+ "does_not_prove": [
132
+ "subjective mix quality",
133
+ "that the best objective candidate should be kept",
134
+ "all possible mix edits"
135
+ ]
136
+ }
137
+ }
@@ -0,0 +1,114 @@
1
+ {
2
+ "version": "riddle-proof.profile.v1",
3
+ "name": "neon-step-sequencer-source-readiness",
4
+ "target": {
5
+ "route": "/games/drum-sequencer?song=monkberry-moon-delight-tab&mix=profile&view=trainer&instrument=bass",
6
+ "viewports": [
7
+ {
8
+ "name": "desktop",
9
+ "width": 1440,
10
+ "height": 1000
11
+ }
12
+ ],
13
+ "timeout_sec": 300,
14
+ "wait_for_selector": ".drum-sequencer h1",
15
+ "setup_actions": [
16
+ {
17
+ "type": "window_eval",
18
+ "label": "install-neon-source-proof",
19
+ "timeout_ms": 10000,
20
+ "store_return_to": "__neonProof.install",
21
+ "script": "window.__neonProofApi=()=>window.__NEON_MIX_PROOF__||window.__RIDDLE_SEQUENCER_PROOF__; window.__neonProofPrepare=async(options={})=>{const api=window.__neonProofApi(); return await (api?.prepareForAudioProof?.(options)||api?.prepareSampleSourcesForProof?.(options)||{ok:false,error:'missing prepareForAudioProof'});}; return {available:Boolean(window.__neonProofApi())};"
22
+ },
23
+ {
24
+ "type": "assert_window_value",
25
+ "path": "__neonProof.install.available",
26
+ "expected_value": true,
27
+ "timeout_ms": 10000
28
+ },
29
+ {
30
+ "type": "window_call",
31
+ "label": "load-required-sources",
32
+ "path": "__neonProofPrepare",
33
+ "args": [
34
+ {
35
+ "loadAll": true
36
+ }
37
+ ],
38
+ "store_return_to": "__neonProof.sources",
39
+ "capture_return": true,
40
+ "timeout_ms": 120000,
41
+ "return_summary_fields": [
42
+ {
43
+ "path": "ok"
44
+ },
45
+ {
46
+ "path": "states.drums.status"
47
+ },
48
+ {
49
+ "path": "states.bass.status"
50
+ },
51
+ {
52
+ "path": "states.guitar.status"
53
+ },
54
+ {
55
+ "path": "states.vocal.status"
56
+ }
57
+ ]
58
+ },
59
+ {
60
+ "type": "assert_window_value",
61
+ "path": "__neonProof.sources.ok",
62
+ "expected_value": true,
63
+ "timeout_ms": 10000
64
+ },
65
+ {
66
+ "type": "screenshot",
67
+ "label": "neon-source-readiness",
68
+ "mode": "viewport"
69
+ }
70
+ ]
71
+ },
72
+ "checks": [
73
+ {
74
+ "type": "route_loaded",
75
+ "expected_path": "/games/drum-sequencer"
76
+ },
77
+ {
78
+ "type": "selector_visible",
79
+ "selector": ".drum-sequencer h1"
80
+ },
81
+ {
82
+ "type": "no_fatal_console_errors"
83
+ }
84
+ ],
85
+ "artifacts": [
86
+ "screenshot",
87
+ "console",
88
+ "dom_summary",
89
+ "proof_json"
90
+ ],
91
+ "baseline_policy": "invariant_only",
92
+ "failure_policy": {
93
+ "environment_blocked": "neutral",
94
+ "proof_insufficient": "review",
95
+ "product_regression": "fail"
96
+ },
97
+ "metadata": {
98
+ "pack_id": "neon_step_sequencer",
99
+ "pack_public_name": "Neon Step Sequencer Pack",
100
+ "evidence_role_pattern": "current_target",
101
+ "purpose": "Current-target audit for sample/source readiness before metric claims.",
102
+ "required_receipts": [
103
+ "source proof helper is available",
104
+ "required source loaders complete",
105
+ "sample/source states are captured",
106
+ "console health is clean"
107
+ ],
108
+ "does_not_prove": [
109
+ "offline metric quality",
110
+ "subjective source quality",
111
+ "full song playback"
112
+ ]
113
+ }
114
+ }