Top 20 Evidence Receipts That Keep Playtest-to-Public Releases Auditable - 2026
Your producer pasted BUILD_RECEIPT.json into standup. Someone else swore OBS concat was fine. Legal blocked the July highlight reel because VO metadata never landed in the WAV. None of those failures were “the game crashed”—they were missing or mis-filed receipts across tools that never shared a folder.
June–July 2026 micro-studios automate promotion gates but still scatter proof in Slack, spreadsheets, and one engineer’s Downloads/. This Listicles & Resource Roundups hub names twenty JSON receipts—what each proves, when to generate it, default path under release-evidence/, and the on-site deep dive that owns implementation detail.
Non-repetition note: 16 free BUILD_RECEIPT hash tools lists validators; this post lists receipt schemas. VO waveform consent tutorial is one lane—here it is receipt #5 in a full map.
Why this matters now (June–July 2026)
- Playtest volume before October Next Fest — More sessions mean more facilitators; without named receipts, every handoff re-invents proof.
- BUILD_RECEIPT column sprawl — Courses now wire 243/250 consent columns beside VOD and smoke gates—teams need a single index.
- Automation without taxonomy — CI can read JSON; it cannot read “trust me, ffmpeg worked.”
- Legal + ops split — Video consent and WAV consent are different receipts; merging schemas causes false GREEN.
- Thursday row review — Ten-minute BUILD_RECEIPT diff ritual only works when receipt filenames are stable.
Direct answer: Pick eight receipts minimum for playtest→public: #1–#7 plus #5 or #4 depending on reels. Add store lanes #8–#14 before fest visibility. Add partner packet #15–#16 when cert intake opens.
Who this list is for
| Audience | Use this list to… |
|---|---|
| Solo dev | Know which JSON files to create before promoting a branch |
| Producer | Audit release-evidence/ without opening twelve tools |
| Facilitator | See how VOD receipts differ from marketing consent receipts |
Time: 45 minutes to read; one sprint to implement the first eight paths.
How to read each entry
| Column | Meaning |
|---|---|
| Proves | What a skeptical reviewer believes after reading the file |
| Generate when | Trigger event—not calendar vanity |
| Default path | Under release-evidence/ unless noted |
| BUILD_RECEIPT | Column or boolean promoted when gates pass |
| Deep dive | Tutorial, lesson, or guide on this site |
Master index (all twenty)
| # | Receipt schema | Lane |
|---|---|---|
| 1 | BUILD_RECEIPT.json + MANIFEST.json |
Core identity |
| 2 | playtest_vod_triage_receipt_v1 |
VOD triage |
| 3 | ffmpeg_concat_decision_receipt_v1 |
VOD recovery |
| 4 | playtest_clip_consent_receipt_v1 |
Video marketing consent |
| 5 | vo_consent_metadata_receipt_v1 |
VO waveform consent |
| 6 | demo_smoke_receipt_v1 |
Pre-promotion smoke |
| 7 | build_receipt_row_diff_receipt_v1 |
Weekly row audit |
| 8 | playtest_isolation_receipt_v1 |
Invite vs public scope |
| 9 | playtest_vod_batch / facilitator batch cousin |
Facilitator SOW |
| 10 | gif_capsule_readability_receipt_v1 |
Store GIF art |
| 11 | gif_capsule_audio_receipt_v1 |
GIF audio promise |
| 12 | loudness_receipt_v1 |
Trailer LUFS |
| 13 | menu_fps_cap_receipt_v1 |
Deck menu GPU |
| 14 | mangohud_idle_recovery_receipt_v1 |
Idle GPU recovery |
| 15 | cors_hosting_decision_receipt_v1 |
HTML5 hosting policy |
| 16 | cors_smoke_receipt_v1 |
itch WASM smoke |
| 17 | orm_channel_receipt_v1 / orm_metallic_flat_receipt_v1 |
Art import |
| 18 | fmod_webgl_snapshot_receipt_v1 |
Web audio buses |
| 19 | language_receipt_v1 |
Ren'Py locale |
| 20 | save_slot_recovery_receipt_v1 |
Branch save labels |
Playtest → public core (receipts 1–7)
1) BUILD_RECEIPT.json + MANIFEST.json
Proves: build_id, depot/branch intent, and file list hash alignment for this upload.
Generate when: Every candidate build leaves CI or manual pack—before any storefront upload.
Default path: release-evidence/build-and-binary/<tag>/
BUILD_RECEIPT: Root artifact—not a column.
Deep dive: Your first BUILD_RECEIPT evening pipeline, 16 hash validator tools.
Beginner mistake: Changing zip filename without updating build_id in JSON.
Developer check: jq -e '.build_id' BUILD_RECEIPT.json matches zip prefix.
2) playtest_vod_triage_receipt_v1
Proves: Session VOD is merge-ready (concat_ok) and Whisper batch may run (whisper_batch_allowed).
Generate when: End of playtest evening before overnight ASR.
Default path: release-evidence/playtest/vod/receipts/
BUILD_RECEIPT: playtest_vod_triage_ok or team equivalent boolean.
Deep dive: Local Whisper triage pipeline, OBS concat beginner evening.
Key fields: concat_ok, whisper_batch_allowed, build_id, surface (playtest_invite vs fest_public).
3) ffmpeg_concat_decision_receipt_v1
Proves: When #2 has concat_ok: false, which recovery path was chosen and verified.
Generate when: Copy concat fails—before per-clip Whisper or cloud upload.
Default path: Beside #2 in same receipts/ folder.
BUILD_RECEIPT: Does not replace concat_ok; documents chosen_path.
Deep dive: ffmpeg concat failure decision tree.
Paths: reencode_concat, per_clip_local, cloud_chunked—never omit chosen_path.
4) playtest_clip_consent_receipt_v1
Proves: Which video fragments may appear in public highlight reels; manifest-driven concat.
Generate when: Before marketing muxes OBS MKV highlights—not after upload.
Default path: release-evidence/playtest/vod/PLAYTEST_CLIP_CONSENT_RECEIPT.json
BUILD_RECEIPT: playtest_clip_consent_ok
Deep dive: Lesson 243, OBS highlight consent preflight.
Cousin rule: Does not prove VO WAV tags—that is #5.
5) vo_consent_metadata_receipt_v1
Proves: Facilitator VO WAV embeds consent_record_id, scope, expiry, opt-out; mux survival verified.
Generate when: After Audacity export, after mux dry-run (V5), before public reel.
Default path: release-evidence/audio/VO_CONSENT_METADATA_RECEIPT.json
BUILD_RECEIPT: vo_consent_metadata_ok / wav_consent_metadata_ok
Deep dive: VO waveform consent beginner tutorial, Lesson 250, Audacity preflight.
Incident pattern: #4 GREEN, legal RED → file #5.
6) demo_smoke_receipt_v1
Proves: Wednesday 15-minute smoke passed on candidate fest branch before promotion.
Generate when: After Wednesday demo smoke ritual—before branch merge.
Default path: release-evidence/qa-and-repro/<tag>/demo_smoke_receipt_v1.json
BUILD_RECEIPT: demo_smoke_ok
Deep dive: Wednesday smoke blog; pairs #7 Thursday diff.
Beginner path: One scripted launch + one save/load + exit—log pass/fail, not essay.
7) build_receipt_row_diff_receipt_v1
Proves: Thursday standup compared BUILD_RECEIPT row to prior tag; drift explained or blocked.
Generate when: Ten minutes after Wednesday smoke, before “promote” chat reply.
Default path: Beside #6 under same <tag>.
BUILD_RECEIPT: Gates promotion when diff unresolved.
Deep dive: Thursday BUILD_RECEIPT row review.
Pair: #6 without #7 invites silent column drift.
Scope, facilitator, and store surfaces (8–14)
8) playtest_isolation_receipt_v1
Proves: Playtest invite build cannot leak into public fest demo scope (depot, saves, copy).
Generate when: You add or rename playtest vs demo branches.
Default path: release-evidence/playtest/
BUILD_RECEIPT: playtest_isolation_ok
Deep dive: Playtest invite isolation trend playbook.
8b) Crash symbolicate receipt (minidump + build_label)
Proves: Symbols uploaded for build_label; test minidump symbolicated; crash_symbolicate_ok on BUILD_RECEIPT.
Schema: crash_symbolicate_receipt_v1.json
Deep dive: Your first Steam crash symbolicate receipt JSON (one evening), Lesson 214.
8c) Refund↔BUILD_RECEIPT correlation receipt (fest promotion gate)
Proves: Refund blocker tags align with receipt booleans (crash_symbolicate_ok, proton_audio_ok, etc.) before October fest promotion.
Schema: refund_build_receipt_correlation_receipt_v1.json
Generate when: Weekly Friday refund review or pre-promotion eve after refund-signals.csv exists.
Default path: release-evidence/06-refunds/receipts/
BUILD_RECEIPT: refund_correlation_receipt_path, refund_dashboard_ok
Deep dive: Refund evening tutorial, October correlation trend playbook, Lesson 215.
9) Facilitator contract + version receipt (multi-channel)
Proves: Facilitator obligations—VERSION, build_id, audio gates, receipt manifest—across GX / Steam / itch.
Generate when: External facilitator starts multi-channel playtest wave.
Default path: release-evidence/playtest/contracts/ (PDF + JSON manifest)
BUILD_RECEIPT: Cross-links #2–#5 requirements.
Deep dive: Multi-channel facilitator contract template, Lesson 206.
Note: SOW is contract + manifest; VOD receipts still filed separately.
10) gif_capsule_readability_receipt_v1
Proves: Steam GIF capsule loops read at store zoom; safe-zone respected.
Generate when: Before October fest capsule refresh.
Default path: release-evidence/marketing-and-demo/
BUILD_RECEIPT: gif_readability_ok (team naming)
Deep dive: Animated GIF safe-zone pass.
11) gif_capsule_audio_receipt_v1
Proves: Marketing does not promise audio from GIF-only slots.
Generate when: Copy review before fest ads.
Default path: Same as #10
BUILD_RECEIPT: Independent from #10
Deep dive: Fest marketing GIF audio opinion.
12) loudness_receipt_v1
Proves: Trailer and demo bus loudness within team LUFS window.
Generate when: New trailer export or platform loudness policy change.
Default path: release-evidence/marketing-and-demo/audio/
BUILD_RECEIPT: loudness_ok
Deep dive: 14 free LUFS tools.
13) menu_fps_cap_receipt_v1
Proves: Menu FPS cap configured for Deck-friendly idle behavior.
Generate when: Before Steam Deck verification pass.
Default path: release-evidence/qa-and-repro/deck/
BUILD_RECEIPT: menu_fps_cap_ok
Deep dive: Fest demos should cap menu frame rate.
14) mangohud_idle_recovery_receipt_v1
Proves: GPU idle spike recovered despite menu cap receipt pass—case evidence.
Generate when: MangoHud shows 99% GPU on menu after cap receipt GREEN.
Default path: Beside #13
BUILD_RECEIPT: Recovery column or incident tag
Deep dive: MangoHud GPU 99% case study.
HTML5, art, audio engine, localization (15–20)
15) cors_hosting_decision_receipt_v1
Proves: Custom itch domain vs subdomain policy documented with CORP/COEP implications.
Generate when: Before enabling custom domain on Construct/HTML5 fest demo.
Default path: release-evidence/build-and-binary/html5/
BUILD_RECEIPT: cors_hosting_decision_ok
Deep dive: Construct custom domain CORS playbook.
16) cors_smoke_receipt_v1
Proves: Subdomain WASM smoke passed before custom domain cutover.
Generate when: First itch HTML5 upload on subdomain.
Default path: Same HTML5 folder
BUILD_RECEIPT: cors_smoke_ok
Deep dive: Construct subdomain WASM smoke evening.
17) orm_channel_receipt_v1 + orm_metallic_flat_receipt_v1
Proves: Fab ORM channels truthful in Godot; metallic not flat after node group change.
Generate when: Art import milestone before fest hero assets.
Default path: release-evidence/art/orm/
BUILD_RECEIPT: Separate art columns
Deep dive: 7-day ORM proof sphere challenge, ORM metallic flat pipeline.
Listicle compression: Two schemas, one art lane—do not merge JSON files.
18) fmod_webgl_snapshot_receipt_v1
Proves: FMOD 2.03 bus snapshots audible on WebGL after integration upgrade.
Generate when: Browser demo branch changes FMOD integration version.
Default path: release-evidence/qa-and-repro/webgl-audio/
BUILD_RECEIPT: fmod_webgl_snapshot_ok
Deep dive: FMOD WebGL snapshot playbook.
19) language_receipt_v1
Proves: Ren'Py language selector matches Weblate PO import for player build.
Generate when: Localization freeze before fest player build.
Default path: release-evidence/localization/
BUILD_RECEIPT: language_selector_ok
Deep dive: Ren'Py language selector evening.
20) save_slot_recovery_receipt_v1
Proves: Save slot labels match Steam branch after promotion incident resolved.
Generate when: Recovery from mismatched save labels post-branch merge.
Default path: release-evidence/qa-and-repro/saves/
BUILD_RECEIPT: save_slot_labels_ok
Deep dive: Mismatched save slot labels case study.
Minimum receipt stack by studio phase
| Phase | Receipts (numbered) |
|---|---|
| First playtest week | 1, 2, 8 |
| VOD + reels | 2, 3, 4, 5 |
| Fest branch promotion | 1, 6, 7, 8 |
| Store marketing | 10, 11, 12 |
| HTML5 itch demo | 15, 16 |
| Deck verification | 13, 14 |
Folder spine (one root)
Use release-evidence taxonomy:
release-evidence/
README.md
build-and-binary/<tag>/BUILD_RECEIPT.json
playtest/vod/receipts/playtest_vod_triage_receipt_v1.json
playtest/vod/PLAYTEST_CLIP_CONSENT_RECEIPT.json
audio/VO_CONSENT_METADATA_RECEIPT.json
qa-and-repro/<tag>/demo_smoke_receipt_v1.json
marketing-and-demo/gif_capsule_*.json
Rule: Receipts are build artifacts, not Slack confirmations.
BEGINNER: first eight receipts this week
- Copy #1 template from BUILD_RECEIPT tutorial.
- Run one playtest; file #2 even if
concat_ok: false. - If concat failed, add #3 before Whisper.
- If marketing uses clips, draft #4.
- If VO in reel, draft #5 (do not skip because #4 passed).
- Wednesday smoke → #6.
- Thursday → #7.
- Verify #8 if playtest and public demo both exist.
Schedule: ~4 hours first week; ~45 minutes per playtest night after.
DEVELOPER: CI hooks (suggested)
| Receipt | CI assert |
|---|---|
| #1 | Schema + build_id match artifact name |
| #2 | concat_ok defined; if false, #3 exists |
| #4 + #5 | Both present before reel_upload job |
| #6 | Age < 7 days on fest branch |
| #7 | Diff row count = 0 or waiver ticket id |
Store waivers in release-evidence/cert-and-platform/waivers/—not in receipt JSON.
Receipts this list does NOT replace
| Topic | Where instead |
|---|---|
| Hash cold drill | SHA256 manifest drill |
| Partner ZIP naming | Partner upload ninety-minute standard |
| 16 OBS/ffmpeg tools | Tool listicle |
| Metadata survives mux challenge | 45-minute M1–M6—cousin to #5 V5 |
Thursday row review lines (producer cheat sheet)
Map one spreadsheet row per receipt family:
| Row label | Receipt # |
|---|---|
| Core build identity | 1 |
| VOD concat / Whisper | 2, 3 |
| Highlight consent video | 4 |
| Highlight consent VO | 5 |
| Demo smoke | 6 |
| Row diff | 7 |
| Playtest isolation | 8 |
Thursday ritual stays ten minutes only when filenames are stable.
Anti-patterns (2026)
- One mega-json merging clip consent + VO metadata + VOD triage.
- Spreadsheet-only proof without JSON in
release-evidence/. - Renaming schemas without
receipt_versionbump. - GREEN BUILD_RECEIPT while #6 older than branch HEAD.
- Skipping #3 because “we always per-clip anyway”—auditors cannot see intent.
Course lesson crosswalk (AI RPG live-ops)
| Lesson | Receipt cousin |
|---|---|
| 220 | #2 batch facilitator |
| 207 | #3 |
| 243 | #4 |
| 250 | #5 |
Forward cluster (backlog #17–#23)
This hub intentionally indexes without owning: July 2026 waveform consent trend, reel design #18, ffprobe duration matrix #19, schema drift governance #20, metadata-as-artifact opinion #21, AI voice reason-codes #22, ten-minute ritual #23. Mux challenge and iXML case study are published—link from trend playbook, not duplicate here.
Receipt #2 field glossary (playtest VOD)
| Field | Beginner meaning | Developer note |
|---|---|---|
build_id |
Which candidate build was played | Must match BUILD_RECEIPT #1 |
surface |
playtest_invite vs fest_public |
Wrong surface = policy incident |
concat_ok |
Merge produced one verified timeline | False triggers #3 |
whisper_batch_allowed |
May overnight ASR run | Not equal to concat_ok |
fragment_count |
MKV count in session folder | Pairs ffprobe table CSV |
Full concat commands: 16 OBS/ffmpeg tools.
Receipt #4 vs #5 standup script
Producer asks: “Is highlight reel consent clear?”
Wrong answer: “ffmpeg succeeded.”
Right answer: “Clip manifest #4 GREEN; VO metadata #5 GREEN; BUILD_RECEIPT columns match.”
If only #4 exists, legal may still block—say so in standup before uploading to social.
Schema version discipline
Every receipt should include:
"schema": "example_receipt_v1",
"receipt_version": "1.0.0",
"generated_at": "2026-05-26T18:00:00Z"
When you bump fields, increment receipt_version and add a row to release-evidence/README.md migration table—backlog #20 (governance) expands this for consent columns only.
Ninety-minute audit workshop (team exercise)
| Minute block | Activity |
|---|---|
| 0–15 | List which of the twenty your repo already generates |
| 15–30 | Open release-evidence/—move stray JSON into correct subfolders |
| 30–45 | Pick playtest tag; verify #1 build_id matches branch |
| 45–60 | Trace last playtest: do #2 and #3 exist if concat failed? |
| 60–75 | Marketing check: #4 and #5 for last reel |
| 75–90 | Add Thursday spreadsheet rows from cheat sheet above |
Facilitators without repo access still deliver #2–#5 into a shared drive path your README names.
Engine-specific receipt triggers (quick reference)
| Engine | Often triggers first |
|---|---|
| Godot 4.x | #8, #13, #17 |
| Unity 6 | #13, #18 (FMOD), glyph table blog cousin |
| Construct 3 | #15–#16, #17 cousin |
| Ren'Py | #19, #20 |
| GameMaker | Export sanity cousin + #1 |
Engines do not replace receipts—they change which of the twenty fire first.
Partner packet receipts (beyond the twenty)
Cert intake still expects SHA256SUMS, upload_log.csv, and cold-hash drills—these are packet mechanics, not playtest lifecycle receipts. After the twenty are stable, add partner ZIP standard artifacts without renaming playtest JSON.
Resource roundups that complement this hub
| Resource | Complements receipt # |
|---|---|
| 15 free Whisper/ffmpeg tools | #2–#3 |
| 18 playtest feedback tools | Ops around #2 |
| 14 GX multi-channel tools | #9 |
Tools generate logs; receipts record pass/fail decisions auditors can diff week to week.
Expanded entries — receipts teams forget (deep notes)
playtest_vod_triage — Whisper handoff sentence
After #2 is GREEN, link the receipt path in your Whisper batch README:
WHISPER_INPUT=release-evidence/playtest/vod/session_merged.wav
TRIAGE_RECEIPT=release-evidence/playtest/vod/receipts/playtest_vod_triage_receipt_v1.json
Local Whisper pipeline gates T1–T6 assume this pointer exists—without it, triage tags attach to wrong build_id.
playtest_clip_consent — manifest-only concat reminder
Lesson 243 and OBS preflight repeat: never glob inbox/*.mkv. Receipt #4 exists to force an explicit clip id → consent id map. If your manifest is empty but ffmpeg “works,” you still fail audit—marketing may have included an opt-out fragment.
demo_smoke — what “smoke” does not prove
#6 does not prove balance, narrative, or cert compliance—it proves launch, one save boundary, clean exit on the candidate binary. Keep scope tiny so facilitators actually run it every Wednesday.
build_receipt_row_diff — unexpected vs waived
status |
Meaning |
|---|---|
expected |
Column changed because you intended promotion |
unexpected |
Blocks promotion until fixed or waived |
waived |
Ticket id documents conscious risk |
Store waiver tickets in release-evidence/cert-and-platform/waivers/ with the same build_id as #7.
playtest_isolation — SAVE_SURFACE cousin
Godot and Ren'Py courses teach save isolation lessons; receipt #8 is the release-wide scope map (invite depot, public demo, cloud saves). File #8 when you add a second Steam branch—not when you fix a single script bug.
loudness + GIF audio — marketing one-two
Fest teams often pass #10 readability then fail #11 because ad copy promises “cinematic audio” while GIF slots are silent. Review both receipts the same afternoon you refresh capsule assets.
ORM receipts — two failure modes
#17 splits channel truth (ORM pack) from engine import appearance (metallic flat). Artists pass sphere challenge but fail in-game—file the second schema, do not reopen the first receipt with edited JSON.
save_slot_recovery — branch promotion trigger
File #20 after mismatched save slot case study pattern: labels on branch B still say branch A. Prevention is #8 + clear BUILD_RECEIPT branch column; #20 is recovery evidence.
Printable wall chart (ASCII)
PLAYTEST NIGHT: 2 → (3?) → Whisper
REEL WEEK: 4 + 5 → upload
BRANCH PROMOTE: 6 → 7 → 1
FEST STORE: 8, 10, 11, 12
HTML5: 15 → 16
Tape this inside release-evidence/README.md until muscle memory sticks.
Key takeaways
- Twenty named schemas beat twenty Slack threads—file JSON under
release-evidence/. - Playtest VOD (#2–#3) is separate from marketing consent (#4–#5).
- BUILD_RECEIPT (#1) is root; other receipts promote columns, not replacements.
- Wednesday smoke (#6) + Thursday diff (#7) pair before branch promotion.
- Playtest isolation (#8) prevents invite→public scope leaks.
- Store/marketing receipts #10–#12 gate fest copy and audio promises.
- HTML5 teams add #15–#16 before custom itch domains.
- Art/audio engine receipts #17–#18 belong in import milestones.
- Localization and saves #19–#20 close player-facing trust gaps.
- Use 16 hash tools to validate; this list tells you what to generate.
FAQ
What are evidence receipts for indie game releases
Named JSON files (often *_receipt_v1.json) that prove a specific gate passed—concat OK, consent embedded, smoke green—stored under release-evidence/ and referenced from BUILD_RECEIPT.
How many receipts does a micro-studio need before Next Fest
At minimum #1, #6, #7, #8 for branch promotion; add #2–#5 when running playtest VOD and public highlight reels.
Is playtest_clip_consent the same as vo_consent_metadata
No. #4 is video fragment manifest consent; #5 is VO WAV embedded metadata—both may be required for the same reel.
Where do ffmpeg concat failures fit
File #3 when #2 has concat_ok: false; see decision tree blog.
Do I need all twenty for itch-only HTML5 demos
No—start with #1, #15, #16 plus #6–#7 if you promote branches; add VOD/consent cluster when you record playtests for marketing.
How often should I regenerate receipt JSON
Regenerate on trigger events in each entry (new playtest night, new reel, branch promotion)—not on a blank calendar. Archive prior tag folders; do not overwrite JSON without changing build_id or tag.
Can one receipt reference another
Yes—cousin paths (e.g. #5 → PLAYTEST_CLIP_CONSENT_RECEIPT.json) are encouraged. Do not duplicate clip manifest bodies inside VO receipts.
Auditable playtest-to-public releases start with a receipt index—generate the JSON, store it once, and let BUILD_RECEIPT row review stay boring on purpose.