MDX Limo
ContentEngine — Technical Addendum #2

ContentEngine — Technical Addendum #2

Content Type Templates, Schema Library, Refresh System & Validation Architecture

FieldValue
AuthorAlton Wells
DateMarch 2026
StatusDraft for Review
Parent SpecContentEngine Technical Specification v3
Depends OnAddendum #1 (LangExtract Implementation)
ScopeContent type definitions, structural templates, JSON-LD schema library, author entity specs, refresh queue system, SEO validation engine v2

1. Purpose & Scope

This addendum defines the complete content production framework for ContentEngine: what content types the system produces, how each type is structurally templated, what schema markup each type carries, how content freshness is managed, and how the SEO validation engine enforces quality at the deployment gate.

1.1 What This Addendum Covers

  • Eight content type definitions with structural templates, required elements, and SEO rules
  • Complete JSON-LD schema library mapped per content type
  • Author entity specifications for three authors (Alton, Stan, Auctor)
  • Organization entity specification for Consul
  • Refresh queue system: scoring model, tiers, calendar integration, 90-day evaluation cycle
  • SEO Validation Engine v2: BLOCKING/WARNING/INFO severity tiers with 16 checks
  • Content depth validation check (brief-to-draft structural coverage)
  • Historical validation score tracking schema

1.2 What This Addendum Does Not Cover

  • Topic cluster definitions (deferred until competitive analysis is complete)
  • Image generation pipeline (manual placement for MVP; pipeline is a future addendum)
  • Agent prompt engineering (separate addendum)
  • Filesystem-as-context architecture (deferred per parent spec)

1.3 Industry Context

Consul is a B2B SaaS AI executive assistant targeting CEOs and founders at a $200/month price point. Content must build trust with high-ticket decision-makers. The vertical is "AI productivity / executive operations" — not YMYL, but E-E-A-T signals are critical because the buyer is sophisticated and skeptical. Schema strategy reflects this: we optimize for commercial intent SERPs, AI Overview citations, and authority signals.


2. Content Type Registry

ContentEngine produces eight content types. Each type has a distinct structural template, schema mapping, internal linking profile, image density rule, and refresh cadence.

2.1 Type Overview

Type IDType NameBuild PatternTypical LengthPrimary SchemaRefresh Cadence
blog_postBlog PostRecurring production1,500–2,500 wordsBlogPosting90-day evaluation
listicleListicleRecurring production1,500–3,000 wordsArticle + ItemList90-day evaluation
guideComprehensive GuideRecurring production3,000–5,000 wordsArticle (long-form)90-day evaluation
how_toHow-To / TutorialRecurring production2,000–4,000 wordsHowTo90-day evaluation
comparisonComparisonRecurring production2,000–4,000 wordsArticle + ItemList or Product90-day evaluation
case_studyCase StudyIrregular, customer-driven1,500–2,500 wordsArticle + ReviewAnnual
pillarPillar / Hub PageOne-time per cluster2,500–4,000 wordsCollectionPageQuarterly
glossaryGlossary / DefinitionOne-time batch500–1,200 wordsDefinedTerm + FAQPageOnly when definitions evolve

2.2 Comparison Sub-Variants

The comparison type covers two structural variants. The Brief Agent specifies which variant applies based on the target keyword.

VariantTrigger KeywordsStructureSchema
Head-to-Head ("vs")"X vs Y", "X alternative", "X compared to Y"Two-option deep comparison with criteria matrixArticle with embedded Product entities using isSimilarTo
Roundup"Best X tools", "Top X for Y", "X options for Y"Multi-option ranked list with per-option sectionsArticle + ItemList with ListItem entries

3. Content Type Template Specifications

Each content type has a required structural scaffold. The Writer Agent must follow this scaffold exactly. The SEO Validation Engine checks structural compliance.

3.1 Blog Post (blog_post)

Purpose: Topical authority pieces targeting informational and commercial-informational keywords. The workhorse content type.

Target length: 1,500–2,500 words

Required structural scaffold:

1# [H1: Title containing primary keyword] 2 3[TL;DR Box: 3-5 bullet point key takeaways in a styled callout. 4 Maps to `speakable` schema. First bullet answers the core question directly. 5 Total length: 80-120 words.] 6 7[Hero image: AI-generated, contextually relevant to topic] 8 9[Opening paragraph: 2-3 sentences. Primary keyword in first sentence. 10 Establishes the problem or question. Hooks the reader.] 11 12## [H2: Section 1 — secondary keyword or subtopic] 13 14[2-4 paragraphs, 200-400 words per section] 15[IMAGE marker if section exceeds 400 words] 16[Internal link within contextual sentence] 17 18## [H2: Section 2] 19... 20 21## [H2: Section N — typically 4-6 H2 sections total] 22 23### [H3 subsections as needed — no H3 without parent H2] 24 25## Frequently Asked Questions 26 27[Minimum 3 Q&A pairs. Questions sourced from PAA extraction data 28 in the content brief. Each answer: 2-4 sentences, concise, 29 citation-ready for AI engines.] 30 31### [Q1: Question text as H3] 32[Answer paragraph] 33 34### [Q2] 35... 36 37## [Closing section: Summary, next steps, or CTA] 38 39[Final paragraph with internal link to related pillar or guide content]

SEO rules specific to blog posts:

  • Internal links: minimum 1 per 400 words, minimum 4 total
  • External links: minimum 1 authoritative source
  • Image density: minimum 3 images (hero + 2 body), 1 per 800 words
  • FAQ: required, minimum 3 Q&A pairs
  • ToC: required if word count exceeds 1,500 words
  • Primary keyword density: 0.8%–2.0%

3.2 Listicle (listicle)

Purpose: High-shareability content targeting "best of," "top N," and curated list queries. Strong for backlink acquisition and social distribution.

Target length: 1,500–3,000 words (scales with list size)

Required structural scaffold:

1# [H1: "N [Noun] for [Audience/Use Case]" or "Top N [Things]"] 2 3[TL;DR Box: Numbered quick-pick list (top 3-5 from the full list) 4 with one-sentence reason per pick. Maps to `speakable`.] 5 6[Hero image] 7 8[Opening paragraph: Why this list matters. What criteria were used. 9 Primary keyword in first sentence.] 10 11## [Table of Contents — auto-generated, anchor-linked] 12 13## [H2: 1. List Item Name] 14 15[Overview paragraph: what it is, why it's on the list] 16[Key details: 2-3 supporting points] 17[Pros/cons or key features if applicable] 18[IMAGE: screenshot, product image, or relevant visual] 19[Internal link if we have related content] 20 21## [H2: 2. List Item Name] 22... 23 24## [H2: N. List Item Name] 25 26## How We Evaluated [Topic] 27 28[Methodology paragraph: explains selection criteria. 29 Builds E-E-A-T credibility. 150-250 words.] 30 31## Frequently Asked Questions 32 33[Minimum 3 Q&A pairs, sourced from PAA data] 34 35### [Q1] 36[Answer] 37 38## Final Thoughts 39 40[Summary with recommendation tiers: 41 "Best overall," "Best for budget," "Best for [use case]"] 42[Internal link to related guide or pillar]

SEO rules specific to listicles:

  • Internal links: minimum 1 per 500 words, minimum 3 total
  • External links: minimum 1 per list item (to the thing being listed, if external)
  • Image density: 1 per list item (minimum), hero image required
  • FAQ: optional but recommended (minimum 3 if included)
  • ToC: required (always exceeds 1,500 words with 5+ items)
  • Primary keyword density: 0.5%–1.5%
  • Each list item H2 must be numbered and descriptively named

3.3 Comprehensive Guide (guide)

Purpose: Pillar-supporting deep-dive content targeting high-volume informational keywords. The authority builder. Designed for AI Overview citation eligibility.

Target length: 3,000–5,000 words

Required structural scaffold:

1# [H1: "The Complete Guide to [Topic]" or "[Topic]: Everything You Need to Know"] 2 3[TL;DR Box: 5-7 bullet point key takeaways. First bullet is a 4 one-sentence definition or core answer. Maps to `speakable`. 5 Total length: 100-150 words.] 6 7[Hero image] 8 9[Opening paragraph: Defines the topic. States why it matters now. 10 Primary keyword in first sentence. Author credibility signal 11 ("Based on our experience building Consul..." or similar).] 12 13## Table of Contents 14[Auto-generated, anchor-linked, levels H2 and H3] 15 16## What Is [Topic]? 17 18[Definition section: 2-3 paragraphs. First paragraph is a 19 citation-ready definition (2-3 sentences, under 60 words, 20 designed to be extractable by AI engines and featured snippets). 21 Remaining paragraphs expand with context.] 22[IMAGE: explanatory diagram or visual] 23 24## Why [Topic] Matters [for Audience] 25 26[Problem/opportunity framing. 200-400 words. 27 Statistics and citations from brief's external resources.] 28 29## [H2: Core Concept Section 1] 30 31### [H3: Subtopic A] 32[200-300 words per H3] 33[Internal link] 34 35### [H3: Subtopic B] 36[IMAGE if section exceeds 600 words without one] 37 38## [H2: Core Concept Section 2] 39... 40 41## [H2: Core Concept Section N — typically 5-8 H2 sections] 42 43## How to Get Started with [Topic] 44 45[Actionable next steps. 3-5 numbered steps. 46 Internal links to how-to content or product.] 47 48## Frequently Asked Questions 49 50[Minimum 5 Q&A pairs for guides. Sourced from PAA data. 51 Answers are concise and citation-ready.] 52 53### [Q1: Question] 54[Answer: 2-4 sentences] 55... 56 57## Conclusion 58 59[Summary paragraph. Internal link to pillar page. 60 CTA: "Learn more about how Consul handles [topic]" or similar.]

SEO rules specific to guides:

  • Internal links: minimum 1 per 300 words, minimum 8 total
  • External links: minimum 3 authoritative sources with citations
  • Image density: minimum 5 images, 1 per 700 words
  • FAQ: required, minimum 5 Q&A pairs
  • ToC: required (always exceeds 1,500 words)
  • Primary keyword density: 0.5%–1.5%
  • Must contain at least one citation-ready definition block (under 60 words, standalone paragraph)
  • H3 sections required under at least 3 H2 sections

3.4 How-To / Tutorial (how_to)

Purpose: Step-by-step instructional content targeting "how to" queries. Highest schema richness (HowTo markup). Strong featured snippet and AI Overview candidate.

Target length: 2,000–4,000 words

Required structural scaffold:

1# [H1: "How to [Action] [with/for Context]"] 2 3[TL;DR Box: Numbered quick-step summary (abbreviated version 4 of the full steps, 1 sentence each). Maps to `speakable`. 5 Total length: 80-120 words.] 6 7[Hero image: shows the end result or the process overview] 8 9[Opening paragraph: What you'll learn. What you'll need. 10 Expected time/difficulty. Primary keyword in first sentence.] 11 12## What You'll Need (Prerequisites) 13 14[Bulleted list of requirements, tools, or knowledge needed. 15 Keep concise — each item 1 sentence max.] 16 17## Table of Contents 18 19## [H2: Step 1 — Action Verb + Description] 20 21[Detailed instructions for this step. 200-400 words. 22 Sub-steps as H3 if this step has multiple parts.] 23[IMAGE: screenshot or visual showing this step] 24[Pro tip or common mistake callout if applicable] 25 26## [H2: Step 2 — Action Verb + Description] 27... 28 29## [H2: Step N] 30 31## Troubleshooting Common Issues 32 33[3-5 common problems with solutions. 34 Each as H3 under this section. 35 Targets "why isn't [thing] working" PAA queries.] 36 37### [Problem 1] 38[Solution: 2-3 sentences] 39 40## Frequently Asked Questions 41 42[Minimum 3 Q&A pairs sourced from PAA data] 43 44## What's Next? 45 46[Next steps after completing the tutorial. 47 Internal links to advanced content or related guides. 48 CTA to Consul if applicable.]

SEO rules specific to how-tos:

  • Internal links: minimum 1 per 400 words, minimum 5 total
  • External links: minimum 1 (tool or resource referenced in steps)
  • Image density: minimum 1 per step, minimum 4 total (hero + step images)
  • FAQ: required, minimum 3 Q&A pairs
  • Troubleshooting section: required
  • ToC: required
  • Primary keyword density: 0.8%–2.0%
  • Every step H2 must begin with an action verb
  • HowTo schema: every step must map to a HowToStep with name, text, and image

3.5 Comparison (comparison)

Purpose: Decision-stage content targeting commercial and transactional keywords. Two sub-variants: head-to-head (vs) and roundup. Critical for bottom-funnel capture.

Target length: 2,000–4,000 words

3.5.1 Head-to-Head Variant

Required structural scaffold:

1# [H1: "[Product A] vs [Product B]: [Differentiator or Audience Context]"] 2 3[TL;DR Box: Quick verdict (3-4 sentences). 4 "Choose [A] if you need X. Choose [B] if you need Y." 5 Maps to `speakable`.] 6 7[Hero image: side-by-side visual or comparison graphic] 8 9[Opening paragraph: Why this comparison matters. 10 Who should read this. Primary keyword in first sentence.] 11 12## Quick Comparison Table 13 14[Feature comparison table with rows for key criteria 15 and columns for Product A, Product B, and "Winner" or "Best For". 16 This table maps to structured data and is a featured snippet target.] 17 18## Table of Contents 19 20## [H2: Product A] Overview 21 22[200-300 word overview. What it is, who it's for, key strengths.] 23[IMAGE: product screenshot or logo] 24 25## [H2: Product B] Overview 26 27[Same structure as Product A] 28 29## [H2: Comparison Criterion 1 — e.g., "Ease of Use"] 30 31[Head-to-head analysis for this criterion. 32 Specific examples, not vague claims. 33 Verdict sentence at end of section.] 34 35## [H2: Comparison Criterion 2] 36... 37 38## [H2: Comparison Criterion N — typically 4-6 criteria] 39 40## Pricing Comparison 41 42[Side-by-side pricing with plan details. 43 Value-for-money analysis, not just numbers.] 44 45## Our Verdict 46 47[3-4 paragraphs. Recommendation segmented by use case. 48 "For [use case A], choose [Product]. For [use case B], choose [other]." 49 Internal link to Consul if we're one of the compared products.] 50 51## Frequently Asked Questions 52 53[Minimum 3 Q&A pairs. Target "is [A] better than [B]" style queries.]

3.5.2 Roundup Variant

Uses the same scaffold as the Listicle type (Section 3.2) but with comparison-specific language: criteria matrix at top, per-option deep dives, and a verdict section instead of "Final Thoughts." Schema uses ItemList with ListItem entries.

SEO rules specific to comparisons:

  • Internal links: minimum 1 per 400 words, minimum 4 total
  • External links: minimum 1 per product compared (to their homepage or pricing page)
  • Image density: minimum 1 per product compared, plus hero and comparison table
  • FAQ: required, minimum 3 Q&A pairs
  • Comparison table: required (featured snippet target)
  • ToC: required
  • Primary keyword density: 0.5%–1.5%
  • Products must be described with specific, verifiable details (no vague claims)

3.6 Case Study (case_study)

Purpose: Social proof and trust-building content. Demonstrates real results from Consul users. Lower SEO volume value but critical for conversion and E-E-A-T.

Target length: 1,500–2,500 words

Required structural scaffold:

1# [H1: "How [Customer/Company] [Achieved Outcome] with Consul"] 2 3[Results Box: 3 key metrics in a styled callout. 4 e.g., "50% reduction in email time | 3 hours saved daily | 2x meeting efficiency" 5 Maps to `speakable`.] 6 7[Hero image: customer headshot or company logo with context] 8 9[Opening paragraph: One-sentence hook with the key result. 10 Customer context (industry, size, role). Primary keyword.] 11 12## The Challenge 13 14[What problem was the customer facing? 15 Specific pain points. Quantify where possible. 16 200-300 words.] 17 18## Why They Chose Consul 19 20[Decision process. What alternatives were considered. 21 What made Consul the choice. 150-250 words.] 22 23## The Solution 24 25[How Consul was implemented. Specific features used. 26 Timeline. 200-400 words.] 27[IMAGE: workflow diagram or product screenshot in context] 28 29## The Results 30 31[Quantified outcomes. Before/after comparisons. 32 Each result as a sub-section or bold callout. 33 300-500 words.] 34 35### [Result 1: Metric + Context] 36### [Result 2] 37### [Result 3] 38 39## [Customer Name]'s Perspective 40 41[Direct quote from the customer. 2-4 sentences. 42 This maps to `Review` schema.] 43 44## Key Takeaways 45 46[3-5 bullet points summarizing lessons. 47 Generalizable insights, not just product promotion.] 48 49[CTA: "See how Consul can help your team" + internal link]

SEO rules specific to case studies:

  • Internal links: minimum 3 (to product, related guide, and pillar)
  • External links: link to customer's website (with their permission)
  • Image density: minimum 3 (hero, solution diagram, results chart)
  • FAQ: not required
  • ToC: optional (most case studies are under 2,500 words)
  • Primary keyword density: 0.3%–1.0% (lower — these are narrative, not keyword-driven)
  • Must contain at least one direct customer quote
  • Must contain at least 2 quantified results

3.7 Pillar / Hub Page (pillar)

Purpose: Cluster parent page that links to all child content within a topic pillar. The topical authority anchor. Optimized for broad, high-volume keywords.

Target length: 2,500–4,000 words

Build pattern: One-time build per topic cluster. Updated quarterly or when new child content is published (add link to new child page).

Required structural scaffold:

1# [H1: "[Topic]: The Complete Resource"] 2 3[TL;DR Box: 5-7 bullet takeaways covering the full topic scope. 4 Maps to `speakable`. 100-150 words.] 5 6[Hero image] 7 8[Opening paragraph: Broad topic definition. Why it matters. 9 Audience framing. Primary keyword in first sentence. 10 Author credibility signal.] 11 12## Table of Contents 13[Anchor-linked, H2 and H3 levels] 14 15## What Is [Topic]? 16 17[Foundational definition section. 300-500 words. 18 Citation-ready definition in first paragraph. 19 IMAGE: concept diagram or overview visual] 20 21## [H2: Subtopic Cluster 1 — e.g., "Email Management"] 22 23[Overview paragraph: 150-250 words. Covers the subtopic broadly. 24 Does NOT go deep — that's what child content does.] 25 26**Key resources:** 27[Internal links to 3-5 child content pieces in this subtopic. 28 Each link has a one-sentence description. 29 These are the cluster links that build topical authority.] 30 31### [H3: Key concept within this subtopic — brief coverage] 32 33## [H2: Subtopic Cluster 2] 34... 35 36## [H2: Subtopic Cluster N — typically 4-7 clusters] 37 38## How to Get Started 39 40[Practical entry point. 200-300 words. 41 Links to beginner-level child content.] 42 43## Frequently Asked Questions 44 45[Minimum 5 Q&A pairs covering the broad topic. 46 These are GLOBAL FAQs about the topic, not piece-specific.] 47 48## Related Resources 49 50[Curated list of 5-10 most important child pages 51 organized by audience need or experience level.]

SEO rules specific to pillar pages:

  • Internal links: minimum 15 (this is the linking hub — every child page must be linked)
  • External links: minimum 3 authoritative sources
  • Image density: minimum 4 (hero, concept diagram, 2+ section images)
  • FAQ: required, minimum 5 Q&A pairs (global/topic-level FAQs)
  • ToC: required
  • Primary keyword density: 0.5%–1.0%
  • Every H2 subtopic section must contain at least 2 internal links to child content
  • Page must be updated when new child content is published in the cluster
  • CollectionPage schema with hasPart referencing all child pages

3.8 Glossary / Definition Page (glossary)

Purpose: Targets "what is [term]" queries. Designed for featured snippet capture, AI Overview citation, and voice search. Builds topical authority at the concept level.

Target length: 500–1,200 words

Build pattern: Batch build (20-40 terms initially), then add terms as new concepts emerge. Refresh only when definitions evolve.

Required structural scaffold:

1# [H1: "What Is [Term]? Definition, Examples & Guide"] 2 3[Definition Box: 1-2 sentence definition in a styled callout. 4 Under 50 words. Optimized for featured snippet extraction 5 and AI Overview citation. Maps to `speakable`.] 6 7[Hero image: conceptual visual for the term] 8 9[Opening paragraph: Expanded definition. 3-4 sentences. 10 Primary keyword in first sentence. 11 "In the context of [domain]..." framing.] 12 13## How [Term] Works 14 15[Explanation section. 200-400 words. 16 Practical, concrete explanation. 17 Example or analogy included.] 18[IMAGE: diagram or visual explanation] 19 20## Why [Term] Matters 21 22[Business value / relevance. 150-250 words. 23 Connects to the reader's context.] 24 25## [Term] Examples 26 27[2-3 concrete examples with brief descriptions. 28 100-200 words total.] 29 30## [Term] vs [Related Term] 31 32[If a commonly confused related term exists. 33 Brief comparison. 100-200 words. 34 Internal link to the related term's glossary page.] 35 36## Frequently Asked Questions 37 38[Minimum 3 Q&A pairs. Target PAA queries. 39 "Is [term] the same as [other term]?" 40 "Who uses [term]?" etc.] 41 42## Related Terms 43 44[List of 3-5 related glossary terms as internal links. 45 Builds the glossary cross-linking mesh.] 46 47## Learn More 48 49[Internal link to the relevant guide or pillar page.]

SEO rules specific to glossary pages:

  • Internal links: minimum 5 (related terms + parent guide/pillar)
  • External links: minimum 1 authoritative definition source
  • Image density: minimum 2 (hero + explanatory diagram)
  • FAQ: required, minimum 3 Q&A pairs
  • ToC: not required (pages are short)
  • Primary keyword density: 1.0%–2.5%
  • Must contain a citation-ready definition block (under 50 words, standalone paragraph in callout)
  • DefinedTerm schema is required
  • speakable must point to the definition box

4. JSON-LD Schema Library

Every page published by ContentEngine carries structured JSON-LD markup in the <head>. Schema is generated programmatically from content metadata and template structure — not manually authored. The CMS (Next.js + Supabase) injects schema at render time.

4.1 Schema Architecture

Each page carries a @graph array containing multiple schema entities. This is the Google-recommended approach for complex pages.

Base graph (present on every page):

1{ 2 "@context": "https://schema.org", 3 "@graph": [ 4 { "@type": "Organization", ... }, 5 { "@type": "WebSite", ... }, 6 { "@type": "WebPage", ... }, 7 { "@type": "[ContentTypeSchema]", ... }, 8 { "@type": "Person", ... }, 9 { "@type": "BreadcrumbList", ... } 10 ] 11}

4.2 Organization Entity (Global — Every Page)

This entity is configured once in system settings and injected on every page via the publisher property.

1{ 2 "@type": "Organization", 3 "@id": "https://consul.ai/#organization", 4 "name": "[PLACEHOLDER: Legal entity name]", 5 "alternateName": "Consul", 6 "url": "https://consul.ai", 7 "logo": { 8 "@type": "ImageObject", 9 "@id": "https://consul.ai/#logo", 10 "url": "https://consul.ai/images/logo.png", 11 "contentUrl": "https://consul.ai/images/logo.png", 12 "width": "[PLACEHOLDER]", 13 "height": "[PLACEHOLDER]", 14 "caption": "Consul - AI Executive Assistant" 15 }, 16 "image": { "@id": "https://consul.ai/#logo" }, 17 "description": "Consul is a trust-first AI executive assistant that closes coordination loops across email, calendar, and messaging.", 18 "foundingDate": "[PLACEHOLDER: YYYY]", 19 "numberOfEmployees": { 20 "@type": "QuantitativeValue", 21 "value": "[PLACEHOLDER]" 22 }, 23 "sameAs": [ 24 "[PLACEHOLDER: LinkedIn URL]", 25 "[PLACEHOLDER: Twitter/X URL]", 26 "[PLACEHOLDER: YouTube URL if applicable]" 27 ], 28 "contactPoint": { 29 "@type": "ContactPoint", 30 "contactType": "customer support", 31 "email": "[PLACEHOLDER: support email]" 32 } 33}

Action item: Fill in all PLACEHOLDER values before first publication. Store these in a site_config table in Supabase, not hardcoded.

4.3 WebSite Entity (Global — Every Page)

1{ 2 "@type": "WebSite", 3 "@id": "https://consul.ai/#website", 4 "url": "https://consul.ai", 5 "name": "Consul", 6 "description": "AI Executive Assistant for CEOs and Founders", 7 "publisher": { "@id": "https://consul.ai/#organization" }, 8 "inLanguage": "en-US" 9}

4.4 Author Entities

Three author entities are defined. Each maps to a dedicated author profile page on the site.

4.4.1 Alton Wells

1{ 2 "@type": "Person", 3 "@id": "https://consul.ai/authors/alton-wells/#person", 4 "name": "Alton Wells", 5 "url": "https://consul.ai/authors/alton-wells/", 6 "image": { 7 "@type": "ImageObject", 8 "url": "https://consul.ai/images/authors/alton-wells.jpg", 9 "caption": "Alton Wells" 10 }, 11 "jobTitle": "[PLACEHOLDER: Title]", 12 "worksFor": { "@id": "https://consul.ai/#organization" }, 13 "knowsAbout": [ 14 "AI executive assistants", 15 "email automation", 16 "calendar management", 17 "AI delegation", 18 "productivity systems", 19 "SaaS product development" 20 ], 21 "sameAs": [ 22 "[PLACEHOLDER: LinkedIn URL]", 23 "[PLACEHOLDER: Twitter/X URL]", 24 "[PLACEHOLDER: Personal site URL if applicable]" 25 ], 26 "description": "[PLACEHOLDER: 1-2 sentence bio for schema]" 27}

4.4.2 Stan [Last Name]

Same structure as Alton. All PLACEHOLDER fields must be filled per individual.

1{ 2 "@type": "Person", 3 "@id": "https://consul.ai/authors/stan//#person", 4 "name": "Stan [PLACEHOLDER: Last Name]", 5 "url": "https://consul.ai/authors/stan/", 6 "image": { ... }, 7 "jobTitle": "[PLACEHOLDER]", 8 "worksFor": { "@id": "https://consul.ai/#organization" }, 9 "knowsAbout": [ ... ], 10 "sameAs": [ ... ], 11 "description": "[PLACEHOLDER]" 12}

4.4.3 Auctor (AI Editorial Author)

Auctor is presented transparently as an AI editorial assistant. The profile and schema reflect this.

1{ 2 "@type": "Person", 3 "@id": "https://consul.ai/authors/auctor/#person", 4 "name": "Auctor", 5 "url": "https://consul.ai/authors/auctor/", 6 "image": { 7 "@type": "ImageObject", 8 "url": "https://consul.ai/images/authors/auctor.jpg", 9 "caption": "Auctor - Consul Editorial AI" 10 }, 11 "jobTitle": "AI Editorial Assistant", 12 "worksFor": { "@id": "https://consul.ai/#organization" }, 13 "knowsAbout": [ 14 "AI productivity tools", 15 "email management", 16 "scheduling automation", 17 "executive workflows", 18 "content research" 19 ], 20 "description": "Auctor is Consul's AI editorial assistant. Articles by Auctor are researched and drafted using AI, then reviewed, enriched with original insights, and approved by Alton Wells or Stan before publication." 21}

4.5 Author Profile Page Specification

Each of the three authors has a dedicated page at /authors/[slug]/. These pages are critical for E-E-A-T signals.

Required content blocks per author profile page:

  1. Hero section: Headshot (or avatar for Auctor), full name, title, one-line tagline
  2. Bio section: 2-3 paragraphs covering credentials, expertise areas, and connection to Consul. For Auctor, this section transparently describes the human-AI editorial process: "Articles by Auctor are researched and drafted using AI, then reviewed and enriched by [Alton/Stan] before publication. Every piece undergoes human editorial review, fact-checking, and the addition of original experience and insights."
  3. Expertise tags: Visual display of knowsAbout topics as clickable tags linking to relevant pillar pages
  4. Social links: All sameAs URLs displayed as icons
  5. Recent articles: Dynamic feed of the 10 most recent articles by this author, pulled from our_pages table filtered by author_id
  6. Article count and topic breakdown: "X articles published across [topics]"

Schema on author profile page:

1{ 2 "@context": "https://schema.org", 3 "@graph": [ 4 { "@type": "ProfilePage", ... }, 5 { "@type": "Person", ... (full entity from above) }, 6 { "@type": "Organization", ... }, 7 { "@type": "BreadcrumbList", ... } 8 ] 9}

4.6 Content Type Schema Mapping

4.6.1 Blog Post Schema

1{ 2 "@type": "BlogPosting", 3 "@id": "https://consul.ai/blog/[slug]/#article", 4 "headline": "[meta title]", 5 "name": "[H1 title]", 6 "description": "[meta description]", 7 "datePublished": "[ISO 8601]", 8 "dateModified": "[ISO 8601]", 9 "author": { "@id": "https://consul.ai/authors/[author-slug]/#person" }, 10 "publisher": { "@id": "https://consul.ai/#organization" }, 11 "mainEntityOfPage": { "@id": "https://consul.ai/blog/[slug]/" }, 12 "image": { 13 "@type": "ImageObject", 14 "url": "[hero image URL]", 15 "width": "[width]", 16 "height": "[height]" 17 }, 18 "wordCount": "[actual word count]", 19 "articleSection": "[topic cluster name]", 20 "keywords": "[primary keyword, secondary keyword 1, secondary keyword 2]", 21 "inLanguage": "en-US", 22 "isPartOf": { "@id": "https://consul.ai/#website" }, 23 "about": [ 24 { 25 "@type": "Thing", 26 "name": "[primary topic]", 27 "sameAs": "[Wikipedia URL if applicable]" 28 } 29 ], 30 "speakable": { 31 "@type": "SpeakableSpecification", 32 "cssSelector": [".tldr-box", ".article-headline"] 33 } 34}

Additional schema when FAQ section is present:

1{ 2 "@type": "FAQPage", 3 "@id": "https://consul.ai/blog/[slug]/#faq", 4 "mainEntity": [ 5 { 6 "@type": "Question", 7 "name": "[Question text]", 8 "acceptedAnswer": { 9 "@type": "Answer", 10 "text": "[Answer text]" 11 } 12 } 13 ] 14}

4.6.2 Guide Schema

Uses Article (not BlogPosting) with articleBody scope and richer hasPart for section structure:

1{ 2 "@type": "Article", 3 "@id": "https://consul.ai/guides/[slug]/#article", 4 "headline": "...", 5 "datePublished": "...", 6 "dateModified": "...", 7 "author": { "@id": "..." }, 8 "publisher": { "@id": "..." }, 9 "wordCount": "...", 10 "speakable": { 11 "@type": "SpeakableSpecification", 12 "cssSelector": [".tldr-box", ".definition-box", ".article-headline"] 13 }, 14 "hasPart": [ 15 { 16 "@type": "WebPageElement", 17 "name": "[H2 section title]", 18 "cssSelector": "#[section-anchor-id]" 19 } 20 ] 21}

Guides always carry FAQPage schema (minimum 5 Q&A pairs).

4.6.3 How-To Schema

This is the richest single-page schema. Every step maps to a HowToStep.

1{ 2 "@type": "HowTo", 3 "@id": "https://consul.ai/tutorials/[slug]/#howto", 4 "name": "[H1 title]", 5 "description": "[meta description]", 6 "datePublished": "...", 7 "dateModified": "...", 8 "author": { "@id": "..." }, 9 "publisher": { "@id": "..." }, 10 "totalTime": "PT[estimated minutes]M", 11 "estimatedCost": { 12 "@type": "MonetaryAmount", 13 "currency": "USD", 14 "value": "0" 15 }, 16 "supply": [], 17 "tool": [ 18 { 19 "@type": "HowToTool", 20 "name": "[tool from prerequisites section]" 21 } 22 ], 23 "step": [ 24 { 25 "@type": "HowToStep", 26 "name": "[Step H2 title]", 27 "text": "[Step content — first paragraph only for schema]", 28 "url": "https://consul.ai/tutorials/[slug]/#step-1", 29 "image": { 30 "@type": "ImageObject", 31 "url": "[step image URL]" 32 } 33 } 34 ], 35 "speakable": { 36 "@type": "SpeakableSpecification", 37 "cssSelector": [".tldr-box", ".article-headline"] 38 } 39}

How-Tos always carry FAQPage schema (minimum 3 Q&A pairs).

4.6.4 Listicle Schema

1{ 2 "@type": "Article", 3 "@id": "https://consul.ai/blog/[slug]/#article", 4 "headline": "...", 5 "author": { "@id": "..." }, 6 "publisher": { "@id": "..." }, 7 "datePublished": "...", 8 "dateModified": "...", 9 "speakable": { ... } 10}

Plus ItemList for the ranked items:

1{ 2 "@type": "ItemList", 3 "@id": "https://consul.ai/blog/[slug]/#list", 4 "name": "[H1 title]", 5 "numberOfItems": "[count]", 6 "itemListOrder": "https://schema.org/ItemListOrderDescending", 7 "itemListElement": [ 8 { 9 "@type": "ListItem", 10 "position": 1, 11 "name": "[Item name]", 12 "url": "[external URL to the item, or anchor link to section]" 13 } 14 ] 15}

4.6.5 Comparison Schema (Head-to-Head)

Uses Article as the base, with embedded Product entities connected via isSimilarTo:

1{ 2 "@type": "Article", 3 "headline": "...", 4 "author": { "@id": "..." }, 5 "mentions": [ 6 { 7 "@type": "SoftwareApplication", 8 "@id": "#product-a", 9 "name": "[Product A]", 10 "applicationCategory": "BusinessApplication", 11 "operatingSystem": "[platforms]", 12 "url": "[product URL]", 13 "isSimilarTo": { "@id": "#product-b" } 14 }, 15 { 16 "@type": "SoftwareApplication", 17 "@id": "#product-b", 18 "name": "[Product B]", 19 "applicationCategory": "BusinessApplication", 20 "url": "[product URL]", 21 "isSimilarTo": { "@id": "#product-a" } 22 } 23 ] 24}

When Consul is one of the compared products, add offers and aggregateRating (when available from third-party platforms):

1{ 2 "@type": "SoftwareApplication", 3 "name": "Consul", 4 "applicationCategory": "BusinessApplication", 5 "operatingSystem": "Web, iOS", 6 "offers": { 7 "@type": "Offer", 8 "price": "200.00", 9 "priceCurrency": "USD", 10 "priceValidUntil": "[YYYY-MM-DD]", 11 "availability": "https://schema.org/OnlineOnly" 12 } 13}

Note: aggregateRating is deferred until third-party review platforms (G2, Capterra) are set up. The schema hook is defined here; the data will be populated when available. On-site testimonials use individual Review schema (see Case Study below), not aggregateRating.

4.6.6 Comparison Schema (Roundup)

Same as Listicle (Article + ItemList) with itemListElement entries linking to each reviewed product.

4.6.7 Case Study Schema

1{ 2 "@type": "Article", 3 "@id": "https://consul.ai/case-studies/[slug]/#article", 4 "headline": "...", 5 "author": { "@id": "..." }, 6 "publisher": { "@id": "..." }, 7 "datePublished": "...", 8 "dateModified": "...", 9 "about": { 10 "@type": "SoftwareApplication", 11 "name": "Consul", 12 "@id": "https://consul.ai/#software" 13 }, 14 "speakable": { 15 "@type": "SpeakableSpecification", 16 "cssSelector": [".results-box", ".article-headline"] 17 } 18}

Plus Review schema from the customer quote:

1{ 2 "@type": "Review", 3 "@id": "https://consul.ai/case-studies/[slug]/#review", 4 "author": { 5 "@type": "Person", 6 "name": "[Customer name]", 7 "jobTitle": "[Customer title]", 8 "worksFor": { 9 "@type": "Organization", 10 "name": "[Customer company]" 11 } 12 }, 13 "reviewBody": "[Customer quote text]", 14 "itemReviewed": { 15 "@type": "SoftwareApplication", 16 "name": "Consul", 17 "@id": "https://consul.ai/#software" 18 } 19}

4.6.8 Pillar Page Schema

1{ 2 "@type": "CollectionPage", 3 "@id": "https://consul.ai/topics/[slug]/#page", 4 "name": "[H1 title]", 5 "description": "[meta description]", 6 "author": { "@id": "..." }, 7 "publisher": { "@id": "..." }, 8 "datePublished": "...", 9 "dateModified": "...", 10 "mainEntity": { 11 "@type": "Thing", 12 "name": "[Topic name]", 13 "description": "[Topic definition]" 14 }, 15 "hasPart": [ 16 { 17 "@type": "WebPage", 18 "name": "[Child page title]", 19 "url": "[Child page URL]" 20 } 21 ], 22 "speakable": { 23 "@type": "SpeakableSpecification", 24 "cssSelector": [".tldr-box", ".article-headline"] 25 } 26}

hasPart is dynamically populated from the content relationship graph — all pages with a child_of edge pointing to this pillar's topic cluster are included.

4.6.9 Glossary Page Schema

1{ 2 "@type": "DefinedTerm", 3 "@id": "https://consul.ai/glossary/[slug]/#term", 4 "name": "[Term]", 5 "description": "[Definition from definition box — under 50 words]", 6 "inDefinedTermSet": { 7 "@type": "DefinedTermSet", 8 "name": "Consul Glossary", 9 "url": "https://consul.ai/glossary/" 10 } 11}

Plus FAQPage schema for the FAQ section, and Article as the base content type.

speakable points to the definition box CSS selector.

4.7 BreadcrumbList Schema (Global — Every Page)

Generated dynamically from the URL path. Present on every page.

1{ 2 "@type": "BreadcrumbList", 3 "@id": "https://consul.ai/[path]/#breadcrumb", 4 "itemListElement": [ 5 { 6 "@type": "ListItem", 7 "position": 1, 8 "name": "Home", 9 "item": "https://consul.ai/" 10 }, 11 { 12 "@type": "ListItem", 13 "position": 2, 14 "name": "[Section]", 15 "item": "https://consul.ai/[section]/" 16 }, 17 { 18 "@type": "ListItem", 19 "position": 3, 20 "name": "[Page Title]", 21 "item": "https://consul.ai/[section]/[slug]/" 22 } 23 ] 24}

4.8 SoftwareApplication Schema (Consul Product Entity)

This entity represents the Consul product itself. Referenced by case studies, comparisons, and product-adjacent content.

1{ 2 "@type": "SoftwareApplication", 3 "@id": "https://consul.ai/#software", 4 "name": "Consul", 5 "description": "AI executive assistant that manages email, calendar, and scheduling for CEOs and founders.", 6 "applicationCategory": "BusinessApplication", 7 "operatingSystem": "Web, iOS", 8 "url": "https://consul.ai", 9 "offers": { 10 "@type": "AggregateOffer", 11 "lowPrice": "50.00", 12 "highPrice": "200.00", 13 "priceCurrency": "USD", 14 "offerCount": 2, 15 "offers": [ 16 { 17 "@type": "Offer", 18 "name": "Founding Member", 19 "price": "50.00", 20 "priceCurrency": "USD", 21 "availability": "https://schema.org/LimitedAvailability", 22 "description": "Lifetime founding member discount" 23 }, 24 { 25 "@type": "Offer", 26 "name": "Standard", 27 "price": "200.00", 28 "priceCurrency": "USD", 29 "availability": "https://schema.org/OnlineOnly" 30 } 31 ] 32 }, 33 "creator": { "@id": "https://consul.ai/#organization" }, 34 "featureList": [ 35 "Automated email triage and drafting", 36 "AI-powered scheduling and calendar management", 37 "Daily briefings via email and iMessage", 38 "Multi-interface access (Web, Email, iMessage)", 39 "24/7 automated workflows" 40 ] 41}

4.9 Speakable Implementation

The speakable property identifies content sections most relevant for text-to-speech and AI extraction. It is not visually rendered — it is encoded in schema only.

CSS selectors referenced by speakable must exist in the page markup:

SelectorMaps ToPresent On
.tldr-boxTL;DR / Key Takeaways callout boxBlog, listicle, guide, how-to, pillar
.definition-boxDefinition callout (under 50/60 words)Guide, glossary
.results-boxKey metrics calloutCase study
.article-headlineH1 elementAll content types
.comparison-tableQuick comparison tableComparison (head-to-head)

The Writer Agent outputs these as markdown callout blocks. The CMS renderer maps them to the correct HTML elements with the specified CSS classes.


5. Refresh Queue System

5.1 Design Principles

Every piece of content is re-evaluated on a maximum 90-day cycle. Re-evaluation does NOT mean automatic refresh — it means the system scores refresh urgency and only pieces crossing a threshold enter the active refresh queue. High-performing content gets its next evaluation pushed out (up to 150 days). The goal is ensuring every published page is either performing well or actively being improved.

5.2 Refresh Urgency Score

Each page receives a composite urgency score calculated from five weighted signals. Score range: 0-100.

SignalWeightData SourceScoring Logic
Position Decay30%GSC our_page_performanceScore = (position drop over trailing 30 days / 10) × 100, capped at 100. A 5-position drop = 50. No drop = 0.
Traffic Decline25%GSC our_page_performanceScore = (% impression decline, trailing 30d vs prior 30d) × 100, capped at 100. 40% decline = 40. Growth = 0.
Content Age20%our_pages.last_updated / dateModifiedScore = (days since last update / 90) × 100, capped at 100. 90+ days = 100. Just updated = 0.
Competitive Displacement15%Graph outperforms edges, competitor_changesScore = count of new/worsened outperforms edges for this page's target keyword × 25, capped at 100.
Factual Staleness10%our_page_extractions (claim entities with dated statistics)Score = (count of claims referencing years older than current year / total claims) × 100.

Composite urgency score = weighted sum of all five signals.

5.3 Refresh Thresholds and Evaluation Scheduling

Urgency ScoreActionNext Evaluation
0–25No action. Content is performing well.Push to 150 days from now
26–50Flag for monitoring. Surface in dashboard as "watch list."Re-evaluate in 60 days
51–70Queue for light refresh.After refresh completes
71–85Queue for moderate refresh.After refresh completes
86–100Queue for heavy refresh. Prioritize immediately.After refresh completes

5.4 Refresh Tiers

TierScopeBrief Required?Writer Agent InstructionsEstimated Human Review Time
LightUpdate statistics, fix broken links, update dateModified, refresh any outdated claims. No structural changes.No brief. Agent receives the page + extraction data showing stale claims."Update the following factual claims with current data. Fix any broken links. Do not change structure, tone, or headings."5 minutes
ModerateRestructure sections, add new content informed by competitive changes, update schema, add/improve FAQ with current PAA data.Abbreviated brief (outline changes only, not full brief)."Apply the following structural changes to the existing content. Add the following new sections. Update FAQ with these questions."15 minutes
HeavyNear-complete rewrite triggered by major rank collapse, topic shift, or competitive leapfrog.Full brief (same as new content).Same as new content creation — full Writer Agent pass.20-30 minutes (same as new content)

5.5 Calendar Integration

Refreshes are mixed into the content calendar at a 70/30 ratio (new content / refreshes). The Strategy Agent manages this allocation.

Rules:

  • The Strategy Agent sees the refresh queue as a prioritized list alongside new content opportunities.
  • When planning a production cycle, the agent allocates approximately 70% of capacity slots to new content and 30% to refreshes.
  • Refresh items are sorted by urgency score (highest first).
  • Light refreshes consume 0.25 capacity units (minimal human review). Moderate refreshes consume 0.5 units. Heavy refreshes consume 1.0 units (same as new content).
  • As the content library grows, the ratio naturally shifts — more pages means more refresh candidates. The 70/30 is a starting target; the Strategy Agent can adjust based on queue depth.
  • If the refresh queue is empty or all scores are below threshold, 100% of capacity goes to new content.

5.6 Refresh Tracking Schema

1CREATE TABLE refresh_evaluations ( 2 id UUID PRIMARY KEY DEFAULT gen_random_uuid(), 3 page_id UUID NOT NULL REFERENCES our_pages(id), 4 evaluated_at TIMESTAMP DEFAULT now(), 5 urgency_score FLOAT NOT NULL, 6 position_decay_score FLOAT NOT NULL, 7 traffic_decline_score FLOAT NOT NULL, 8 content_age_score FLOAT NOT NULL, 9 competitive_displacement_score FLOAT NOT NULL, 10 factual_staleness_score FLOAT NOT NULL, 11 action_taken VARCHAR(20) NOT NULL, -- 'none', 'watch', 'light', 'moderate', 'heavy' 12 next_evaluation_date DATE NOT NULL, 13 refresh_plan_item_id UUID REFERENCES content_plan_items(id), -- links to the refresh work item if queued 14 notes TEXT 15); 16 17CREATE INDEX idx_refresh_page ON refresh_evaluations(page_id); 18CREATE INDEX idx_refresh_next ON refresh_evaluations(next_evaluation_date);

When a refresh is queued, a content_plan_items row is created with a new status enum value:

1ALTER TYPE content_plan_item_status ADD VALUE 'refresh_light'; 2ALTER TYPE content_plan_item_status ADD VALUE 'refresh_moderate'; 3ALTER TYPE content_plan_item_status ADD VALUE 'refresh_heavy';

This integrates refreshes into the existing calendar UI and workflow pipeline.

5.7 Refresh-Specific SEO Rules

When a page is refreshed, the following SEO requirements apply:

  • dateModified in schema MUST be updated to the refresh publication date.
  • datePublished MUST remain the original publication date (never change).
  • The URL/slug MUST NOT change. If a slug change is absolutely necessary (rare), a 301 redirect from old to new URL must be created and the validation engine must verify the redirect is in place.
  • The canonical URL must remain the same page URL.
  • All existing internal links pointing TO this page from other pages must be verified (the Publishing Agent checks inbound links_to graph edges).
  • If the refresh adds new sections, the Publishing Agent must run the should_link_to analysis to identify existing pages that should link to the refreshed page's new content.
  • After refresh publication, the same post-publish pipeline fires: LangExtract re-extraction, summary regeneration, graph edge rebuild.

6. SEO Validation Engine v2

6.1 Architecture Overview

The validation engine runs as deterministic code — no LLM involved. It operates like a CI/CD deployment gate: every content piece must pass all BLOCKING checks before publication. WARNING and INFO checks are logged, tracked, and surfaced in the dashboard but do not block publication.

6.2 Severity Tiers

TierBehaviorAnalogy
BLOCKINGPublication halted. Auto-fix attempted (max 3 cycles). If still failing, escalate to human with specific failure report.Failing test in CI — merge blocked.
WARNINGLogged in validation report. Surfaced in dashboard. Tracked historically. Does not block publication but contributes to content health score.Linting warning — merge allowed, tech debt tracked.
INFOLogged for analytics. Never blocks. Used for trending analysis and optimization over time.Code coverage metrics — informational only.

6.3 Complete Check Registry

BLOCKING Checks (Must Pass)

Check B1: Meta Title

  • Length: 50-60 characters
  • Contains primary keyword
  • Unique across all our_pages (checked against our_page_seo.meta_title)
  • Will not truncate in SERPs (validated via pixel-width estimation, max 580px)
  • Auto-fixable: Yes (truncation adjustment, keyword insertion)

Check B2: Meta Description

  • Length: 150-160 characters
  • Contains primary keyword
  • Contains value proposition or call-to-action language
  • Unique across all our_pages
  • Auto-fixable: Yes

Check B3: Heading Hierarchy

  • Exactly one H1
  • H1 contains primary keyword
  • No skipped heading levels (H1 → H3 without H2)
  • Logical nesting throughout
  • H2s use secondary keywords from brief where natural
  • Auto-fixable: Partial (can fix skipped levels, cannot fix missing keyword)

Check B4: Primary Keyword Presence

  • Primary keyword appears in: meta title, H1, first 100 words, at least one H2, meta description
  • All five placements are required
  • Auto-fixable: Partial

Check B5: Keyword Density

  • Primary keyword density: within range specified per content type (see Section 3)
  • No keyword stuffing patterns (3+ identical keyword phrases within 200 words)
  • Auto-fixable: No (requires content rewriting)

Check B6: Internal Linking Minimum

  • Meets minimum link count for content type (varies — see Section 3)
  • All internal links resolve to published pages (verified against our_pages table)
  • Anchor text is descriptive (no "click here", "read more", "this article")
  • Anchor text is diversified (no more than 30% exact-match keyword anchors)
  • Links are contextually placed (not in a footer dump section)
  • Auto-fixable: Partial (can verify resolution, cannot add missing links)

Check B7: Schema Validity

  • JSON-LD present and parseable
  • Schema type matches content type mapping (Section 4.6)
  • All required properties for the schema type are present and non-empty
  • author references a valid author entity
  • publisher references the Organization entity
  • datePublished is present and valid ISO 8601
  • dateModified is present and >= datePublished
  • speakable selector references exist in page markup
  • For HowTo: every step H2 maps to a HowToStep
  • For FAQPage: every FAQ Q&A pair maps to a Question/Answer
  • For CollectionPage: hasPart contains all child pages from graph
  • Auto-fixable: Yes (schema is generated programmatically — fix is regeneration)

Check B8: URL & Slug

  • URL-friendly (lowercase, hyphens, no special characters, no spaces)
  • Contains primary keyword or close variant
  • Under 75 characters (path portion only)
  • No duplicate slug in our_pages table
  • For refreshes: URL matches original (no slug changes without redirect)
  • Auto-fixable: Partial (can suggest slug, cannot auto-change)

Check B9: Date Integrity

  • datePublished present in schema and matches visible publish date
  • dateModified present in schema
  • For new content: dateModified equals datePublished
  • For refreshed content: dateModified is the refresh date, datePublished is the original date
  • Visible "last updated" date on page matches schema dateModified
  • Auto-fixable: Yes

Check B10: Content Type Structural Compliance

  • Content matches the required structural scaffold for its content type (Section 3)
  • Required sections are present (e.g., FAQ section on types that require it)
  • Required elements exist (e.g., comparison table on comparison pages, prerequisites on how-tos, customer quote on case studies)
  • TL;DR box present on types that require it
  • ToC present when required (word count threshold or type requirement)
  • Auto-fixable: No (structural issues require content rework)

WARNING Checks (Logged, Not Blocking)

Check W1: Image Density

  • Meets minimum image count for content type
  • Meets minimum density (1 per 800 words)
  • No 2 consecutive H2 sections without an image
  • Hero image present
  • All images have alt text (human-written)
  • All images have explicit width and height attributes

Check W2: External Linking

  • Meets minimum external link count for content type
  • No links to competitor domains (checked against competitors table)
  • External links have rel="noopener" on new-tab links
  • External links point to authoritative domains (heuristic: domain authority check if available)

Check W3: Readability Score

  • Flesch-Kincaid readability within configured range (target: grade 8-12 depending on content type)
  • No paragraph exceeds 300 words
  • Sentence length variety present (standard deviation of sentence lengths > 5 words)

Check W4: Content Depth Coverage

  • Draft covers all H2 sections specified in the approved brief
  • Each H2 section meets its target word count (within ±20%)
  • No brief-specified subtopic is missing entirely
  • This is a structural check, not a quality judgment

Check W5: FAQ Section Quality

  • FAQ section meets minimum Q&A count for content type
  • Questions are actual questions (end with "?")
  • Answers are 2-4 sentences each (citation-ready length)
  • Questions are unique (no near-duplicates within the same page)

Check W6: Mobile & Performance

  • All images have explicit width/height (prevents CLS)
  • Images use loading="lazy" except hero image (above-the-fold)
  • No inline styles that break mobile viewport
  • Tables have responsive handling (horizontal scroll wrapper)
  • No excessively large embedded content (>500KB individual assets)

INFO Checks (Analytics Only)

Check I1: Word Count Delta

  • Actual word count vs. brief target word count
  • Logged as percentage delta (e.g., "+12%", "-8%")

Check I2: Keyword Density Exact

  • Primary keyword density as exact percentage
  • Secondary keyword presence (count and density)

Check I3: Schema Richness Score

  • Count of schema properties populated beyond minimum required
  • Scored 0-100 based on optional property coverage
  • Tracks how "complete" the schema is vs. maximum possible

Check I4: Internal Link Density Ratio

  • Internal links per 1,000 words
  • Compared to site-wide average for the same content type

Check I5: Estimated Reading Time

  • Calculated from word count (avg 250 wpm)
  • Logged for analytics and potential on-page display

Check I6: Citation-Ready Block Count

  • Number of standalone paragraphs under 60 words that contain factual claims or definitions
  • These are the blocks most likely to be extracted by AI engines
  • Higher count = higher AI citation eligibility

6.4 Validation Output Schema

1interface SeoValidationResult { 2 pageId: string; 3 contentType: ContentType; 4 validatedAt: Date; 5 validationVersion: string; // schema version of the check suite 6 7 // Gate decision 8 passed: boolean; // true if all BLOCKING checks pass 9 10 // Summary scores 11 blockingScore: string; // "10/10", "8/10" 12 warningScore: string; // "5/6", "4/6" 13 infoMetrics: Record<string, string | number>; 14 15 // Individual checks 16 checks: Array<{ 17 id: string; // "B1", "W3", "I2" 18 name: string; 19 tier: "BLOCKING" | "WARNING" | "INFO"; 20 passed: boolean; 21 value?: string | number; // actual measured value 22 target?: string | number; // expected value or range 23 details: string; 24 failureReason?: string; 25 autoFixable: boolean; 26 autoFixApplied?: boolean; 27 }>; 28}

6.5 Historical Validation Tracking

Every validation run is stored for trend analysis and refresh signal generation.

1CREATE TABLE validation_history ( 2 id UUID PRIMARY KEY DEFAULT gen_random_uuid(), 3 page_id UUID NOT NULL REFERENCES our_pages(id), 4 validated_at TIMESTAMP DEFAULT now(), 5 validation_trigger VARCHAR(20) NOT NULL, -- 'pre_publish', 'refresh_eval', 'scheduled_audit', 'manual' 6 passed BOOLEAN NOT NULL, 7 blocking_score VARCHAR(10) NOT NULL, 8 warning_score VARCHAR(10) NOT NULL, 9 check_results JSONB NOT NULL, -- full check array 10 info_metrics JSONB NOT NULL, 11 content_hash VARCHAR(64) NOT NULL, -- detect if content changed between validations 12 validation_version VARCHAR(20) NOT NULL 13); 14 15CREATE INDEX idx_val_page ON validation_history(page_id); 16CREATE INDEX idx_val_date ON validation_history(validated_at); 17CREATE INDEX idx_val_trigger ON validation_history(validation_trigger);

Usage: The refresh evaluation system (Section 5) can query validation_history to detect score decay. If a page's warning score drops between validation runs (e.g., a link target was unpublished, breaking an internal link), this contributes to refresh urgency.

Scheduled audit: A weekly Trigger.dev job runs the full validation suite against all published pages. This catches degradation from external changes (broken links, updated competitor content, expired schema data).

6.6 Auto-Fix Pipeline

When a BLOCKING check fails, the auto-fix pipeline attempts resolution before escalating to human review.

Pipeline:

  1. Validation runs. If any BLOCKING check fails, collect all failures.
  2. For each failure marked autoFixable: true, the Final Cleanup Agent applies the fix.
  3. Validation re-runs on the fixed content.
  4. Maximum 3 fix-revalidate cycles.
  5. If all BLOCKING checks pass after auto-fix, proceed to publication.
  6. If any BLOCKING check still fails after 3 cycles, escalate to human with a report listing all remaining failures, fix attempts made, and specific guidance on what needs manual correction.

Auto-fixable checks and their fix strategies:

CheckFix Strategy
B1: Meta TitleTruncate to 60 chars at word boundary. Insert primary keyword if missing (prepend).
B2: Meta DescriptionTruncate to 160 chars at sentence boundary. Insert primary keyword if missing.
B3: Heading Hierarchy (partial)Insert missing H2 parent for orphaned H3s. Cannot fix missing keyword in H1.
B7: Schema ValidityRegenerate schema from content metadata. This always works since schema is programmatic.
B9: Date IntegritySet dates from content metadata in Supabase.

7. Content Depth Validation — Detailed Design (Check W4)

This check closes the loop between the Brief Agent's competitive gap analysis and the Writer Agent's actual output. It ensures the draft covers what the brief specified.

7.1 How It Works

The check compares the approved brief's outline against the draft's actual heading structure and section content.

Input:

  • Approved brief outline (from content_briefs.outline JSONB field)
  • Draft content (markdown with heading structure)

Validation logic:

1For each H2 in brief.outline: 2 1. Find matching H2 in draft (fuzzy string match, >70% similarity threshold) 3 2. If no match found: FAIL — "Brief section '[heading]' missing from draft" 4 3. If match found: 5 a. Count words in draft section 6 b. Compare to brief's suggestedWordCount for that section 7 c. If actual < (suggested × 0.8): WARNING — "Section '[heading]' is 8 [X]% below target word count" 9 4. Check that H3 subsections specified in brief exist under this H2 10 11Report: 12 - sections_covered: [count] / [total brief sections] 13 - sections_missing: [list] 14 - sections_underweight: [list with actual vs target] 15 - coverage_percentage: sections_covered / total × 100

Threshold: Coverage percentage must be >= 85% to pass. Below 85% triggers a WARNING.

7.2 Why This Is a WARNING, Not BLOCKING

Content depth is a quality signal, not a binary pass/fail. A writer may deliberately merge two brief sections or cover a topic differently than outlined if they discover better framing during writing. Blocking publication for structural deviation would create false negatives. The WARNING surfaces the gap for human review without halting the pipeline.


8. Image Placement Rules

8.1 Writer Agent Image Markers

The Writer Agent outputs image placement markers in the following format:

1[IMAGE: {description of what should go here} | alt: {suggested alt text basis}]

The description tells the human image placer what type of image fits. The alt field gives a starting point for alt text (human refines this).

8.2 Placement Rules

RuleSpecification
Hero imageRequired on every content type. Placed immediately after the TL;DR/Results box, before the first body paragraph.
Density floorMinimum 1 image per 800 words of body content.
Section gapNo more than 2 consecutive H2 sections without an image between them.
Minimum per typeBlog: 3, Listicle: 1 per item + hero, Guide: 5, How-to: 1 per step + hero, Comparison: 1 per product + hero, Case study: 3, Pillar: 4, Glossary: 2
Image typeAI-generated images relevant to the page content.
Format requirementsWebP preferred (with JPEG fallback). Max 500KB per image. Explicit width and height in HTML attributes. loading="lazy" on all images except hero.
Alt textWritten by human during image placement. Must be descriptive and include relevant keywords naturally. 10-125 characters. Must not start with "Image of" or "Picture of."

8.3 Schema for Images

Every image maps to an ImageObject in the page schema. The hero image is referenced by the content type schema's image property. Step images in how-tos are referenced by their corresponding HowToStep.image.


9. Open Questions for Review

#QuestionImpactRecommended Default
1Should the speakable CSS selectors be validated against actual deployed HTML, or only against the markdown template spec? Deployed HTML validation requires a post-render check.Speakable schema accuracyValidate against template spec at build time. Add deployed HTML validation as a Phase 2 enhancement.
2The comparison type allows Consul as one of the compared products. Should there be a review flag for comparisons that mention Consul directly, to ensure objectivity?Brand credibilityYes. Any comparison mentioning Consul should have a requires_objectivity_review: true flag on the content plan item.
3For the glossary batch build (20-40 terms), should terms be identified by the Strategy Agent from SERP extraction data, or manually curated?Glossary relevanceHybrid. Strategy Agent proposes terms from PAA and SERP data. Human curates final list.
4Should validation history be retained indefinitely, or pruned after a retention period?StorageRetain indefinitely. Validation records are small (JSONB per check, ~2-5KB per run). Annual storage for 500 pages × 52 weekly audits = ~130MB. Negligible.
5The auto-fix pipeline for meta title/description involves prepending keywords. Should there be a "preferred format" template per content type (e.g., "[Keyword]: [Benefit]Consul")?Meta tag consistency and brand

End of Addendum #2

Next addendum: Hierarchical Summary Generation — defining how LangExtract extraction outputs are aggregated into navigable Level 0-3 summaries for agent consumption.