skills/pre-publish-checker/SKILL.md
Pre-publication validation for Hugo posts: front matter, SEO, links, images.
npx skillsauth add notque/claude-code-toolkit pre-publish-checkerInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
This skill performs rigorous pre-publication validation for Hugo blog posts using a Sequential Validation workflow: assess structure, validate fields, check assets, and report results. It embeds Hugo-specific rules and SEO best practices to catch publication blockers before they reach production.
The skill is non-destructive (modifies files only with explicit user request), complete (shows all validation results—always shows complete output), and severity-aware (distinguishes BLOCKER from SUGGESTION throughout the workflow).
/pre-publish [path-to-post]
/pre-publish content/posts/2025-01-my-post.md
/pre-publish --check-external content/posts/2025-01-my-post.md
If no path provided, prompt user to specify the post file.
Goal: Parse post structure and extract all validatable elements.
Step 1: Read the target markdown file
Verify the file exists. If not, list available posts and ask user to confirm.
Step 2: Extract front matter
Hugo supports both TOML and YAML front matter. Detect delimiter type:
+++ delimiters--- delimitersParse all fields into structured data.
Step 3: Extract body content
Everything after front matter closing delimiter. Inventory:
Gate: File parsed successfully. Front matter extracted. Body content inventoried. Proceed only when gate passes.
Goal: Run all validation checks with correct severity classification.
Step 1: Front matter validation
| Field | Requirement | Severity | Reasoning |
|-------|-------------|----------|-----------|
| title | Present, non-empty | BLOCKER | Hugo build fails without title |
| date | Present, valid format | BLOCKER | Publishing requires valid timestamp |
| draft | Must be false | BLOCKER | Hugo excludes draft posts; this is a non-negotiable check |
| description | Present, 150-160 chars | SUGGESTION | SEO optimization; user may omit intentionally |
| tags | Present, 3-5 items | SUGGESTION | Recommendation for taxonomy consistency; not required |
| categories | Present, 1-2 items | SUGGESTION | Recommendation for site organization; not required |
Always validate draft field first. Treat as highest-priority blocker—draft posts are excluded from production builds entirely.
Step 2: SEO validation
| Check | Optimal Range | Severity | Reasoning | |-------|---------------|----------|-----------| | Title length | 50-60 characters | SUGGESTION | Search engine display optimization | | Description length | 150-160 characters | SUGGESTION | Meta description window sizing | | Slug format | URL-friendly, no special chars | SUGGESTION | Internal naming convention |
Derive slug from filename: 2025-01-my-post.md becomes my-post.
Step 3: Content quality validation
| Check | Requirement | Severity | Reasoning | |-------|-------------|----------|-----------| | Word count | Minimum 500 words | SUGGESTION | Depth indicator; user retains discretion | | Reading time | Calculate at 200 WPM | INFO | Report only, not a blocker | | Header structure | H2/H3 present, logical hierarchy | SUGGESTION | Readability and scannability | | Opening paragraph | No preamble phrases | SUGGESTION | Content quality; user may override |
Preamble detection phrases: "In this post, I will...", "Today I'm going to...", "Let me explain...", "Welcome to...", "First of all...", "Before we begin..."
Step 4: Link validation
](/posts/...) or ](/images/...). Verify target exists. Severity: BLOCKER if missing (broken links prevent navigation).](https://...). Skip by default. Severity: WARNING if unreachable (when enabled). Rationale: External validation adds network latency and rate-limiting concerns; skip unless user opts in with --check-external. or Hugo shortcodes. Verify file exists in static/. Severity: BLOCKER if missing (reader sees broken image).Step 5: Image validation
| Check | Requirement | Severity | Reasoning | |-------|-------------|----------|-----------| | Alt text | All images must have non-empty alt | SUGGESTION | Accessibility best practice | | File existence | All referenced images exist in static/ | BLOCKER | Missing images break page rendering | | Path format | Correct Hugo static path convention | SUGGESTION | Consistency with site standards |
Hugo image path patterns: /images/filename.png (absolute from static/), images/filename.png (relative), {{< figure src="..." >}} (shortcode).
Step 6: Anti-AI pattern validation
| Check | Requirement | Severity | Reasoning | |-------|-------------|----------|-----------| | AI pattern scan | Run anti-AI editor skill scan | BLOCKER | AI-sounding content damages voice authenticity and reader trust |
Invoke the anti-AI editor skill (not a script) by reading skills/anti-ai-editor/SKILL.md and applying its ASSESS phase. At minimum, load skills/anti-ai-editor/references/detection-patterns.md and scan for all 14 detection categories. A severity score above 15 is a BLOCKER. Score 6-15 is a WARNING with specific line numbers and suggested fixes. Score 0-5 is a PASS.
This check exists because voice validation and joy-check do not catch AI writing patterns. Content can pass both gates while containing emotional flatlines ("This is the part I find most interesting"), false concessions, synonym cycling, and other patterns that signal AI-generated text. The anti-AI editor catches these through regex patterns and contextual analysis.
Step 7: Draft status validation
| Check | Requirement | Severity | Reasoning |
|-------|-------------|----------|-----------|
| draft field | Must be false | BLOCKER | Hugo build filter; non-negotiable |
| TODO comments | None present | WARNING | Development artifact—likely unintentional in published post |
| FIXME comments | None present | WARNING | Development artifact—likely unintentional in published post |
| Placeholder text | None present | BLOCKER | Content is incomplete if placeholders remain |
Placeholder patterns: [insert X here], [TBD], [TODO], XXX, PLACEHOLDER, Lorem ipsum.
Gate: All validation checks executed. Each check produced a status (PASS, FAIL, WARN, SKIP, INFO). Proceed only when gate passes.
Goal: Provide actionable taxonomy suggestions when tags or categories are missing.
Step 1: Build taxonomy index
Read existing posts to collect all tags and categories currently in use. Rationale: Always read existing posts before suggesting. Inventing generic tags like "programming" or "tech" without checking the site creates inconsistent taxonomy and fragments content organization.
Step 2: Analyze content
Match current post content against existing taxonomy terms. Prefer established terms over inventing new ones.
Step 3: Generate suggestions
Suggest 3-5 tags and 1-2 categories. Distribute suggestions evenly across the taxonomy rather than over-suggesting popular tags; distribute evenly across the taxonomy. Report suggestions even if tags/categories are already present—they validate against site conventions.
Gate: Taxonomy suggestions generated from existing site data (not invented). Proceed only when gate passes.
Goal: Generate structured validation report with clear outcome.
Format the report as:
===============================================================
PRE-PUBLISH CHECK: [file path]
===============================================================
FRONT MATTER:
[status] field: "value" (details)
SEO:
[status] check: result (optimal range)
CONTENT:
[status] metric: value
LINKS:
[status] type: count valid/invalid
IMAGES:
[status] check: result
AI PATTERNS:
[status] anti-ai-editor score: N (threshold: 15)
DRAFT STATUS:
[status] check: result
===============================================================
RESULT: [READY FOR PUBLISH | NOT READY - N blockers]
===============================================================
Status icons: [PASS], [WARN], [FAIL], [SKIP], [INFO]
Result classification:
Ensure accurate blocker count. Count blockers and suggestions independently in the final result—count them independently.
Gate: Report generated with accurate blocker count. Result matches blocker tally.
User says: "Check my kubernetes post before I publish" Actions:
User says: "Is my draft ready?" Actions:
Cause: Wrong path, running from wrong directory, or file moved Solution:
ls content/posts/Cause: Syntax errors in TOML/YAML, mismatched delimiters, invalid date Solution:
+++ or ---)Cause: Non-standard path format, Hugo shortcode variant, or missing static/ directory Solution:
/, resolve relative paths)static/ and assets/ directoriesfigure and img variants${CLAUDE_SKILL_DIR}/references/seo-guidelines.md: SEO length requirements and best practices${CLAUDE_SKILL_DIR}/references/hugo-frontmatter.md: Hugo front matter fields and formats${CLAUDE_SKILL_DIR}/references/checklist.md: Complete validation checklist referencedocumentation
Document translation: quick/normal/refined modes with chunked parallel subagents and glossary support.
development
AI image generation: Gemini and Nano Banana backends; single/series/batch workflows with prompt-to-disk.
testing
Unified voice content generation pipeline with mandatory validation and joy-check. 13-phase pipeline: LOAD, GROUND, STATS-CHECKPOINT, GENERATE, HOOK-GATE, VALIDATE, REFINE, VARIETY-GATE, JOY-CHECK, ANTI-AI, CLOSE-GATE, OUTPUT, CLEANUP. Use when writing articles, blog posts, or any content that uses a voice profile. Use for "write article", "blog post", "write in voice", "generate content", "draft article", "write about".
documentation
Critique-and-rewrite loop for voice fidelity validation.