Every guide on this site goes through the same pipeline. It starts messy and ends clean, and Claude Code does most of the mechanical work. The interesting part is how I keep the output from reading like AI wrote it.

The pipeline

1. Rough capture

Ideas start as bullet points, comments, or fragments in Obsidian. Sometimes it’s a problem I just solved and want to document while it’s fresh. Sometimes it’s a note that’s been sitting in my inbox for weeks.

The bar for starting is low: if I can explain why someone would care in one sentence, it’s worth writing up.

2. Workshop with Claude

I paste the rough notes into Claude Code and talk through the idea. This is more conversation than dictation - I’m clarifying my own thinking as much as generating text. Claude has access to my vault, so it can cross-reference existing guides, check for consistency with what I’ve already published, and flag gaps in my reasoning.

The key files Claude reads during this phase:

  • Context files in 07 System/ - my technical setup, preferences, worldview
  • Existing guides - to avoid contradicting or repeating myself
  • Works in Progress - what’s currently in flight

This is where the structure emerges. By the end of a back-and-forth, I usually have a clear outline - the dialogue helps spur creativity, brings in other angles, and develops the post beyond where I’d have taken it solo.

3. Draft generation

Claude writes a full draft based on our conversation. For technical guides, this follows a specific format: a human-readable section up top (the “why” and “what”), then an implementation section below aimed at Claude Code users who want to paste the URL and have it set things up.

I review the draft for technical accuracy - does the code actually work? Are the steps in the right order? Did it miss an edge case I hit during the actual setup?

4. Voice restoration (/de-ai-ify)

This is the step that matters most. AI-generated text has a distinctive sound: too many hedges (“it’s worth noting”), too many transitions (“moreover”, “furthermore”), too many soft qualifiers (“relatively”, “somewhat”). It reads like a corporate blog post.

I run a custom /de-ai-ify slash command that strips these patterns and rewrites in my actual voice. The command knows my preferences: direct statements over hedged ones, short sentences for key points, technical vocabulary without dumbing down, concrete examples from real experience.

Before:

It’s worth noting that this approach offers a relatively robust solution for managing your configuration files, though it may require some initial setup effort.

After:

This handles config files well. Setup takes about 20 minutes.

The ideas stay the same. The delivery changes completely.

5. Proofread and polish

Final read-through for flow, accuracy, and anything that still sounds off. I check that links work, code blocks render correctly, and the frontmatter is right.

6. Build and deploy

./scripts/deploy.sh

One command. Hugo compiles the markdown into static HTML, rsync pushes only the changed files to the server. About 10 seconds start to finish.

Setting this up yourself

What you need to replicate this pipeline with Claude Code.

Prerequisites

  • Claude Code installed and working
  • A Hugo site (or any static site generator - the pipeline works the same regardless)
  • An Obsidian vault (optional - Claude Code works with any directory of markdown files)

Hugo and the build/deploy pipeline

Hugo is a static site generator. You write markdown files, Hugo turns them into a folder of HTML/CSS that any web server can host. No databases, no server-side runtime, no WordPress - just files.

The project structure:

your-site/
β”œβ”€β”€ config/config.toml       ← Site settings (title, URL, theme)
β”œβ”€β”€ content/                  ← Your posts (markdown files)
β”‚   β”œβ”€β”€ _index.md             ← Homepage content
β”‚   └── my-post.md            ← Each post is one .md file
β”œβ”€β”€ themes/minimal-blog/      ← Theme (HTML templates + CSS)
β”œβ”€β”€ scripts/
β”‚   β”œβ”€β”€ build.sh              ← Runs Hugo to generate HTML
β”‚   β”œβ”€β”€ deploy.sh             ← Build + push to server
β”‚   └── deploy.env            ← Server connection details
└── CLAUDE.md                 ← Claude Code project instructions

Each post is a markdown file with YAML frontmatter at the top:

---
title: "My Post Title"
subtitle: "Optional subtitle"
date: 2026-02-06
summary: "One-liner that appears on the homepage list."
---

Post content goes here. Standard markdown.

Hugo reads every file in content/, applies your theme’s templates, and outputs a folder of static HTML. The build takes under a second for a site with 20+ posts.

Build script (scripts/build.sh):

#!/usr/bin/env bash
set -euo pipefail
cd "$(dirname "$(dirname "${BASH_SOURCE[0]}")")"

rm -rf dist/public
hugo --source . \
     --config config/config.toml \
     --destination dist/public \
     --themesDir themes \
     --minify

Deploy script (scripts/deploy.sh) - builds then pushes to your server via rsync:

#!/usr/bin/env bash
set -euo pipefail
cd "$(dirname "$(dirname "${BASH_SOURCE[0]}")")"

source scripts/deploy.env
./scripts/build.sh

rsync -avz --delete \
      --compress-level=9 \
      --chmod=D755,F644 \
      dist/public/ \
      "$VPS_HOST:$VPS_DEST/"

Server config (scripts/deploy.env):

VPS_HOST="your-server"        # SSH alias or user@hostname
VPS_DEST="/var/www/your-site"  # Where the files go on the server

Hugo compiles markdown to HTML. Rsync diffs the output against what’s on the server and uploads only what changed. The web server (Caddy, Nginx, whatever) serves the static files. You can preview locally with hugo server -D before deploying.

Project CLAUDE.md

Your site’s CLAUDE.md tells Claude Code how your blog works. Put it at the root of the Hugo project:

# Blog Project - Claude Instructions

## Writing Style
- No emojis unless specifically appropriate
- Evidence-based, show your reasoning
- Concise - say it once, well

## Content Workflow
1. Draft in conversation with Claude
2. Claude writes full draft
3. Run /de-ai-ify for voice restoration
4. Proofread and deploy

## Deploy
./scripts/deploy.sh

Adapt the writing style section to your preferences. Claude reads this automatically when you start a session in the project directory.

The /de-ai-ify command

The most important piece. Create ~/.claude/commands/de-ai-ify.md:

---
name: de-ai-ify
aliases: [humanize, voice-check]
description: Remove AI writing patterns and restore the user's authentic voice
---

# De-AI-ify - Voice Restoration

You are a voice editor. Transform AI-generated text into the user's
authentic writing voice.

## AI patterns to remove

**Lexical clichΓ©s:**
- "delve", "dive deep", "unpack", "leverage", "robust"
- "it's worth noting that", "importantly", "essentially"
- "in today's world", "in this modern age"
- Unnecessary hedging ("arguably", "somewhat", "relatively")

**Structural patterns:**
- Generic introduction ("In a world where...")
- Numbered listicles without narrative thread
- Repetitive transitions ("Moreover,", "Furthermore,", "Additionally,")
- Conclusion that restates introduction

## Voice profile

Load the user's voice from their existing writing. Look for:
- Sentence structure (short declarative vs longer analytical)
- Technical vocabulary they use naturally
- Hedging patterns (when do they hedge vs state directly?)
- How they use examples (concrete/personal vs generic)

Check these locations for voice training data:
- Blog posts in the current project
- Notes in Obsidian vault (if accessible)
- Any writing samples the user provides

## Process

1. Identify AI patterns in the text
2. Load voice profile from existing writing
3. Rewrite: preserve ideas, replace AI delivery with user's voice
4. Present original vs rewritten with a summary of changes

This is a simplified version of what I use. The key insight: train it on your writing, not just tell it to remove AI patterns. Point it at your existing blog posts or notes so it learns your actual voice.

Voice training

The command tells Claude to read your existing writing. The more samples it has, the better it works. If you’re starting from scratch with no published writing, give it:

  • Emails or messages you’ve written (your natural voice)
  • Notes or documentation you’ve authored
  • Even social media posts - anywhere you write as yourself

Example session

What writing a post looks like end to end. This is condensed - real sessions have more back-and-forth.

$ claude

> I want to write a guide about setting up restic backups with
> Backblaze B2. Here are my rough notes:
>
> - restic is great because snapshots, dedup, encryption
> - B2 is cheapest cloud storage
> - need to init repo first, then set up systemd timer
> - gotcha: B2 app keys need specific bucket permissions
> - I spent 2 hours debugging because I used a master key
>   instead of a bucket-scoped key

Claude reads your CLAUDE.md and any context files, then responds
with questions and suggestions:

  A few things to clarify before I draft:
  1. Do you want the human/Claude Code split format?
  2. Should I check your existing guides for related content?
  3. The app key gotcha is a good hook - want to lead with that?

> Yes to all three. Lead with the debugging story, then explain
> the setup. Check if I've covered restic or B2 anywhere else.

Claude searches your vault, finds no conflicts, and drafts the post:

  Here's the draft. I led with your B2 key debugging experience,
  then walked through init, config, systemd timer, and verification.
  The Claude Code section below covers automated setup.

  [full draft in your Hugo frontmatter format]

> Looks good but the systemd section is too long. Shorten it
> and just link to the Arch wiki for timer syntax.

Claude revises the draft.

> /de-ai-ify

Claude loads your existing posts, identifies AI patterns in the
draft, and rewrites in your voice:

  Key changes:
  - Removed: "robust backup solution", "it's worth noting",
    "comprehensive guide"
  - Shortened: 3 hedged sentences to direct statements
  - Restructured: moved the "why restic over duplicity"
    paragraph - was burying the lead

  [rewritten draft]

> Ship it.

Claude writes the file to content/restic-backups.md and runs
./scripts/deploy.sh.

The whole process takes about 15 minutes for a typical guide. Most of that is me thinking about what to include, not writing.

Why this works

The pipeline separates thinking from writing from editing. Claude handles the parts where volume and recall matter (drafting, cross-referencing, formatting). I handle the parts where judgment matters (what to write about, whether the technical advice is correct, whether it sounds like me).

The /de-ai-ify step is what makes it sustainable. Without it, I’d either spend hours manually rewriting AI output or publish content that sounds generic. With it, I get the speed of AI drafting and the voice of writing it myself.