Process & Workflow May 25, 2026

Thursday BUILD_RECEIPT Row Review Ritual - Ten Minutes After Wednesday Smoke

2026 Process workflow—ten-minute Thursday BUILD_RECEIPT row diff after Wednesday demo smoke, with build_receipt_row_diff_receipt_v1.json and promotion gate pairing.

By GamineAI Team

Thursday BUILD_RECEIPT Row Review Ritual - Ten Minutes After Wednesday Smoke

Pixel-art hero for Thursday BUILD_RECEIPT row review ritual after Wednesday demo smoke 2026

Your Wednesday demo smoke log says GREEN. Marketing schedules branch promotion for Thursday lunch. Stable receipt filenames for each row live in the top 20 evidence receipts index—use the same names in build_receipt_row_diff_receipt_v1.json notes. At 3 p.m. you discover BUILD_RECEIPT.json still lists last week's build_id, surface still says internal, and channel_label_match is missing the itch HTML5 row you uploaded Tuesday. The binary was fine—the receipt lied.

May–October 2026 micro-studios fixed store copy with Wednesday metadata diff and fixed boot crashes with Wednesday smoke. The third failure mode is quieter: receipt row drift between what you tested and what partners, Steamworks, and your own upload log claim. This Process & Workflow article defines a ten-minute Thursday BUILD_RECEIPT row review—a diff of gate columns and scope rows, not another FAQ or descriptor checklist.

Non-repetition note: This URL owns receipt row diff after smoke. It does not replace BUILD_RECEIPT beginner tutorial (schema authoring), Wednesday metadata diff (store copy), or playtest isolation (scope policy)—it closes the loop between them.

Who this is for and what you get

Audience You will be able to…
Solo dev Diff this week's receipt against last promoted row in ten minutes
Release owner Block promotion when R4–R7 fail even if smoke was GREEN
Producer Require build_receipt_row_diff_receipt_v1.json beside demo_smoke_receipt_v1.json

Time: 10 minutes every Thursday (default), immediately after Wednesday smoke when both run the same week.
Prerequisites: BUILD_RECEIPT.json for current build_id, archived receipt from last promotion, Wednesday smoke log + demo_smoke_receipt_v1.json, and a one-page row catalog (below).

Why this matters now (May 2026)

  1. Multi-channel uploads — GX.games, itch HTML5, and Steam now appear in one receipt; triple-channel label help exists because teams forget rows—not because smoke failed.
  2. Receipt columns multipliedmenu_fps_cap, loudness_receipt, string_table_receipt, wasm_mime_receipt, and demo_smoke gates ship in 2026 tutorials; a diff catches stale false faster than re-reading JSON by hand. July VO clusters add wav_consent_metadata_ok, metadata_survives_mux_ok, and ffprobe_duration_matrix_ok—pair row diffs with consent scope and expiry governance so booleans are not GREEN on deprecated consent_scope values. After the H1 trust arc, add a Capstone block for Lessons 212–216 via Lesson 217: H1 player trust observability capstone (h1_player_trust_capstone_v1.json). After Q1 post-fest recovery, add Q1 Capstone for Lessons 224–228 via Lesson 229 (q1_post_fest_capstone_v1.json).
  3. Playtest vs fest surfacesPlaytest isolation fails when surface in receipt still says playtest_invite after you promoted fest_public.
  4. Partner diligenceQ3 evidence packets join receipt hash, smoke receipt, and upload log—row review is how you prove they describe one build.
  5. Refund dashboardsRefund signal spreadsheets tag build_id; receipt drift makes tags meaningless.

Direct answer: Open BUILD_RECEIPT.json and last promoted receipt side by side; run gates R1–R10; write build_receipt_row_diff_receipt_v1.json; no promotion if R4–R7 are RED—even when Wednesday smoke was GREEN.

Three Wednesdays, one Thursday (ritual map)

Day Ritual Layer This article
Wednesday AM Metadata diff Store copy and media Prerequisite—fix copy lies first
Wednesday PM Demo smoke Installed binary Prerequisite—prove golden path
Thursday BUILD_RECEIPT row review (this) Machine-readable claims about that binary Diff rows before promotion
Friday Block 5 evidence hygiene Folder + archive cleanup Weekly—not a promotion gate

Smoke GREEN with receipt RED still ships governance theater—partners see a receipt that does not match the build players install.

Row catalog (what to diff every week)

Store release-evidence/05-operations/receipt-row-catalog.md once; link from BUILD_RECEIPT template notes:

Row key Type Must match smoke? Typical drift
build_id string Yes Forgot to bump after hotfix
git.commit string Yes Smoke on commit A, receipt still B
surface enum Yes playtest_invite vs fest_public
channel / channels[] list Yes Added itch row, receipt still Steam-only
channel_label_match bool Yes false when GX + Steam labels differ
demo_smoke.promotion_allowed bool Yes true in log, false in receipt
demo_smoke.iso_week string Yes Last week's W20 receipt
menu_fps_cap.verified bool If menu demo Missing after menu FPS opinion
loudness_receipt.master_ok bool If trailer shipped Stale after LUFS listicle pass
string_table_receipt.tables_ok bool If localized build Empty tables after Addressables strip (help)
wasm_mime_receipt.post_upload_mime_ok bool If itch HTML5 CDN MIME regression (help)
playtest_scope_map.version string If playtest surface Scope map not bumped with branch
human_signoff.signed_at_utc timestamp Yes Unsigned receipt promoted anyway

Add rows when you adopt new JSON sidecars—never delete rows mid-fest without a receipt_version bump documented in the diff notes.

Gates R1–R10 (Thursday promotion blockers)

Gate Name Pass criteria
R1 File exists Current BUILD_RECEIPT.json in repo + zip mirror path documented
R2 build_id parity Same string in receipt, smoke receipt, upload_log last row
R3 git parity git.commit matches machine that produced smoke build
R4 surface parity surface matches intended promotion target this week
R5 channel rows Every live channel has a row; no orphan uploads in upload_log.csv
R6 channel_label_match true when multi-channel; documented exception in notes if false
R7 demo_smoke linkage demo_smoke_receipt_v1.json attached path + promotion_allowed true
R8 Gate columns Required bool rows for this SKU (menu, loudness, wasm, string table) not stale vs last week
R9 signoff human_signoff.signed_at_utc within 7 days of smoke
R10 diff receipt build_receipt_row_diff_receipt_v1.json committed

R4–R7 are promotion blockers when RED. R8 YELLOW allows promotion only with written waiver in diff notes (producer sign-off).

The ten-minute ritual (minute-by-minute)

Min Action
0–1 Confirm Wednesday smoke log GREEN; open current + receipts/{last_promoted}.json
1–3 R1–R3: build_id, commit, branch string equality
3–5 R4–R6: surface, channels, channel_label_match
5–7 R7: open demo_smoke_receipt_v1.json; verify promotion_allowed
7–9 R8–R9: bool gate columns vs catalog; signoff freshness
9–10 Write diff receipt; mark RED/YELLOW/GREEN; calendar "promotion allowed?"

Calendar invite: "Thursday BUILD_RECEIPT row review — promotion gate (receipt)."

Same-week calendar (recommended)

Day Block Total
Wednesday Metadata diff + demo smoke ~30 min
Thursday Row review (this) 10 min
Thursday PM Branch promotion (human) Only if Wed + Thu GREEN

build_receipt_row_diff_receipt_v1.json

{
  "schema": "build_receipt_row_diff_receipt_v1",
  "iso_week": "2026-W21",
  "reviewed_at_utc": "2026-05-22T09:12:00Z",
  "current_build_id": "nextfest-oct-2026-rc4",
  "baseline_build_id": "nextfest-oct-2026-rc3",
  "paired_demo_smoke": "release-evidence/05-operations/demo-smoke/demo_smoke_receipt_v1-rc4.json",
  "gates": {
    "R1_file_exists": "pass",
    "R2_build_id_parity": "pass",
    "R3_git_parity": "pass",
    "R4_surface_parity": "pass",
    "R5_channel_rows": "pass",
    "R6_channel_label_match": "pass",
    "R7_demo_smoke_linkage": "pass",
    "R8_gate_columns": "pass",
    "R9_signoff": "pass",
    "R10_diff_receipt": "pass"
  },
  "row_diff": [
    {
      "key": "surface",
      "baseline": "playtest_invite",
      "current": "fest_public",
      "expected": "fest_public",
      "status": "fixed"
    },
    {
      "key": "channel_label_match",
      "baseline": false,
      "current": true,
      "expected": true,
      "status": "fixed"
    }
  ],
  "promotion_allowed": true,
  "notes": "Promoted after rc3 playtest; rc4 adds itch HTML5 channel row"
}

Commit under release-evidence/05-operations/receipt-diffs/. Validate-packet can assert promotion_allowed and row_diff[].status != unexpected.

Diff mechanics (beginner-friendly)

You do not need a custom tool on day one—jq or a ten-line Python script is enough.

jq one-liners (illustrative)

jq -r '.build_id, .surface, .gates.demo_smoke.promotion_allowed' BUILD_RECEIPT.json
jq -r '.build_id, .surface' release-evidence/05-operations/receipts/nextfest-oct-2026-rc3.json
diff <(jq -S .gates release-evidence/05-operations/receipts/nextfest-oct-2026-rc3.json) \
     <(jq -S .gates BUILD_RECEIPT.json)

Python sketch (row catalog driven)

import json
from pathlib import Path

CATALOG = ["build_id", "surface", "channel_label_match",
           "demo_smoke.promotion_allowed", "menu_fps_cap.verified"]

def get(obj, dotted):
    for part in dotted.split("."):
        obj = obj.get(part, {}) if isinstance(obj, dict) else None
    return obj

cur = json.loads(Path("BUILD_RECEIPT.json").read_text())
base = json.loads(Path("receipts/baseline.json").read_text())
for key in CATALOG:
    b, c = get(base, key), get(cur, key)
    if b != c:
        print(key, b, "->", c)

Run in CI after smoke job uploads artifacts—fail build if R4–R7 would be RED.

Worked example (composite duo, fest week)

Context: nextfest-oct-2026-rc4 smoke GREEN Wednesday; Thursday review finds receipt drift.

Gate Finding Status
R2 Smoke receipt rc4, BUILD_RECEIPT still rc3 RED
R4 surface still playtest_invite RED
R6 channel_label_match false; itch uploaded Monday RED
R7 Smoke promotion_allowed true but receipt lacks demo_smoke block RED

Outcome: Promotion slipped one day. Engineer bumped build_id, set fest_public, added itch channel row + channel_label_match: true, copied smoke JSON path into receipt, re-ran R1–R10—all GREEN. Marketing promoted Thursday PM instead of lunch.

Lesson: Smoke caught gameplay; Thursday caught paperwork that would have broken playtest isolation analytics and GX multi-channel resources.

Pairing with specialized receipts (2026 stack)

Sidecar Receipt row Review focus
demo_smoke_receipt_v1.json demo_smoke.* promotion_allowed, iso_week, build_id
menu_fps_cap_receipt_v1.json menu_fps_cap.verified Deck menu power (opinion)
loudness_receipt_v1.json loudness_receipt.master_ok Trailer/master chain (14 tools)
playtest_vod_triage_receipt_v1.json playtest_vod.last_run Optional; proves triage ran (Whisper pipeline)
string_table_receipt_v1.json string_table_receipt.tables_ok Localization fest builds
wasm_mime_receipt_v1.json wasm_mime_receipt.post_upload_mime_ok itch HTML5 CDN

Thursday review asks: did the bool in BUILD_RECEIPT change when the sidecar changed? If sidecar updated Tuesday and receipt bool still false Wednesday, R8 is RED.

Engine and SKU notes (row expectations)

Steam-only NW.js demo

Minimum rows: build_id, surface, demo_smoke, channel_label_match (single channel true), S7 console row in smoke notes.

Steam + itch HTML5

Require channels[] length ≥ 2, channel_label_match true, wasm_mime_receipt row when itch row present. Cross-check itch MIME help.

Steam + GX.games

build_label / VERSION alignment per GX receipt help; triple-channel cases use triple storefront help.

Localized Unity fest build

Add string_table_receipt and Weblate freeze cross-links (localization resource); R8 fails if store shows CN but tables_ok false.

upload_log.csv cross-check (R5)

Last three upload_log.csv rows must map to channels[] or explicit notes:

uploaded_at_utc,build_id,portal,zip_filename,portal_ticket,result,notes
2026-05-21T18:00:00Z,nextfest-oct-2026-rc4,steam_depot,rc4.zip,DEP-991,submitted,
2026-05-21T19:10:00Z,nextfest-oct-2026-rc4,itch_html5,rc4-html5.zip,,submitted,
2026-05-21T20:05:00Z,nextfest-oct-2026-rc4,gx_games,rc4-gx.zip,,submitted,

Orphan portal upload without receipt channel row → R5 RED.

RED / YELLOW / GREEN (Thursday)

Status Meaning Promotion
RED R4–R7 fail; build_id mismatch; unsigned receipt No
YELLOW R8 optional gate stale with documented waiver No until waiver in diff notes
GREEN R1–R10 pass; row_diff only fixed or unchanged Yes if Wednesday rituals also GREEN

Log template (markdown)

# Thursday BUILD_RECEIPT row review — 2026-W21
current_build_id: nextfest-oct-2026-rc4
baseline_build_id: nextfest-oct-2026-rc3
reviewer: release_owner

| gate | status | notes |
|------|--------|-------|
| R1 | GREEN | |
| R2 | GREEN | |
| R3 | GREEN | |
| R4 | GREEN | surface fest_public |
| R5 | GREEN | steam + itch + gx |
| R6 | GREEN | channel_label_match true |
| R7 | GREEN | smoke receipt linked |
| R8 | GREEN | menu_fps + loudness ok |
| R9 | GREEN | signoff 2026-05-21 |
| R10 | GREEN | diff json committed |

Promotion this week: ALLOWED (receipt)

Save beside smoke logs under release-evidence/05-operations/receipt-diffs/.

Automation hooks (when you are ready)

Hook Trigger Action
CI post-smoke demo_smoke_receipt_v1.json uploaded Fail if BUILD_RECEIPT.build_id differs
Pre-promote script Human runs promote Require build_receipt_row_diff.promotion_allowed
Friday Block 5 Weekly hygiene Archive diff + smoke + metadata logs together

Start manual ten minutes; automate only after two GREEN fest weeks—otherwise you script the wrong rows.

Starter validate snippet (optional)

Add to your existing validate-packet folder as validate-receipt-row-diff.sh:

#!/usr/bin/env bash
set -euo pipefail
DIFF="release-evidence/05-operations/receipt-diffs/build_receipt_row_diff_receipt_v1.json"
test -f "$DIFF" || { echo "missing diff receipt"; exit 1; }
jq -e '.promotion_allowed == true' "$DIFF" >/dev/null
jq -e '[.row_diff[] | select(.status == "unexpected")] | length == 0' "$DIFF" >/dev/null
echo "receipt row diff OK"

This does not replace human judgment on ambiguous UX gates—it only catches forgotten files and hard false promotion flags.

Distributed team handoff

Role Thursday duty
Engineer (EU) Run R1–R3 before standup
Producer (US) R4–R6 surface + channels
Either R7–R10 + commit diff receipt

Leave notes in diff JSON when Asia overnight smoke used a different Steam account—Asia-EU continuity depends on readable diffs, not Slack threads.

Evidence folder layout (one-time setup)

Create once under release-evidence/05-operations/:

05-operations/
  BUILD_RECEIPT.template.json
  upload_log.csv
  receipt-row-catalog.md
  demo-smoke/
    wednesday-demo-smoke-YYYY-WW.md
    demo_smoke_receipt_v1-{build_id}.json
  receipt-diffs/
    thursday-row-review-YYYY-WW.md
    build_receipt_row_diff_receipt_v1-{build_id}.json
  receipts/
    {archived_build_id}.json
  store-metadata/
    wednesday-metadata-diff-YYYY-WW.md

Naming rule: ISO week in markdown logs; build_id in JSON filenames. Friday Block 5 archives anything older than eight weeks into archive/2026-Q2/—do not delete diff receipts that partners still reference.

When row review fails mid-promotion (rollback script)

If promotion already happened and Thursday review finds RED:

  1. Stop further marketing sends and Discord announcements.
  2. Document incident row in refund dashboard with tag receipt_drift.
  3. Roll back branch to last known-good build_id per branch naming checklist.
  4. Re-run Wednesday smoke on rolled-back depot.
  5. Fix receipt rows; re-run Thursday; attach both diff receipts (rc4_bad, rc3_restored) for partner transparency.

This is rare when Thursday runs before promotion—it is expensive when skipped.

Receipt version bumps (schema discipline)

When you add a new gate column mid-fest:

"receipt_version": "1.1",
"changelog": [
  { "version": "1.1", "date": "2026-05-25", "added": ["wasm_mime_receipt.post_upload_mime_ok"] }
]

Thursday R8 compares only keys present in both baseline and current when versions differ—treat missing baseline keys as introduced in row_diff, not unexpected. Document in receipt-row-catalog.md the same day you ship schema 1.1.

Micro-studio time budget (realistic)

Team size Weekly ops total Thursday share
Solo 40 min (metadata + smoke + row) 10 min
Duo 35 min split 5 min each
Contractor QA +15 min spot-check Contractor runs R7–R8 only

Cheaper than one store-demo mismatch recovery day.

Pairing with October localization week

When Weblate freeze and store-page QA refresh land the same week, Thursday must include string_table_receipt.tables_ok and store_copy_receipt rows if your BUILD_RECEIPT template was extended—metadata diff alone will not catch in-game English-only selector bugs (Ren'Py language help when published).

Audit questions partners ask (answer from diff receipt)

Partner question Row / file that answers
Which build did you smoke-test? R2 + demo_smoke_receipt_v1.json
Is this the public fest depot or playtest? R4 surface
Did all storefront uploads share labels? R6 channel_label_match
Who signed release this week? R9 human_signoff
What changed since last submission? row_diff[] in diff receipt

Keep answers in README bullets—do not send raw JSON unless requested.

Common mistakes (beginners)

Mistake Fix
Diffing store FAQ text That is Wednesday metadata, not this ritual
Promoting on smoke alone Add Thursday row review
Copy-paste entire old receipt Use row_diff; bump only changed keys
Ignoring itch row R5 fails when upload_log has orphan portal
Skipping signoff R9 RED—partners treat unsigned as incomplete

Promotion checklist (append to runbook)

[ ] Wednesday metadata diff GREEN (same ISO week)
[ ] Wednesday demo smoke GREEN (same ISO week)
[ ] Thursday BUILD_RECEIPT row review GREEN (this article)
[ ] build_receipt_row_diff_receipt_v1.json promotion_allowed == true
[ ] upload_log.csv last row build_id matches receipt
[ ] No RED rows in row_diff array

Outbound references

Related GamineAI reads

Key takeaways

  • Thursday row review diffs BUILD_RECEIPT gate rows against last promoted receipt—not store metadata.
  • Run it after Wednesday smoke when both happen the same week.
  • Gates R4–R7 (surface, channels, channel_label_match, smoke linkage) are promotion blockers.
  • Ship build_receipt_row_diff_receipt_v1.json with a row_diff[] array documenting every changed key.
  • Cross-check upload_log.csv so no portal upload lacks a receipt channel row.
  • Pair specialized sidecars (menu FPS, loudness, wasm MIME, string tables) with matching receipt bools.
  • Ten minutes weekly beats promoting a GREEN binary with a RED receipt.
  • Automate with jq or Python only after manual discipline works two fest weeks.
  • Completes the trio: metadata Wednesday AM, smoke Wednesday PM, receipt Thursday.
  • Fulfills forward links from playtest isolation and multi-channel resource briefs.

FAQ

Is this the same as Wednesday metadata diff?

No. Metadata diff compares store page copy and media to git-approved sources. Thursday review compares BUILD_RECEIPT.json rows to last promoted receipt and Wednesday smoke—binary claims, not FAQ text.

Can I promote if smoke was RED but I fixed receipt rows?

No. Receipt review assumes smoke GREEN. Fix binary first, re-smoke, then run R1–R10.

How is this different from SHA256 cold validation?

Cold validation proves file bytes. Row review proves scope and gate columns inside the receipt describe the build you hashed and smoked.

Do I need all sidecar JSON files every week?

Only the sidecars your SKU uses this week—see row catalog. Missing optional sidecar is fine; missing required bool for an active channel is R8 RED.

What if we only promote every two weeks?

Run row review on promotion weeks; on off weeks, still archive a diff against baseline so Friday Block 5 does not find silent drift.

Where does Blog-Planner go after this post?

Active Blog Backlog hits zero—schedule Blog-Planner refill before the next go expects another non-escape-hatch pitch.

Can partners see build_receipt_row_diff_receipt_v1.json?

Usually internal under release-evidence/05-operations/. Summarize pass/fail in partner README bullet linking BUILD_RECEIPT—same pattern as partner ZIP naming.

What surface values should fest demos use?

Align with playtest isolationfest_public on the depot players install from the fest library slot, not playtest_invite or internal unless documented.