CtrlK
BlogDocsLog inGet started
Tessl Logo

jbaruch/blog-writer

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

1.43x
Quality

94%

Does it follow best practices?

Impact

99%

1.43x

Average score across 7 eval scenarios

SecuritybySnyk

Advisory

Suggest reviewing before use

Overview
Quality
Evals
Security
Files

process.mdreferences/

Blog Writing Process

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.

Blog Home Directory

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 threads
  • Per-post working directories as organized by the author

Per-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.

Research Memory Bank

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:

  • Update sections as new information arrives — don't just append, keep each section current.
  • Before starting Phase 3, re-read the entire memory bank to confirm you have everything.
  • The memory bank is a working document, not a deliverable. It doesn't need to be pretty.

Phase 0: Intake

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:

  • Who is involved (speakers, collaborators, quoted individuals)
  • What was built or demonstrated
  • What went wrong (there's almost always a failure story)
  • What went right (the fix, the alternative approach, the insight)
  • What was shown on screen that the transcript references but you can't see
  • Jokes, asides, and cultural references that surfaced naturally

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.


Phase 1: Clarification

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:

  1. Narrative gaps (what happened when) — needed to structure the post
  2. Technical gaps (exact commands, outputs, configurations) — needed for accuracy
  3. Visual gaps (what was on screen) — needed for placeholders
  4. Context gaps (references to other work, people, previous posts) — needed for callbacks

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.


Phase 2: Editorial Planning

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.

2a: Main Idea

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.

2b: CTA

What should the reader do after reading this? Options typically include:

  • Install/try a tool or library (with exact commands)
  • Read the next post in a series
  • Watch the video/stream
  • Check out a specific repository or resource

If the author has product context configured, suggest a product-related CTA and confirm. Otherwise, suggest a general CTA appropriate to the content.

2c: Series Context

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:

  • Which callbacks or running jokes should continue in this post?
  • What's the teaser for the next installment?
  • Any new recurring elements to establish?

2d: Structure Outline

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.


Phase 3: First Draft

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.

Writing rules:

  1. Start with the opening hook, NOT the TLDR. Write the TLDR last.

  2. Write sections in narrative order. The reader should feel like they're on a journey, not reading a report.

  3. 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.

  4. 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.

  5. 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:

    • Passive summaries replacing specific moments ("Implementation proceeded" vs "I hit enter and the agent scaffolded 62 files in twelve seconds")
    • Missing human reactions (what did you say? what did your collaborator say? what did you feel?)
    • Abstract nouns replacing lived experience ("The architectural convergence" vs "Three companies shipped the same idea within a month")
    • Paragraphs that could be rewritten as bullet points without losing anything Re-read references/tone-guide.md section "Narrative Density: Show, Don't Summarize" for the full diagnostic.
  6. 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.

  7. 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.

  8. 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.

  9. 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.

  10. 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:

    • Write the "before" story and the "after" story as separate narratives with different sentence structures, not as matched pairs
    • If you catch yourself writing "[thing A] does X, [thing B] does Y" in any form, rewrite so only one of them gets a full sentence and the other is folded into a different construction
    • The anti-pattern check for comparison posts should include an extra pass specifically looking for mirrored clause pairs, even if they don't match the exact examples in the anti-pattern file

Placeholder conventions:

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.

  • Screenshots: [Screenshot 01: description], [Screenshot 02: description], ...
  • Code to verify: [Code 01: description] <!-- VERIFY: reconstructed from transcript -->
  • Links to confirm: [Link 01: description]
  • Facts to check: [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.

After writing:

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:

  • No opinions anywhere — facts reported but never reacted to
  • No uncertainty or mixed feelings — everything is confidently resolved
  • No first-person voice when the content warrants it
  • No humor, edge, or personality — technically clean but reads like Wikipedia
  • Uniform energy — every paragraph has the same emotional temperature
  • Press-release tone — sounds like it was written to impress rather than to communicate

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:

  • #2 (Parallel Binary) — the most likely pattern to survive a rewrite, because describing a comparison naturally produces mirrored clauses. If you rewrote a parallel binary and the new version still has two clauses about two different things, check the grammatical skeleton. If both clauses have the same shape, you just wrote another parallel binary.
  • #6 (Self-Answering Fragment) — rewrites often turn "The result? Great." into a longer question with a longer answer, but the structure is identical.

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:

  • For every sentence, ask: "would the reader miss this if it vanished?" If not, cut it.
  • Identify redundancies — two sentences making the same point in different words. Keep the stronger one.
  • Kill bloated transitions: "Now that we've seen X, let's look at Y" can almost always be replaced by just starting Y.
  • Check for hedging filler that crept in: "basically," "essentially," "in order to."
  • One data point per beat: if a paragraph has two statistics making the same point ("reduced from 45 minutes to 90 seconds, a 97% improvement, saving 6 hours per week"), pick the one that hits hardest and cut the rest. The extras are noise.
  • Isolate the punchline: the final sentence of a key section should get its own line. If the punchline is buried in a paragraph, give it a line break so it lands with weight.
  • The goal is to tighten without losing substance. A post that's 1,700 words of meat is better than 2,000 words with padding.

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.


Phase 4: Revision

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:

  • Tone adjustments ("this section sounds too corporate")
  • Technical corrections ("that's not how the API actually works")
  • Structural changes ("move this section before that one")
  • Cuts ("we don't need this paragraph")
  • Additions ("add a section about X")
  • Screenshot and code placeholder updates

How to handle feedback:

  • Apply changes to the draft file using Edit
  • Re-run the anti-pattern check (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 patterns
  • Re-run the product accuracy check if any product feature descriptions, commands, or terminology were added or changed (only if persona/product.md is configured) — use WebFetch against docs pages as needed
  • If a change conflicts with the tone guide, flag it but defer to the author
  • When replacing placeholders with actual content, integrate smoothly — don't just drop in an image or code block without adjusting the surrounding prose
  • Re-run the tightening pass on any new or rewritten sections — additions tend to introduce redundancy with existing content

The 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 Summary

PhaseGateWho decides
0: IntakeMaterial read, gaps identifiedAutomatic
1: ClarificationAll gaps resolvedAuthor confirms
2: Editorial PlanningMain idea + CTA + outline approvedAuthor approves
3: First DraftDraft written, anti-patterns checkedDelivered to author
4: RevisionPost meets author's standardsAuthor declares done

README.md

SKILL.md

tessl.json

tile.json