Bpm Preflight Gate
BPM Pre-Flight Gate — Production Render Authorisation Checklist
Standard locked 2026-05-14 after Daniel's pre-flight ask:
"i want to spend money once, and know its coming out the other end well… arming doors and cross checking every step… is the compliance moat intact? would we be flagged? would we have copyright issues? would we trigger the youtube algorithm for ai-slop? would we be flagged for inappropriate content?"
This standard is MANDATORY before any --mode full --i-confirm-spend render. The pre-flight gate runs as agents/yt/bpm-preflight-gate.py <script.md> and produces PASS/FAIL per item. Any FAIL blocks the render. Any WARN flags for Daniel review but does not block.
The 15-item gate
🎯 Section A — Content Integrity
A1. Script approved
- Frontmatter status: approved present
- Fact-check passes-log exists alongside script
- Spoken-doctor -v2-spoken.md variant exists alongside script
- FAIL = block
A2. Fact-check residuals reviewed
- For any flagged residual in the fact-check log, Daniel has logged reviewed: material|nuance per feedback_factcheck_iteration_diminishing_returns.md
- WARN if any residual remains unreviewed; FAIL only if material residual unresolved
A3. Script length within YouTube algo sweet spot
- 8-12 minutes long-form for finance/tech educational (HHQ + StackSensible)
- 60-90 sec short-form
- WARN outside band, FAIL outside 4-20 min for long-form
A4. AI disclosure block in script
- Last 5-10 seconds of script discloses AI involvement explicitly
- Standard wording: "This video uses AI for narration and B-roll generation. All facts, sources, and recommendations are reviewed by a human. Full citations in the description."
- FAIL if missing
🎤 Section B — Voice + Render Settings
B1. Voice ID locked
- ELEVENLABS_DANIEL_HHQ_VOICE_ID resolves to a professional category voice in ElevenLabs
- Voice owner consent confirmed (PVC training requires consent recording — verified at training)
- FAIL if cloned (IVC) — IVC quality is not acceptable for production per Daniel's 2026-05-14 review
B2. Voice settings within production band
- stability 0.50-0.65, similarity 0.85-0.95, style 0.0-0.20
- WARN outside band
B3. Pre-render test in cheap mode confirmed
- A -PVC-*.mp4 exists for this script in channels/{channel}/renders/
- Daniel has signed off on the cheap-mode render (state file: approvals/<slug>.json with cheap_mode_approved: true)
- FAIL if missing
🛡️ Section C — Legal + Compliance
C1. AI-generated disclosure for YouTube Studio
- YouTube's "Altered content" checkbox must be ticked at upload (this is set via upload SOP, but gate confirms description includes disclosure too)
- WARN
C2. Financial / medical / legal advice disclaimer
- HHQ content REQUIRES financial-advice disclaimer in description: "This content is general information only and does not constitute financial advice. Consult a licensed Australian financial adviser for personal recommendations."
- StackSensible content REQUIRES no-warranty disclaimer for software/tool recommendations: "Recommendations are based on testing as of [date]. Software pricing + features change. Verify before purchasing."
- FAIL if missing from description
C3. Copyright clearance
- Music: ONLY from royalty-free sources — YouTube Audio Library / Suno (with watermark removed in paid tier) / Epidemic Sound (paid) / Artlist (paid)
- License source documented in channels/{channel}/renders/<slug>-music-license.txt
- FAIL if music used but no license documented
C4. Brand / trademark visibility in B-roll
- Veo3-generated B-roll may include text or logos that could be mistaken for real brands
- Manual review of generated B-roll before render-publish
- WARN — Daniel signs off on a contact sheet
C5. Real-person likeness
- No generated content depicting identifiable real people without permission
- WARN — Daniel reviews
📺 Section D — Distribution Assets
D1. Description copy written
- channels/{channel}/content/scripts/<slug>.description.md exists
- Length: 800-1500 chars for SEO (Australian + finance/tech niches)
- Hook in first 125 chars (above the fold)
- Hashtags: 3-5, niche-specific
- FAIL if missing
D2. In-video links resolved
- If script says "link in description" or "download below", the corresponding asset MUST exist
- Script-referenced URLs all resolve (HTTP 200) or are stable internal paths
- FAIL if any broken reference
D3. Thumbnail produced
- channels/{channel}/renders/<slug>-thumbnail.png exists
- Resolution 1280×720 (YouTube spec)
- Text visible at 480×270 mobile preview size
- Face / subject visible (not blank text-on-color)
- Brand consistency with prior channel videos
- WARN if missing; FAIL if missing on first upload of the channel
D4. CTA alignment
- Script CTA matches description CTA matches end-screen CTA
- Single primary CTA per video (Subscribe OR free download OR test prompt — not all three with equal weight)
- WARN if misaligned
D5. End-screen plan
- 20-second end-screen segment with subscribe + suggested-video components
- WARN if missing
🚦 Section E — Algorithm + Channel Health
E1. Title within YouTube algo limits
- 60 characters max for full mobile preview
- Avoids clickbait flag words (verified, exposed, you won't believe, etc) unless content delivers
- Title ↔ thumbnail ↔ first-15-seconds alignment
- WARN
E2. AI-slop fingerprint review
- Manual review against AI-slop indicators:
- Generic stock-footage feel
- Robotic voice (covered by PVC + tune2)
- Content density / fact density (high-density = lower AI-slop signal)
- Repetitive sentence structure (covered by spoken-doctor pass)
- Inconsistent visual style across beats
- WARN — Daniel reviews contact sheet
E3. Channel-creation prerequisite check
- YouTube channel for this script's destination exists + monetisation-eligible
- Anti-spam cooldown cleared (StackSensible was 24-48h from 2026-05-12)
- FAIL if channel doesn't exist (we don't render before channel exists)
How the gate runs
python3 agents/yt/bpm-preflight-gate.py <script.md>
Output: JSON + console table showing each item, PASS/WARN/FAIL, and notes. Exit code 0 only if all FAIL items pass.
To override a single WARN (Daniel decision), use:
python3 agents/yt/bpm-preflight-gate.py <script.md> --ack-warn=D3,E2
What happens if gate passes
The gate produces an approvals/<slug>.json file with preflight_passed: true + timestamp + voice_id used + cost estimate. The render command (bpm-render-v2.py --mode full --i-confirm-spend) refuses to run unless that approval exists for the script.
Diff vs locked BPM brief
The locked BPM brief (brief_LOCKED_bpm.md) defines the compliance moat at a strategic level. This gate is the OPERATIONAL implementation — every individual render gets gated. Both documents stay in sync; if Daniel changes the strategic moat, the gate items change too.
Cost economics post-gate
Once a script passes the gate, full-mode render is:
- ElevenLabs narration: $0 (cached from cheap-mode pre-render)
- fal.ai Veo3 fast: ~$0.50-0.80 per second of B-roll × ~65 sec = $33-52
- Music: $0 (royalty-free)
- Thumbnail: $0 (Cloudflare Workers AI Flux, free tier)
- Per-video full-mode cost: $33-52
Daniel approves this cost ONLY when gate is all-green. Each green script is a "production-ready" asset — the render is just the mechanical step.
Change log
- 2026-05-14 — Initial standard locked after Daniel's pre-flight ask. 15-item gate, 5 sections.