{
  "version": "riddle-proof.profile.v1",
  "name": "lilarcade-neon-ui-mixer-control-guitar",
  "target": {
    "route": "/neon-lab/games/drum-sequencer?song=monkberry-moon-delight-tab&mix=profile&view=trainer&instrument=guitar",
    "viewports": [
      {
        "name": "desktop",
        "width": 1440,
        "height": 1000
      }
    ],
    "timeout_sec": 240,
    "wait_for_selector": ".drum-sequencer h1",
    "setup_actions": [
      {
        "type": "window_eval",
        "label": "apply-ui-mixer-level-control",
        "args": [
          {
            "track": "guitar",
            "targetLevel": 0.5
          }
        ],
        "store_return_to": "__neonUiMixerControl.receipt",
        "capture_return": true,
        "timeout_ms": 15000,
        "script": "\nconst [payload] = args;\nconst track = String(payload?.track || '');\nconst targetLevel = Number(payload?.targetLevel);\nconst wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));\nconst escapeAttr = (value) => String(value).replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"');\nconst readNumber = (value) => {\n  const number = Number(value);\n  return Number.isFinite(number) ? number : null;\n};\nconst approxEqual = (a, b, epsilon = 0.01) => (\n  Number.isFinite(Number(a)) && Number.isFinite(Number(b)) && Math.abs(Number(a) - Number(b)) <= epsilon\n);\nconst parseReadout = (value) => {\n  const match = String(value ?? '').match(/-?\\d+(?:\\.\\d+)?/u);\n  return match ? Number(match[0]) : null;\n};\nconst getApi = () => window.__NEON_MIX_PROOF__ || window.__RIDDLE_NEON_PROOF_CONTRACT__ || window.__RIDDLE_SEQUENCER_PROOF__;\nconst readMixerLevel = () => {\n  const api = getApi();\n  const mixer = api?.getMixerState?.();\n  return readNumber(mixer?.levels?.[track]);\n};\nconst selectorTrack = escapeAttr(track);\nconst lane = document.querySelector('[data-proof-surface=\"instrument-lane\"][data-proof-track=\"' + selectorTrack + '\"]');\nconst input = document.querySelector('[data-proof-control=\"mixer-level\"][data-proof-track=\"' + selectorTrack + '\"]');\nconst readout = document.querySelector('[data-proof-readout=\"mixer-level\"][data-proof-track=\"' + selectorTrack + '\"]');\nconst beforeContractLevel = readMixerLevel();\nconst beforeInputLevel = readNumber(input?.value);\nconst beforeReadoutLevel = parseReadout(readout?.textContent);\nconst findings = [];\nif (!getApi()) findings.push('missing_neon_proof_contract');\nif (!lane) findings.push('missing_instrument_lane');\nif (!input) findings.push('missing_mixer_level_input');\nif (!readout) findings.push('missing_mixer_level_readout');\nif (input?.disabled) findings.push('mixer_level_input_disabled');\nif (!Number.isFinite(targetLevel)) findings.push('invalid_target_level');\nif (findings.length) {\n  const failed = {\n    ok: false,\n    interactionKind: 'ui_mixer_level_slider',\n    proofApiEditUsed: false,\n    track,\n    targetLevel,\n    beforeContractLevel,\n    beforeInputLevel,\n    beforeReadoutLevel,\n    findings,\n  };\n  window.__neonUiMixerControl = { ...(window.__neonUiMixerControl || {}), receipt: failed };\n  return failed;\n}\nconst setter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, 'value')?.set;\nif (setter) setter.call(input, String(targetLevel));\nelse input.value = String(targetLevel);\ninput.dispatchEvent(new Event('input', { bubbles: true }));\ninput.dispatchEvent(new Event('change', { bubbles: true }));\nawait wait(500);\nconst afterContractLevel = readMixerLevel();\nconst afterInputLevel = readNumber(input.value);\nconst afterReadoutLevel = parseReadout(readout.textContent);\nconst levelMoved = Number.isFinite(beforeContractLevel)\n  ? Math.abs(Number(afterContractLevel) - Number(beforeContractLevel)) > 0.001\n  : true;\nconst contractMatchesTarget = approxEqual(afterContractLevel, targetLevel);\nconst inputMatchesTarget = approxEqual(afterInputLevel, targetLevel);\nconst readoutMatchesTarget = approxEqual(afterReadoutLevel, targetLevel);\nif (!levelMoved) findings.push('contract_level_did_not_move');\nif (!contractMatchesTarget) findings.push('contract_level_target_mismatch');\nif (!inputMatchesTarget) findings.push('slider_value_target_mismatch');\nif (!readoutMatchesTarget) findings.push('readout_target_mismatch');\nconst receipt = {\n  ok: findings.length === 0,\n  interactionKind: 'ui_mixer_level_slider',\n  proofApiEditUsed: false,\n  track,\n  targetLevel,\n  beforeContractLevel,\n  beforeInputLevel,\n  beforeReadoutLevel,\n  afterContractLevel,\n  afterInputLevel,\n  afterReadoutLevel,\n  levelDelta: Number.isFinite(beforeContractLevel) && Number.isFinite(afterContractLevel)\n    ? Number((afterContractLevel - beforeContractLevel).toFixed(4))\n    : null,\n  levelMoved,\n  contractMatchesTarget,\n  inputMatchesTarget,\n  readoutMatchesTarget,\n  findings,\n};\nwindow.__neonUiMixerControl = { ...(window.__neonUiMixerControl || {}), receipt };\nreturn receipt;\n",
        "return_summary_fields": [
          {
            "path": "ok"
          },
          {
            "path": "track"
          },
          {
            "path": "targetLevel"
          },
          {
            "path": "beforeContractLevel"
          },
          {
            "path": "afterContractLevel"
          },
          {
            "path": "proofApiEditUsed"
          }
        ]
      },
      {
        "type": "assert_window_value",
        "path": "__neonUiMixerControl.receipt.ok",
        "expected_value": true,
        "timeout_ms": 10000
      },
      {
        "type": "assert_window_value",
        "path": "__neonUiMixerControl.receipt.proofApiEditUsed",
        "expected_value": false,
        "timeout_ms": 10000
      },
      {
        "type": "screenshot",
        "label": "neon-ui-mixer-control-after",
        "mode": "viewport"
      },
      {
        "type": "window_call",
        "label": "render-post-ui-control-metrics",
        "path": "__NEON_MIX_PROOF__.renderOfflineMetrics",
        "args": [
          {
            "bars": 1,
            "seed": "neon-ui-mixer-control-guitar",
            "monitorProfile": "smallSpeaker"
          }
        ],
        "store_return_to": "__neonUiMixerControl.render",
        "capture_return": true,
        "timeout_ms": 120000,
        "return_summary_fields": [
          {
            "path": "ok"
          },
          {
            "path": "mixHealth.peak"
          },
          {
            "path": "mixHealth.rms"
          },
          {
            "path": "mixHealth.headroomDb"
          },
          {
            "path": "mixHealth.clipping"
          },
          {
            "path": "mixHealth.lowLevel"
          }
        ]
      },
      {
        "type": "window_eval",
        "label": "classify-ui-mixer-control-guardrails",
        "store_return_to": "__neonUiMixerControl.summary",
        "capture_return": true,
        "timeout_ms": 10000,
        "script": "\nconst receipt = window.__neonUiMixerControl?.receipt || {};\nconst render = window.__neonUiMixerControl?.render || {};\nconst mixHealth = render.mixHealth || {};\nconst findings = [];\nif (!receipt.ok) findings.push(...(receipt.findings || ['ui_mixer_control_receipt_failed']));\nif (!render.ok) findings.push('offline_render_failed');\nif (mixHealth.clipping === true) findings.push('post_control_render_clipping');\nif (mixHealth.lowLevel === true) findings.push('post_control_render_low_level');\nconst peak = Number(mixHealth.peak);\nif (Number.isFinite(peak) && peak >= 0.98) findings.push('post_control_peak_too_high');\nconst summary = {\n  ok: findings.length === 0,\n  status: findings.length === 0 ? 'ui_mixer_control_ready' : 'deterministic_findings_present',\n  track: receipt.track || null,\n  targetLevel: receipt.targetLevel ?? null,\n  beforeContractLevel: receipt.beforeContractLevel ?? null,\n  afterContractLevel: receipt.afterContractLevel ?? null,\n  levelDelta: receipt.levelDelta ?? null,\n  proofApiEditUsed: receipt.proofApiEditUsed === true,\n  guardrails: {\n    renderOk: render.ok === true,\n    clipping: mixHealth.clipping === true,\n    lowLevel: mixHealth.lowLevel === true,\n    peak: Number.isFinite(peak) ? peak : null,\n    rms: Number.isFinite(Number(mixHealth.rms)) ? Number(mixHealth.rms) : null,\n    headroomDb: Number.isFinite(Number(mixHealth.headroomDb)) ? Number(mixHealth.headroomDb) : null,\n  },\n  findings,\n  boundary: 'UI control and deterministic audio guardrails only; this does not prove subjective mix taste.',\n};\nwindow.__neonUiMixerControl = { ...(window.__neonUiMixerControl || {}), summary };\nreturn summary;\n",
        "return_summary_fields": [
          {
            "path": "ok"
          },
          {
            "path": "status"
          },
          {
            "path": "guardrails.peak"
          },
          {
            "path": "guardrails.clipping"
          },
          {
            "path": "guardrails.lowLevel"
          }
        ]
      },
      {
        "type": "assert_window_value",
        "path": "__neonUiMixerControl.summary.ok",
        "expected_value": true,
        "timeout_ms": 10000
      },
      {
        "type": "window_eval",
        "label": "restore-ui-mixer-level-control",
        "store_return_to": "__neonUiMixerControl.restore",
        "capture_return": true,
        "timeout_ms": 15000,
        "script": "\nconst wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));\nconst escapeAttr = (value) => String(value).replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"');\nconst approxEqual = (a, b, epsilon = 0.01) => (\n  Number.isFinite(Number(a)) && Number.isFinite(Number(b)) && Math.abs(Number(a) - Number(b)) <= epsilon\n);\nconst receipt = window.__neonUiMixerControl?.receipt || {};\nconst track = String(receipt.track || '');\nconst restoreLevel = Number(receipt.beforeContractLevel);\nconst getApi = () => window.__NEON_MIX_PROOF__ || window.__RIDDLE_NEON_PROOF_CONTRACT__ || window.__RIDDLE_SEQUENCER_PROOF__;\nconst readMixerLevel = () => Number(getApi()?.getMixerState?.()?.levels?.[track]);\nconst input = document.querySelector('[data-proof-control=\"mixer-level\"][data-proof-track=\"' + escapeAttr(track) + '\"]');\nconst findings = [];\nif (!input) findings.push('missing_mixer_level_input');\nif (!Number.isFinite(restoreLevel)) findings.push('missing_restore_level');\nif (!findings.length) {\n  const setter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, 'value')?.set;\n  if (setter) setter.call(input, String(restoreLevel));\n  else input.value = String(restoreLevel);\n  input.dispatchEvent(new Event('input', { bubbles: true }));\n  input.dispatchEvent(new Event('change', { bubbles: true }));\n  await wait(400);\n}\nconst restoredLevel = readMixerLevel();\nif (!approxEqual(restoredLevel, restoreLevel)) findings.push('restore_level_mismatch');\nconst restore = {\n  ok: findings.length === 0,\n  interactionKind: 'ui_mixer_level_restore',\n  proofApiEditUsed: false,\n  track,\n  restoreLevel: Number.isFinite(restoreLevel) ? restoreLevel : null,\n  restoredLevel: Number.isFinite(restoredLevel) ? restoredLevel : null,\n  findings,\n};\nwindow.__neonUiMixerControl = { ...(window.__neonUiMixerControl || {}), restore };\nreturn restore;\n",
        "return_summary_fields": [
          {
            "path": "ok"
          },
          {
            "path": "track"
          },
          {
            "path": "restoreLevel"
          },
          {
            "path": "restoredLevel"
          },
          {
            "path": "proofApiEditUsed"
          }
        ]
      },
      {
        "type": "assert_window_value",
        "path": "__neonUiMixerControl.restore.ok",
        "expected_value": true,
        "timeout_ms": 10000
      }
    ]
  },
  "checks": [
    {
      "type": "route_loaded",
      "expected_path": "/neon-lab/games/drum-sequencer"
    },
    {
      "type": "selector_visible",
      "selector": ".drum-sequencer h1"
    },
    {
      "type": "no_horizontal_overflow",
      "max_overflow_px": 1
    },
    {
      "type": "no_fatal_console_errors"
    }
  ],
  "artifacts": [
    "screenshot",
    "console",
    "dom_summary",
    "proof_json"
  ],
  "baseline_policy": "invariant_only",
  "failure_policy": {
    "environment_blocked": "neutral",
    "proof_insufficient": "review",
    "product_regression": "fail",
    "needs_human_review": "review"
  },
  "metadata": {
    "pack_id": "neon_step_sequencer_local",
    "evidence_role_pattern": "interaction_snapshots",
    "purpose": "UI-only proof that the real Neon mixer level slider updates contract state and preserves deterministic render guardrails.",
    "required_receipts": [
      "actual range input dispatch",
      "contract mixer level changed",
      "visible readout changed",
      "proof API mixer edit helper not used",
      "post-control offline render metrics",
      "no clipping or low-level render guardrail failure",
      "UI slider restoration"
    ],
    "does_not_prove": [
      "subjective mix taste",
      "that every mixer control is reachable on every viewport",
      "that proof API controlled edits and UI edits are equivalent for all tracks"
    ]
  }
}
