---
reliability: 3.8 # 5 − character image gen .3 − kontext page-edit chain .2 − cover image gen .3 − tts .2 − 1 stage over 5 (.2); optional LoRA path costs a further .8 when used; no proven E2E showcase yet
---

# Kids' storybook — agent playbook

> Paste this whole file (with the BRIEF filled in) into Claude cowork, chat, or Code. The agent walks through it with you and stops for your approval at every step that matters.

## What you'll get

A complete eight-page illustrated children's storybook with a matching read-aloud audio track. The same character appears on every page — that's the part most AI tools get wrong, and the part this playbook gets right.

What lands at the end:

- **A cover page** with the title
- **Eight illustrated spreads**, with the main character looking the same across all of them
- **Per-page narration**, so you can tap a page and the agent reads that page aloud
- **A full audiobook track** the family can listen to at bedtime, all eight pages stitched together with gentle pauses
- **An HTML flip-book** that opens on any tablet or laptop, with a print-friendly stylesheet so you can print and bind a physical book

**Tone**: warm, simple, age-appropriate. Short sentences. Active verbs. Pages feel like a hug, not a lesson.

**Time**: ~30 minutes wall clock. **Your attention**: about 8 minutes across 5 approvals. **Cost**: $1.20 – $2.80, depending on options.

## The hardest part — character consistency

Most AI image tools draw a different child on every page. That breaks the story — the reader's brain says "wait, who is this now?"

This playbook locks the character on page 1 and then **edits** that same picture for each later page rather than redrawing it. Same hair, same outfit, same face — different scene every time. Optional: if you supply 3-5 photos of your own child, the agent trains a quick character model so it's *your kid* in the book, not a generic one.

## Tell the agent about the story

```yaml
story_title:         # e.g. "Mira and the Sleepy Star"
child_name:          # e.g. Mira (the main character's name in the story)
age_range:           # 3-5 | 5-7 | 7-9 (affects sentence complexity)
character_look:      # 1-2 sentences. e.g. "a small girl with curly black hair, brown eyes, a yellow raincoat, and one missing front tooth"
story_about:         # 1-2 sentences. e.g. "She helps a tired star find its way home through her bedroom window."
setting:             # 1-2 sentences. e.g. "Her bedroom on a rainy night, then the sky, then a cloud city"
mood:                # one of: cozy-bedtime | adventurous-bright | gentle-learning | playful-silly
hero_color:          # one hex color anchoring the palette, e.g. #FFC857 for warm yellow
custom_character_photos:  # OPTIONAL — comma-separated URLs if you want your own child to BE the character.
                          # Leave blank to use the character_look description instead.
launch_slug:         # kebab-case for filenames, e.g. mira-sleepy-star
```

## How the agent should run this (interaction contract)

1. **CONFIRM (one message, ≤1 question):** restate in 1 line ("8-page book about <child_name>, <mood>, ~$1.20–2.80, ~30 min") + the real choices: description-only character (default) vs LoRA from your photos (+$1.50, +5 min) · audiobook on/off. Ask only the palette question; otherwise state assumptions and start.
2. **PREVIEW CHECKPOINT:** the character reference + 8-page outline (~$0.04 + text) gate everything; page 1 is the anchor gate — never batch pages 2–8 on an unapproved page 1.
3. **NARRATE:** 1 line + ETA per batch ("pages 2–4 rendering, kontext-edit, ~60–90s, jobs …"); poll `get_create_media` every 8–15s (LoRA training every 60s); never silent >2 min.
4. **FAIL GRACEFULLY:** page face-drift → ONE re-edit from the page-1 anchor with tightened "same face, hair, outfit"; gpt-image cover 422 or garbled title → soften → `nano-banana` → render the cover textless and put the title in the flip-book HTML (text-rendering ceiling); `ffmpeg-audio-mix` array bug → sequential `ffmpeg-concat` fallback (see Notes). 1-line WHAT/WHY/fallback; ≤2 retries per page; ship 8 pages with 1 flagged weak page over stalling.
5. **DELIVER:** flip-book HTML + audiobook MP3 + one honest line ("character holds on 7/8 pages; page 6's smile drifts — edit-chain ceiling") + ONE next step ("print it tonight, or refine page 6").

## What can disappoint (cap ceilings)

- **Edit-chain drift compounds** — each page edits from page 1, but small face/outfit shifts accumulate; pages 7–8 are the most likely to wobble.
- **Cover title text** — gpt-image renders titles best-in-class but still garbles names sometimes; the HTML-overlay fallback always works.
- **LoRA likeness is ~80%** — your child is recognizable, not photographic; set expectations before the +$1.50.
- **TTS warmth varies per take** — listen to page 1 before approving all 8 (the playbook gates this).

## Quality controls (new — auto-applied)

This playbook leverages the closed quality loop. The agent applies these by default; you don't have to ask:

- **Cost upfront.** Before any multi-step batch fires, the agent calls `submit_plan` with `confirm:false` and shows you the proposed steps + total cost. Nothing runs until you approve.
- **Auto-retry on weak shots.** The server default is `quality_threshold: 0.7`. For hero shots and brand-locked images the playbook step tells the agent to pass `quality_threshold: 0.85` so a low-confidence first try gets one auto-retry before you see it.
- **Critic verdict on the result.** When a multi-scene step finishes, the agent reads the `critique` field on the response (verdict: ship / iterate, plus issues / missing items) and surfaces it for your review.
- **One-click recovery.** If a step fails, `get_plan` returns a `recovery` hint pointing at `replan({plan_id})` — the agent classifies the failure and proposes a recovery plan you can approve.
- **End-of-project scorecard.** The final wrap-up calls `get_scorecard({project_id})` with succeeded count, mean quality score, critic verdict, total cost, and wall time.

You can override any of these per step: pass `quality_gate: false` on cost-sensitive tries, `quality_threshold: 0.6` for stylized/abstract work where strict adherence isn't the point, or `submit_plan({plan_id, confirm:true})` to skip the cost-preview pause when you trust the chain.

> **Character consistency (new):** after page 1 renders, the agent captures its URL as `quality_anchor_url` for every subsequent page. The cross-asset critic will catch face drift even if the per-image gate passes.

## How this works

Five gates. At each one the agent shows you what it made and asks one question. Answer in one word or one short phrase. You can always refine before approving.

## The steps

### Step 0 — Confirm and pick a palette

The agent reads back the BRIEF and suggests a 4-color palette based on the mood:

- **cozy-bedtime** → cream + amber + dusty blue + plum
- **adventurous-bright** → cream + magenta + sky blue + lime
- **gentle-learning** → cream + sage + butter yellow + slate
- **playful-silly** → cream + tomato + lavender + lime

**STOP**: "Brief and palette look right? (approve / palette [4 hexes] / edit [field] [value])"

### Step 1 — Lock the character and write the story (~1 min, or ~5 min if using your child's photos)

Two things happen here:

**A. The character reference.** The agent draws a full-body picture of the main character from your `character_look` description — neutral background, soft light, looking gently at the camera. This is the anchor image. Every later page edits from this one so the character stays the same.

*Optional path*: if you supplied photos of your own child, the agent uses them to train a small character model (~5 min, ~$1.50 extra) so the book's character looks like your actual kid. Skip this if you're using the description-only path.

**B. The story arc.** The agent writes an 8-page outline — one clear visual beat per page, 1-3 sentences each, sentence complexity tuned to the age range. Page 1 introduces the character and the world. Page 8 is the gentle resolution. Pages 2-7 are the journey.

> **For the agent**: write at these levels:
> - age 3-5: 6-10 words per sentence, simple present tense
> - age 5-7: 10-15 words, simple past + dialogue
> - age 7-9: 15-25 words, more emotion and interior thought

**STOP**: "Character reference + 8-page story shown. Approve, or refine? (approve / refine character [direction] / refine story [direction])"

### Step 2 — Page 1, the anchor (~30s, ~$0.04)

> **For the agent**: pass `quality_threshold: 0.85` on page 1 — it becomes the character anchor for every subsequent page, so a low-confidence first try poisons the whole book. The auto-retry fires once.

Draw page 1 by **editing** the character reference into the story's opening scene. Same character — same hair, same outfit, same face — now in the world of the story. This is the most important page to get right because it becomes the new anchor for pages 2-8.

> **For the agent**: use `create_media({ action: "restyle", model_override: "kontext-edit", source_url: <character_reference> })` (the identity-preserving editor). Prompt: "same character, same look as the source — now in this scene: [page 1's visual beat description]."

**STOP**: "Page 1 illustration shown. The character has to look right here — we're going to use it as the anchor for pages 2-8. Approve, or refine? (approve / refine [direction])"

### Step 3 — Pages 2, 3, 4 (~2 min, ~$0.12)

The agent generates pages 2, 3, and 4 in parallel. Each one edits from page 1 with a new scene description. The character should look the same across all three.

**STOP**: "Pages 2-4 ready. The character should look the same across all of them. Approve, or refine one? (approve / refine [page#] [direction])"

### Step 4 — Pages 5, 6, 7, 8 (~2 min, ~$0.16)

Same as step 3, for the back half of the book. After this, pages 1-8 should feel like one continuous story.

**STOP** (foldable): "Pages 5-8 ready. Pages 1-8 should feel like one continuous story. Final approval? (approve / refine [page#] [direction])" — if the user approved pages 2-4 without edits, you may run steps 3+4 as one wave and take a single pages-2-8 approval here.

### Step 5 — The cover (~30s, ~$0.04)

The cover is page 1's setting but more dramatic, with the title baked in.

> **For the agent**: use `gpt-image` (or `mai-image-2.5`) for the cover — these render readable title text far better than flux/kontext, so it looks like a real published book, not a hallucinated mess.

### Step 6 — The read-aloud (~3 min, ~$0.03)

For each of the eight pages, the agent records a short narration in a warm, gentle voice via `create_media({ model_override: "chatterbox-tts" })` (or `inworld-tts` for a more natural read). Each one is 1-3 sentences (under 10 seconds of speech).

**STOP**: "Listen to page 1's narration. Approve this voice for all 8 pages, or try a different one? (approve / try [gentler|warmer|slower])"

If you ask for a different voice, the agent re-records page 1; once you approve, it renders the other seven.

### Step 7 — Stitch the audiobook (no gate, ~2 min, ~$0.01)

Eight page narrations stitched into one MP3 with ~1 second of silence between pages — so the listener has time to turn the page mentally. The full audiobook runs 1-3 minutes, perfect for bedtime.

### Step 8 — Write the storybook HTML

The flip-book is a single HTML file with:

- A cover page with the title
- 8 page spreads, each with the illustration, the page's text, and a "▶ read this page" button that plays the per-page audio
- A "▶ read the whole story" button on the cover that plays the full audiobook
- A print stylesheet — open in a browser, ⌘P / Ctrl+P, print "backgrounds: yes" and you get two pages per A4 sheet, ready to fold and staple into a physical booklet

Saved to `public/launches/{launch_slug}-storybook.html`.

### Final step — scorecard wrap-up

After all deliverables ship, call:

```
get_scorecard({ project_id: "{the project id from earlier steps}" })
```

The response is a one-page report card:

```
Scorecard for cjob_xxx
{N}/{N} scenes shipped — critic: SHIP (or ITERATE)
Title: <your project name>
Steps: N/N succeeded (100%)
Quality: mean X.XX · M/N passed · K retries
Critic: SHIP/ITERATE
  • issue: <only present if iterate>
  • missing: <only present if iterate>
Cost: $X.XX actual (est $Y.YY) · Ts wall time
Viewer: <project URL>
```

Paste the scorecard into Slack or the project channel so reviewers see the actual quality numbers, not vibes.

## When you're done

The agent prints:

```
✅ Storybook flip-book: public/launches/{launch_slug}-storybook.html
✅ Cover: <URL>
✅ 8 pages: see flip-book
✅ Audiobook MP3 (full): <URL>

Total spent: $X.XX
Total wall-clock: MM:SS

To read tonight:
  Open the storybook HTML on a tablet. Tap "read the whole story" and
  the audiobook plays while your child looks at the pages.

To print:
  Open in a browser, ⌘P / Ctrl+P, turn on "Print backgrounds: yes".
  Prints two pages per sheet for a foldable physical booklet.
```

## What to do next

1. **Read it tonight** — the audiobook is 1-3 minutes; perfect bedtime length.
2. **Print and bind** — the print stylesheet lays out two pages per A4 sheet. Fold, staple, hand to the child. About $2 at a print shop.
3. **Send to grandparents** — the flip-book HTML works on any browser. Email the URL or send the file.
4. **Save the character + brief** — next book uses the same character. Build a series. Books 2 and 3 are an afternoon of work each.
5. **For a classroom** — if a child is in a class, you can run the playbook once per child (swap `child_name` + `character_look`). 30 books in an afternoon, about $60 total.

---

## Notes for the agent (only read if a step fails)

**Character anchor mechanism**: page 1 generation passes the character reference image as `source_url` to the identity-preserving editor. Pages 2-8 pass page 1's URL as `source_url`. This chains visual identity forward without drift.

**Optional LoRA path**: if `custom_character_photos` is non-empty in the BRIEF:
1. Submit a LoRA training job with the photos and a trigger word like `{child_name}_kid`.
2. Poll training status every 60s; takes ~4-6 minutes.
3. On training completion, pass the LoRA weights + trigger word in every later page-image call instead of the source_url-chaining pattern.

**Audiobook stitching**: the `ffmpeg-audio-mix` capability (with a `tracks` array + per-track `delay`) hits the MCP envelope array-drop bug. Fallback: use sequential `ffmpeg-concat` on the audio tracks via direct SDK (it accepts up to 30 clips with `transition: "cut"`):

```bash
curl -X POST https://sdk.daydream.monster/inference \
  -H "Authorization: Bearer $DAYDREAM_API_KEY" -H "Content-Type: application/json" \
  -d '{"capability":"ffmpeg-concat","params":{"clips":[<page1_audio>,...,<page8_audio>],"transition":"cut"}}'
```

**Polling**: poll `get_create_media` every 8-15s until `done` or `failed`. LoRA training polls every 60s.

**On capability failure**: retry once after 5s. On second failure, ask the user.

**Templates**: substitute `{{PLACEHOLDER}}` markers in `public/playbooks/_templates/storybook-flipbook.html`. The template handles the 8-page layout, per-page audio buttons, sticky audiobook bar, and print stylesheet. Fill in: `{{STORY_TITLE}}`, `{{CHILD_NAME}}`, `{{COVER_IMAGE_URL}}`, `{{AUDIOBOOK_URL}}`, `{{BACK_COVER_BLURB}}`, `{{PALETTE_HEXES}}`, and `{{PAGES_HTML}}` (an array of 8 page sections — see the template comment for the exact shape).
