/blog-post - Blog Post Production Pipeline
Single entry point for producing a cryptoflexllc.com blog post. Coordinates the Blog Captain (opus), which runs a specialist team: writer, voice agent, senior editor, UX agent, diagram author, and brand-graphics cover artist.
This skill is callable from ANY repo or directory. Never rely on the current working directory: resolve all paths absolutely.
Step 0: Repo Resolution
BLOG_REPO="$HOME/GitProjects/cryptoflexllc"
[[ -d "$BLOG_REPO" ]] || BLOG_REPO="$HOME/Github_Projects/cryptoflexllc"
Every file operation in this pipeline uses absolute paths under $BLOG_REPO or ~/.claude/. If neither repo path exists, stop and tell the user.
Step 1: Post Inventory
bash ~/.claude/scripts/blog-inventory.sh --minimal
The output now includes series, seriesOrder, coverImage, and featured per post, plus a series_summary block with each series' post count and highest seriesOrder. Series matching is quote-normalized by the script; never grep frontmatter for series values yourself.
From the inventory, derive:
- The 3 most recently active series (for the series question below)
- The next seriesOrder for whichever series is chosen (
series_summary[].max_order + 1)
- The 2 most recent post paths (calibration posts for the captain)
Step 2: Voice Profile
Read ~/.claude/skills/blog-voice-profile.md in full. Pass the complete text to the captain (subagents may not be able to read ~/.claude/skills/ themselves).
Step 3: User Discovery
Use AskUserQuestion (one call, four questions):
- Destination ("Destination"): "Production" (live after deploy,
src/content/blog/) or "Backlog" (draft, src/content/backlog/, published later via the /backlog admin page).
- Source material ("Material"): what the post is built from:
- "This session": what was accomplished in the current Claude Code session
- "Today's work": everything done today across repos (git logs since midnight)
- "Last 24 hours": same sweep with
--since="24 hours ago"
- "A specific feature or topic": deep dive on a named skill, feature, incident, or subject (user supplies specifics via Other or a follow-up)
- Series ("Series"): offer the 3 most recently active series from the inventory plus "None (standalone)". The user can type any other series name (including a brand-new one) via Other. When a series is chosen, use the next seriesOrder computed in Step 1; for a new series, seriesOrder is 1.
- Tone ("Tone"): "Educational and friendly" (default voice), "Witty and accessible" (humor, GIFs, Info boxes for every concept; for general readers), or "Technical reference" (documentation style).
If the answers leave the topic ambiguous, ask a plain follow-up question before spawning the captain. Never guess at source material: the pipeline must not fabricate.
Step 4: Research Recipes (pass to captain)
Repos for research, all absolute:
$BLOG_REPO (the site)
$HOME/GitProjects/CJClaude_1, $HOME/GitProjects/cryptoflex-ops (private; never linked in posts)
~/.claude (claude-code-config)
By material type:
- This session: review the current conversation; identify the most educational moments, real commands, real errors.
- Today's work / Last 24 hours: parallel Explore agents (haiku) running
git log --since=... --stat across the repos above, plus CHANGELOG/MEMORY updates.
- Specific feature/topic: read the actual source files, config, and history behind it. Quote real code only.
Step 5: Spawn the Captain
Spawn ONE Task agent:
- subagent_type: general-purpose
- model: opus
- name: blog-captain
Pass it, in the prompt:
- "You are the Blog Captain. Follow the instructions in ~/.claude/agents/blog-captain.md"
BLOG_REPO (resolved absolute path)
- The inventory JSON from Step 1 and the 2 calibration post paths
- The user's answers: destination, material, series + seriesOrder, tone
- The full voice profile text
- The applicable research recipes from Step 4
- If destination is Backlog: "Write to src/content/backlog/. Commit prefix 'chore: add backlog draft'. Note the backlog runtime differences in your instructions."
The captain runs the full pipeline: research, draft, parallel review + diagram authoring, revision, cover graphic, build, and user approval. It returns a JSON report.
Step 6: After the Captain Returns
- Display the post details, scores, revision history, cover/diagram outputs, and any unresolved issues.
- If the captain did not commit (approval pending), offer to commit and push. Production commits include the MDX,
public/blog/<slug>/, and any new diagram/registry files.
- Report the URL:
https://cryptoflexllc.com/blog/<slug> (production) or "Draft saved to backlog; publish via the /backlog admin page."
- Backlog publishes (user-triggered via the admin page) rename the file on the remote with 2 commits; after one, run
git pull --ff-only in $BLOG_REPO.
- Backlog drafts in a series carry the seriesOrder assigned at draft time, which goes stale as the series grows. When a draft with
series: is about to be published, re-check the inventory and bump its seriesOrder to max_order + 1 first.
Known Gotchas
- Cover uniqueness bar: every cover is a bespoke composition derived from the post's story, sharing branding only; the contract and composition register live in
$BLOG_REPO/docs/cover-graphics-standards.md, and the captain reviews the render as an art director (unique vs recent covers, one focal point, balanced, filled panels, legible at card size) before accepting it.
- Diagram visual bar: inline SVG diagrams follow the editorial diagram system, matching the cover-infographic aesthetic. Contract:
$BLOG_REPO/docs/editorial-diagram-standards.md; primitives: src/components/mdx/diagram-editorial.tsx; exemplar: ReviewPipelineDiagram in diagrams-security-review-round-two.tsx. Plain outlined boxes joined by crossing diagonal lines are below the bar, and the diagram author must run the standards doc's screenshot verification loop before handing off.
- Tailwind v4 dynamic class purging (matters for diagram TSX): never interpolate class fragments (
bg-${accent}-600). Use a static as const class map. Hit in TerminalPromo.tsx 2026-07-21.
- MDX runtime traps (caught by
~/.claude/scripts/validate-mdx.sh, but know them): bare < before digits (<100ms) parses as a JSX tag and breaks at render with HTTP 200; nested double quotes inside JSX attribute values render as an error boundary with no build error; slugs are [a-z0-9-] only, no dots.
- Series data: quoting is normalized to unquoted in frontmatter (
series: Claude Code Workflow). The inventory script is the only source of truth for seriesOrder.
1---2name: blog-post3description: Write a new blog post for cryptoflexllc.com: 5-agent captain pipeline with cover graphic, diagrams, voice QA, and CI-matched validation4---56# /blog-post - Blog Post Production Pipeline78Single entry point for producing a cryptoflexllc.com blog post. Coordinates the Blog Captain (opus), which runs a specialist team: writer, voice agent, senior editor, UX agent, diagram author, and brand-graphics cover artist.910This skill is callable from ANY repo or directory. Never rely on the current working directory: resolve all paths absolutely.1112## Step 0: Repo Resolution1314```bash15BLOG_REPO="$HOME/GitProjects/cryptoflexllc"16[[ -d "$BLOG_REPO" ]] || BLOG_REPO="$HOME/Github_Projects/cryptoflexllc"17```1819Every file operation in this pipeline uses absolute paths under `$BLOG_REPO` or `~/.claude/`. If neither repo path exists, stop and tell the user.2021## Step 1: Post Inventory2223```bash24bash ~/.claude/scripts/blog-inventory.sh --minimal25```2627The output now includes `series`, `seriesOrder`, `coverImage`, and `featured` per post, plus a `series_summary` block with each series' post count and highest seriesOrder. Series matching is quote-normalized by the script; never grep frontmatter for series values yourself.2829From the inventory, derive:30- The 3 most recently active series (for the series question below)31- The next seriesOrder for whichever series is chosen (`series_summary[].max_order + 1`)32- The 2 most recent post paths (calibration posts for the captain)3334## Step 2: Voice Profile3536Read `~/.claude/skills/blog-voice-profile.md` in full. Pass the complete text to the captain (subagents may not be able to read `~/.claude/skills/` themselves).3738## Step 3: User Discovery3940Use AskUserQuestion (one call, four questions):41421. **Destination** ("Destination"): "Production" (live after deploy, `src/content/blog/`) or "Backlog" (draft, `src/content/backlog/`, published later via the /backlog admin page).432. **Source material** ("Material"): what the post is built from:44 - "This session": what was accomplished in the current Claude Code session45 - "Today's work": everything done today across repos (git logs since midnight)46 - "Last 24 hours": same sweep with `--since="24 hours ago"`47 - "A specific feature or topic": deep dive on a named skill, feature, incident, or subject (user supplies specifics via Other or a follow-up)483. **Series** ("Series"): offer the 3 most recently active series from the inventory plus "None (standalone)". The user can type any other series name (including a brand-new one) via Other. When a series is chosen, use the next seriesOrder computed in Step 1; for a new series, seriesOrder is 1.494. **Tone** ("Tone"): "Educational and friendly" (default voice), "Witty and accessible" (humor, GIFs, Info boxes for every concept; for general readers), or "Technical reference" (documentation style).5051If the answers leave the topic ambiguous, ask a plain follow-up question before spawning the captain. Never guess at source material: the pipeline must not fabricate.5253## Step 4: Research Recipes (pass to captain)5455Repos for research, all absolute:56- `$BLOG_REPO` (the site)57- `$HOME/GitProjects/CJClaude_1`, `$HOME/GitProjects/cryptoflex-ops` (private; never linked in posts)58- `~/.claude` (claude-code-config)5960By material type:61- **This session:** review the current conversation; identify the most educational moments, real commands, real errors.62- **Today's work / Last 24 hours:** parallel Explore agents (haiku) running `git log --since=... --stat` across the repos above, plus CHANGELOG/MEMORY updates.63- **Specific feature/topic:** read the actual source files, config, and history behind it. Quote real code only.6465## Step 5: Spawn the Captain6667Spawn ONE Task agent:68- **subagent_type:** general-purpose69- **model:** opus70- **name:** blog-captain7172Pass it, in the prompt:731. "You are the Blog Captain. Follow the instructions in ~/.claude/agents/blog-captain.md"742. `BLOG_REPO` (resolved absolute path)753. The inventory JSON from Step 1 and the 2 calibration post paths764. The user's answers: destination, material, series + seriesOrder, tone775. The full voice profile text786. The applicable research recipes from Step 4797. If destination is Backlog: "Write to src/content/backlog/. Commit prefix 'chore: add backlog draft'. Note the backlog runtime differences in your instructions."8081The captain runs the full pipeline: research, draft, parallel review + diagram authoring, revision, cover graphic, build, and user approval. It returns a JSON report.8283## Step 6: After the Captain Returns84851. Display the post details, scores, revision history, cover/diagram outputs, and any unresolved issues.862. If the captain did not commit (approval pending), offer to commit and push. Production commits include the MDX, `public/blog/<slug>/`, and any new diagram/registry files.873. Report the URL: `https://cryptoflexllc.com/blog/<slug>` (production) or "Draft saved to backlog; publish via the /backlog admin page."884. Backlog publishes (user-triggered via the admin page) rename the file on the remote with 2 commits; after one, run `git pull --ff-only` in `$BLOG_REPO`.895. Backlog drafts in a series carry the seriesOrder assigned at draft time, which goes stale as the series grows. When a draft with `series:` is about to be published, re-check the inventory and bump its `seriesOrder` to `max_order + 1` first.9091## Known Gotchas9293- **Cover uniqueness bar**: every cover is a bespoke composition derived from the post's story, sharing branding only; the contract and composition register live in `$BLOG_REPO/docs/cover-graphics-standards.md`, and the captain reviews the render as an art director (unique vs recent covers, one focal point, balanced, filled panels, legible at card size) before accepting it.94- **Diagram visual bar**: inline SVG diagrams follow the editorial diagram system, matching the cover-infographic aesthetic. Contract: `$BLOG_REPO/docs/editorial-diagram-standards.md`; primitives: `src/components/mdx/diagram-editorial.tsx`; exemplar: `ReviewPipelineDiagram` in `diagrams-security-review-round-two.tsx`. Plain outlined boxes joined by crossing diagonal lines are below the bar, and the diagram author must run the standards doc's screenshot verification loop before handing off.95- **Tailwind v4 dynamic class purging** (matters for diagram TSX): never interpolate class fragments (`bg-${accent}-600`). Use a static `as const` class map. Hit in TerminalPromo.tsx 2026-07-21.96- **MDX runtime traps** (caught by `~/.claude/scripts/validate-mdx.sh`, but know them): bare `<` before digits (`<100ms`) parses as a JSX tag and breaks at render with HTTP 200; nested double quotes inside JSX attribute values render as an error boundary with no build error; slugs are `[a-z0-9-]` only, no dots.97- **Series data**: quoting is normalized to unquoted in frontmatter (`series: Claude Code Workflow`). The inventory script is the only source of truth for seriesOrder.