{
 "use_case": "record",
 "title": "Tamper-evident record: 30 seconds of a town council meeting, streamed from a file",
 "about": "The first 30 seconds of a synthetic town council meeting, streamed from a WAV file over the live WebSocket as if it came from a microphone. The session must produce captions and end in a signed, hash-chained record that verifies, and one edited caption must be caught.",
 "licence": "Synthetic: a script written for Decosa (fictional town and people) read by Decosa house voices (Kokoro-82M stock voicepacks, Apache-2.0), each allowed by the consent ledger for project decosa-record-demo. Part of decosa-api, AGPL-3.0-or-later.",
 "inputs": [
  {"file": "inputs/council-meeting-30s.wav", "what": "16 kHz mono 16-bit WAV. Your own recordings must be in the same format (ffmpeg -i in.m4a -ac 1 -ar 16000 -sample_fmt s16 out.wav)."},
  {"file": "inputs/council-meeting-script.json", "what": "The script the audio was made from, to compare the captions against by eye."}
 ],
 "steps": [
  {"id": "session", "live": {"vertical": "record", "audio": "inputs/council-meeting-30s.wav", "speed": 2}, "timeout": 120},
  {"id": "verify", "method": "POST", "path": "/record/verify", "auth": false, "body": {"$ref": "session.done.summary.record"}},
  {"id": "tampered", "method": "POST", "path": "/record/verify", "auth": false, "body": {"$ref": "session.done.summary.record"},
   "tamper": {"at": "entries[kind=caption].text", "set": "Member Foster is present. (edited)"}}
 ],
 "checks": [
  {"says": "the session ends with a done event", "path": "session.done", "exists": true},
  {"says": "the session reports no errors", "path": "session.errors", "count": 0},
  {"says": "final captions arrive", "path": "session.captions", "count_min": 2},
  {"says": "the captions carry the roll call of the town council", "path": "session.captions.text", "contains": "council"},
  {"says": "the server's own check of the sealed record passes", "path": "session.done.summary.record_check.ok", "equals": true},
  {"says": "the signed record verifies", "path": "verify.ok", "equals": true},
  {"says": "a record with one caption edited no longer verifies", "path": "tampered.ok", "equals": false},
  {"says": "the verifier names the first bad entry", "path": "tampered.first_bad", "exists": true},
  {"says": "every speech and model call has a signed receipt", "receipts": "signed"}
 ]
}
