Write developer blog posts from video transcripts, meeting notes, or rough ideas. Extracts narrative from source material, structures content with hooks and technical sections, formats code examples with placeholders, and checks drafts against 31 AI anti-patterns with structural variant detection, three-pass scanning (surface, skeleton, soul check), and rewrite auditing. Auto-updates anti-pattern list from Wikipedia before each session. Includes interactive onboarding to learn the author's voice from writing samples. Persona files live at ~/.claude/blog-writer-persona/ by default, with symlink support for custom locations (e.g. Google Drive for backup). Optional global voice saves your voice profile to Claude Code user memory so it applies across all projects. Use this skill whenever the user wants to write a blog post, draft a blog, turn a transcript into a blog, work on blog content, or mentions "blog" in the context of content creation. Also trigger when the user provides a video transcript and wants written content derived from it, or when continuing work on a blog series.
97
94%
Does it follow best practices?
Impact
99%
1.43xAverage score across 7 eval scenarios
Advisory
Suggest reviewing before use
This document defines the step-by-step workflow from raw input (usually a video transcript) to a finished blog post draft. Follow these phases in order. Do not skip phases. Do not start writing prose until Phase 3.
The blog home directory is set by the author at session start. All blog artifacts live there.
Directory structure:
_blog-skill/ — Skill-wide persistent storage (series trackers, learned preferences,
cross-post memory). Survives across all posts and sessions.
series-tracker.md — Series state, episode numbers, callbacks, open threadsPer-post files (research banks, drafts) go in the post's working directory. The working directory is usually set by the author before starting.
At the start of every blog session, read _blog-skill/series-tracker.md (if it exists)
to know the current state of all series. At the end of every session where a post is
published or substantially completed, update it.
Maintain a structured notes file throughout the process. This serves two purposes: it's a working document that keeps research organized across phases, and it persists across sessions if the conversation is resumed later.
The slug is provided by the author at the start of the conversation (see Phase 0). Examples:
deep-dive-ep4, never-trust-llm, intent-chain.
File: blog-research-[slug].md in the current working directory.
Write to it at phase checkpoints and whenever significant new information arrives (clarification answers, author feedback, editorial decisions).
Structure:
# Research Memory Bank: [working title]
Created: [date]
Last updated: [date] — [phase]
## Source Material Summary
[Phase 0: key narrative beats, people involved, what was shown, failures, successes]
## Product Context
[Phase 0: relevant product features, verified claims from docs, CLI commands, terminology.
Skip this section if no product context is configured.]
## Clarification Log
[Phase 1: numbered Q&A — questions asked, answers received, all rounds]
## Editorial Plan
[Phase 2: main idea sentence, CTA, series context, approved structure outline]
## Draft Notes
[Phase 3+: any decisions made during writing, author feedback, revision notes]Rules:
First thing: Ask the author for a short slug (kebab-case, 2-4 words) to identify this
post. Examples: deep-dive-ep4, never-trust-llm, intent-chain. Use this slug to name
the research memory bank and draft files. Do not proceed until you have the slug.
Then check for an existing blog-research-[slug].md in the working directory. If found,
read it and tell the author where you left off. If not found, create a new one.
Input: The author provides source material. This is usually a video transcript but could also be meeting notes, a rough outline, a conference talk transcript, or a previous blog post to extend.
What to do:
Read the entire source material. Build a mental model of the narrative. Identify:
Gather product context (if configured): If persona/product.md exists and contains
content, list every product feature, command, or concept mentioned in the source material.
Consult persona/product.md and use WebFetch to pull the relevant docs pages directly —
don't ask the author to provide them. Fetch as many pages as the post needs to be accurate
(the 1M context window can handle it). If the source material references a feature that
doesn't appear in any docs page, flag it for the author in Phase 1. If no product context
is configured, skip this step.
Fetch previous posts in the series: If this post belongs to a series, use WebFetch to
read the previously published posts (URLs are in persona/examples.md). This ensures
continuity of callbacks, running jokes, character dynamics, and narrative arc. You have the
context budget for it — use it.
Do NOT start writing. Do NOT summarize. Move to Phase 1.
Purpose: Fill every gap in your understanding. The transcript is a lossy compression of a video. Things that were obvious on screen are invisible in text. Things that were said casually might be technically important.
How to do it:
Ask one question at a time. Each question presents 1-4 concrete options plus an open answer escape hatch. Mark your best guess with an arrow or "← my guess". The author should be able to answer with a single number in most cases.
EVERY question MUST include your best guess as one of the options. Do not ask open-ended questions like "what happened here?" or "what was on screen?" Instead, reconstruct what you think happened from context and present it as the likely option. The author should be able to answer most questions with a single number. You do the heavy lifting.
Example format:
At ~12:30 you said "and then this happened." What was on screen at that point?
1. The agent's terminal output showing an error ← my guess
2. The IDE with the config file open
3. The browser showing the dashboard
4. Something else (describe briefly)Wait for the answer, then proceed to the next question. Do not batch questions.
Question grouping: Group questions by type under section headers, in this order:
Present each group as a headed section (e.g., "### Narrative gaps") with its questions underneath. This lets the author scan by category instead of reading a flat numbered list.
Keep asking questions one at a time until you can reconstruct the entire narrative without uncertainty. Tell the author roughly how many questions you expect ("I have about 6 questions to fill in the gaps") so they know what to expect, and update if the count changes.
Checkpoint: The author confirms the narrative reconstruction is accurate. No ambiguity remains.
Purpose: A transcript wanders. A blog post has a spine. Determine the one thing this post is about, and everything else is either supporting evidence or cut material.
Answer this in one sentence: "This post shows that [specific claim], demonstrated by [specific evidence]."
If you can't fill that template, the post isn't focused enough. Propose a main idea and confirm with the author.
What should the reader do after reading this? Options typically include:
If the author has product context configured, suggest a product-related CTA and confirm. Otherwise, suggest a general CTA appropriate to the content.
If this is part of a series, read _blog-skill/series-tracker.md (in the Blog Home
Directory) for the full state: title patterns, previous episodes, established callbacks,
open threads, and teasers. Then confirm with the author:
Propose section headers and a 1-2 sentence description of each section's purpose. Confirm with the author before proceeding.
Placeholders go in the outline, not just the draft. For each section, include the specific placeholders that will appear there, using the standard format with independent numbering per type:
[Screenshot 01: the Grafana panel showing memory usage][Code 01: the rate limiter middleware config][Link 01: OWASP rate limiting guide]Screenshot, Code, Link, and Fact each have their own counter starting at 01. The outline is where placeholder planning happens — don't defer it to the draft.
Checkpoint: Author approves the main idea, CTA, and structure outline.
Purpose: Write the post. Use the approved structure. Follow the tone guide religiously.
Re-read persona/voice.md now. Actually re-read the file — do not rely on memory from
earlier in the conversation. Confirm you can name at least 3 rhetorical devices from the
profile before writing a single sentence.
Start with the opening hook, NOT the TLDR. Write the TLDR last.
Write sections in narrative order. The reader should feel like they're on a journey, not reading a report.
Every section must earn its place. If a section doesn't serve the main idea or the narrative arc, cut it or fold it into another section.
Code blocks are part of the story. Don't dump code without context. Set up why the reader is about to see this code, show it, then explain what it means.
Maintain narrative density in EVERY section, not just the opening. This is the most common quality failure. The opening hook always has personality because writers focus there. But by mid-post, the voice drifts toward report/analyst style. Watch for:
references/tone-guide.md section "Narrative Density: Show, Don't Summarize"
for the full diagnostic.Placeholders use INDEPENDENT numbering per type. There is NO shared counter across types. Screenshots start at 01 and increment on their own. Code starts at 01 and increments on its own. Same for Links and Facts. WRONG: Screenshot 01, Code 02, Screenshot 03. RIGHT: Screenshot 01, Code 01, Screenshot 02.
[Screenshot 03: the agent re-ingesting 100 files]
[Code 02: the config file after installing the plugin]The last number of each type = total assets of that type the author needs to prepare.
Aim for 1,500-2,000 words. 2,000 is a target, not a cliff. A tight 2,200 that earns every sentence is better than a padded 1,800. If you're under 1,200, you're probably not going deep enough on the technical content. Don't pad to hit a number and don't butcher good content to stay under one.
Write the TLDR last. ALWAYS bullets, 2-4 items. Never prose paragraphs. Each bullet is a standalone provocation — something that makes the reader think "wait, really?" The TLDR sells the journey, it doesn't summarize the destination.
End with the author bio. Follow the schema in persona/bio.md. The kicker
must connect to something specific in THIS post. Propose a kicker and confirm with the
author — don't reuse the same one across posts unless nothing better fits.
The Comparison Trap. Posts that involve before/after demos, A/B tests, or tool comparisons are magnets for patterns #1, #2, #5, and #6. The content naturally involves contrasts (old vs. new, broken vs. fixed, input vs. output), and every sentence about those contrasts will default to mirrored grammatical structure unless you actively fight it. When writing a comparison post:
Each placeholder type has its own independent numbering sequence, zero-padded. Counters are separate per type — there is NO shared counter. A post can have Screenshot 10, Code 03, Link 05, and Fact 02 all at the same time. The last number of each type tells the author exactly how many of that asset they need to prepare. WRONG: Screenshot 01, Code 02, Link 03, Screenshot 04. RIGHT: Screenshot 01, Code 01, Link 01, Screenshot 02.
[Screenshot 01: description], [Screenshot 02: description], ...[Code 01: description] <!-- VERIFY: reconstructed from transcript -->[Link 01: description][Fact 01: description]Example in a draft: a post might contain, in order: Screenshot 01, Code 01, Screenshot 02, Screenshot 03, Code 02, Link 01, Screenshot 04. That's 4 screenshots, 2 code blocks, 1 link — each count is immediately obvious from the last number in its sequence.
Run the anti-pattern check (three passes). Open references/ai-anti-patterns.md and scan
the draft:
Pass 1 — Surface scan: Read the draft against each of the 31 patterns, looking for the forms described in the examples and structural variants.
Pass 2 — Skeleton scan: For each pair of adjacent sentences, strip the content and look at the grammatical skeleton only. Ask: "Do these two sentences have the same shape?" Subject-verb-object mirroring, parallel prepositional phrases, matching parenthetical structures — any of these in adjacent sentences is a flag, regardless of whether it matches a named pattern. Vary the structure of one sentence in the pair. Pass 2 catches patterns that Pass 1 misses because the vocabulary is different but the grammar is identical.
Pass 2 must also cover lists and example sequences, not just adjacent sentence pairs. When a paragraph contains 3+ examples, case studies, or items in a series, check whether they share an identical grammatical skeleton across items. Full-sentence examples hiding inside a dense paragraph are still a pattern if they all follow "[agent did X] — fix went into [Y]" or any repeated skeleton. Sentence length does not excuse structural repetition.
Thematic number trap: When the post's content naturally involves a specific number (e.g., three tiers, five stages), the LLM will lean into that number harder than a human would — manufacturing neat "[N] things, [N] results" summaries that announce the pattern instead of letting the examples show it. Be extra suspicious of numerical summaries that echo the post's theme. If the content already demonstrates the count, the sentence announcing it is manufactured symmetry.
Pass 3 — Soul check: Step back from the pattern list and ask one holistic question: "What makes this draft obviously AI-generated?" Read the draft as a skeptical reader would, not checking against specific patterns but reacting to the overall feel. Look for:
A draft can pass all 31 patterns and still read as obviously AI because it has no soul. If
Pass 3 flags the draft as sterile, the fix is not another anti-pattern rewrite — it's going
back to persona/voice.md and injecting the author's actual rhetorical devices, opinions,
and attitude into the flat sections.
Rewrite any hits. This is not optional.
Rewrite audit: After rewriting any anti-pattern hit, re-read the replacement sentence in isolation and check it against ALL 31 patterns. Rewrites frequently introduce the same pattern in a different surface form. This is especially true for:
Do not consider an anti-pattern fixed until the replacement passes a full 31-pattern scan on its own.
Voice check: After confirming the rewrite is anti-pattern clean, re-read it against
persona/voice.md. Does it still sound like the author? If the rewrite is correct but
flat, redo it using the author's rhetorical devices. A mechanically clean sentence that
sounds like a different person is not a fix.
Run the product accuracy check (if configured). If persona/product.md exists and contains
content, verify every claim the draft makes about the product — feature names, CLI commands,
behavior, terminology — against the docs pages fetched in Phase 0. If the draft references
something you didn't fetch, fetch that specific page from persona/product.md now. Do not
guess. Flag anything that contradicts the docs or isn't covered by them. If no product
context is configured, skip this check.
Run the tightening pass. Re-read the draft sentence by sentence with fresh eyes:
Checkpoint: Write the first draft to blog-draft-[slug].md in the working directory.
Tell the author the file is ready for review. Also display a summary in conversation: word
count, placeholder counts by type, and any open questions or flags.
Purpose: Iterate based on author feedback. This phase loops until the author declares the post done.
Re-read persona/voice.md now. Every time you enter Phase 4 or return to it after
author feedback, re-read the file. Long revision cycles are where voice drift happens.
Draft is a file. All revisions happen in blog-draft-[slug].md using the Edit tool.
This gives the author a persistent artifact they can review in their editor, diff against
previous versions, and eventually copy to the CMS. Don't rewrite the entire draft in
conversation — edit the file surgically.
What to expect:
How to handle feedback:
references/ai-anti-patterns.md) after changes — all
three passes (surface scan + skeleton scan + soul check) for new or rewritten sections.
Apply the rewrite
audit rule: every rewrite must pass a full 31-pattern scan on its own before it's
considered fixed. Then run the voice check: re-read against persona/voice.md and
redo any rewrite that's clean but flat. New writing can introduce new patternspersona/product.md is configured) — use
WebFetch against docs pages as neededThe post is done when the author says it's done. Not before.
When a post is finished and added to persona/examples.md: The persona has been updated
with new writing. Ask the global voice preference question from references/setup.md Step 10.
| Phase | Gate | Who decides |
|---|---|---|
| 0: Intake | Material read, gaps identified | Automatic |
| 1: Clarification | All gaps resolved | Author confirms |
| 2: Editorial Planning | Main idea + CTA + outline approved | Author approves |
| 3: First Draft | Draft written, anti-patterns checked | Delivered to author |
| 4: Revision | Post meets author's standards | Author declares done |
evals
scenario-1
scenario-2
scenario-3
scenario-4
scenario-5
scenario-6
scenario-7
example-persona