deepdive

star 2

Produce a long-form (~20+ min, 16:9) operator-narrated deep-dive video — an orchestrated film of many small `explainer` segments (cold-open → Act I → sponsor → Act II → sponsor → Act III → CTA), assembled RAM-safely into one master with chapters + captions. Use when the user wants a "deep dive", "long-form explainer", "YouTube tutorial video", "20-minute video", or runs "/deepdive <topic>". Brand-parameterized (FWF-first). You author the plan + per-segment script/deck and drive the record/review loop; a pure-Python pipeline does narrate→align→render →mux per segment and conform→concat→validate for the master. Generation only — it writes a labeled program dir + crash-safe manifest; it NEVER posts to social platforms (that's Phase 3).

nemock By nemock schedule Updated 6/7/2026

name: deepdive description: >- Produce a long-form (~20+ min, 16:9) operator-narrated deep-dive video — an orchestrated film of many small explainer segments (cold-open → Act I → sponsor → Act II → sponsor → Act III → CTA), assembled RAM-safely into one master with chapters + captions. Use when the user wants a "deep dive", "long-form explainer", "YouTube tutorial video", "20-minute video", or runs "/deepdive ". Brand-parameterized (FWF-first). You author the plan + per-segment script/deck and drive the record/review loop; a pure-Python pipeline does narrate→align→render →mux per segment and conform→concat→validate for the master. Generation only — it writes a labeled program dir + crash-safe manifest; it NEVER posts to social platforms (that's Phase 3).

/deepdive

Build a long-form deep-dive film from a topic. It composes MANY single-explainer projects (one per ~60–90s sub-segment + the cold-open + CTA) plus pre-rendered sponsor interstitials, then conforms and concatenates them into one master. You (Claude) own the generation + editorial judgment; the deepdive and explainer CLIs own the deterministic media + assembly.

Architecture rules (do not violate)

  • You author structured artifacts only: content-plan.md (the editorial spine), and per segment a script.json + deck.json (same contract as /explainer — never raw HTML).
  • The media path (narrate → align → render → mux) and the assembler (conform → concat → validate) make zero LLM calls — they run unattended and resumably.
  • Each sub-segment is its own explainer project under segments/<id>/. The master is built by conform → concat demuxer + stream copy, never a whole-film filtergraph.
  • The manifest is the single source of truth and is crash-safe — only ever mutate it through the deepdive CLI. Resume anytime; run deepdive doctor <program> to see state + next actions.
  • Generation only. Stop at master/ + manifest + packaging. Never post.

Environment

  • Run from the explainer-system repo. Console commands (editable-installed): deepdive and explainer. Media/assembly steps are synchronous — run in the foreground, no polling.
  • Brand: FFW (Founders Who Finish) + --theme fwf. The brand carries a talk_time block → author in the operator's real voice (see /explainer step 4a).
  • Knowledge: the shared cb vault at make_money/brain/ — query it library-first before the web (see deep-dive/BRAIN-RECIPE.md); promote durable findings back on completion.
  • Operator specifics (FWF instance config, voice library) live in ~/.claude/explainer-brands/ dave-byline/ — read them; never copy that content into this public repo.

Workflow

1. Initiate

Confirm the topic + the transformative outcome (what the viewer can DO after — D9), then:

deepdive new "<slug>" --title "<benefit-forward working title>"

Creates deep-dive/programs/<date>_<slug>/ with program.json (a skeleton order cold-open→act-1→fwf-sponsor→act-2→thebuild-sponsor→act-3→cta) + an initial manifest. The act-1/2/3 entries are placeholders you expand into sub-segments in step 4b — don't author to them as-is.

2. Research (library-first)

Query the brain first (personas, the 4 named frameworks, the source roster), THEN the web for what's missing — every on-screen/narrated claim must trace to a source. Per deep-dive/ BRAIN-RECIPE.md: cb list-nodes / cb get-node (or the query skill). Keep working notes in programs/<slug>/research/ (scratch — promoted to the brain only on completion).

3. Content plan (the editorial spine) — BEFORE recording

deepdive plan <program_dir>

Author the scaffolded content-plan.md: the transformative outcome, the throughline thesis + why-watch-this, the open-loop / payoff ledger (2–3 loops, each with a tagged payoff beat), the act structure (default ~15/55/30 — Act II carries the teaching; warn only on extreme lopsidedness), idea-boundary sub-segments with explicit hand-off lines, the cold open (10–20s: payoff/stakes + primary loop), pre-sponsor teases, and a shot list (Adobe Stock search prompts to review). Record the film's archetype for the variety guard: deepdive set-arc (or set rubric.arc via the manifest) — hook archetype / three-act rhythm / payoff type.

4. Plan rubric gate (§8.5) — self-critique, then approve

deepdive rubric <program_dir> plan      # emits the checklist

Honestly evaluate each item (transformative outcome named, benefit-forward title, hook strength, 2–3 open loops with payoffs, act balance, MECE horizontal logic, beat variety, why-watch-this). Revise the plan until it passes. Run the variety guard (warns if this arc repeats recent films). Then:

deepdive approve-plan <program_dir> --notes "<what you checked>"

Recording/assembly is gated on this — the manifest refuses to assemble an unapproved plan.

4b. Expand the order into your sub-segments (the segment model — read this)

order is a FLAT, ordered list of build/record units. Each entry is either one explainer project (a ~60–90s sub-segment, the cold-open, or the CTA) under segments/<id>/, or a registered interstitial. There is no nested "act → sub-segments" structure in the manifest — the assembler walks order top-to-bottom, conforms each entry's MP4, and concatenates them. The record/align/gate/review loop also operates per order entry. So:

  • Acts are a grouping concept, not a manifest level. Replace each act-N skeleton entry with that act's actual sub-segments, each its own order entry + segments def. Edit program.json directly (it's the intent file; deepdive reconciles the manifest from it):
    "order": ["cold-open", "act1-sub01", "act1-sub02", "fwf-sponsor",
              "act2-sub01", "act2-sub02", "act2-sub03", "thebuild-sponsor",
              "act3-sub01", "act3-sub02", "cta"],
    "segments": {
      "cold-open":  { "kind": "act", "title": "Cold open",        "chapter": "Intro" },
      "act1-sub01": { "kind": "act", "title": "<sub-seg hook>",   "chapter": "Act I — <act title>" },
      "act1-sub02": { "kind": "act", "title": "<...>",            "chapter": "Act I — <act title>" },
      "fwf-sponsor":{ "kind": "interstitial", "registry_ref": "interstitial-fwf-book", "title": "Founders Who Finish" },
      "act2-sub01": { "kind": "act", "title": "<...>",            "chapter": "Act II — <act title>" }
      /* … */
    }
    
  • IDs are free-form (use act1-sub01-style ids so order reads clearly). kind is "act" for your projects, "interstitial" for sponsors/CTA (with a registry_ref).
  • chapter groups sub-segments into ONE YouTube chapter. Give every sub-segment of an act the same chapter string → the assembler collapses them into a single act-level chapter (without it, you'd get a chapter per 60–90s sub-segment). title stays per-segment (used as the chapter label only when chapter is absent).
  • After editing order, run deepdive doctor <dir> — it reconciles the manifest to the new list.

5a. Author every sub-segment (scaffold + script/deck) — do this for ALL of them first

For each act/cta sub-segment in order (skip interstitials):

  1. Scaffold it as an explainer project. Act sub-segments use --no-cta — it keeps the FWF watermark but suppresses the auto-appended book-CTA slide + spoken CTA tail (the --brand default adds one to every project, which is right for short-form Reels but would put a book CTA at the end of every 60–90s beat). The film's single CTA is the dedicated closing cta segment.
    explainer scaffold "<seg-id>" --theme fwf --aspect 16:9 --brand FFW --no-cta \
        --voice-source operator --outdir <program_dir>/segments
    
    then rename segments/<date>_<seg-id>/segments/<seg-id>/ to match the manifest id. (The closing cta segment is the ONE place to keep the CTA: scaffold it --brand FFW WITHOUT --no-cta. Sponsor interstitials are pre-rendered and carry their own CTAs.)
  2. Author script.json + deck.json (the /explainer device catalog — favor McKinsey treatments: action title + source line on data-viz, kind:"muted" insight highlight, narration-paced build). Ground the words in the operator's voice via explainer talktime --brand FFW --topics "<keywords>" — quote verbatim, adapt, never fabricate.
  3. Offer the operator a quick script review before any recording (re-recording is the costly step).

5b. Record sprint — YOU DRIVE THIS LOOP. Do NOT hand the operator a command list.

This is an interactive, coached loop: you run every command; the operator only reads the teleprompter and clicks Finish. Walk them through the segments one at a time — never dump the segment list + commands for them to run themselves. For each act/cta sub-segment, in order (skip interstitials):

  1. Launch the recorder in the background (so you stay responsive and aren't killed by a tool timeout while they read):
    deepdive record "<program_dir>" "<seg-id>" --gate-only
    
    --gate-only records → aligns → runs the alignment gate but skips rendering, so there's no render wait between takes — the operator powers straight through. It opens the teleprompter in their browser, pre-loaded with the prior segment's hand-off line for tonal continuity.
  2. Say one short line: "Recording </strong> — read the teleprompter, hit <strong>Finish</strong> when done."</em> Then <strong>wait</strong> for the background command to complete (you'll be notified).</li> <li>Read the <strong>gate</strong> result:<ul> <li><strong>Passed</strong> → <em>"✓ clean take"</em> and <strong>immediately launch the next segment</strong> (auto-advance).</li> <li><strong>Failed</strong> → tell them exactly what it caught (the timestamps: an ad-lib, dropped phrase, or long pause) and <strong>re-launch the recorder for the same segment</strong>. If they changed the wording on purpose, edit that segment's <code>script.json</code> to match and re-run.</li> </ul> </li> <li>Repeat until every act/cta segment is recorded + gated. Resume anytime — <code>deepdive doctor</code> shows what's left.</li> </ol> <h3>5c. Render the recorded segments (batch, unattended)</h3> <p>After the sprint, render each recorded segment — the slow frame-capture step, no operator needed. Run them <strong>one at a time</strong> (RAM-safe), in the background:</p> <pre><code>deepdive build-segment "<program_dir>" "<seg-id>" # narrate(assemble clips) -> align -> gate -> render -> mux </code></pre> <h3>5d. Review (approve/reject) — assembly gates on <code>approved</code></h3> <p>Spot-check each rendered segment (a frame or a quick playback), then record the verdict:</p> <pre><code>deepdive review "<program_dir>" "<seg-id>" approve|reject --notes "<why>" </code></pre> <p><em>(Fully-TTS draft/preview: scaffold WITHOUT <code>--voice-source operator</code>, skip 5b entirely, and run <code>deepdive build-segment</code> per segment — the gate passes trivially since the narration is the script.)</em></p> <h3>6. Sponsor + CTA interstitials</h3> <p>The FWF book / The Build / CTA interstitials are <strong>pre-rendered, registered</strong> MP4s (<code>deep-dive/brand/interstitials/interstitial-registry.json</code>). The assembler verifies their hash + format automatically. If they're still TTS placeholders, note that in the report; Dave swaps in the face-cam composites later (then they're re-registered).</p> <h3>7. Assemble the master</h3> <pre><code>deepdive assemble <program_dir> --check # preflight conformance table (catches format drift) deepdive assemble <program_dir> # conform -> concat -> captions -> chapters -> validate </code></pre> <p>Gated on the approved plan + every act segment <code>approved</code>. Produces <code>master/deepdive_16x9.mp4</code>, <code>captions.srt</code>/<code>.vtt</code>, <code>chapters.txt</code>, and a master-integrity report (duration, audio continuity, caption bounds, monotonic chapters, level-matched seams). Use <code>--dry-run</code> for a cheap ordered preview first.</p> <h3>8. Whole-film rubric gate (§8.5) — before publish</h3> <p>Watch the master end-to-end. Then:</p> <pre><code>deepdive rubric <program_dir> film # retention read, seam check, callbacks paid, dead-air, # sponsor teases, packaging present deepdive approve-film <program_dir> --notes "<what you checked>" </code></pre> <h3>9. Boundary + promote</h3> <p>Report the master + chapters + captions + the manifest path. <strong>Stop here — never post</strong> (Phase 3 publishes via Blotato). On completion, <strong>promote</strong> durable research (sourced facts, a new named framework, what-worked patterns, the produced piece) from <code>research/</code> into the brain via the <code>atomize</code> / <code>intake</code> skills (<code>deep-dive/BRAIN-RECIPE.md</code>).</p> <h2>Observability & resume</h2> <ul> <li><code>deepdive status <program_dir></code> — concise state · <code>deepdive doctor <program_dir></code> — full lifecycle checklist + manifest-vs-disk drift + concrete next actions.</li> <li><code>build-log.jsonl</code> records every stage's timing + peak RAM; <code>.history/transitions.jsonl</code> is the audit trail. A crashed segment (dead owner PID) is auto-detected and re-surfaced by <code>doctor</code>.</li> </ul> <h2>Out of scope (current phase)</h2> <p>Packaging automation (title variants + thumbnail composite) is landing in 2.5; YouTube publishing</p> <ul> <li>the snippet promo engine are <strong>Phase 3</strong> (never in this skill). Cross-dissolve transitions, act-bed ducking wiring, and stock B-roll compositing are later sub-phases — don't fake them; note them.</li> </ul> </article> </div> <!-- Right: Metadata & Command Sidebar --> <div class="w-full lg:w-80 shrink-0 flex flex-col gap-6" data-astro-cid-7zzsworf> <!-- Install Card --> <div class="p-6 rounded-xl bg-surface-container border border-border/80 flex flex-col gap-4 shadow-sm" data-astro-cid-7zzsworf> <span class="text-xs font-bold uppercase tracking-widest text-on-surface-variant/60 font-mono" data-astro-cid-7zzsworf>Install via CLI</span> <div class="flex flex-col gap-2" data-astro-cid-7zzsworf> <div id="detail-install-cmd" class="font-mono text-[11px] p-3 rounded-lg bg-black/40 border border-border select-all break-all text-primary font-bold leading-relaxed" data-astro-cid-7zzsworf> npx skills add https://github.com/nemock/video-explainer-system --skill deepdive </div> <button id="detail-copy-btn" class="w-full py-2.5 rounded-lg bg-primary hover:bg-primary-hover text-on-primary font-sans font-bold text-sm shadow transition-all active:scale-95 flex items-center justify-center gap-1.5" data-astro-cid-7zzsworf> <span class="material-symbols-outlined text-[16px]" data-astro-cid-7zzsworf>content_copy</span> <span data-astro-cid-7zzsworf>Copy Command</span> </button> </div> </div> <!-- Details & Stats Card --> <div class="p-6 rounded-xl bg-surface-container border border-border/80 flex flex-col gap-4 shadow-sm text-on-surface" data-astro-cid-7zzsworf> <span class="text-xs font-bold uppercase tracking-widest text-on-surface-variant/60 font-sans" data-astro-cid-7zzsworf>Repository Details</span> <div class="flex flex-col gap-3.5" data-astro-cid-7zzsworf> <div class="flex justify-between items-center text-sm" data-astro-cid-7zzsworf> <span class="text-on-surface-variant/70 flex items-center gap-1.5" data-astro-cid-7zzsworf> <span class="material-symbols-outlined text-[16px] text-on-surface-variant/60" data-astro-cid-7zzsworf>star</span> Stars </span> <span class="font-mono font-bold text-on-surface" data-astro-cid-7zzsworf>2</span> </div> <div class="flex justify-between items-center text-sm" data-astro-cid-7zzsworf> <span class="text-on-surface-variant/70 flex items-center gap-1.5" data-astro-cid-7zzsworf> <span class="material-symbols-outlined text-[16px] text-on-surface-variant/60" data-astro-cid-7zzsworf>call_split</span> Forks </span> <span class="font-mono font-bold text-on-surface" data-astro-cid-7zzsworf>1</span> </div> <div class="flex justify-between items-center text-sm" data-astro-cid-7zzsworf> <span class="text-on-surface-variant/70 flex items-center gap-1.5" data-astro-cid-7zzsworf> <span class="material-symbols-outlined text-[16px] text-on-surface-variant/60" data-astro-cid-7zzsworf>navigation</span> Branch </span> <span class="font-mono bg-surface border border-border px-2 py-0.5 rounded text-[11px] text-on-surface-variant" data-astro-cid-7zzsworf>main</span> </div> <div class="flex justify-between items-start text-sm" data-astro-cid-7zzsworf> <span class="text-on-surface-variant/70 flex items-center gap-1.5 mt-0.5" data-astro-cid-7zzsworf> <span class="material-symbols-outlined text-[16px] text-on-surface-variant/60" data-astro-cid-7zzsworf>article</span> Path </span> <span class="font-mono bg-surface border border-border px-2 py-0.5 rounded text-[11px] text-on-surface-variant truncate max-w-[150px]" title="SKILL.md" data-astro-cid-7zzsworf>SKILL.md</span> </div> </div> </div> <!-- Occupations Tag Card --> <!-- Related Creators Card --> <div class="p-6 rounded-xl bg-surface-container border border-border/80 flex flex-col gap-3 shadow-sm" data-astro-cid-7zzsworf> <span class="text-xs font-bold uppercase tracking-widest text-on-surface-variant/60 font-sans" data-astro-cid-7zzsworf>More from Creator</span> <div class="flex items-center gap-2" data-astro-cid-7zzsworf> <img class="w-8 h-8 rounded-full border border-border" src="https://avatars.githubusercontent.com/u/6521252?v=4" alt="nemock" onerror="this.src='https://avatars.githubusercontent.com/u/9919?v=4'" data-astro-cid-7zzsworf> <div class="flex flex-col min-w-0" data-astro-cid-7zzsworf> <span class="font-bold text-sm truncate text-on-surface" data-astro-cid-7zzsworf>nemock</span> <a href="/?creator=nemock" class="text-xs text-primary hover:underline font-semibold transition-all" data-astro-cid-7zzsworf>Explore all skills →</a> </div> </div> </div> </div> </div> </div> </div> <script> const copyBtn = document.getElementById("detail-copy-btn"); const installCmd = document.getElementById("detail-install-cmd"); if (copyBtn && installCmd) { copyBtn.addEventListener("click", () => { const cmd = installCmd.textContent.trim(); navigator.clipboard.writeText(cmd).then(() => { const originalText = copyBtn.innerHTML; copyBtn.innerHTML = ` <span class="material-symbols-outlined text-[16px]">check</span> <span>Copied!</span> `; copyBtn.style.background = "#10b981"; copyBtn.style.borderColor = "#10b981"; setTimeout(() => { copyBtn.innerHTML = originalText; copyBtn.style.background = ""; copyBtn.style.borderColor = ""; }, 1500); }); }); } </script> </div> <!-- Footer --> <footer class="border-t border-border bg-surface-container-low text-on-surface-variant py-8 px-gutter mt-16 rounded-xl"> <div class="max-w-container-max mx-auto flex flex-col md:flex-row justify-between items-center gap-6"> <div class="flex items-center gap-2"> <div class="w-6 h-6 rounded bg-primary bg-opacity-20 flex items-center justify-center"> <span class="material-symbols-outlined text-primary text-sm">code_blocks</span> </div> <span class="font-bold text-on-surface text-sm">SkillMD</span> </div> <div class="flex flex-wrap justify-center gap-6 text-sm"> <a href="/about" class="hover:text-primary transition-colors">About Us</a> <a href="/contact" class="hover:text-primary transition-colors">Contact Us</a> <a href="/privacy" class="hover:text-primary transition-colors">Privacy Policy</a> <a href="/terms" class="hover:text-primary transition-colors">Terms of Service</a> <a href="/support" class="hover:text-primary transition-colors">Support</a> </div> <div class="text-xs text-on-surface-variant/80"> © 2026 SkillMD. All rights reserved. </div> </div> </footer> </main> <!-- Script for Theme Toggle, Mobile Menu, and Sidebar Filter Redirection --> <script> // Theme setup const savedTheme = localStorage.getItem("theme") || "dark"; function applyTheme(theme) { document.documentElement.classList.remove("dark", "green", "dracula", "nord"); if (theme === "dark") { document.documentElement.classList.add("dark"); } else if (theme === "green") { document.documentElement.classList.add("dark", "green"); } else if (theme === "dracula") { document.documentElement.classList.add("dark", "dracula"); } else if (theme === "nord") { document.documentElement.classList.add("dark", "nord"); } document.documentElement.setAttribute("data-theme", theme); const themeMoon = document.getElementById("theme-moon"); const themeSun = document.getElementById("theme-sun"); const themeLeaf = document.getElementById("theme-leaf"); const themeDracula = document.getElementById("theme-dracula"); const themeNord = document.getElementById("theme-nord"); if (themeMoon && themeSun && themeLeaf && themeDracula && themeNord) { themeMoon.style.display = theme === "dark" ? "inline" : "none"; themeSun.style.display = theme === "light" ? "inline" : "none"; themeLeaf.style.display = theme === "green" ? "inline" : "none"; themeDracula.style.display = theme === "dracula" ? "inline" : "none"; themeNord.style.display = theme === "nord" ? "inline" : "none"; } } applyTheme(savedTheme); const themeToggleBtn = document.getElementById("theme-toggle-btn"); if (themeToggleBtn) { themeToggleBtn.addEventListener("click", () => { const currentTheme = document.documentElement.getAttribute("data-theme") || "dark"; let newTheme = "dark"; if (currentTheme === "dark") { newTheme = "light"; } else if (currentTheme === "light") { newTheme = "green"; } else if (currentTheme === "green") { newTheme = "dracula"; } else if (currentTheme === "dracula") { newTheme = "nord"; } else { newTheme = "dark"; } applyTheme(newTheme); localStorage.setItem("theme", newTheme); }); } // Mobile menu toggle and sidebar logic const mobileMenuToggle = document.getElementById("mobile-menu-toggle"); const sidebarMenu = document.getElementById("sidebar-menu"); const sidebarOverlay = document.getElementById("sidebar-overlay"); function isMobile() { return window.innerWidth < 768; // 768px is the 'md' breakpoint in Tailwind } function openSidebar() { if (sidebarMenu) { sidebarMenu.classList.remove("-translate-x-full"); } if (sidebarOverlay) { sidebarOverlay.classList.remove("hidden"); } } function closeSidebar() { if (sidebarMenu && isMobile()) { sidebarMenu.classList.add("-translate-x-full"); } if (sidebarOverlay) { sidebarOverlay.classList.add("hidden"); } } if (mobileMenuToggle && sidebarMenu) { mobileMenuToggle.addEventListener("click", (e) => { e.stopPropagation(); if (isMobile()) { const isClosed = sidebarMenu.classList.contains("-translate-x-full"); if (isClosed) { openSidebar(); } else { closeSidebar(); } } }); document.addEventListener("click", (e) => { if (isMobile()) { if (!sidebarMenu.contains(e.target) && !mobileMenuToggle.contains(e.target)) { closeSidebar(); } } }); if (sidebarOverlay) { sidebarOverlay.addEventListener("click", () => { if (isMobile()) { closeSidebar(); } }); } // Collapse sidebar when clicking a filter button, creator button, or nav item inside it sidebarMenu.addEventListener("click", (e) => { if (isMobile()) { const clickTarget = e.target.closest("button, a"); if (clickTarget) { closeSidebar(); } } }); // Sync sidebar state on window resize window.addEventListener("resize", () => { if (!isMobile()) { // Desktop: sidebar should be visible, no overlay if (sidebarMenu) { sidebarMenu.classList.remove("-translate-x-full"); } if (sidebarOverlay) { sidebarOverlay.classList.add("hidden"); } } else { // Mobile: start collapsed if (sidebarMenu) { sidebarMenu.classList.add("-translate-x-full"); } if (sidebarOverlay) { sidebarOverlay.classList.add("hidden"); } } }); } // If not on homepage, redirect on sidebar filter click const isHomepage = window.location.pathname === "/"; document.querySelectorAll("#occupation-filters .filter-btn").forEach(btn => { btn.addEventListener("click", (e) => { const occ = e.currentTarget.getAttribute("data-occupation"); if (!isHomepage) { window.location.href = occ ? `/?occupation=${encodeURIComponent(occ)}` : "/"; } }); }); document.querySelectorAll("#creator-filters .creator-btn").forEach(btn => { btn.addEventListener("click", (e) => { const creator = e.currentTarget.getAttribute("data-creator"); if (!isHomepage) { window.location.href = `/?creator=${encodeURIComponent(creator)}`; } }); }); </script> </body> </html>