| name | podcast-writer |
| description | Create one-person podcast scripts from user-provided sources such as PDFs, text files, websites, and YouTube links. Use when Codex needs to collect and preprocess source material, fetch YouTube transcripts with the bundled Python helper, fall back to GPU-only local Whisper transcription when YouTube captions are unavailable, write a clean TTS-ready plain-text monologue script, save it as .txt, and run strict subagent content-quality evaluation until every rubric item passes. |
Podcast Writer
Create a one-person podcast script from supplied source material, then save only the final script body as a plain .txt file.
Hard Rules
- Produce a one-person monologue. Do not use speaker labels such as
화자1:, Host:, Narrator:, or dialogue/interview formatting.
- Save the final approved
.txt under the current project root as ./scripts/<descriptive-name>.txt. Do not save the podcast output inside skills/podcast-writer/scripts/.
- Save the final
.txt with script body only. Do not include headings, metadata, evaluation notes, source notes, or "here is the script" wrappers in the saved script.
- After the evaluator returns all-pass, delete temporary working files created by this skill, including downloaded audio, extracted transcripts, scratch source notes, draft scripts, and evaluation handoff files. Do not delete user-provided original source files or the final approved
./scripts/*.txt output.
- Follow the user's requested topic, angle, audience, length, tone, emphasis, and exclusions.
- Ground the script in the provided sources. Do not invent source facts or present speculation as fact.
- Blend all provided sources into one unified podcast script. Do not mention source boundaries in the final script, such as "in the PDF", "the website says", "the video explains", "source one", or separate source-by-source summaries, unless the user explicitly requests source attribution.
- Remove preprocessing noise before writing the podcast script: timestamps, repeated captions, navigation text, ads, transcript artifacts, broken subtitle fragments, boilerplate, and duplicate passages.
- Treat TTS-readability rules as writer obligations, not evaluator duties. Keep the script clean for speech output, but do not ask the evaluator to judge TTS or formatting.
- Before completion, send the script and source notes to a newly created independent strict subagent for content-quality evaluation using
references/evaluation-rubric.md.
- Create a fresh independent evaluator subagent for every evaluation attempt, including every re-evaluation after revisions. Do not reuse the same evaluator thread.
- Revise and re-evaluate with a fresh independent evaluator until every rubric item is
PASS. Do not report the task complete while the evaluator returns any FAIL.
- If subagent tools are unavailable or repeated evaluation cannot progress because of missing source access, stop and report the blocker instead of silently skipping evaluation.
Source Handling
-
Local text or Markdown: read the file, separate user-authored content from metadata, and keep relevant structure.
-
PDF: extract text with an appropriate PDF workflow. If extraction quality is uncertain, inspect rendered pages or use OCR only when needed.
-
Website URL: fetch the current page, extract main article/body content, and remove navigation, footer, comments, ads, related links, and cookie text.
-
YouTube URL: first use the bundled transcript helper:
uv run skills/podcast-writer/scripts/fetch_youtube_transcript.py '<youtube-url-or-video-id>' --format text
The helper accepts normal watch URLs, youtu.be, Shorts, embed, and live URL forms. Quote full URLs in shells such as zsh so ? is not treated as a glob. It preserves transcript segment text, including music cues or lyrics; content filtering happens later during source preprocessing. If uv is unavailable, run the script with Python only when youtube-transcript-api is already installed.
-
YouTube audio fallback: if the transcript helper fails because captions are unavailable or unusable, use the GPU-only Whisper fallback helper:
uv run skills/podcast-writer/scripts/transcribe_youtube_gpu.py '<youtube-url-or-video-id>' --format text
This fallback downloads the YouTube audio with yt-dlp and transcribes it with faster-whisper on CUDA only. The default model is turbo, the faster-whisper alias for Whisper large-v3-turbo. Do not use CPU fallback. If no CUDA GPU is available, stop and report the blocker.
-
Multiple sources: process each source separately only in private working notes, then merge the useful material into one coherent script. Do not structure the final script as source-by-source explanation or attribution unless the user explicitly requests that format.
Workflow
- Identify source inputs, requested output path, language, audience, topic angle, target length, and any explicit exclusions.
- Collect source text. Use
fetch_youtube_transcript.py for YouTube transcripts. If captions are unavailable, use transcribe_youtube_gpu.py; it must run through uv run and must fail instead of using CPU when CUDA is unavailable. Preserve a working source-notes file or scratch summary outside the final script.
- Preprocess sources into concise notes:
- core claims and evidence
- necessary background
- important examples or quotes to paraphrase
- source conflicts or uncertainty
- material to exclude as noise
- Choose a central episode message. The script should not be a flat summary; it should have a clear content point.
- Draft the one-person podcast script as a polished monologue that integrates all selected source material into one narrative. Do not say or imply that the script is walking through separate source files.
- Save working drafts outside the final output path while iterating. After strict evaluation passes, save the final approved script body to
./scripts/<descriptive-name>.txt under the current project root.
- Read
references/evaluation-rubric.md, then create a new independent strict evaluator subagent. Provide file paths, not pasted full script text:
- path to the candidate script file
- path to concise source notes or source extracts needed to verify content
- the user's original instructions
- the fixed output contract from the rubric
- If any rubric item is
FAIL, revise the script according to REQUIRED_FIXES, then create another fresh independent evaluator subagent for the revised script. Never re-use the previous evaluator for re-evaluation.
- If an evaluator outputs
PASS, FAIL, RESULT: PASS, or RESULT: FAIL before writing the required assessment sections, treat that evaluator output as invalid and failed even if it later includes reasons. Start a fresh independent evaluator with the same candidate files and stricter instructions.
- Finish only after the evaluator returns
RESULT: PASS with every item marked PASS and no pass/fail judgment appears before the assessment text.
- Delete temporary files created during source collection, preprocessing, audio download, draft writing, and evaluator handoff. Keep only the final approved
./scripts/*.txt output and any user-provided original source files.
Evaluation Delegation Prompt Contract
Ask the evaluator to assess only script content quality. Do not ask it to evaluate TTS formatting, speaker labels, file naming, or source ingestion mechanics.
Use a new independent evaluator subagent for each evaluation attempt. The evaluator should receive only paths to the revised candidate script and source notes, user instructions, and this rubric contract. Do not paste the full script content into the prompt. Do not include previous evaluator conclusions unless the user explicitly asks to preserve an audit trail.
Before sending the prompt, replace every {{...}} field with the actual task content. {{SOURCE_NOTES_PATH}} and {{CANDIDATE_SCRIPT_PATH}} must be readable local file paths. Do not leave template variables in the prompt sent to the evaluator.
Use this prompt template for every evaluation and re-evaluation:
You are an independent strict podcast script content-quality evaluator.
Evaluate only the content quality of the candidate one-person podcast script.
Do not evaluate TTS readiness, speaker labels, plain-text formatting, file paths, transcript-fetch mechanics, or whether the writer followed operational workflow rules.
Be very strict. PASS is allowed only when the script is strong as podcast content, not merely acceptable.
When uncertain, choose FAIL for the affected criterion.
The final RESULT may be PASS only if every criterion is PASS.
Your first output line must be exactly `EVALUATION:`.
Do not write `PASS`, `FAIL`, `RESULT: PASS`, or `RESULT: FAIL` before completing every `Assessment` field.
If you put any pass/fail judgment before the assessment text, your evaluation is invalid and must be treated as FAIL.
USER INSTRUCTIONS:
{{USER_INSTRUCTIONS}}
SOURCE NOTES:
Read the source notes from this local path:
{{SOURCE_NOTES_PATH}}
CANDIDATE SCRIPT:
Read the candidate script from this local path:
{{CANDIDATE_SCRIPT_PATH}}
RUBRIC:
- Source Fidelity: accurate source understanding; no distortion, unsupported facts, or essential omissions.
- Content Selection: strong selection and weighting of important material for the user's goal.
- Insight And Interpretation: meaningful explanation of significance, context, stakes, or implications beyond plain summary.
- Logical Coherence: claims, background, evidence, transitions, and conclusions connect cleanly.
- Non-Repetition: no repeated claim, setup, explanation, example, transition, or conclusion unless it adds new substance.
- User Intent Fit: user purpose, audience, angle, emphasis, and exclusions shape the content choices.
- Source Integration: multiple sources are synthesized into one coherent script without source-by-source narration or unnecessary source mentions.
- Overall Content Value: worth listening to as a finished episode with a clear through-line and message.
Return exactly this structure:
EVALUATION:
- Source Fidelity:
Assessment: ...
Criterion Result: PASS|FAIL
- Content Selection:
Assessment: ...
Criterion Result: PASS|FAIL
- Insight And Interpretation:
Assessment: ...
Criterion Result: PASS|FAIL
- Logical Coherence:
Assessment: ...
Criterion Result: PASS|FAIL
- Non-Repetition:
Assessment: ...
Criterion Result: PASS|FAIL
- User Intent Fit:
Assessment: ...
Criterion Result: PASS|FAIL
- Source Integration:
Assessment: ...
Criterion Result: PASS|FAIL
- Overall Content Value:
Assessment: ...
Criterion Result: PASS|FAIL
REQUIRED_FIXES:
- Use `None` only when every item is PASS. Otherwise list concrete content revisions required to reach PASS.
RESULT: PASS|FAIL
All eight evaluation items must be PASS for RESULT: PASS. When the evaluator is uncertain, it must choose FAIL.
For every criterion, write Assessment before Criterion Result. Do not output a criterion-level PASS or FAIL before the assessment text.
If the evaluator returns PASS, FAIL, RESULT: PASS, or RESULT: FAIL before the assessment text, treat that evaluator output as FAIL regardless of any later explanation.
Response
When finished, report:
- saved script path
- sources used and any sources that could not be accessed
- that strict subagent evaluation passed all rubric items
- that temporary working files created by the skill were deleted
- any important source uncertainty preserved in the script