# Chapter Content Generator

> Generates detailed chapter content for an intelligent textbook — text, diagrams, MicroSims, and exercises at the appropriate Bloom's level. Use when a chapter's index.md exists with title, summary, and concept list.

- Skill: `dmccreary/chapter-content-generator` (Agent Skill, multi-file: 5 files)
- Install (CLI): `npx skillmds@latest add dmccreary/chapter-content-generator`
- Raw SKILL.md: https://api.skillmd.com/api/skills/dmccreary/chapter-content-generator/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- License: Creative Commons Attribution-NonCommercial 4.0 International (CC
- Author: dmccreary (https://skillmd.com/u/dmccreary)
- Updated: 2026-09-10
- Page: https://skillmd.com/skills/dmccreary/chapter-content-generator

---


# Chapter Content Generator

**Version:** 1.10

**Version 1.10 Features:**
- **Mascot placement rules single-sourced** - Step 2.4 principle 4 no longer carries its own copy of the Chapter 1 self-introduction pattern or the mascot frequency numbers. Both now live in the canonical `$BK_HOME/skills/book-installer/references/mascot-placement-rules.md`, which every skill in the library references instead of restating. This ends the drift that had left conflicting per-chapter counts in two different placement tables.
- **Version tracked in frontmatter** - as `metadata.ibook.version`, under `metadata:` rather than a bare `version:` key, which strict packaging validation would reject.

**Version 1.09 Features:**
- **BREAKING: CIS-driven elaboration budget** - Per-concept word count and non-text-element requirements are no longer a flat chapter-wide target ("3000-5000 words, 4-6 non-text elements"). Each concept now gets its own word-count range and minimum non-text-element requirement computed from its **Concept Impact Score** (CIS), read from the `CIS Score` column that `book-chapter-generator` v1.0.0+ writes into each chapter's "Concepts Covered" table. Foundational, high-impact concepts get real elaboration (worked examples, diagrams); narrow, low-impact concepts get efficient, brief treatment. See "Elaboration Budget" (Step 2.3b) below. Requires chapters generated by `book-chapter-generator` v1.0.0+ (table format) and a `learning-graph.json` from `learning-graph-generator` v1.06+ (has `node.cis`).

**Version 0.09 Features:**
- **Mascot self-introduction in Chapter 1** - When the project CONTENT-GENERATION-GUIDE.md defines a pedagogical mascot, the FIRST mascot admonition in Chapter 1 must be a self-introduction that names the mascot and enumerates each pose-role it will play across the book. The pattern is defined once for the whole library in `mascot-placement-rules.md` (see Step 2.4, principle 4)

**Version 0.07 Features:**
- **Instructional scaffolding** - Define-before-display rules ensure terms are explained before diagrams use them, code parameters are explained before code examples, and tables reinforce rather than introduce concepts (see Step 2.4, principle 3)
- **Sequential execution** - Generate content one chapter at a time to avoid excessive token usage. A user may override this with the phrase "use parallel execution" but the skill will warn them that a 38% additional tokens will be used
- **Edge direction validation** - Mandatory check to prevent inverted dependency bugs (see Step 1.3a)

## When to Use This Skill

Use this skill when:
- The `book-chapter-generator` skill has created chapter directories with index.md files
- A chapter index.md contains: title, summary, and concepts covered list
- Detailed chapter content needs to be generated
- Content should be adapted to a specific reading level (junior high, senior high, college, graduate)
- Rich non-text elements (diagrams, MicroSims, infographics) are desired

Do NOT use this skill when:
- Chapter structure hasn't been created yet (use `book-chapter-generator` first)
- Content already exists and just needs editing (use Edit tool directly)
- Generating other types of content (prompts, glossaries, etc.)
- The user is almost out of tokens (over 95% of used in a 5-hour window)

## Execution Modes

### Sequential Mode (Default for all use-cases)

- Always only do one chapter at a time due to large overhead of parallel mode
- Wait for a chapter to totally finish and log the session before you begin the next chapter
- Clearly indicate to the user when each chapter is finished

### Parallel Mode (Only on request)

Parallel mode should ONLY be used when the user specifically request parallel execution.
Warn the user that there will be a substantial token penalty to pay for parallel execution.

### Single Chapter Mode

Use for:
- Updating one chapter after outline revision
- Testing content format before batch generation

## Workflow

### Phase 1: Setup (Sequential)

This phase runs once before any content generation, reading shared context that all agents will need.

#### Step 1.1: Capture Start Time for Logging

```bash
date "+%Y-%m-%d %H:%M:%S" >>logs/ch-{NN}-content-generation.md
```

Where {NN} is the two digit chapter number with zero padding.

Log the start time for the session report.

#### Step 1.2: Indicate Skill Running

Notify the user: "Chapter Content Generator Skill v1.10 running in [parallel/sequential] mode."

#### Step 1.3: Read Shared Context

Read and cache these files for all agents:

1. **Course Description** (`docs/course-description.md`)
   - Extract target audience and reading level
   - Note course objectives and tone guidelines in the project CONTENT-GENERATION-GUIDE.md
   - Identify any mascot or narrative elements (e.g., Delta in calculus) in the project CONTENT-GENERATION-GUIDE.md

2. **Learning Graph** (`docs/learning-graph/learning-graph.json` and/or `learning-graph.csv`)
   - Load concept list with dependencies
   - Understand concept relationships for pedagogical ordering
   - **Compute `cis_max`** = the maximum `cis` value across all nodes in the
     book (`max(n.get('cis', 1) for n in data['nodes'])`). This one number
     is reused for every chapter in the session -- Elaboration Budget
     normalization (Step 2.3b) is always **global** (against the whole
     book), never local to one chapter, since a concept's importance is a
     book-wide claim, not a chapter-local one. If every node's `cis` is `1`,
     the learning graph predates `learning-graph-generator` v1.06 -- report
     this to the user and suggest regenerating `learning-graph.json` before
     proceeding, rather than silently falling back to flat word counts.

   !!! info "Learning Graph = Concept Dependency Graph (a DAG)"
       A learning graph is a **Concept Dependency Graph** -- a directed acyclic
       graph (DAG) where each edge represents a "depends on" relationship. We use
       the **dependency direction** (edges point FROM a concept TO the concepts it
       depends on) because this aligns with standard graph theory algorithms for
       topological sorting, cycle detection, and transitive reduction.

       Some learning management systems use an **enablement graph** where edges
       point the opposite way (FROM prerequisite TO enabled concept). That direction
       is more intuitive for some teachers but less natural for graph algorithms.
       This project uses the dependency direction exclusively.

   !!! danger "CRITICAL: Edge Direction in learning-graph.json"
       In the vis-network JSON format, edges point **FROM dependent TO prerequisite**
       (the dependency direction).

       - Edge `{from: 5, to: 1}` means "Biodiversity (5) depends on Ecology (1)"
       - It does NOT mean "Ecology leads to Biodiversity" (that would be the enablement direction)

       **To build a prerequisite map:**
       ```python
       # CORRECT: dependency direction -- from=dependent, to=prerequisite
       prereqs[edge['from']].add(edge['to'])
       ```

       **NEVER use:**
       ```python
       # WRONG: accidentally converts to enablement direction, inverting ALL dependencies
       prereqs[edge['to']].add(edge['from'])
       ```

       Getting this wrong produces hundreds of false violations and wastes
       significant tokens on invalid chapter designs. Always validate with
       Step 1.3a before proceeding.

3. **Glossary** (`docs/glossary.md`)
   - Load term definitions for consistent terminology if they exist
   - In most cases the glossary is created after the content is generated
   - Note which concepts have glossary entries

4. **Project CONTENT-GENERATION-GUIDE.md** (if exists)
   - Load project-specific guidelines
   - Note any reading level, mascot specifications, tone requirements, or special formatting

5. **Chapter List** (scan `docs/chapters/` directory)
   - Enumerate all chapter directories
   - Identify which chapters need content generation (have outline but no content)

#### Step 1.3a: Validate Edge Direction (MANDATORY)

Before using any dependency data, verify the edge direction is correct. This step prevents the most common and expensive bug in chapter generation -- an inverted dependency map that silently produces invalid chapter orderings.

**Validation procedure:**

1. Identify foundational concepts -- those with empty Dependencies in the CSV, or with zero prerequisites in the JSON
2. Build the prerequisite map using `prereqs[edge['from']].add(edge['to'])`
3. Check that foundational concepts have ZERO entries in the prereqs map

```python
import json
from collections import defaultdict

with open('docs/learning-graph/learning-graph.json') as f:
    data = json.load(f)

# Build prereqs: from=dependent, to=prerequisite
prereqs = defaultdict(set)
for e in data['edges']:
    prereqs[e['from']].add(e['to'])

# Find concepts with zero prerequisites (foundational)
all_ids = {n['id'] for n in data['nodes']}
foundational = all_ids - set(prereqs.keys())

print(f"Foundational concepts (no prerequisites): {len(foundational)}")
for fid in sorted(foundational):
    node = next(n for n in data['nodes'] if n['id'] == fid)
    print(f"  {fid}: {node['label']}")

# SANITY CHECK: foundational concepts should be simple/introductory
# If you see advanced concepts here, the edge direction is WRONG
```

**Pass criteria:**

- Foundational concepts should be simple, introductory terms (e.g., "Ecology", "Energy", "System")
- If advanced concepts appear as foundational (e.g., "Sustainability", "Climate Change", "Tipping Points"), the edge direction is inverted -- STOP and fix before proceeding
- The number of foundational concepts should be small (typically 3-10 for a 200-400 concept graph)
- If you see 50+ "foundational" concepts, the direction is likely inverted

**If validation fails:** Do NOT proceed with content generation. Report the issue to the user and suggest re-running with the correct edge direction.

#### Step 1.3b: Verify Chapter Dependency Order (MANDATORY)

After validating edge direction, verify that every chapter's concept prerequisites have already been covered in earlier chapters. This ensures content can reference prior material without forward references.

```python
# Build chapter_map: concept_id -> chapter_index
chapter_map = {}
for i, (title, cids) in enumerate(chapters):
    for cid in cids:
        chapter_map[cid] = i

# Check: for every concept, all prerequisites must be in same or earlier chapter
violations = []
for i, (title, cids) in enumerate(chapters):
    for cid in cids:
        for dep in prereqs.get(cid, set()):
            if dep in chapter_map and chapter_map[dep] > i:
                violations.append(
                    f"  {nodes[cid]['label']}(ch{i+1}) needs "
                    f"{nodes[dep]['label']}(ch{chapter_map[dep]+1})"
                )

if violations:
    print(f"DEPENDENCY VIOLATIONS: {len(violations)}")
    for v in violations:
        print(v)
    print("\nDo NOT generate content until all violations are resolved.")
else:
    print("All dependencies respected. Safe to generate content.")
```

**Pass criteria:** Zero violations. If any exist, the chapter structure must be fixed before content generation begins.

#### Step 1.4: Determine Reading Level

Extract the grade reading level from the course description:

**Reading level indicators:**
- "grade-school", "grade school", "grades 1-6", "elementary school" → Elementary School
- "junior-high", "junior high", "grades 7-9", "middle school" → Junior High
- "senior-high", "senior high", "grades 10-12", "high school" → Senior High
- "college", "undergraduate", "bachelor" → College
- "graduate", "master", "masters", "master's", "PhD", "doctoral" → Graduate

**Reading level characteristics:**
- **Grade School (Grades 1-6):** Very sentences (10-14 words), common vocabulary, concrete examples, frequent visual aids
- **Junior High (Grades 7-9):** Simple sentences (12-18 words), common vocabulary, concrete examples, frequent visual aids
- **Senior High (Grades 10-12):** Mixed sentence complexity (15-22 words), technical vocabulary with definitions, balance of concrete and abstract
- **College:** Academic style (18-25 words), technical terminology, case studies, research context
- **Graduate:** Sophisticated prose (20-30+ words), full jargon, theoretical depth, research literature

Default to Grade 10 (Senior High) if not specified.

#### Step 1.5: Plan Chapter Batches (Parallel Mode)

Divide chapters into batches for parallel processing:

**Batch Size Guidelines:**
- 4-8 chapters: 2 agents (2-4 chapters each)
- 9-15 chapters: 3-4 agents (3-4 chapters each)
- 16-24 chapters: 4-6 agents (4-5 chapters each)
- 25+ chapters: 5-6 agents (5-6 chapters each)

**Example for 23 chapters:**
```
Agent 1: Chapters 1-4 (Foundations)
Agent 2: Chapters 5-8 (Core Concepts Part 1)
Agent 3: Chapters 9-12 (Core Concepts Part 2)
Agent 4: Chapters 13-16 (Applications Part 1)
Agent 5: Chapters 17-20 (Applications Part 2)
Agent 6: Chapters 21-23 (Advanced Topics)
```

### Phase 2: Content Generation (Parallel or Sequential)

#### Parallel Execution

Spawn multiple Task agents simultaneously using the Task tool. Each agent receives:

1. **Shared context** (course info, reading level, glossary terms, tone guidelines)
2. **Assigned chapters** (specific chapter directories)
3. **Content format template** (the standard format from this skill)
4. **Output instructions** (write content to each chapter's index.md)

**Agent Prompt Template:**

```
You are generating educational content for an intelligent textbook. Generate
detailed chapter content for the following chapters.

COURSE CONTEXT:
- Course: [course name]
- Target audience: [audience]
- Reading level: [level] - [characteristics]
- Tone: [tone guidelines from course description or CONTENT-GENERATION-GUIDE.md]

ELABORATION BUDGET (per concept -- computed in Step 2.3b, see below):
[Insert the per-chapter elaboration budget table here: Concept | CIS | Tier | Target Words | Required Elements]

CONTENT GUIDELINES:
- Follow the per-concept word count and required-element targets in the
  Elaboration Budget table above -- do NOT apply a flat word count to every
  concept regardless of importance
- No more than 4 paragraphs of pure text without a non-text element
- Use diverse element types (lists, tables, diagrams, MicroSims)
- Present concepts in pedagogical order (simple to complex)
- Include LaTeX equations where appropriate (backslash delimiters: `\( \)` for inline, `\[ \]` for display)

SCAFFOLDING (CRITICAL):
- Define every technical term in prose BEFORE it appears in a diagram, code block, or table
- Before code examples, explain what the code does and what key parameters mean in plain language
- Tables must summarize concepts already explained — never introduce new concepts via tables
- Add bridging sentences before complex elements ("Before we examine this diagram, let's define...")

MASCOT (if a mascot is defined in CONTENT-GENERATION-GUIDE.md):
- The pose-by-pose rules, per-chapter counts, and hard limits are defined in the
  project's CONTENT-GENERATION-GUIDE.md (rendered from the canonical
  $BK_HOME/skills/book-installer/references/mascot-placement-rules.md). Read that
  section before placing any mascot admonition and follow it exactly.
- If you are processing CHAPTER 1, the FIRST mascot admonition must be the
  one-time self-introduction described in those rules. See Step 2.4 principle 4.
- For chapters 2 and beyond, open with a normal mascot-welcome admonition that gets straight into chapter-specific content. Do NOT repeat the self-introduction.

NON-TEXT ELEMENTS:
- Markdown lists and tables: embed directly (blank line before)
- Diagrams, MicroSims, infographics: use <details markdown="1"> blocks with #### Diagram: header

CHAPTERS TO PROCESS:
[List specific chapter directories with full paths]

FOR EACH CHAPTER:
1. Read the chapter index.md file to get title, summary, and the "Concepts
   Covered" table (Concept | CIS Score)
2. Compute the Elaboration Budget for this chapter's concepts (Step 2.3b) --
   the chapter's total word count is the SUM of each concept's target, not
   a flat chapter-wide number. Chapters with more high-CIS concepts will
   naturally run longer than chapters of mostly narrow, low-CIS concepts --
   this is expected and correct, not an error to normalize away.
3. Generate content following each concept's individual word-count range
   and required-element targets from the budget table
4. Verify all concepts from "Concepts Covered" are addressed AND that each
   one's actual word count and element mix roughly matches its budget tier
5. Write the content to docs/chapters/[chapter-dir]/index.md

METADATA FORMAT (add to top of each file):
---
title: [Chapter Title]
description: [Short description]
generated_by: claude skill chapter-content-generator
date: [YYYY-MM-DD HH:MM:SS]
version: 1.09
---

REPORT when done:
- Chapter name
- Word count (and how it compares to the sum of the concepts' budgeted targets)
- Non-text elements (lists, tables, admonitions, diagrams, MicroSims)
- Concepts covered (X of Y), with any concept whose actual length fell outside its budget's tolerance flagged
```


#### Sequential Execution

For sequential mode or fewer than 4 chapters, process each chapter one at a time following the per-chapter steps below.

### Phase 2 Steps (Per Chapter - used by agents or sequential mode)

#### Step 2.1: Verify Chapter File Exists

Verify that the chapter file exists and has required elements.

**Expected input format:**
- Chapter name: "01-intro-to-itil-and-config-mgmt" or "Chapter 1"
- Full path: "/docs/chapters/01-intro-to-itil-and-config-mgmt/index.md"
- Relative path: "chapters/01-intro-to-itil-and-config-mgmt/index.md"

**Chapter directory structure:**
```
/docs/chapters/NN-lowercase-name/index.md
```

Where:
- `NN` = Two-digit chapter number with leading zero (e.g., "01", "07", "12")
- `lowercase-name` = URL-friendly lowercase name with dashes, no spaces

**Launching Parallel Agents:**
This is done ONLY if the user request parallel execution. 

Use the Task tool with multiple invocations in a SINGLE message to run agents in parallel:

```markdown
[Call Task tool for Agent 1: Chapters 1-4]
[Call Task tool for Agent 2: Chapters 5-8]
[Call Task tool for Agent 3: Chapters 9-12]
[Call Task tool for Agent 4: Chapters 13-16]
[Call Task tool for Agent 5: Chapters 17-20]
[Call Task tool for Agent 6: Chapters 21-23]
```

**IMPORTANT:** All Task tool calls MUST be in a single message to execute in parallel. If sent in separate messages, they will run sequentially.

#### Step 2.2: Verify Chapter Outline

Open the chapter file and check for required elements.

**Required elements:**

1. **Title** in header 1 (# Title)
2. **Summary** in level 2 header (## Summary)
3. **Concepts Covered** in level 2 header (## Concepts Covered) with a
   `Concept | CIS Score` markdown table (written by `book-chapter-generator`
   v1.0.0+; see Step 1.4a)

**Actions:**
1. Parse the chapter index.md file
2. Extract:
   - Chapter title
   - Summary text
   - Concepts Covered table: a list of `(concept_name, cis_score)` pairs, in
     the row order given (this is the pedagogical order)
3. If any element is missing, skip chapter or ask user to provide content
4. If "Concepts Covered" is a numbered list without CIS scores (a chapter
   generated by `book-chapter-generator` before v1.0.0), do not fabricate
   CIS values -- report this to the user and suggest regenerating the
   chapter's scaffold with the current `book-chapter-generator`
5. Store the concept/CIS list for the Elaboration Budget (Step 2.3b) and for
   verification in Step 2.5

#### Step 2.3: Add Metadata

Add metadata to the top of the index file:

```markdown
---
title: Chapter Title
description: Short description of title
generated_by: claude skill chapter-content-generator
date: YYYY-MM-DD HH-MM-SS
version: 1.09
---
```

#### Step 2.3b: Compute the Elaboration Budget (CIS-Driven)

**This step replaces the old flat "3000-5000 words, 4-6 non-text elements
per chapter" instruction.** Content length and richness are no longer set
per chapter -- they are set **per concept**, driven by each concept's
Concept Impact Score (CIS), so that concepts many other concepts transitively
depend on get real elaboration (worked examples, diagrams) while narrow,
low-impact concepts get efficient, brief treatment. This mirrors how a human
subject-matter expert naturally spends more explanatory effort on
foundational ideas than on peripheral vocabulary.

**1. Compute each concept's Elaboration Score, `E(c)`:**

```python
import math

# cis_max was computed once in Step 1.3 across the WHOLE book -- reuse it
# here. Normalization is always GLOBAL, never local to this chapter: a
# concept's importance is a book-wide claim. (An earlier, chapter-local
# normalization was tried and rejected -- it produced a degenerate result
# where a chapter's own single most-important concept always looked like
# the book's most important concept, even when it wasn't.)
def elaboration_score(cis, cis_max):
    if cis_max <= 1:
        return 0.0
    return math.log(cis + 1) / math.log(cis_max + 1)
```

`E(c)` is in `[0, 1]`. Using `log(cis+1)`, not raw CIS, matters: CIS is
heavy-tailed (on a typical ~200-concept graph roughly half of all concepts
sit at the minimum CIS of 1), so a linear or population-percentile scale
would make that entire lower half indistinguishable from each other while
one or two hub concepts dominate the range. This exact failure mode was
found and fixed during development -- see the "Predicting Concept Content
Size" paper (Definition 4) if curious about the details.

**2. Assign a tier from `E(c)`:**

| Tier | `E(c)` range | Target words | Required elements |
|------|--------------|---------------|--------------------|
| A (full treatment) | `>= 0.5` | 500-750 | >=1 worked example AND >=1 diagram/chart/table/MicroSim |
| B (standard) | `0.2 <= E(c) < 0.5` | 250-400 | >=1 worked example |
| C (brief) | `< 0.2` | 120-200 | A clear definition; a short example is optional, not required |

These cut points and ranges are a validated starting point (checked against
two real chapters with opposite CIS profiles -- one foundational, one
specialized -- during development), not an immutable constant. If a chapter
comes out with an unreasonable tier mix for its actual content (e.g. every
single concept in one tier), sanity-check the tiering before generating, but
do not silently revert to a flat per-chapter word count.

**3. Build the chapter's Elaboration Budget table** (one row per concept,
in the same pedagogical order as "Concepts Covered"):

| Concept | CIS | E(c) | Tier | Target Words | Required Elements |
|---------|-----|------|------|---------------|--------------------|
| [Concept 1] | 187 | 0.83 | A | 500-750 | worked example + diagram |
| [Concept 2] | 4 | 0.22 | B | 250-400 | worked example |
| [Concept 3] | 1 | 0.00 | C | 120-200 | definition |

The chapter's **total word count is the sum of the per-concept targets** --
it is not set independently. A chapter containing several Tier A concepts
will naturally run longer than a chapter of mostly Tier C concepts; this
variation is the point, not a bug to normalize away (see Common Pitfalls
below).

**4. Use this table to drive Step 2.4.** When generating prose, follow each
concept's individual budget row rather than an even split of chapter length
across all concepts.

#### Step 2.4: Generate Detailed Chapter Content

Generate comprehensive educational content based on the chapter outline, concept list, and reading level.

**Content generation principles:**

1. **Reading level adaptation:**
   - Apply appropriate sentence complexity, vocabulary, and explanation style
   - See `references/reading-levels.md` for specific guidelines

2. **Concept ordering:**
   - Present simple concepts first, complex concepts last
   - Follow natural pedagogical progression
   - Do NOT necessarily follow the order in "Concepts Covered" list
   - Build on previously explained concepts

3. **Scaffolding — define before you display:**
   - **Vocabulary before visuals:** Every diagram, code example, or table must be preceded by prose that defines all technical terms it contains. If a diagram shows "vectors" and "embeddings," those terms must be explained in the paragraph(s) immediately before the diagram. A reader should never encounter a term for the first time inside a non-text element.
   - **Bridge sentences before code:** Before any code example, include a plain-language sentence explaining what the code does and what its key parameters mean. Never present code and defer the explanation to a later section — the explanation must come first. Example: "The `temperature` parameter controls randomness (0 = deterministic, 1 = creative). The `max_tokens` parameter sets the maximum response length."
   - **Prose first, tables reinforce:** Tables summarize or compare information the reader already understands. Never use a table to introduce new concepts. The pattern is: (1) explain concepts in prose, (2) then present a table that organizes or compares them. If a reader would need to reverse-engineer meaning from table cells, the table is premature.
   - **Signpost what's coming:** Before complex elements, add a navigation cue: "Before we examine this diagram, let's define two key terms." or "The following table summarizes the three approaches we just discussed." These one-sentence bridges transform content from a reference document into a guided learning experience.

4. **Mascot placement (when a mascot is defined):**

   Which pose carries which pedagogical job, how many of each belong in a
   chapter, the hard limits, and the one-time **Chapter 1 self-introduction**
   pattern are all defined in a single file shared by every skill in this
   library:

   ```
   $BK_HOME/skills/book-installer/references/mascot-placement-rules.md
   ```

   Each book carries a rendered copy of those rules in its own
   `CONTENT-GENERATION-GUIDE.md`, between `<!-- BEGIN mascot-placement-rules -->`
   sentinels. **Read that section before placing any mascot admonition** and
   follow it exactly.

   Do not restate the rules here, and do not invent pose-roles the project does
   not define. If a rule needs to change, change it in the canonical file so
   every skill picks the change up at once.

   Two points bear repeating because they are the ones most often missed:

   - The Chapter 1 self-introduction happens **once**, on the mascot's very
     first appearance. Chapters 2+ open with a normal `mascot-welcome` that gets
     straight into chapter-specific content.
   - The mascot image goes in the admonition **body** using Markdown image
     syntax — `![alt](path){ class="mascot-admonition-img" }` — never a raw HTML
     `<img>` tag.

5. **Non-text elements:**
   - Follow the Required Elements column from the Elaboration Budget (Step
     2.3b) for each concept -- Tier A concepts require a worked example AND
     a diagram/chart/table/MicroSim; Tier B requires a worked example; Tier
     C requires only a clear definition. These are per-concept minimums, not
     a chapter-wide element count to hit independently of concept mix.
   - Goal: No more than 4 paragraphs of pure text without a non-text element.
   - Use diverse element types (don't repeat the same type).
   - Place special focus on interactive elements (infographics, MicroSims).
   - When appropriate, render equations in LaTeX using backslash delimiters:
     - Inline math: `\( equation \)` for equations within sentences
     - Display math: `\[ equation \]` for standalone equations on their own line
   - Do NOT use dollar sign delimiters (`$` or `$$`)
   - See the math-equations.md file in the references for proper formatting of equations.

**Non-text element types:**

Elements embedded directly in markdown (no `<details markdown="1">` block):

1. **Markdown lists** (bullet or numbered) - ALWAYS put blank line before list
2. **Markdown tables** - ALWAYS put blank line before table

Elements requiring diagram header and `<details markdown="1">` specification blocks:

3. **Diagrams/drawings** - System architectures, relationships, data flows
4. **Interactive infographics** - Clickable concept maps, progressive disclosure, hovers with definitions appearing in tooltips consistent with the glossary
5. **MicroSims** - p5.js simulations with interactive controls
6. **Charts** - Bar, line, pie charts with quantitative data
7. **Timelines** - Historical progression, sequential events
8. **Maps** - Geographic distribution with movement arrows
9. **Workflow diagrams** - Business processes with hover text
10. **Graph data models** - Entity relationships using vis-network
11. **Causal Loop Diagrams** - used in systems thinking and explaining causality

**MicroSim reuse check (REQUIRED before writing any new interactive-element specification):**

Hundreds of MicroSims already exist across the dmccreary/* textbooks, indexed in the
search-microsims catalog. Before writing a SPECIFICATION block for a MicroSim, workflow
diagram, chart, timeline, map, or infographic, check whether an existing hosted MicroSim
already teaches the same concept — and if so, embed it via iframe instead of specifying
a new one that must be generated and debugged from scratch.

1. **Availability check (once per session):** run
   `test -x /Users/dan/Documents/ws/search-microsims/.venv-embeddings/bin/python && test -f /Users/dan/Documents/ws/search-microsims/data/microsims-embeddings.json && echo AVAILABLE`
   If this does not print `AVAILABLE`, SKIP this entire reuse step for the whole session
   and generate specifications exactly as described below. Graceful degradation — never
   block chapter generation on the search service.
2. **Draft the WHAT query** for the element in the embedding query format:
   `Title: <working title> | Topic: <concept> | Subjects: <subject areas> | Grade Level: <level> | Learning Objectives: <objective with Bloom verb>`
3. **Run the reuse search:**
   ```
   /Users/dan/Documents/ws/search-microsims/.venv-embeddings/bin/python \
     /Users/dan/Documents/ws/search-microsims/src/find-similar-templates/find-similar-templates.py \
     --mode reuse --query "<WHAT query>" --top 3 --json --quiet
   ```
   If the command errors or takes more than ~60 seconds, fall back to normal spec
   generation for the rest of the session.
4. **Decide using the top result's `recommendation` field:**
   - `reuse` (WHAT score ≥ 0.75): emit the **Reused block** (below) instead of a
     specification. First sanity-check that the candidate's `grade_level` and `subject`
     fit this book; if clearly wrong (e.g., a graduate-level sim in a middle-school
     book), treat it as `template` instead. If `docs/sims/<sim-id>/` already exists
     locally in THIS book, embed the local sim with a relative iframe instead.
   - `template` (0.60 ≤ WHAT score < 0.75): write a normal specification, and add one
     line to the details block: `**Template:** <github_url of top match><br/>`
     so the microsim-generator can use the existing sim's code as a starting point.
   - `generate` (WHAT score < 0.60): write a normal specification as usual.
5. **Log reuse decisions** in the chapter-generation summary: n reused, n from
   template, n newly specified.

**Reused block structure** (used instead of a specification when reusing):

```markdown
#### Diagram: [Title of the existing MicroSim]

<iframe src="[fullscreen_url from the search result]" width="100%" height="500px" scrolling="no"></iframe>

[Run the [Title] MicroSim fullscreen]([fullscreen_url]){ .md-button }

<details markdown="1">
<summary>[Title] (reused MicroSim)</summary>
Type: [element-type]
**sim-id:** [sim directory name from the source repo]<br/>
**Library:** [framework from the search result]<br/>
**Status:** Reused<br/>
**Source:** [live_url from the search result]<br/>
**Source Repo:** [github_url from the search result]

Reused from the MicroSim catalog (WHAT match score [what_score]). Learning objective: [the objective as used in this chapter].
</details>
```

The `**Status:** Reused` field is what keeps downstream batch tools from trying to
scaffold or implement the sim: `generate-todo.py` excludes reused specs from TODO.md
and `extract-sim-specs.py` records them as complete. `Reused` is a terminal lifecycle
state — reused sims never advance through `specified → scaffolded → implemented →
validated → deployed`; they are already deployed in their source repository.

For each `<details markdown="1">` block element, use this structure:

```markdown
#### Diagram: [Brief descriptive title]

<details markdown="1">
<summary>[Brief descriptive title]</summary>
Type: [element-type]
**sim-id:** [kebab-case-directory-name]<br/>
**Library:** [p5.js | vis-network | Chart.js | Mermaid | Plotly | Leaflet | vis-timeline]<br/>
**Status:** Specified

[Detailed specification following guidelines in references/content-element-types.md]

Implementation: [Technology/approach]
</details>
```

The three structured fields enable machine-readable extraction by batch utilities:
- **sim-id** — kebab-case directory name (e.g., `angle-type-explorer`), used by `extract-sim-specs.py`
- **Library** — JavaScript library for CDN selection by `generate-sim-scaffold.py`
- **Status** — initial lifecycle state (`Specified` for new specs; `Reused` when the reuse check matched an existing MicroSim — a terminal state that downstream batch tools skip)

Do not indent any text within a `<details markdown="1">` block. Do not put any leading spaces or tabs on newlines within a `<details markdown="1">` block.

Make SURE to put the level 4 header with the prefix `#### Diagram:` before the details. This is REQUIRED!

**Specification requirements:**
- Detailed enough that another skill or developer can implement without additional context
- Include all visual elements, data, labels, colors, interactions
- Specify canvas sizes, layout, default parameters
- Specify that the visual elements must have a responsive design that must respond to window resize events
- For MicroSims: describe learning objective, controls, visual elements, behavior
- See `references/content-element-types.md` for complete specification guidelines for each element type

**Content structure:**

1. Start with introductory paragraphs connecting to chapter summary
2. Present concepts in pedagogical order (simple to complex)
3. Integrate non-text elements naturally throughout
4. Use markdown lists and tables frequently (with blank lines before them)
5. Include `<details markdown="1">` blocks for complex visual/interactive elements
6. Place a level 4 markdown header before each `details` block
   ```#### Diagram: [Diagram Name]```
7. End with summary or key takeaways section

**Interactive elements emphasis:**

**CRITICAL: Every diagram, chart, infographic, MicroSim, timeline, map, workflow, and graph model MUST be interactive.** NEVER specify a static image that does not give the learner feedback. At minimum, every visual element must support at least one of: clickable nodes/regions/bars that open an infobox, hoverable elements that reveal tooltips, or controls that change the rendered output. Mermaid diagrams are acceptable ONLY when every node has a `click` directive that reveals a definition or explanation in an infobox — a plain Mermaid diagram with no click handlers is a static image and is forbidden. If a candidate diagram cannot meet this bar, redesign it as a MicroSim, an interactive infographic, or a clickable Mermaid diagram — or cut it. See `references/content-element-types.md` "CRITICAL RULE: Every Visual Element Must Be Interactive" for the full specification.

- Prioritize MicroSims and infographics that enable:
  - Student interaction tracking
  - Progress gauging
  - Personalized content recommendations
- Each interactive element should have clear **Learning objectives:**
- Reference a section of the 2001 Bloom Taxonomy when you describe a learning objective:
   - **Remembering:** Recalling facts, terms, basic concepts, and answers without necessarily understanding their meaning.
   - **Understanding:** Explaining ideas or concepts, demonstrating comprehension by summarizing or rephrasing information.
   - **Applying:** Using acquired knowledge to solve problems in new or unfamiliar situations.
   - **Analyzing:** Breaking down information into parts to understand its structure and relationships, and drawing comparisons.
   - **Evaluating:** Making judgments about information based on set criteria or standards, requiring critical thinking and justification.
   - **Creating:** Producing new or original work by combining elements to form a novel whole or solution.
- For the per-level action-verb lists and detailed question-writing guidance, read the canonical reference `references/blooms-taxonomy.md` (also used by faq-generator and quiz-generator).

#### Step 2.5: Verify Completeness

After generating chapter content, verify all concepts have been covered.

**Verification process:**
1. Review the generated content
2. Check that each concept from "Concepts Covered" list appears in the content
3. Create a checklist showing which concepts were covered
4. If any concepts missing:
   - Add content covering those concepts
   - Integrate them naturally into existing structure
5. Update the chapter index.md file with the complete generated content
6. Make **Absolutely Sure** that the content has been written to the chapter index.md file. Do a word count to make sure that **ALL** the content is present and that the TODO has been removed.

**Actions:**
- Replace the "TODO: Generate Chapter Content" placeholder with generated content
- Keep the existing title, summary, concepts list, and prerequisites sections
- Add the new detailed content after the prerequisites section

### Phase 3: Aggregation (Sequential, after parallel agents complete)

After all parallel agents complete, aggregate results.

#### Step 3.1: Collect Agent Results

Wait for all Task agents to complete. Collect from each:
- List of chapter files created/updated
- Per-chapter statistics (word count, non-text elements, concepts covered)
- Any errors or issues encountered

#### Step 3.2: Generate Summary Report

Create a summary of all content generation:

```markdown
# Chapter Content Generation Report

Generated: YYYY-MM-DD
Execution Mode: Parallel (6 agents)
Wall-clock Time: X minutes Y seconds

## Overall Statistics

- **Total Chapters:** 23
- **Total Words:** ~100,000
- **Avg Words per Chapter:** ~4,350
- **Total Non-text Elements:** ~115

## Execution Summary (Parallel Mode)

| Agent | Chapters | Words | Elements | Time |
|-------|----------|-------|----------|------|
| Agent 1 | 1-4 | 17,200 | 20 | 3m 15s |
| Agent 2 | 5-8 | 18,100 | 22 | 3m 42s |
| Agent 3 | 9-12 | 17,800 | 19 | 3m 28s |
| Agent 4 | 13-16 | 18,500 | 21 | 3m 51s |
| Agent 5 | 17-20 | 17,900 | 18 | 3m 33s |
| Agent 6 | 21-23 | 13,200 | 15 | 2m 45s |

## Per-Chapter Summary

| Chapter | Words | Lists | Tables | Diagrams | MicroSims | Concepts |
|---------|-------|-------|--------|----------|-----------|----------|
| 1. Foundations | 4,200 | 6 | 3 | 2 | 1 | 15/15 ✓ |
| 2. Limits | 4,500 | 5 | 2 | 3 | 2 | 14/14 ✓ |
| ... | ... | ... | ... | ... | ... | ... |
```

#### Step 3.3: Capture End Time and Write Session Log

Capture the end time:

```bash
date "+%Y-%m-%d %H:%M:%S"
```

Export the session information to `logs/chapter-content-generator-YYYY-MM-DD.md`:

```markdown
# Chapter Content Generator Session Log

**Skill Version:** 1.09
**Date:** YYYY-MM-DD
**Execution Mode:** Parallel (6 agents)

## Timing

| Metric | Value |
|--------|-------|
| Start Time | YYYY-MM-DD HH:MM:SS |
| End Time | YYYY-MM-DD HH:MM:SS |
| Elapsed Time | X minutes Y seconds |

## Token Usage

| Phase | Estimated Tokens |
|-------|------------------|
| S

…(truncated)
