# blog-content-creation-gate Full Instructions

## Content Creation Gate

**Before creating or substantially editing blog content:**

1. Run `php v2/scripts/blog/validate-improvement-readiness.php --post={slug} --category={category}` (add `--new-post` for new posts)
2. Run `php v2/scripts/blog/validate-serp-outline-ready.php --post={slug} --category={category}` – SERP filled, outline target set, Unique Value checked
3. Run `php v2/scripts/blog/validate-content-outline-quality.php --post={slug} --category={category}` (CLI default: outline target ≥90% of competitive-depth; **aim 100%** in CONTENT_OUTLINE; use `--target-ratio=1.0` to enforce; `--target-ratio=0.8` legacy only). Optional: `--strict-evidence` requires enough `**Evidence:**` rows per H2.
4. Run `php v2/scripts/blog/check-outline-h2-overlap.php --post={slug} --category={category}` – merge or rephrase overlapping H2s
5. **Keyword gate (lexikon/ratgeber in progress):** `KEYWORD_DECISION.md` should document primary + secondary sources; `data/keywords-sistrix.json` should be fresh before drafting body (see [blog-data-collection.mdc](blog-data-collection.mdc) cadence). Run `php v2/scripts/blog/validate-keyword-decision.php --post={slug} --category={category}` (warnings by default; `--strict` optional). See [KEYWORD_RESEARCH_WORKFLOW.md](docs/content/blog/KEYWORD_RESEARCH_WORKFLOW.md).

**All must pass before editing `content.html`.** Unique Value section in CONTENT_OUTLINE must have ≥1 checked item. **Before applying content:** Run [ANTI_FLUFF_CHECKLIST.md](docs/content/blog/ANTI_FLUFF_CHECKLIST.md) – no filler; cut micro-fluff; address gaps substantively. Fix before `update-post-content.php`.

## Content Edit Method (CRITICAL)

- **Never** use search_replace or direct text editing on `v2/data/blog/posts/**/*.json`
- **Always** use `php v2/scripts/blog/update-post-content.php` to apply content changes (or `./v2/scripts/blog/apply-and-validate-post.sh` to apply + run validators in one step)
- **Single working file in git:** `docs/content/blog/posts/{category}/{slug}/content-draft.html` — iterate via commits/branches, not new filenames (`*-expanded`, `*-comprehensive`, `*-improved`). Scratch: `--stdin` or `/tmp/{slug}-body.html` until ready to commit. See [CONTENT_DRAFT_LEGACY_INVENTORY.md](../../docs/content/blog/CONTENT_DRAFT_LEGACY_INVENTORY.md).
- After script-based edits: run `sync-post-content-text.php` if HTML was modified outside update-post-content.php
- See [BLOG_CONTENT_EDIT_WORKFLOW.md](../../docs/content/blog/BLOG_CONTENT_EDIT_WORKFLOW.md)

## Intro Prohibition (Lexikon/Ratgeber)

**Never start a post or intro with "Definition:"** – use human-first, engaging intros instead. Hook (bold claim, surprising stat, question, relatable scenario) → context → value proposition. The definition belongs in the first H2; the intro should not repeat it verbatim. See [AI_CONTENT_AVOIDANCE_GUIDE.md](../../docs/content/AI_CONTENT_AVOIDANCE_GUIDE.md) and [CONTENT_FLOW_GUIDELINES.md](docs/content/blog/CONTENT_FLOW_GUIDELINES.md).

**Also avoid meta-SERP intros** (“Warum ein eigener Artikel…?”, “Weil Suchanfragen…”, “verlinken wir gezielt”, “Suchintention”, “Such- und Praxisthema”, “Keyword-Kannibalisierung” in body copy). **Before final:** optional `python3 v2/scripts/blog/audit-meta-intro-language.py`.

## Best-in-Class Content

Use outline to cover PAA, competitor gaps, and GSC queries. Prioritize completeness and unique value over word count. **Topic-Angle Coverage:** Each H2 must cover a distinct angle (Definition, How, Comparison, Rules, Edge Case, Practical, Conclusion). No redundancy between H2s. See [SKYSCRAPER_TECHNIQUE_2026.md](docs/content/blog/SKYSCRAPER_TECHNIQUE_2026.md) Topic-Angle Coverage; [CONTENT_DEPTH_GUIDELINES.md](docs/content/blog/CONTENT_DEPTH_GUIDELINES.md) Cross-Section Redundancy Check.

**Topical authority:** Assign cluster and internal links per [blog-cluster-mapping.mdc](blog-cluster-mapping.mdc) and [docs/reference/architecture/content-clusters/CLUSTER_MAPPING.md](../../docs/reference/architecture/content-clusters/CLUSTER_MAPPING.md)—skyscraper depth includes **cluster context**, not isolated long pages.

**PAA / completeness ≠ competitive depth:** `validate-content-completeness` can pass while **`compare-content-to-competitors.php`** still flags a low ratio vs `competitive-depth-analysis.md`. Treat **`blog-post-validate-strict`** + **`compare-content-to-competitors --strict`** as the publish-time skyscraper enforcement when policy requires. See [CONTENT_PIPELINE_AUDIT_2026-03-23.md](docs/content/blog/CONTENT_PIPELINE_AUDIT_2026-03-23.md).

## Prohibited

- **Incremental word-count chasing:** Do not add filler sentences to reach target. Use outline-driven section-by-section drafting per [CONTENT_CREATION_WORKFLOW_2026.md](docs/content/blog/CONTENT_CREATION_WORKFLOW_2026.md).

## Required Before Content Creation

- **Outline scaffold (default):** When `data/competitive-depth-analysis.md` exists, run `php v2/scripts/blog/synthesize-outline-scaffold.php --post={slug} --category={category}` → merge `data/outline-scaffold.generated.md` into CONTENT_OUTLINE.md (competitor H2 themes, PAA, gaps, intent). **Skip** only for narrow/errata posts or missing depth file—document in `CREATION_NOTES.md`.
- **Section briefs:** Run `generate-section-briefs.php` or manually fill section key points, target words, formats per H2 in CONTENT_OUTLINE.md. **Read `data/section-briefs.md` before writing each H2** – key points, target words, formats inform section depth.
- **Sparse competitor data:** Pipeline auto-remediates sparse top N (default 7) via Firecrawl (1 credit/URL). If running validation manually: `validate-blog-competitor-data-completeness.php --post={slug} --category={category} --top=7 --remediate`. Default config: proactive top 3. Document findings in SERP_ANALYSIS.md. See [SERP_MCP_IMPROVEMENT_GUIDE.md](../../docs/content/blog/SERP_MCP_IMPROVEMENT_GUIDE.md), [FIRECRAWL_3K_PLAN_OPTIMIZATION.md](../../docs/systems/firecrawl/FIRECRAWL_3K_PLAN_OPTIMIZATION.md).

## Post-Write Validation (Don't Stop Until Complete)

**Do not stop until all validators pass.** Run validation after each content pass. If any fails, address gaps and re-run until all pass. See [CONTENT_EXPANSION_CONTINUITY.md](docs/content/blog/CONTENT_EXPANSION_CONTINUITY.md).

**Mandatory sequence:** compare-content-to-competitors → validate-section-depth → validate-content-completeness → validate-faq-quality → validate-new-post. **Shortcut:** `make blog-post-validate POST={slug} CAT={category}` runs compare + section-depth + completeness + geo-citability + aeo-capsules + **aeo-capsule-diversity** (warn-only) + faq-quality + h2-faq-overlap + new-post strict. **Pre-publish stricter chain:** `make blog-post-validate-strict POST={slug} CAT={category}` also runs `compare-content-to-competitors --strict`, `validate-internal-links-exist`, `validate-content-flow --exit-on-error`, and **validate-aeo-capsule-diversity.php --strict**. **For new posts:** Use `validate-new-post.php --strict` (or `--new-post`) so word count below 80% of outline target is an ERROR, not a warning. Do not apply content until gap addressed.

**Body vs FAQ ergonomics:** After editing `content-draft.html`, prefer `make blog-apply-validate POST={slug} CAT={category} HTML=docs/content/blog/posts/{category}/{slug}/content-draft.html` (or `blog-apply-validate-strict` before publish). **FAQ-only** work: `make blog-post-validate-faq POST={slug} CAT={category}` (still run full strict if body/meta/links changed in the same session). See [BLOG_WORKFLOW_EFFICIENCY.md](docs/content/blog/BLOG_WORKFLOW_EFFICIENCY.md).

**Tables in body HTML:** Do not put Tailwind classes on `table` / `thead` / `tr` / `th` / `td` (grey headers break contrast). Use plain semantic tables inside `table-breakout-wrapper` per [BLOG_TABLE_FORMAT.md](../../docs/content/blog/BLOG_TABLE_FORMAT.md). `validate-new-post.php` warns on violations; repair legacy markup with `php v2/scripts/blog/fix-blog-table-styling.php --post={slug} --category={category}`.

**Repetitive AEO labels:** After large rewrites, optionally run `make audit-blog-repetition` (repo-wide inventory). Do not repeat **„In Kürze:“** under every question H2—see [CONTENT_DEPTH_GUIDELINES.md](../../docs/content/blog/CONTENT_DEPTH_GUIDELINES.md) (AEO capsules without repetitive labels).

**Stricter competitive check (single step):** `php v2/scripts/blog/compare-content-to-competitors.php --post={slug} --category={category} --strict` exits 1 on WARN or &lt;80% of competitive-depth recommended — included in `blog-post-validate-strict`.

**Image alt & meta (before publish):** Run `validate-featured-image-alt.php --post={slug} --category={category}` and `validate-seo-meta.php` (index/category/post sample). Per-post alt is included in `validate-new-post.php`. See [AUDIT_RUNBOOK.md](docs/content/blog/AUDIT_RUNBOOK.md) Blog Image & Meta Audit.

- **Content quality self-edit:** Run [CONTENT_QUALITY_PRE_PUBLISH_CHECKLIST.md](docs/content/blog/CONTENT_QUALITY_PRE_PUBLISH_CHECKLIST.md) before applying – AI avoidance, anti-fluff, copy quality, redundancy check. Fix failures before `update-post-content.php`.
- **Ordio promotion:** Run `php v2/scripts/blog/suggest-ordio-feature.php --post={slug} --category={category}` before or after content; add 2–4 contextual product links in body (section-level). Body-first: Ordio in main content, not only FAQs. See ordio-promotion-contextual.mdc.
- `php v2/scripts/blog/compare-content-to-competitors.php --post={slug} --category={category}` – **Mandatory before finalizing**; address gaps (`--strict` optional)
- `php v2/scripts/blog/validate-section-depth.php --post={slug} --category={category}`
- `php v2/scripts/blog/validate-content-completeness.php --post={slug} --category={category}` – For lexikon: verify Fazit H2 present (warns if missing)
- `php v2/scripts/blog/validate-geo-citability.php --post={slug} --category={category}` – Definition signal, Fazit, FAQ count (`--strict` fails on warnings)
- `php v2/scripts/blog/validate-aeo-capsules.php --post={slug} --category={category}` – Question H2 → first paragraph length (`--strict` fails on warnings)
- `php v2/scripts/blog/validate-aeo-capsule-diversity.php --post={slug} --category={category}` – „In Kürze:“ overuse (warn; `--strict` with `blog-post-validate-strict`)
- `php v2/scripts/blog/validate-faq-quality.php --post={slug} --category={category}` – FAQ count ≥ 10 for lexikon/ratgeber (fails if &lt; 10; override with `--min-faqs=6` for narrow topics); targets **published** `faqs` in post JSON (see [FAQ_SOURCE_OF_TRUTH.md](docs/content/blog/FAQ_SOURCE_OF_TRUTH.md))
- After substantive FAQ edits: optional read-only drift check `php v2/scripts/blog/audit-faq-source-drift.php --post={slug} --category={category}` when `faq-answers-optimized.json` exists (post `faqs` vs pipeline file)
- Optional (warn-only): `php v2/scripts/blog/validate-strong-density.php --post={slug} --category={category}` – flags decorative overuse of `<strong>` in prose; see [BLOG_STRONG_AND_EMPHASIS.md](docs/content/blog/BLOG_STRONG_AND_EMPHASIS.md)

## Blockers (Do Not Write Content If)

- **SERP_ANALYSIS.md** – Manual sections have placeholders (e.g. `- [ ] Format`, `*Min 30 min browser review*`, empty "Recommendations"). Run `validate-serp-outline-ready.php` before content.
- **CONTENT_OUTLINE** – Target word count is below 90% of competitive-depth recommended (when `competitive-depth-analysis.md` exists). **Suggested:** Aim for 100%. Use `--target-ratio=0.8` for legacy workflows.
- **Word count below 80% of outline target** – Treat as BLOCKER for both new posts and improvement workflows. Use `validate-new-post.php --strict` (new) or `--min-word-ratio=0.8` (improvement). Do not mark a post complete or apply content until the minimum is met. Expand using data-driven approach: competitive-depth-analysis, PAA coverage, section briefs, skyscraper technique. No filler—address specific gaps with substantive content.
- **Outline structure** – Fewer than 8 H2s (6 for inside-ordio) in CONTENT_OUTLINE.md
- **PAA off-topic** – If competitive-depth-analysis PAA list has >30% off-topic, create `paa-questions-manual.json` before content creation. See [PAA_QUALITY_AND_MANUAL_OVERRIDE.md](docs/content/blog/PAA_QUALITY_AND_MANUAL_OVERRIDE.md).

## New Posts

When creating new posts: Complete PRE_CONTENT_CHECKLIST (new-post variant) before Phase 4. Run `generate-pre-content-checklist.php --new-post`; pipeline does this automatically.

## Tables

Use plain `table`/`thead`/`th`/`td`; wrap in `table-breakout-wrapper` for desktop breakout. **Never** use `bg-gray-50` or Tailwind background/border on table elements – they override blog CSS (blue headers). See [BLOG_TABLE_FORMAT.md](docs/content/blog/BLOG_TABLE_FORMAT.md).

## Section Depth

Each H2 section needs **2+ paragraphs** or **1 paragraph + list/table** per [CONTENT_DEPTH_GUIDELINES.md](docs/content/blog/CONTENT_DEPTH_GUIDELINES.md). No thin or half-assed sections.

## Content Format Patterns

- **Formulas:** Use `<div class="formula-block">` for formulas and calculations. **Never use tables for formulas or calculations** – formula-block has dedicated styling (light blue background, monospace, left border). **Notes:** Use `<blockquote class="blog-note blog-note--important">` for "Wichtig:" callouts. **Lists:** Prefer `<ul>` over inline comma-separated items (4+). See [CONTENT_FORMAT_PATTERNS.md](docs/content/blog/CONTENT_FORMAT_PATTERNS.md).

## Section Structure (H3, Restructuring)

- **Numbered steps:** Use `<ol>`, never inline (1)(2)(3) in a paragraph. See [CONTENT_DEPTH_GUIDELINES.md](docs/content/blog/CONTENT_DEPTH_GUIDELINES.md).
- **H3 planning:** For each H2 with 3+ distinct subtopics, Formen/Arten, Vor-/Nachteile, Tipps, or Rechtliche Grundlagen, plan H3s in the outline **only if each item has 2+ sentences**. **Do not tie H3s to word count** – use structure, TOC value, and scannability on a case-by-case basis. Document "Planned H3s" in CONTENT_OUTLINE section briefs. Run `python3 v2/scripts/blog/audit-content-structure.py` for posts >1,500 words; address "Consider reviewing structure" before publish.
- **List vs H3:** Prefer list over H3 when items are 1-2 sentences each or when 4+ consecutive items. H3 requires 2+ sentences per item. Ensure structure variety – mix H2+paragraphs, H2+list, H2+H3 across sections.
- **H3s are optional and case-by-case.** Include H3s only where they add clarity (distinct subtopics, steps, tips, comparisons). H2+paragraphs is valid for short or simple sections. Don't force structure. See [TOC_BEST_PRACTICES.md](docs/content/blog/TOC_BEST_PRACTICES.md) and [BLOG_CONTENT_RESTRUCTURING_GUIDE.md](docs/content/blog/BLOG_CONTENT_RESTRUCTURING_GUIDE.md).
- **When H3s are used:** Optional intro paragraph between H2 and first H3 for smoother flow. Content-driven; avoid cheesy transitions. See [CONTENT_WRITING_GUIDELINES.md](docs/content/blog/CONTENT_WRITING_GUIDELINES.md).
- **Restructure consideration:** Before content creation, assess: Can any H2s be consolidated with H3s? Are there competitor topics missing that warrant new H2/H3 sections?

## AEO/GEO Integration

When creating content: **Answer-first** – 120–150 character answer capsule immediately after question H2s (AEO/GEO best practice). FAQ schema for PAA alignment; question-style headings where PAA matches; declarative headings where flow/clarity matters; entity clarity (Probezeit, Kündigungsfrist, etc.). Use question H2s where PAA matches; declarative where flow/clarity matters. Do not force questions everywhere. See [SEO_GEO_AEO_CHECKLIST.md](docs/content/blog/SEO_GEO_AEO_CHECKLIST.md) and [EXTERNAL_CONTENT_SEO_RESEARCH_LOG.md](docs/content/blog/EXTERNAL_CONTENT_SEO_RESEARCH_LOG.md). Hub: [CONTENT_SYSTEM_INDEX.md](docs/content/blog/CONTENT_SYSTEM_INDEX.md).

**PAA sources:** PAA questions from `paa-questions.json` or `faq-research.json` must inform H2s and FAQs. Run `collect-post-paa-questions.php` if faq-research has empty `paa_questions`.

## H2-FAQ Separation

FAQs must not duplicate H2 questions. Run `php v2/scripts/blog/check-h2-faq-overlap.php --post={slug} --category={category}`; overlap similarity should be < 0.65. Remove or rephrase overlapping FAQs. See [FAQ_H2_SEPARATION_GUIDELINES.md](docs/content/blog/FAQ_H2_SEPARATION_GUIDELINES.md).

## Backward Compatibility

For existing improvement workflows (no competitive-depth): Use `validate-improvement-readiness.php --skip-outline-quality` to bypass outline-quality checks when appropriate.
