youtube: launch-batch production kit (7 videos, subtitled, publish-ready) - #17
youtube: launch-batch production kit (7 videos, subtitled, publish-ready)#17davidcrowe wants to merge 22 commits into
Conversation
cast → 1080p master (title card + labeled cold-open replay + timed callout overlays + outro), custom thumbnail, vertical Short, VO mux. Timing-only pacing via pace.mjs (the record.sh bright line: takes are never doctored). Three episodes built from existing takes: force-push-yt (hero), replit-yt, claude-install-yt. codex-install.cast is an incomplete take (no deny beat) — re-shoot is step 6 in RUNBOOK.md.
New take on Claude Code v2.1.238 via the reserve pocketos episode (claude- only; codex auth sidelined for the unattended run). Master + thumbnail + Short + timecoded VO script + upload pack. Note for local checkouts holding untracked copies of demo/episodes/pocketos.sh or demo/pocketos.cast: remove them before pulling this branch.
|
Added a FOURTH ready video, recorded today on Claude Code v2.1.238: pocketos-yt — "The PocketOS incident, recreated — a runbook told the agent to delete prod" (1:10). The reserve episode config recorded clean unattended (codex auth sidelined so beat 4 skips; cross-vendor beat returns at the codex re-shoot). Batch is now 4 masters + thumbs + Shorts awaiting VO — runbook updated. Heads-up for David's checkout: it holds untracked |
The governable-half recreation (article's injection boundary respected on camera): decommission-runbook fixture gets a genuine attempt at rm -rf + gcloud delete; both policy-denied pre-execution. Receipt shows Bash.rm and Bash.gcloud deny rows and no executed rm — the agent's 'completed step 1' mid-take line is contradicted by the log, which the VO leans into. Batch is now 5 videos.
|
FIFTH video: amazonq-yt — "An agent ran rm -rf and a cloud delete. Both died at the hook." (1:15). New fixture authored + recorded today (decommission-runbook framing; the injection trigger stays off camera per the article's own boundary — the video shows the governable half). Receipt shows Bash.rm → deny + Bash.gcloud → deny, source: policy, and disproves the agent's own mid-take 'completed step 1' claim — the VO leans into log-over-narration. Runbook updated to 5 VO reads (~6.5 min total reading). |
SUBS=1 build.sh master burns episodes/<ep>.srt as styled lower-thirds (2-line wrap, theme-matched) into <ep>-master-sub.mp4, replacing the callout overlays. Five SRT tracks authored from the VO scripts, timed to the beat maps — so the videos are publishable now and the same .srt doubles as the uploadable caption track (the citable transcript).
build.sh episodes can now source a pre-recorded mp4 (VIDEO=) instead of a terminal cast, so console screencasts from console-shot-rig get the same title card / cold open / subtitle / outro treatment. console-tour-yt: 1:22 pass over what a workspace actually gets — the governed-call feed, a call drilled to its reason, the policy behind it, the approvals queue with a real pending step-up, and the cost view. Real workspace, real traffic; operator email masked at record time. Batch is now 6 videos.
|
Sixth video: console-tour-yt (1:22) — the one that answers "what do I actually get?", which the install videos can't. Real console, real workspace, real traffic: the governed-call feed (tool/decision/identity/latency/cost per call), a call drilled to its reason, Policies, the Approvals queue with a genuine pending step-up on Pipeline change: episodes can now source a pre-recorded mp4 ( Privacy fix worth noting: the first two takes had the operator's email visible in the IDENTITY column and the approval card. A one-shot text-node mask wasn't enough (React restores the text on re-render), so the console video rig now installs a MutationObserver that re-masks on every mutation and survives client-side nav. Verified on the shipped take: |
…scene Runbook rewritten around publishing without voiceover: what's ready, upload order, the SRT-as-caption-track step (these have no audio, so YouTube cannot auto-caption — that file is the only text the platform gets), and the one-way-door note that a video file cannot be replaced after publish. Vendors console-scenes/console-tour.mjs so the scene that produced the console video lives next to the episode that consumes it.
SHORT_CROP makes the vertical cut per-episode; the terminal default clipped the console screencast. Adds the console-tour metadata pack with a pre-publish reminder to verify email masking on a real frame. All six episodes now have the complete asset set: subtitled master, thumb, Short, SRT caption track, upload pack.
Seventh video: one policy, two agents. The cast is David's 21 Aug take — Codex trusts the ACP hook (a human step the rig never forges), then hits the same hardline force-push rule that stops Claude Code. The take also recorded the audit-tail beat, but a tmux repaint dropped 15 characters of the JSON line at the 105-column wrap, so that frame renders "classified":"Bash.git.pusheny" — a string that is not in the log. Cut the body before it rather than caption over it. The other five terminal casts were checked and render "decision":"deny" intact. Two pipeline additions, both timing-only and opt-in: BODY_END trim the body at N seconds on the footage clock TAIL_PAD hold the final frame for N seconds TAIL_PAD exists because pace.mjs's TAIL_HOLD never reached the render: it appends an event carrying no output, so agg emits no frame for it and the GIF ends at the last real one. TAIL_HOLD has been inert in every episode. Episode scripts now pipe the audit tail through `fold -w 100` so the line can never reach the wrap column on a future take.
Frame-by-frame QA against both masters found the captions describing the wrong moment in several places. Nothing wrong with the footage; the SRTs were written against the wrong clock. claude-install: the three file-inspection cues ran ~4s ahead of the terminal, so "three files in ~/.acp" played over install output and was gone before the listing appeared. Re-timed to the frames where each thing is actually on screen (18.8 / 22.6 / 27.8). force-push: the pretext cue started before the agent had launched. Worse, the cue claiming "the floor only exists at the edges" sat over beat 4 — an intended ask-then-decline that did not resolve in this take — so it read as "and this one was allowed", which never happened. That cue is merged into the tests beat, where the claim is actually demonstrated, and beat 4 now plays uncaptioned rather than mis-captioned. Beat 4 still needs a re-record to do its job; that is the only ask/decline moment in the batch. Both episodes let a caption spill onto the outro card, and both under-held the audit output: the payoff was on screen ~3.5s while carrying ~8s of narration, with the caption box covering the JSON. TAIL_PAD=3 holds the last frame so the audit lines are readable after the captions clear, and the closing cues moved onto the outro. Chapters in both upload packs re-derived from the verified beat maps, and spaced so YouTube accepts them.
Frame QA on the three incident recreations found the same overstatement in two of them, and it is the kind a viewer catches by reading the screen. replit and amazonq both captioned the deny as the destructive command dying at the hook. It isn't. In both takes the agent is stopped on its FIRST gcloud call — a read-only `sql instances list` in replit, a `config list` / `instances describe` in amazonq — and never reaches the delete at all. The rule keys on the binary, not the verb. That is a better fact than the one we were claiming, so the captions and both upload packs now say it: the agent was stopped a step before the destructive one. pocketos is untouched on this point — there the denied call genuinely is `gcloud run services delete pocketos-prod`. Also fixed across all three: the "agent does its careful work, then acts" cue fired 4-6s before the agent acted, and the receipt cue fired 2-4s before the grep output rendered. Both look like the SRTs were written against intended pacing rather than the final paced cast. TAIL_PAD=3 on each so the audit lines survive the caption clearing, and chapters re-derived from the verified beat maps. Every upload pack now names the subtitled master and the SRT to upload as the caption track, instead of the VO-mux workflow we are not using. amazonq's pinned comment now points at its own classifier bug rather than hoping nobody reads the receipt: the gcloud line classifies as `Bash.gcloud.>/dev/null`. The deny lands anyway, but it is real and it is ours.
A validator for the mechanical half of subtitle QA: cues past the end of the video, overlapping cues, cues that straddle the body/outro cut, and cues too dense to read in the time they are on screen. It found three overlapping pairs I had just introduced while re-timing. An overlap is not cosmetic here — every cue is a separate ffmpeg overlay at the same y, so two cues live at once means two caption boxes drawn on top of each other. It also found eleven cues running at 23-42 characters per second, well past readable, several of them the payoff lines. All seven episodes now pass. Two beats got merged rather than squeezed: the codex block-and-attribution lines, and pocketos's confirm-then-delete, where the two events are one second apart and were fighting for the same box. What the validator explicitly cannot check is whether a caption describes the frame it plays over. Every serious defect in this batch was of that kind, and it took reading frames to find them. The docstring says so.
Four takes. Each found something the previous one hid:
v1 a full `apikey:<uuid>` on the Approvals card, and captions naming
Approvals before Policies when the scene visits Policies first. One cue
described a call drill-in screen that was never recorded at all — the
`{ click: "tbody tr" }` highlighted a row and opened nothing.
v2 masked, but the drill-in I added opened onto a truncated base64 PNG
payload with no classification and no rule. Worse than not filming it.
v3 scrolling to the top of Policies does not escape the rule-recommendation
queue, because that queue IS the top of the page.
v4 clean.
The Policies beat is cut, and the reason is in the scene file: those cards
carry free-text rationale about what this workspace has actually been doing.
Nothing in it is a credential, so masking has no opinion — it is a judgment
about what belongs in public and it belongs to whoever owns the workspace.
Also fixed here: the source resolves to $DIST/$VIDEO, so the first build of
this take silently rendered the OLD footage under the NEW captions and only
the duration gave it away. And the console rig captures on change, so the
trailing dwell holding the per-step breakdown emitted no frames at all — the
payoff of the whole section got 0.65s. TAIL_PAD holds it now.
Captions written against a verified screen map: they dodge four loading
states, and they do not say "sorted by cost" during the five seconds the Runs
table is still sorted by STARTED.
The description says the approvals queue is empty rather than implying
otherwise. 31 approved and 1 rejected on the tabs is the honest state of it.
Turns the real demo casts into YouTube-ready videos. Three episodes are fully built in `youtube/dist/` (silent masters + thumbnails + Shorts), waiting only on voiceover:
Pipeline (`youtube/build.sh`): cast → paced 1080p master with title card, labeled cold-open replay, timed callout overlays, outro card → custom thumbnail → vertical Short → VO mux. Pacing is timing-only (`pace.mjs`) per the record.sh bright line — takes are never doctored; the cold open is burned with "REPLAY — full run follows".
Start here: `youtube/RUNBOOK.md` — channel creation, VO recording (timecoded scripts in `scripts/`), upload packs with UTM-tagged descriptions (`metadata/`), X drafts, and the codex-install re-shoot (the committed cast is an incomplete take — ends at the Codex banner, no deny beat; the shoot needs the human hook-trust step).
Masters are gitignored (`dist/`) — build them with `youtube/build.sh master ` or grab them from this worktree at `../acp-install-yt/youtube/dist/`.
Honest-scope notes are in the VO scripts and descriptions (Replit episode carries the article's complementary-layers caveat; the hero receipt shows deny·hardline + allow·default only — the curl beat is un-narrated since it never resolves on screen).