Receipt — Phase IX: producer/playout/mixer shipped, built, and proven on-node
[redacted: category] — 1 private address. Nothing else was altered. The document is otherwise exactly as it is written in the repository, and the sha256 below is of the original, so what was ingested stays checkable.How to read this page
A Plain and a Clear version of this page have not been written yet. What follows is the document itself.
Precise — the source document
This is the document. Rendered from the repository at the commit above, with nothing rewritten for the web. A gate re-renders it on every deploy and fails the build if a single byte differs.
Status: Phase IX deploy gate MET. The show-runner (producer + playout + mixer scene build +
overlays-on-program gate) is deployed on uni-lab-79740c, boot-persistent, and proven end-to-end.
Every claim below is backed by a captured gate output, not process existence.
Node: uni-lab-79740c (mesh [redacted: private-address]). All mutations via the uni-lab MCP, os_exec
dry_run→confirm, one human approval each. Ship discipline: git archive of a pushed+tagged ref →
sha256 → LAN fetch on-node → sha256sum -c before unpack (CLAUDE.md rule 2).
What shipped
- Tag
prod-firstlight-20260712T0010Z-e(commit1e080db),production/subtree, tarball sha2564d589e998a429a45ef1411d58139f346ca931c3d6a16d028f9e68d66efc0535d, sha-verified on-node (ship-e.tar.gz: OK). Provenance stamped in/var/lib/uni/broadcast-src-b/SHIP_PROVENANCE.txt. The a5d1a85 P1 lock (/var/lib/uni/broadcast-src) was left untouched — this ship staged to a separatebroadcast-src-b, so the DEPLOYED_STATE control-file lock stays valid (re-proven below). - Installed:
/opt/uni/production/{producer,playout,mixer}(add-only;mcp/etc. untouched); host units/etc/systemd/system/uni-{producer,playout}.service; run-of-show config to/var/lib/uni/broadcast/run-of-show/(weekly-grid.yaml, slot-4h.yaml, templates/, GUIDE.md). - Venv deps (were missing — the live MCP's OBS/TTS paths had never been exercised on-node, so
its 401 "healthy" signature never needed them).
pip installinto/opt/uni/.venv(Python 3.13):websocket-client 1.9.0(obs adapter),requests 2.34.2+urllib3 2.7.0+charset_normalizer 3.4.9(tts adapter). Captured in/run/uni-pip.log.
Gates captured
- Scene build —
BUILD COMPLETE (8 scenes)(/run/uni-buildscenes.log). 8 canonical scenes (COLONY GLASS GUESTS CLIP NEWSDESK TITLE STANDBY PIP), program parked on STANDBY, Fade 400ms. Canvas pinned[0/9] pinning OBS canvas -> 1280x720@30 (was 1920x1080)→canvas now 1280x720. - Overlays-on-program proof —
SCENE PROOF: PASS(production.mixer.verify_scenes,/run/uni-verifyscenes.log): the program scene AND STANDBY both carryovl_lower3rd, ovl_ticker, ovl_caption, ovl_onair, ovl_title, ovl_clock(enabled, → 127.0.0.1:8099); STANDBY additionally carriesovl_standby;:8099/overlays/state.jsonparsed. This is the System-2 analog ofviewer/verify_overlays.cjsand closes the "System 2 has no overlays-on-program gate" hole. (First-light receipt #4.) - Services up, boot-persistent.
uni-producer+uni-playoutsystemctl enable --now(symlinks created inmulti-user.target.wants). Producer log: clean start, no errors. Playout log:(re)loaded: catalog rows=0, templates=8, weekly-grid days=7,entering slot SUN-S1, watchdog active.producer.ndjsonshows a continuous standby beat loop (sb-01-hold ↔ sb-02-reel) + a watchdog cutover — the standby/fallback machinery works. - Show-runner wiring proven end-to-end. Injected one
start_segmentin playout's exact wire shape ({"cmd":"start_segment","args":{"template":"news-desk","params":{"language":"en"}}}) intoqueue.jsonl;producer.ndjsonrecorded{"event":"run_template","template":"news-desk", "segmentId":"manual-verify-newsdesk", audit_id 24facfcf...}then beatsnd-01-title(TITLE) andnd-02-anchor-intro(NEWSDESK). playout → producer → template beats → OBS scene cuts, confirmed. - Honesty covenant intact. Throughout the news-desk run,
broadcast.jsononAir.textstayed"STANDBY"(never a fake"LIVE"). Only a humanstart_broadcastor an explicitset_livefrom playout may claim LIVE. - P1 core untouched —
P1 PROOF GATE: ALL PASS(verify_p1.sh, postship): overlays :8099, relay :9997, mixer :4455 (426), production-MCP :8095 (401 double-probe), + all 5 control-file sha256 locks match the DEPLOYED_STATE table. (First-light receipt #2, postship.)
Three real bugs caught by RUNNING the services (not by inspection)
- OBS canvas was 1920x1080, build assumed 1280x720 → overlays landed in the top-left quadrant.
Fix (commit
07ce965):build_scenesnow pins base+output+fps to the 720p30 floor (ADR-PROD-003 / G-ENC) as step 0 — the set-once builder is authoritative regardless of the OBS/container default. - Every template's
{layer: nowPlaying}beat overlay raised "unknown overlay layer" (nowPlaying is a broadcast.json block with its ownset_now_playing, not aset_overlaylayer). Fix (commita29f2d6): the producer special-casesnowPlayinglikeonAirand routes it toset_now_playing, an explicit beat value winning over the per-beat auto-default. Honors the authored GUIDE/template contract; kills the per-beat error noise. - playout's
start_segmentcommand was dropped ("unknown queue cmd ignored") — the producer's dispatch only knewrun_template/cutover/resume/set_live, so it never ran the scheduled run-of-show. Fix (commit1e080db):_handle_run_templatenow reads playout'sargs-wrapped shape and is registered under bothstart_segment(playout's real command) andrun_template(alias). This is the fix gate #4 proved.
Honest caveats / follow-ups (not blockers for a non-broadcasting idle system)
- Colony posture (Phase XIV = WITHHELD) — RESOLVED via a reversible gate. The colony lane's
forage RED verdict is WITHHELD (commit
3bec962: "hunt loop did not engage, both arms starved"; confirmed by the colony lane) — no proven colony survival. Per the plan's Phase XIV FAIL path, first-light is STANDBY + CLIP + TITLE only. Initially the deployed run-of-show still cued the COLONY scene (colony-live template ×2 slot segments + news-desk/explainer colony cut-ins = 8scene:COLONYbeats). Fixed 2026-07-12 (commit3ddbfd0, tag-f): the producer now gates any COLONY-scene beat to STANDBY unlessUNI_COLONY_ONAIRis set (default off). Proven on-node: an injectedcolony-livesegment loggedbeat cl-01-open: COLONY scene gated off (colony not proven on-air; UNI_COLONY_ONAIR unset) -> STANDBY— the dead source never reached program. One switch to restore when the colony passes its RED:UNI_COLONY_ONAIR=truein/etc/uni/runtime.env+ restartuni-producer. Owner to flip: colony-gate reconciliation + operator. - Canvas-pin persistence.
build_scenespins 720p at build time.production/containers/ obs-entrypoint.shsetsUNI_BCAST_WIDTH/HEIGHT=1280/720but the running OBS still came up at 1920x1080 (it defaulted to the Xvfb screen). So on a mixer-container restart the canvas may revert untilbuild_scenesis re-run. Follow-up: makeobs-entrypoint.shactually apply the base canvas, or runbuild_sceneson mixer start. - Catalog is empty (
catalog rows=0) — Phase V (catalog.json bootstrap + placeholder.mp4 + music bed) not yet staged; playout tolerates this honestly (roll_clip/standby-reel content unavailable, live grid still runs). A deliberatelayout: nowPlayingcleanup across templates was made unnecessary by the producer-side fix. - Transient gate units (
uni-buildscenes,uni-verifyscenes,uni-pipinstall) live in/run/systemd/system(tmpfs — gone on reboot, by design). The durable gates are the committedproduction.mixer.{build_scenes,verify_scenes}modules; a persistent wrapper unit is optional. - One
manual-verify-newsdeskline remains inqueue.jsonl(the wiring-proof injection, already consumed; the producer offset is past it) — left as an honest record of the test.
Ship trail (tags this phase)
prod-firstlight-20260711T2332Z-b (initial producer/playout/mixer) → -c (canvas-pin) →
-d (nowPlaying) → -e (start_segment). Only -e is deployed; earlier tags are the incremental
fix history. All pushed to origin/lab/ozone-life-uni-hard-science.
sha256 9940a328d0b67d31 — of the original file, so what was ingested stays checkable.