---
reliability: 4.0 # 5 − .2 tts − .3 scene image gen − .3 infographic image gen − .2 6th-stage overflow; letter LLM-only, Ken-Burns video is deterministic ffmpeg (loop/concat/mux); no proven E2E showcase
---

# Charity appeal — 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 year-end appeal package for your organization:

- **A 90-second appeal video** with a warm voiceover from your executive director (or whoever signs the letter)
- **An impact infographic** that shows your year in plain numbers
- **An appeal letter, email-ready** — paste into Mailchimp, Substack, or any newsletter tool
- **A thank-you postcard** for after donors give
- **An appeal landing page** with your donate button

**Tone**: trust, plainness, faces over graphics, numbers over adjectives. Restraint is the aesthetic. Glamour kills credibility in this work — what you make should look *less* designed than a brand campaign, not more. Your supporters give because they trust you. The design has to match.

**Time**: ~20 minutes wall clock. **Your attention**: about 6 minutes across 5 approvals. **Cost**: $1.20 – $2.10 end to end. (We keep the budget low because every dollar of overhead is a dollar that doesn't reach the people you serve.)

## Three rules the agent will enforce — no exceptions

This work has higher stakes than commercial. Before any step runs:

1. **No fabricated faces of the people you serve.** If you ask for a "real beneficiary photo," the agent will refuse and route to a real photo your org owns. Generated images stay abstract or illustrative.
2. **Every impact number comes from your real data.** If your BRIEF is missing a number, the agent leaves it blank and asks you — it will not invent a plausible-sounding stat.
3. **No stock-photo glamour.** Restraint is the aesthetic. If a generated image feels like a corporate brochure, the agent regenerates it plainer.

If your BRIEF asks the agent to violate any of these, it will halt and ask you to confirm before continuing.

## Tell the agent about the appeal

```yaml
org_name:            # e.g. Maplewood Food Bank
org_mission:         # one sentence, e.g. "We get groceries to families in our county who can't make it through the month."
year:                # current year, e.g. 2026
impact_stats:        # 3-5 hard numbers FROM YOUR ACTUAL DATA. Examples:
                     #   - "423 families served"
                     #   - "$0.92 of every dollar reaches a family"
                     #   - "11,540 meals delivered"
                     # Format as bullet list.
beneficiary_archetype: # WHO you serve — one sentence. e.g. "working parents, single grandparents, families with young kids"
                       # NOT a specific person. We will not generate their face.
ask_amount:          # the suggested donation, e.g. "$50"
ask_unit:            # what one unit of the ask buys, e.g. "50 meals" or "a week of groceries for a family"
appeal_window:       # date range, e.g. "December 1 – December 31, 2026"
donor_voice_speaker: # name + title of the human signing the letter. e.g. "Sarah Chen, Executive Director"
                     # This is who narrates — adds the trust signal. Use a real name.
donate_url:          # the actual donation page URL, e.g. "https://maplewoodfoodbank.org/donate"
launch_slug:         # kebab-case for filenames, e.g. maplewood-foodbank-2026-eoy
```

## Quality controls (new — auto-applied)

> **Restraint posture:** this playbook deliberately produces non-polished imagery (documentary aesthetic). Each step tells the agent to **skip the auto-retry on hero shots** (`max_quality_retries: 0`) so a first take with documentary roughness stays. The cross-asset critic still fires — its job here is to flag glamour creeping in, not to enforce polish.

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.

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

1. **CONFIRM (one message, ≤1 question):** restate in 1 line ("year-end appeal package for <org>: 90s video + infographic + letter + postcard + landing page, ~$1.20–2.10, ~20 min") + real choices: palette (the mission-matched default vs your 4 hexes) · voice clone of the speaker vs default warm narrator. The ONE question that matters is Step 1's: "are these impact numbers from your real data?" — never invent a stat.
2. **PREVIEW CHECKPOINT:** the **verified numbers + the full appeal script/letter ($0.01)** BEFORE any TTS or image spend — the trust lives in the words and the numbers, not the renders. Second cheap gate: the 3 atmospheric scenes (~$0.10) before video assembly.
3. **NARRATE:** 1-liner per step with ETA ("voicing 90s narration, ~1–2 min", "Ken-Burns assembly: loop ×3 → concat → mux, ~2 min"); poll `get_create_media` every 8–15s, never silent >2 min.
4. **FAIL GRACEFULLY:** scene comes out glossy/stock → regenerate with "more restrained, plainer composition" (≤2 retries) — glamour is the failure mode here, not roughness; infographic digits garble → `mai-image-2.5`/`gpt-image` only, still garbled → typeset the numbers in the HTML deliverable instead of the image; 90s TTS exceeds the per-call cap → split 2×45s + concat; `ffmpeg-loop` duration not exposed via MCP → direct SDK `/inference`. A letter + infographic without the video still ships.
5. **DELIVER:** the 3 files + video + infographic URLs + one honest line ("generated scenes are illustrative, no real faces — run the five-line publish check before going live") + ONE next step ("A/B the ask amount: each rerun ~$2").

## How this works

Five gates. At each one the agent shows you what it made and asks one question. Answer with one word or one short phrase. The first gate is unusual — it's a numbers check, not a design choice. We do that first because the numbers are load-bearing.

## The steps

### Step 0 — Confirm and pick a palette

The agent reads back the BRIEF and suggests a 4-color palette appropriate to your mission:

- **food / hunger** → cream + terracotta + sage + ink
- **education** → cream + forest green + butter yellow + ink
- **refugee / housing** → cream + dusty blue + soft ochre + ink
- **medical / care** → cream + claret + sage + ink
- **environment** → cream + leaf + sky + ink

These are muted on purpose. They read trustworthy, not festive.

**STOP**: "Brief and palette look right? Especially: check the impact numbers come from your real data. (approve / palette [4 hexes] / edit [field] [value])"

### Step 1 — Verify the impact numbers (no spend, ~30s)

The agent reads back your `impact_stats` one by one and asks you to confirm each is correct (no rounding, no embellishment). This is the only gate without any generation — numbers are load-bearing in fundraising; we double-check before they go in the appeal.

**STOP**: "I will use these numbers as-is in the appeal. Confirm each is correct: [list each stat]. Approve, or edit? (approve / edit [stat#] [new value])"

### Step 2 — Write the appeal letter and narration (~1 min, ~$0.01)

The agent writes a 90-second spoken appeal from `donor_voice_speaker`. The script follows a specific arc:

1. **Open (10s)** — A specific small moment from this year. Not statistics yet — a single concrete image.
2. **Why this year (20s)** — What changed for the people you serve.
3. **The numbers (20s)** — Your impact stats, plainly. "Three hundred forty-seven. Served. Delivered." Never decorate the numbers.
4. **The mission in one sentence (10s)** — `org_mission` restated cleanly.
5. **The ask (15s)** — "$50 buys 50 meals. If 200 of you give, we feed [calculation]." Specific and small.
6. **Close (15s)** — Thanks the listener as a peer, not a beggar. Mentions the `appeal_window`.

The agent also writes a longer 5-paragraph version of the same letter, paragraph-by-paragraph, for the email.

Tone: plain, warm, slow. Not urgent. Not emotional manipulation. Trust comes from sounding like a real person who shows up to work and knows the families.

**STOP**: "Appeal script and email version shown. Approve, or refine the tone? (approve / refine [direction])"

### Step 3 — Voice the appeal (~2 min, ~$0.015)

The voice must be warmer and slower than a commercial. Not perky, not urgent — trustworthy.

> **For the agent**: use the warm narration voice (not the upbeat brand voice). If a voice clone of `donor_voice_speaker` is supplied in the BRIEF, use it. Otherwise the default warm-female works.

**STOP**: "Play the narration. Does it sound like someone trustworthy enough to be your executive director? (approve / re-voice [slower|warmer|less-perky])"

### Step 4 — Three atmospheric scenes (~2 min, ~$0.10)

Three illustrations. Atmospheric. Restrained. No faces we generated, no stock-photo polish.

1. **The opening moment** — a pair of hands receiving a paper grocery bag, soft window light, no faces. The small moment the letter opens with.
2. **The work** — interior of your org during a busy hour. Volunteers' backs to camera, boxes being moved, full tables. No identifiable faces.
3. **The result** — a doorway at evening light, full bags lined up waiting to be carried out. Empty room, no people. Hopeful but plain.

> **For the agent**: hand-illustrated style, NOT photorealistic. If a scene comes out too glossy or "stock photo," regenerate with "more restrained, less staged, plainer composition" appended.

**STOP**: "3 atmospheric scenes shown. Each should look plain, not glamorous. Faces are abstract. Approve, or regenerate one? (approve / regen [scene#] [direction])"

### Step 5 — The impact infographic (~1 min, ~$0.04)

One clean infographic. Vertical layout. Four big numbers stacked, each with a short plain-language label below. At the bottom, your `org_mission` in one line. Cream background. No photographic elements — just typography.

Looks like a printed annual report page, not a marketing graphic.

> **For the agent**: use `mai-image-2.5` (best photoreal + readable in-image text) or `gpt-image` for the infographic — the numbers must be perfectly legible, that's the whole point. Do NOT use flux-dev/recraft for number-heavy typography; they garble digits.

### Step 6 — The 90-second appeal video (~3 min, ~$0.20)

Not a cinematic edit. The agent builds a slow Ken-Burns sequence over your 3 scenes from step 4 (~30 seconds each as a static loop via `ffmpeg-loop`), concats them to a ~90s base (`ffmpeg-concat`, `transition: "cut"`), then muxes the 90-second narration over the whole thing with `ffmpeg-mux` (the VO already runs the full length, so the visuals are sized to match it — no looping needed). Three slow stills, the speaker's voice all the way through. The pacing feels like a real letter being read, not an ad.

**STOP**: "Appeal video ready. The pacing should feel slow and real — not like an ad. Approve, or re-do? (approve / redo [direction])"

### Step 7 — Three deliverables written (no gate)

**Appeal landing page** — `public/launches/{launch_slug}-appeal.html`. A quiet single-page landing with: org header, the appeal video, the 5-paragraph letter, the impact numbers block, the three scene images as a strip, the ask block with the donate button, and a final thank-you line.

**Email-ready letter** — `public/launches/{launch_slug}-letter.md`. A plain markdown file with the 5-paragraph letter, the impact stats as a bullet list, the mission line, and the ask + donate URL. Paste-ready into Mailchimp, Substack, or any newsletter tool.

**Thank-you postcard** — `public/launches/{launch_slug}-postcard.html`. A small A6 print-ready postcard you send to donors *after* they give. The thank-you is itself a signal for next year's appeal.

### 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:

```
✅ Appeal landing page: public/launches/{launch_slug}-appeal.html
✅ Email-ready letter: public/launches/{launch_slug}-letter.md
✅ Thank-you postcard: public/launches/{launch_slug}-postcard.html
✅ Appeal video (90s): <URL>
✅ Impact infographic: <URL>

Total spent: $X.XX (budget was $4)
Total wall-clock: MM:SS
```

## Before you publish — a five-line check

The agent will ask you to confirm:

- [ ] Every number in the infographic comes from a real source the org can defend.
- [ ] No generated image looks like a specific real person.
- [ ] The narration speaker's name and title is accurate.
- [ ] The donate URL works.
- [ ] The appeal window dates are correct.

If any are no, fix before going live.

## What to do next

1. **Email the letter** to your list — paste the markdown into Mailchimp. The infographic is a separate image attachment.
2. **Post the appeal video** on your donate landing page. Not on TikTok / IG — this isn't social content, it's a direct ask.
3. **Print 200 postcards** at a local print shop for ~$30. Send to your top 200 donors as thank-yous *after* they give.
4. **Save the brief** — re-run next year with refreshed `impact_stats` and `year`. Year two should look like year one's sibling. Supporters notice continuity.
5. **A/B the ask** — re-run with `ask_amount` = $25, $50, $100. Three appeal pages, each one a sibling of the others. Watch which converts. Each rerun is about $2.

---

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

**The Ken-Burns sequence**: this is unusual for this playbook because the appeal video isn't cinematic — it's an animated still sequence. For each scene from step 4, use `ffmpeg-loop` (direct SDK, the MCP envelope doesn't expose `duration` cleanly):

```bash
curl -X POST https://sdk.daydream.monster/inference \
  -H "Authorization: Bearer $DAYDREAM_API_KEY" -H "Content-Type: application/json" \
  -d '{"capability":"ffmpeg-loop","params":{"source_url":"<scene_url>","duration":30}}'
```

Then concat the 3 loops with `transition: "cut"`, then mux the narration on top with `ffmpeg-mux`.

**Long narration**: if the 90-second script exceeds the warm-narration model's per-call cap, split into 2 chunks of ~45s each and concat the wavs locally before mux.

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

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

**Templates**: substitute `{{PLACEHOLDER}}` markers in `public/playbooks/_templates/appeal-letter.html`. The template is deliberately restrained — no gradients, no flex flourishes. Fill in: `{{ORG_NAME}}`, `{{ORG_MISSION}}`, `{{YEAR}}`, `{{SPEAKER_NAME}}`, `{{APPEAL_VIDEO_URL}}`, `{{INFOGRAPHIC_URL}}`, `{{IMPACT_STATS}}` (as `<dl>` rows), `{{LETTER_PARAGRAPHS}}` (as `<p>` blocks), `{{ASK_AMOUNT}}`, `{{ASK_UNIT}}`, `{{DONATE_URL}}`, `{{APPEAL_WINDOW}}`, `{{SCENE_IMAGES}}` (3 `<img>` tags), plus palette hexes.

**Ethics-rule enforcement**: if the BRIEF asks for a photorealistic close-up of a "real beneficiary," halt and ask the user to provide a real photo their org owns. If `impact_stats` is missing or vague, halt and ask for a specific number. If a generated image comes out glossy or stock-photo-feeling, regenerate with "more restrained, less staged, plainer composition."
