# Content Creation Workflow 2026

**Last Updated:** 2026-04-04  
**Purpose:** Outline-first, section-by-section comprehensive drafting—replace incremental word-count chasing with best-in-class skyscraper content creation.

**Default word target:** Set `CONTENT_OUTLINE.md` **Target Word Count** to **100%** of `data/competitive-depth-analysis.md` **Recommended Target**. The **80%** threshold is a **validation floor** (`validate-new-post.php --strict`), not the skyscraper goal. Legacy or narrow topics may document an explicit exception. See [SKYSCRAPER_CONTENT_QUALITY_ENFORCEMENT.md](SKYSCRAPER_CONTENT_QUALITY_ENFORCEMENT.md).

**Outline scaffold from data:** After the pipeline, run `php v2/scripts/blog/synthesize-outline-scaffold.php --post=slug --category=lexikon` and merge `data/outline-scaffold.generated.md` into your outline (then `generate-section-briefs.php`). Hub: [CONTENT_SYSTEM_INDEX.md](CONTENT_SYSTEM_INDEX.md).

## Overview

This workflow replaces the incremental "temp file + add until word count" approach with a **single comprehensive pass** driven by a fully fleshed outline. Each section is written to full depth from the outline before moving on—no "add until word count."

## Data Flow

**Pipeline order (run-new-post-pipeline.php):** SISTRIX Keywords → **parallel:** PAA Questions + SERP Features + Competition Levels + Search Intent (separate files; all must finish before FAQ) → **FAQ Research** (merges PAA + SERP) → Competitor Analysis → Competitor Depth → Firecrawl Validation → SERP Skeleton → Content Depth Report → Pre-Content Checklist. Use `--dry-run` to print the DAG and commands.

**PAA source hierarchy:** `paa-questions-manual.json` (override) > `serp-features.json` > `paa-questions.json` > SISTRIX. collect-faq-research-data merges into `faq-research.json`. Downstream scripts use: manual > faq-research > paa-questions.

```mermaid
flowchart TB
    subgraph Pipeline [Pipeline Steps]
        K[collect-post-keywords-sistrix] --> KW[keywords-sistrix.json]
        PAA[collect-post-paa-questions] --> PAAJ[paa-questions.json]
        SERP[collect-post-serp-features] --> SERPJ[serp-features.json]
        FAQ[collect-faq-research-data] --> FAQJ[faq-research.json]
        COMP[collect-post-competitor-analysis] --> COMPJ[competitor-analysis.json]
        DEPTH[analyze-competitor-content-depth] --> DEPTHJ[competitive-depth-analysis.md]
    end
    subgraph Manual [Manual Steps]
        SERP_REVIEW[SERP analysis 30min]
        OUTLINE[Create CONTENT_OUTLINE.md]
    end
    subgraph Content [Content Creation]
        BRIEFS[generate-section-briefs] --> BRIEFSJ[section-briefs.md]
        WRITE[Write content]
    end
    KW --> FAQ
    PAAJ --> FAQ
    SERPJ --> FAQ
    COMPJ --> DEPTH
    DEPTHJ --> OUTLINE
    SERP_REVIEW --> OUTLINE
    OUTLINE --> BRIEFS
    BRIEFSJ --> WRITE
```



## Core Principles

1. **Outline-First:** No content writing until CONTENT_OUTLINE.md is complete with section briefs (key points, target words, formats). Outlines must be research-based (SERP, competitor, PAA). **Comparison / „vs.“-Abschnitte:** nur mit **Evidence** (PAA, Competitor-H2, GSC); sonst Abschnitt anpassen — siehe [COMPARISON_AND_VS_SECTIONS_GUIDE.md](COMPARISON_AND_VS_SECTIONS_GUIDE.md).
2. **Section-by-Section Drafting:** Write one H2 at a time, to full depth from outline before moving on
3. **Single Apply:** Write complete HTML in one working file; apply via `update-post-content.php` when ready
4. **Completeness Over Word Count:** Focus on covering all outline key points, PAA, and content gaps—not hitting a number
5. **Iterative Outline Improvement:** Review and update CONTENT_OUTLINE.md as you implement—add missing sections, refine key points, adjust depth based on validation. Outlines are living documents.
6. **Consolidation pass (after first full draft):** If `validate-new-post.php` or readability review flags **too many thin H3s** (decorative fragmentation vs. [HEADING_HIERARCHY_GUIDE.md](HEADING_HIERARCHY_GUIDE.md)), merge subtopics into **deeper H2 sections** using short **answer capsules** after question-style H2s, `<ol>`/`<ul>` with bold lead-ins, and extra paragraphs—rather than one-sentence H3s. Re-run `validate-section-depth.php` (and optionally `--check-h3`). **Trade-off:** `validate-new-post.php` may WARN “consider H3s” when H3=0; that is acceptable if every H2 meets depth rules and the outline documents intentional H2-only structure. Update `CONTENT_OUTLINE.md` / `CREATION_NOTES.md` so the team knows H3s were omitted by design.

## Prohibited

- **Incremental word-count chasing:** Adding filler sentences to reach target
- **"Add a paragraph here"** without outline-driven purpose
- **Patching content** piecemeal until word count
- **Adding filler** like "Alle Angaben beziehen sich auf das Jahr 2026" or "Details findest du beim..." solely to reach target

## Workflow Steps

### Step 1: Complete Outline with Section Briefs

Before writing content:

1. Ensure CONTENT_OUTLINE.md has section briefs for each H2:
  - **Target words:** ~X (from target ÷ H2 count)
  - **Key points:** 2–5 bullet points from PAA, competitor, content gaps
  - **Formats:** Table | List | Paragraphs
  - **PAA covered:** Which PAA questions this section addresses
  - **Planned H3s:** For each H2, apply the H3 checklist from [CONTENT_DEPTH_GUIDELINES.md](CONTENT_DEPTH_GUIDELINES.md): 3+ distinct subtopics? Formen/Arten, Vor-/Nachteile, Tipps, Rechtliches? >250 words? **List vs H3:** If 4+ items or each item 1-2 sentences → plan list. If 2+ sentences per item and 3 or fewer items → plan H3s. **Structure variety:** Mix formats across sections.
2. Generate section briefs from data:
  ```bash
   php v2/scripts/blog/generate-section-briefs.php --post=slug --category=category
  ```
3. Copy relevant items from `data/section-briefs.md` into CONTENT_OUTLINE.md PAA matrix, competitor H2 mapping, or content gap checklist.
4. Run `check-outline-h2-overlap.php` before writing; merge or rephrase overlapping H2s:
  ```bash
   php v2/scripts/blog/check-outline-h2-overlap.php --post=slug --category=category
  ```
5. Review [ANTI_FLUFF_CHECKLIST.md](ANTI_FLUFF_CHECKLIST.md) before drafting—no filler.
6. **Redundancy check (outline):** For each H2, verify it covers a distinct angle. No two H2s answer the same question. If CONTENT_OUTLINE has "Avoid" per section, ensure key points don't overlap. See [SKYSCRAPER_TECHNIQUE_2026.md](SKYSCRAPER_TECHNIQUE_2026.md) Topic-Angle Coverage.

### Step 2: Section-by-Section Drafting

Write each H2 section in order:

1. **Before writing each H2:** Read `data/section-briefs.md` for that section. Ensure key points and PAA are covered.
2. **Open section brief** (from outline or data/section-briefs.md)
3. **Write to full depth** – 2+ paragraphs or 1 paragraph + list/table per H2
4. **Use H3s where planned** – If outline/section brief lists planned H3s (Formen, Vor-/Nachteile, Tipps, Rechtliches), implement them **only when each item has 2+ sentences**; otherwise use list. Optional intro paragraph between H2 and first H3 for smoother flow.
5. **Cover all key points** from the section brief
6. **Include formats** (table, list) where recommended
7. **Visual format pass (smart styling):** After the section meets depth, apply `formula-block`, `table-breakout-wrapper`, and `blog-note` only where they add scan value—**not** in every section. Use the matrix and rules of thumb in [CONTENT_FORMAT_PATTERNS.md](CONTENT_FORMAT_PATTERNS.md) § *Visual format decision guide*; consolidate duplicate formula blocks before apply.
8. **Ordio mentions in body** – Add 2–4 contextual Ordio mentions in the main content (intro, relevant H2 sections, Fazit). Do not put all promotions only in FAQs. See [ORDIO_PROMOTION_GUIDE.md](ORDIO_PROMOTION_GUIDE.md) principle 6 (Body-First Placement).
9. **Internal links inline** – Integrate links to related posts, tools, and product pages naturally within sentences. Never append "Weitere Lexikon-Artikel:" or similar link dumps at the end of paragraphs. **Lexikon-to-Lexikon:** When mentioning a topic that has a dedicated lexikon post (e.g. Soft Skills, Nachfolgeplanung, Recruiting), add a link on first meaningful mention. See [INTERNAL_LINKING_GUIDE.md](guides/INTERNAL_LINKING_GUIDE.md).
10. **Do not move on** until the section meets depth requirements

Each section should be substantive—no placeholder or thin content.

**Per-section E-E-A-T check:** Does this section demonstrate experience or expertise? Is it trustworthy? Add examples, correct terminology, or internal links where appropriate. See [CONTENT_DEPTH_GUIDELINES.md](CONTENT_DEPTH_GUIDELINES.md) E-E-A-T Signals.

**Per-section redundancy check:** Before moving to the next H2, ask: "Did I repeat content from a previous section?" If yes, cut the repeat or replace with a cross-reference ("Wie in [H2 X] beschrieben…"). See [CONTENT_DEPTH_GUIDELINES.md](CONTENT_DEPTH_GUIDELINES.md) Cross-Section Redundancy Check.

**Sibling/paired post benchmark:** When creating a post that has a natural paired post (e.g. Hard Skills when Soft Skills exists, Job Enrichment when Job Rotation exists), compare section depth and formats to the sibling before finalizing. Ensure parity on: comparison list/table, branchenspezifisch examples with industry links, concrete training formats, practical HR steps (e.g. situational questions, STAR-Methode). Avoid one post being noticeably thinner than its pair.

### Step 2.5: Content Quality Self-Edit (Before Apply)

**Before** calling `update-post-content.php`, run the [CONTENT_QUALITY_PRE_PUBLISH_CHECKLIST.md](CONTENT_QUALITY_PRE_PUBLISH_CHECKLIST.md):

1. **Quick scan** – No AI tells, no duplicate H2s, no intro fluff
2. **AI avoidance** – Sentence variety, no generic transitions, specific examples
3. **Anti-fluff** – Front-load answers, cut vague claims, value test per section
4. **Copy quality** – Du tone, Ordio in body, benefits over features
5. **Redundancy check** – No H2 repeats, no paragraph restating intro
6. **People-first body (no SERP meta in `<p>`)** – Run [PEOPLE_FIRST_INTRO_AND_LINKING.md](PEOPLE_FIRST_INTRO_AND_LINKING.md) QA: no “In Suchergebnissen…”, “Suchbegriffe aus dem Privatkontext”, “unten ordnen wir…”, or similar. **Before apply**, scan draft + JSON (optional `content.html`):
  ```bash
   python3 v2/scripts/blog/audit-meta-intro-language.py --json-posts --post=SLUG --category=lexikon --fail-on high
  ```
   Exit code must be **0** before `update-post-content.php`. **After apply / pre-publish**, `make blog-post-validate-strict` runs `make blog-audit-meta-intro`, which scans **only the JSON body** (`--json-body-only`) so a stale `content-draft.html` does not fail the strict chain. See [BLOG_WORKFLOW_EFFICIENCY.md](BLOG_WORKFLOW_EFFICIENCY.md).
7. **Thin-H2 spot check (optional but recommended for skyscraper):** After a full draft, compare **relative** depth between H2s (strip HTML, approximate word count per section). If one H2 is far below siblings (e.g. disambiguation or Fazit under ~120–150 words while others are 200+), add **one** substantive block: payroll consequence, team communication, Controlling vs. HR vocabulary, or a short process rule &mdash; not filler. Example revision: `lexikon/urlaubskonto` (2026-03).

Fix any failures before applying. Do not add filler to pass—address gaps substantively.

### Step 3: Single Apply

Write complete HTML in one working file (e.g. `content-draft.html`). Apply when ready:

```bash
php v2/scripts/blog/update-post-content.php --post=slug --category=lexikon --html=path/to/content-draft.html
```

Do not apply incrementally. Apply once when the full draft is complete.

### Step 3b: Image Phase (when generating featured image)

Before running `generate-blog-featured-image.py`:

1. **Template:** Use `docs/content/blog/posts/_templates/IMAGE_PROMPT_TEMPLATE.md` when creating `IMAGE_PROMPT.md`
2. **Anti-repetition:** Include composition (camera angle) and negative-instruction clause; avoid blue sphere, sundial, generic clock
3. **Audit:** Run `python3 v2/scripts/blog/audit-blog-image-scene-types.py` (optionally `--report-adjacent=3`) to check diversity before batch generation

See [BLOG_FEATURED_IMAGE_GENERATION.md](BLOG_FEATURED_IMAGE_GENERATION.md) and [BLOG_FEATURED_IMAGE_STYLE_GUIDE.md](BLOG_FEATURED_IMAGE_STYLE_GUIDE.md).

### Step 4: Validation (Iterative – Don't Stop Until Complete)

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

**After content draft:** Run `compare-content-to-competitors.php` and address gaps before finalizing:

```bash
php v2/scripts/blog/compare-content-to-competitors.php --post=slug --category=category
```

Then run validation:

```bash
# Section depth (2+ paragraphs or 1+list per H2)
php v2/scripts/blog/validate-section-depth.php --post=slug --category=category --check-h3

# Content completeness (PAA, gaps, formats, definition)
php v2/scripts/blog/validate-content-completeness.php --post=slug --category=category

# Content structure (H3 usage for posts >1,500 words)
python3 v2/scripts/blog/audit-content-structure.py
```

**If any validator fails:** Address the specific gaps (thin sections, uncovered PAA, missing formats). Re-apply content and re-run all validators. **Do not consider content done until all pass.** If `audit-content-structure` flags the post for "Consider reviewing structure," assess whether H3s would improve scannability per [CONTENT_DEPTH_GUIDELINES.md](CONTENT_DEPTH_GUIDELINES.md). Never add filler—address gaps substantively.

## Completion Criteria

Content is complete when:

- All outline key points covered
- All PAA addressed (in H2 or FAQ)
- **Unique value** – At least one item from CONTENT_OUTLINE Unique Value checklist is present in content
- Formats (tables, lists) from competitive-depth included where recommended
- **Visual formats** used deliberately: `formula-block` for canonical equations (not every numeric example), tables for comparison—not for formulas, notes used sparingly. See [CONTENT_FORMAT_PATTERNS.md](CONTENT_FORMAT_PATTERNS.md) § *Visual format decision guide*
- **Tables** use correct format (plain table/thead/th/td, wrap in `table-breakout-wrapper`; no Tailwind on table). See [BLOG_TABLE_FORMAT.md](BLOG_TABLE_FORMAT.md)
- **Lexikon:** H2 Fazit (2–3 paragraphs) included
- **Ordio in body:** 2–4 contextual mentions in main content (not only in FAQs). See [ORDIO_PROMOTION_GUIDE.md](ORDIO_PROMOTION_GUIDE.md).
- Definition in first 20%
- Section depth (2+ paragraphs or 1+list per H2) verified
- `validate-section-depth.php` and `validate-content-completeness.php` both pass

## Expand vs Stop

**Stop** when all criteria above are met.

**Expand** when:

- `validate-content-completeness.php` reports specific gaps (PAA, content gaps, format recommendations)
- `validate-section-depth.php` reports thin sections

**Never** add filler to reach word count. Address specific gaps with substantive content.

## Working File

Use `**content-draft.html`** as the only tracked HTML body per post. **Legacy / duplicates:** Do not add `content-expanded.html`, `content-draft-expanded.html`, or `*-improved-content.html` to the repo—use Git history for iterations. Known stragglers: [CONTENT_DRAFT_LEGACY_INVENTORY.md](CONTENT_DRAFT_LEGACY_INVENTORY.md). Apply via `update-post-content.php` or `./v2/scripts/blog/apply-and-validate-post.sh`.

**Renten- / Behörden-Links und `validate-content-flow`:** URLs mit dem Pfadsegment `/FAQ/` können den „FAQ im Fließtext“-Check auslösen (Wortgrenze `\bFAQ\b`). DRV- und Behörden-Seiten ggf. auf Einstiegs-URLs ohne `FAQ` im Pfad verlinken. Formulierungen mit **„häufig“** unmittelbar vor einem **„Fragen“**-Wort im selben Absatz können Regex-False-Positives auslösen; Synonyme wie **„oft“** nutzen oder Satz trennen.

## Pilot Post: rufbereitschaft (2026-02-11)

Full workflow completed on `lexikon/rufbereitschaft`:

- Competitive-depth target: 3,000 words
- CONTENT_OUTLINE created with 9 H2s (including Fazit) and section briefs
- `generate-section-briefs.php` produced `data/section-briefs.md` with PAA mapping
- Content written section-by-section in `content-draft.html` (one pass, outline-driven)
- Applied via `update-post-content.php` with backup
- **Result:** 1,652 words | 9 H2s (incl. Fazit) | Table (plain format, table-breakout-wrapper, blue headers) | Lists
- `validate-section-depth.php`: **PASS** – all 9 sections meet depth
- `validate-content-completeness.php`: **COMPLETE** – PAA 15/15, tables yes, lists yes, definition in first 20%
- Table styling fixed: plain table (no Tailwind); wrap in `table-breakout-wrapper` per [BLOG_TABLE_FORMAT.md](BLOG_TABLE_FORMAT.md)

**Quality vs incremental approach:** Single pass produced substantive content with no filler. All PAA covered, section depth met, format recommendations (table, lists) included. Fazit added. Table format corrected for Ordio blue headers.

## Pilot Post: human-resources (2026-02-11)

Full workflow completed on `lexikon/human-resources`:

- Primary keyword: "Human Resources" (vs. Personalwesen)
- **PAA/competitor gotcha:** The pipeline may misinterpret multi-word primary keywords (e.g. "Human" instead of "Human Resources"). If PAA/competitor data looks wrong, verify keyword in pipeline scripts and correct SERP_ANALYSIS.md + competitive-depth-analysis.md manually.
- CONTENT_OUTLINE created with 8 H2s (Definition, Abgrenzung, Aufgaben, Personalentwicklung, Ziele, HR in Kleinunternehmen, Arbeitsrecht, Fazit)
- Content written section-by-section; table HR vs Personalabteilung vs Personalwesen; 7 internal links
- **Result:** ~1,072 words | 8 H2s | 6 FAQs | Reciprocal link with personalabteilung

## Pilot Post: krankengeld (2026-02-12)

Full workflow completed on `lexikon/krankengeld`:

- Primary keyword: Krankengeld
- CONTENT_OUTLINE created with 9 H2s (Was ist Krankengeld?, Anspruch, Dauer, Berechnung, 2026, Beantragung, Steuer, Sonderfälle, Fazit)
- Content written section-by-section; 4 tables (Anspruch, Zeitablauf, Berechnung, Beitragsbemessungsgrenze)
- Internal links: krankmeldung, arbeitsunfaehigkeitsbescheinigung, lohnersatzleistungen, minijob, midijob
- FAQs: 10 manually created (generator skipped PAA); faq-answers-optimized.json used
- Related posts: suggest-related-posts + add-new-post-to-related-carousels (krankmeldung, lohnersatzleistungen, arbeitsunfaehigkeitsbescheinigung)
- Pillar: Zeiterfassung (absence/payroll)
- **Result:** ~1,350 words | 9 H2s | 10 FAQs | Featured image (Gemini) | seo-meta.json + sync-meta-to-posts

## Pilot Post: spesen (2026-02-12)

Full workflow completed on `lexikon/spesen`:

- Primary keyword: Spesen
- Pipeline: Run without `--allow-paa-failure`; PAA succeeded (15 questions). Do not use `--allow-paa-failure` preemptively.
- CONTENT_OUTLINE created with 9 H2s (Was sind Spesen?, Arten, Verpflegungspauschalen Inland 2026, Spesen bei Auslandsreisen, Kilometerpauschale, Spesen abrechnen, Steuerliche Behandlung, Sonderfälle, Fazit)
- Content written section-by-section; 3 tables (Spesenarten, Verpflegungspauschalen Inland, Beispiele Ausland)
- Internal links: verpflegungsmehraufwand, reisekostenabrechnung, bewirtungskosten, lohnabrechnung
- FAQs: 10 manually created (generator filtered all PAA); faq-answers-optimized.json used
- Related posts: suggest-related-posts + add-new-post-to-related-carousels (verpflegungsmehraufwand, reisekostenabrechnung, bewirtungskosten)
- Pillar: None (No Pillar per TIER1; verpflegungsmehraufwand/reisekostenabrechnung not in TIER1)
- seo-meta.json + sync-meta-to-posts
- **Result:** ~1,269 words | 9 H2s | 10 FAQs | Featured image (Gemini) | seo-meta.json + sync-meta-to-posts

## Pilot Post: initiativbewerbung (2026-02-12)

Full workflow completed on `lexikon/initiativbewerbung`:

- Primary keyword: Initiativbewerbung
- CONTENT_OUTLINE created with 9 H2s (Definition, vs Blindbewerbung, Wann lohnt sich, Vorbereitung, Anschreiben, Lebenslauf, Versand & Follow-up, Fehler, Fazit)
- Content expanded to ~2,370 words (2 tables: Vergleich Initiativ vs Blind, Anschreiben-Struktur; checklisten, ATS-Tipps, Follow-up-Timing)
- FAQs: 8 manually created (generator filtered PAA); faq-answers-optimized.json used
- Related posts: suggest-related-posts + add-new-post-to-related-carousels (arbeitszeugnis, personalfragebogen, personalabteilung)
- Featured image: IMAGE_PROMPT.md with SILHOUETTES scene type; added to BLOG_FEATURED_IMAGE_STYLE_GUIDE.md
- seo-meta.json + sync-meta-to-posts
- **Result:** ~2,370 words | 9 H2s | 8 FAQs | Featured image (Gemini) | validate-section-depth + validate-content-completeness: PASS

## References

- [ANTI_FLUFF_CHECKLIST.md](ANTI_FLUFF_CHECKLIST.md) – No filler; cut micro-fluff and redundant paragraphs
- [CONTENT_OUTLINE.md](posts/_templates/CONTENT_OUTLINE.md) – Template with section briefs
- [BLOG_TABLE_FORMAT.md](BLOG_TABLE_FORMAT.md) – Table format (no Tailwind; blue headers)
- [BLOG_CONTENT_EDIT_WORKFLOW.md](BLOG_CONTENT_EDIT_WORKFLOW.md) – How to apply content
- [CONTENT_DEPTH_GUIDELINES.md](CONTENT_DEPTH_GUIDELINES.md) – Section depth standards
- [SKYSCRAPER_TECHNIQUE_2026.md](SKYSCRAPER_TECHNIQUE_2026.md) – Skyscraper technique

