Lesson 224: OBS MKV Gap Reencode Concat Receipt on BUILD_RECEIPT (2026)

Direct answer: When normalize + WAV concat pass audio checks but merged duration is short of fragment sum, file mkv_gap_reencode_receipt_v1.json after a +genpts MKV re-encode lane, set reencode_concat: true on playtest_vod_triage_receipt_v1.json, and promote playtest_vod_gap_recovery on BUILD_RECEIPT—after Lesson 220 batch discipline and distinct from Lesson 207 (full path tree).

Lesson hero for OBS MKV gap reencode concat receipt on BUILD_RECEIPT

Why this matters now (January 2027 post-fest VOD recovery)

January 2027 teams close the H2 fest hardening capstone and immediately batch October playtest VOD for Q1 issue triage. Discord repeats: “concat_ok was true on session 1, session 2 merge is two minutes short.” That is usually MKV timestamp gaps at Replay Buffer boundaries—not missing audio (zero-duration help) and not “pick per-clip Whisper” until gap recovery fails (Lesson 207).

The OBS MKV gap preflight is the ninety-second editor gate; this lesson is the BUILD_RECEIPT milestone that ops can grep on Thursday review. Planned blog #12 (ffmpeg decision tree) and help #5 (MKV concat fix) pair this row.

Beginner path (gap recovery night)

Step Action Success check
1 Confirm normalize preflight GREEN Audio on every fragment
2 Run duration delta probe (G2) delta > 2 s → gap lane
3 Re-encode MKV with +genpts (G3) reencoded/ count = fragments
4 Re-normalize + concat (G4–G5) Merge within 1 s of sum
5 File mkv_gap_reencode_receipt_v1.json gap_recovery_pass: true
6 Update BUILD_RECEIPT playtest_vod_gap_recovery GREEN

Time: ~20 min recovery + 15 min receipt—68 minutes first session with two facilitators.

Developer path (gates G1–G6)

Gate Check Fail when
G1 Normalize path documented Skipped straight to genpts on video-only MKV
G2 Duration delta measured No duration_delta_seconds_before
G3 +genpts re-encode complete Partial reencoded/ folder
G4 WAV re-normalized from reencoded Stale normalized/ from pre-gap MKV
G5 Concat smoke + E4 parity concat_ok true without duration check
G6 BUILD_RECEIPT row Ops runs batch Whisper without gap receipt

G2 — Duration delta (copy-paste)

sum=0
for f in playtest-vod/fragments/*.mkv; do
  d=$(ffprobe -v error -show_entries format=duration -of csv=p=0 "$f")
  sum=$(echo "$sum + $d" | bc)
done
merged=$(ffprobe -v error -show_entries format=duration -of csv=p=0 playtest-vod/merged_playtest.wav)
echo "delta=$(echo "$sum - $merged" | bc)"

Gap lane when delta > 2 after honest WAV concat from N4.

mkv_gap_reencode_receipt_v1.json

{
  "schema": "mkv_gap_reencode_receipt_v1",
  "build_label": "playtest-vod-2027-01-08-facilitator-b",
  "session_id": "session-2027-01-08-01",
  "surface": "steam_playtest",
  "fragments_count": 4,
  "duration_delta_seconds_before": 38.6,
  "duration_delta_seconds_after": 0.6,
  "genpts_reencode": true,
  "paired_receipts": {
    "playtest_vod_triage": "release-evidence/playtest/vod/PLAYTEST_VOD_TRIAGE_RECEIPT.json",
    "facilitator_vod_batch": "release-evidence/playtest/FACILITATOR_VOD_BATCH_RECEIPT.json"
  },
  "gates": {
    "G1_normalize_green": "pass",
    "G2_gap_detected": "pass",
    "G3_genpts_reencode": "pass",
    "G4_renormalize": "pass",
    "G5_concat_smoke": "pass",
    "G6_build_receipt": "pass"
  },
  "gap_recovery_pass": true
}

Pin under release-evidence/playtest/vod/MKV_GAP_REENCODE_RECEIPT.json.

Triage receipt extension

{
  "schema": "playtest_vod_triage_receipt_v1",
  "build_label": "playtest-vod-2027-01-08-facilitator-b",
  "concat_ok": true,
  "reencode_concat": true,
  "mkv_gap_reencode_receipt_path": "release-evidence/playtest/vod/MKV_GAP_REENCODE_RECEIPT.json",
  "whisper_batch_allowed": true
}

Batch rule: If Lesson 220 batch_manifest.csv lists multiple sessions, every session with gap recovery must link its own mkv_gap_reencode_receipt before whisper_batch_allowed on the batch aggregate.

BUILD_RECEIPT row (G6)

Column Pass when
playtest_vod_gap_recovery mkv_gap_reencode_receipt_v1.json exists for build_label
playtest_vod_triage reencode_concat matches gap receipt when used
playtest_vod_batch No batch Whisper while any session gap receipt missing
ALTER TABLE release_publish_gate ADD COLUMN IF NOT EXISTS
  playtest_vod_gap_recovery_required BOOLEAN NOT NULL DEFAULT false;

CI verify_mkv_gap_reencode_v1 fails when duration_delta_seconds_before > 2 and no gap receipt path on triage JSON.

Proof table (Thursday review)

Session delta before delta after reencode_concat Batch OK?
fac-a-eve 41.2 0.5 true yes
fac-b-eve 0.1 false yes
fac-c-eve 22.0 (pending) no

Key takeaways

  1. Short merge ≠ no audio—run N-gates before G-gates.
  2. +genpts re-encode is the default gap recovery—not the first concat attempt.
  3. mkv_gap_reencode_receipt is separate from ffmpeg_concat_decision_receipt (207).
  4. Gap recovery is playtest triage lane—not trailer master exports.
  5. Guide G1–G6 must pass before filing this lesson’s receipt.
  6. Lesson 220 blocks batch Whisper until all sessions GREEN.
  7. Q1 capstone 229 will wire this receipt with Ren'Py, Wwise, review keys, and WebGL rows.
  8. Thursday BUILD_RECEIPT review should show playtest_vod_gap_recovery when used.

Common mistakes

  • Setting concat_ok: true before G5 duration check after re-encode.
  • Re-encoding one fragment but concatting old normalized WAVs.
  • Filing gap receipt without updating batch manifest session row.
  • Using genpts on marketing trailer masters—wrong lane tag.
  • Skipping link to 207 when gap recovery still fails after G5.

Troubleshooting

Symptom Lane
Still short after genpts Lesson 207 per_clip_local
No audio stream OBS zero-duration help
Batch blocked Fix red session; refresh Lesson 220 manifest
ffprobe columns missing OBS ffprobe concat_ok preflight

Mini exercise (68 minutes)

  1. Seed three MKV fragments with intentional gap (stop/start Replay Buffer).
  2. Pass normalize; confirm G2 delta > 2 s.
  3. Run G3–G5; file mkv_gap_reencode_receipt_v1.json.
  4. Add row to BUILD_RECEIPT; link from triage receipt.
  5. Add second session without gap—build batch_manifest.csv; confirm batch blocks until both receipts exist.

Continuity — Q1 2027 post-fest recovery (224–229)

Lesson Receipt focus
224 (this) MKV gap reencode on BUILD_RECEIPT
225 Ren'Py PO-hash language
226 Wwise DSP packaged
227 Review keys
228 FMOD WebGL fest
229 Q1 capstone

Previous: Lesson 223 — H2 fest hardening capstone
Next: Lesson 225 — Ren'Py PO-hash language receipt.

FAQ

Same as Lesson 207?
207 documents all Whisper paths when concat fails; 224 promotes mkv_gap_reencode_receipt on BUILD_RECEIPT for the timestamp gap lane only.

Same as the OBS guide chapter?
Guide = ninety-second preflight; lesson = BUILD_RECEIPT + batch + CI gate.

Must every team hit this?
No—file receipt only when G2 detects gap; column stays n/a otherwise.

Public highlight reels?
Gap recovery is for triage audio; pair highlight clip consent preflight with Lesson 243 playtest clip consent receipt for marketing concat.


A two-minute-short merge without mkv_gap_reencode_receipt is not “close enough for Whisper”—it is a silent triage lie on BUILD_RECEIPT.