返回 ppt-master
image-generator.md
根目录 / skills / ppt-master / references / image-generator.md
1 > See [`image-base.md`](./image-base.md) for the common framework. For the web sourcing path, see [`image-searcher.md`](./image-searcher.md).
2
3 # Image_Generator Reference Manual
4
5 Role definition for the **AI image generation path**: convert each active `Acquire Via: ai` row into an optimized prompt, generate the image, and save it to `project/images/`; also defines the `slice` derivation path for AI-generated illustration sheets.
6
7 **Trigger**: the Default Generate resource list contains `Acquire Via: ai` or `slice`, or Quick Generate has resolved a required AI/sliced image in active context. Load only when at least one such resource exists.
8
9 ---
10
11 ## 1. Core Principle — Maximize AI Image Capability in Service of the Deck
12
13 AI images exist to serve the deck's communication goal. Pick whatever combination of `page_role` and `text_policy` makes the page work best.
14
15 **Two page roles** (orthogonal to type):
16
17 | `page_role` | Use |
18 |---|---|
19 | `local` | Image occupies a prepared SVG region. The AI composes inside that bitmap/container; it does not choose the page region or final SVG geometry |
20 | `hero_page` | Image is the page's main voice — cover, chapter divider, mood transition, single-number hero, closing quote. SVG above may be minimal or empty |
21
22 **Two text policies** (orthogonal to page_role):
23
24 | `text_policy` | Use |
25 |---|---|
26 | `none` | No text inside the image |
27 | `embedded` | Image contains stable text as part of the artwork — decorative lettering, artistic wordmarks, hand-lettered keywords, or figure-internal labels |
28
29 **Hard rule — only what's actually hard**:
30
31 - Same `deck_rendering` + same core deck color anchors/semantic behavior for every image in the deck
32 - HEX codes and color names are rendering guidance — never visible text in the image
33 - Long body copy / data points / bulleted lists / long quotes stay in SVG (improving them later means regenerating the image, which is expensive)
34 - **In-image text is only for words that will not need editing later** — visual keywords, decorative lettering, mood words. Editable text (titles that may be reworded, subtitles, dates, authors, captions, body) belongs in SVG. Changing one in-image word costs an image regeneration; one SVG word costs a keystroke.
35 - Prompts are one coherent prose paragraph, not tag soup (a model-output reality, not an aesthetic choice)
36
37 Everything else inside the prepared bitmap is the AI's judgment per page. No mandated padding, no type-locked text_policy, no scenario whitelists for hero_page.
38
39 ---
40
41 ## 2. Style and Composition Inputs
42
43 Every AI image uses one deck-wide rendering, the deck's stable color anchors/semantic behavior, and a per-image type / internal composition. Only rendering is a separate image-direction decision.
44
45 | Dimension | Decides | When fixed |
46 |---|---|---|
47 | **Rendering** | Visual style family (vector / sketch-notes / 3d-isometric / corporate-photo / …) | Once per deck — every AI image in the deck shares one rendering |
48 | **Deck colors** | Core background / primary / accent / secondary-accent / text anchors from `spec_lock.md colors` in Default Generate, or from the active-context visual decisions in Quick Generate | Default: anchored after Stage 2; Quick: resolved before acquisition |
49 | **Type** | Optional recall for a local structural infographic's internal skeleton (infographic / flowchart / framework / matrix / cycle / funnel / pyramid / comparison / timeline / map / scene). Use it when one template fits; otherwise omit type and write the composition directly in §4.1 E prose. Local single-subject/portrait and `hero_page` images also omit type. | Per image |
50
51 > Rendering decides *how the image is drawn* (line quality, texture, depth). Color instructions begin from the deck roles: background / secondary background usually dominate, primary carries main forms, and accents stay scarce. Adjust proportions and derive coherent lighting/material/tint transitions for the image context; do not replace the deck's identity with an unrelated image-only palette.
52
53 ### 2.1 Where to find each dimension
54
55 | Reference | Loaded |
56 |---|---|
57 | [`image-renderings/_index.md`](./image-renderings/_index.md) — rendering catalog + auto-selection table | Always (Step 1 below) |
58 | [`image-type-templates/_index.md`](./image-type-templates/_index.md) — type catalog + auto-selection table | Always (Step 1 below) |
59 | `image-renderings/<chosen>.md` | After Step 2 resolves the rendering — one preset file, or every exact reference listed for `custom` |
60 | `image-type-templates/<chosen>.md` | After Step 3 picks the type per image — only the types actually used |
61
62 **Hard rule — on-demand loading**:
63
64 - Read the rendering and type `_index.md` files once at role entry.
65 - After locking inputs, read **only** the specific preset rendering, custom rendering references, and type files selected.
66 - **Never** glob-read an entire subdirectory (`image-renderings/*.md` is forbidden). Token cost balloons and the AI loses focus.
67
68 ---
69
70 ## 3. Workflow
71
72 ### Step 1 — Load the dimension indices
73
74 Read the two index files that own user-visible image direction and per-image internal composition.
75
76 ```
77 read_file references/image-renderings/_index.md
78 read_file references/image-type-templates/_index.md
79 ```
80
81 ### Step 2 — Resolve deck-wide rendering + deck colors
82
83 **Default Generate path — Strategist already recorded rendering and core deck color anchors in `spec_lock.md colors`**:
84
85 ```
86 image_rendering: vector-illustration
87 background: #F8F9FA
88 primary: #1E3A5F
89 accent: #D4AF37
90 ```
91
92 Use them as identity anchors. Do not create another user-facing image-color choice. The rendering and image subject may derive coherent tonal transitions, material colors, lighting, and atmospheric hues when the context requires them, while the core roles keep their established meaning.
93
94 **Quick Generate path**: the main agent resolves one active-context rendering/color set, honoring explicit user values and deciding the rest without interaction. Write it to `image_prompts.json`; create no planning artifacts.
95
96 **Hard rule — `custom` catalog basis**: when `image_rendering` is `custom`, first inspect the optional `image_rendering_references` row. If present, read every exact `image-renderings/<id>.md` it lists and synthesize their line, texture, depth, material, and mood guidance under `image_rendering_behavior` before assembling prompts. If absent, the custom is genuinely novel: read no preset file and use `image_rendering_behavior` directly. Never infer or add adjacent references during execution. The deck color-role rows remain authoritative.
97
98 **Declared-inference fallback — when an existing `spec_lock.md` omits the `image_rendering` key** (see [`failure-recovery.md`](../workflows/governance/failure-recovery.md) §2):
99
100 This fallback covers a missing key only. An empty or invalid value stops for lock repair. Outside the active [`quick-generate`](../workflows/profiles/quick-generate.md) profile, if `spec_lock.md` itself is absent, stop at [`generate-pptx.md`](../workflows/generate-pptx.md) Step 5 before prompt assembly or image generation; do not use `design_spec.md` as a substitute.
101
102 | Signal | Maps to |
103 |---|---|
104 | `design_spec.md d. Style` mode + descriptor | Rendering (consult renderings `_index.md` auto-selection table) |
105 | Existing `spec_lock.md colors` rows | Deck color anchors; interpret them with the completed `design_spec.md`, never replace confirmed identity from a second palette |
106 | Existing `spec_lock.md icons.library` | Sanity check: chosen rendering should be compatible with the icon library's visual weight |
107
108 If rendering inference surfaces multiple candidates, pick the first; do not present another choice after confirmation.
109
110 If the table returns `custom`, stop and repair the lock: authoring `image_rendering_behavior` is a planning decision this fallback cannot make, and the deck's SVG style prose is not an image-rendering description.
111
112 > **Tell the user**: when falling back, print one line "spec_lock.md has no `image_rendering`—inferring `<X>` from design_spec; image colors still use the locked deck roles." Then proceed.
113
114 Then read the **single resolved** rendering file. It gives you:
115
116 - The 80-120 word style paragraph (rendering)
117 - Two ready-to-paste rendering snippets (fewshot)
118
119 Derive color behavior from the available roles and image context: background / secondary background usually carry most of the field, primary carries main forms, and accent / secondary accent remain selective. A rendering may justify a different balance and coherent derived tones; decorative text colors must remain readable. Add a new lock role only when that derived color becomes a reusable cross-image semantic token.
120
121 ### Step 3 — Per-image type + assembly
122
123 For each `Acquire Via: ai` row, use Strategist-owned §VIII/lock by default or the main agent's active-context Quick resource decision. Explicit values remain binding; Quick resolves omissions automatically.
124
125 `Layout pattern` is a page-realization preference and is not copied wholesale into the bitmap prompt. Any generation-time subject direction, focal placement, quiet region, or overlay-safety requirement must therefore be present in the row's `Reference`, the matching §IX block, or Quick's active-context visual intent.
126
127 1. **Determine `page_role`** — the owning row's explicit value wins; a blank or omitted value resolves to `local`. In Default Generate, `hero_page` must be Strategist-explicit; in Quick Generate, the main agent may resolve it before acquisition in active context.
128 2. **Determine `text_policy`** — the owning row's value wins when set. **Declared-inference fallback for a blank or omitted value**: pick `none` or `embedded` from the row's `Purpose`, `Reference`, and page intent based on whether in-image text serves the page. Long body / data / lists stay in SVG.
129 3. **Determine type or free composition** — an Illustration Sheet omits manifest `type` and follows §4.3's grid composition. For another local structural infographic, use one of the 11 types only when the `_index.md` offers a real match; otherwise omit type and author the intended structure directly with §4.1 E. A local single-subject/portrait image omits type and uses §4.1 A/B inside its actual region. A `hero_page` omits type and uses §4.1 A/B/C/D/E.
130 4. `read_file references/image-type-templates/<type>.md` only when a type was selected (and only if not already read).
131 5. **Assemble the prompt** by combining:
132 - The rendering's style paragraph (from Step 2)
133 - Color-role instructions anchored by the deck HEX values and refined for the image context (from Step 2)
134 - The selected type's structural layout, or the no-type composition prose (from Step 3)
135 - The image's specific `Reference` intent (from `design_spec.md §VIII` or the Quick Generate active-context decision)
136 - Container sizing from the selected type file, or the row's Dimensions for no-type prose
137 - The hard rules from §5 below (HEX-not-as-text, rendering-aligned human depiction and likeness authorization, text policy)
138
139 The assembled prompt is **one cohesive paragraph**, not a bulleted list of tags. See §4 for the assembly template.
140
141 ### Step 4 — Write the manifest and execute the selected path
142
143 Write `project/images/image_prompts.json` per §6, then follow §7. Default uses its confirmed path; Quick uses an explicit active-context path or `auto` without asking.
144
145 ---
146
147 ## 4. Prompt Assembly Template
148
149 Every assembled prompt follows this paragraph structure. **Write prose, not tag soup**.
150
151 ```
152 [Rendering style paragraph — 80-120 words from the chosen rendering file].
153 [Deck color behavior — state the core anchors and any context-justified tonal treatment, e.g. "secondary background #F8F9FA provides the breathing field, primary #1E3A5F carries main forms, accent #D4AF37 marks one emphasis; subtle lighter/darker material transitions remain in the same visual family"].
154 [Composition — from the chosen type file or §4.1 no-type prose].
155 [Image-specific subject — translated from the row's Reference intent into concrete visual nouns].
156 [Container note — "composed as a {W}x{H}px image for {page_role} use"; add composition cues only when the page actually needs them. SVG-overlay-reservation cues ("leave the lower band calm — SVG title overlays it", "keep the right third calmer for SVG text") are valid when `page_role: hero_page`, or when §VIII `Reference` / §IX `Layout` explicitly plans native labels, hotspots, lenses, or other SVG overlays inside a `local` image region. Otherwise a `local` image is a self-contained region block and reserves no interior overlay space].
157 [Hard rules — see §5].
158 ```
159
160 **Word budget**: 150-300 words. Embedded-text prompts skew longer; pure background prompts can be shorter.
161
162 **Forbidden — tag-soup prompts**:
163
164 ```
165 ❌ "modern, flat design, gradient, vibrant, professional, clean, 4K, high quality"
166 ```
167
168 This produces generic, model-average output. The model is not weighting your tags — write **one coherent visual scene** instead.
169
170 ### 4.1 No-type composition primitives
171
172 Use these when no structural type applies. A/B can describe either a hero image or a local single-subject/portrait region; scale their framing to the actual container. C/D are hero-page compositions. E authors any custom hero or local composition, including a structural infographic that does not genuinely match one of the 11 type templates.
173
174 **Primitive A — single dominant subject (product / object / concept hero)**
175
176 > Start with one dominant subject as the clear focal point, positioned with intent (centered, rule-of-thirds offset, or slight left/right). Scale it to command the container while keeping supporting context subordinate. Leave a deliberate open side when the page composition needs breathing room or an overlay; no fixed padding is implied. No second-place subject competing.
177
178 Use for: product reveal, concept introduction, chapter-opener visual, brand statement, or a local single-object region.
179
180 **Primitive B — single human subject (portrait)**
181
182 > One person, frontal or three-quarter turn, head + upper body. Start with the face as the clear focal point, centered or rule-of-thirds offset, with eyes near the upper-third horizontal line. Background neutral, minimal, or softly blurred. Keep comfortable headroom and no competing foreground objects; adjust framing to the container rather than enforcing fixed padding.
183
184 Use for: founder profile, speaker bio, testimonial page, or executive intro, including a local bio region. Let the chosen rendering and Reference determine photographic, editorial, painterly, graphic, or other figure treatment; see §5.2.
185
186 **Primitive C — typographic hero (the text *is* the image)**
187
188 > The image's central content is one large text element — a short headline, big number, or single word — rendered as art and carrying dominant visual weight. Keep any supporting visual (small icon, geometric anchor, accent line) clearly subordinate. Give the letterforms enough breathing room for readability, adjusting scale and spacing to the actual text and container.
189
190 Use with `text_policy: embedded`. Must obey the §5.3 rule — text that is part of the artwork and stable can be embedded; copy that must stay exact or editable goes to SVG overlay (switch to Primitive D).
191
192 **Primitive D — atmospheric backdrop (no subject)**
193
194 > Atmospheric field with no dominant subject — gradients, subtle patterns, or restrained color blocks. A small geometric anchor may sit in a corner or along an edge. Arrange visual activity around the SVG overlay region named by the page plan so that region stays calm enough for its title or text; its position and extent follow the composition rather than a fixed percentage.
195
196 **Applies to `page_role: hero_page` only.** The "calm center for SVG overlay" contract defines this primitive. A `local` image uses §3 type templates or §4.1 A/B/E instead; when §VIII / §IX explicitly plans native overlays inside that region, its prompt may reserve only the named focal/quiet area without turning the whole asset into Primitive D.
197
198 Use for: cover background, chapter divider background, breathing-page background, any page where the SVG layer carries the words and the image only sets tone.
199
200 **Primitive E — custom (escape hatch)**
201
202 When none of A/B/C/D describe the page's intended layout (triptych, asymmetric multi-focal, narrative diorama, etc.), write the composition description directly into the prompt's composition sentence — same paragraph slot A/B/C/D occupy, but in your own words. No new field; the freedom is in the prose.
203
204 **Default — concise custom composition prose (may override for subject accuracy)**:
205
206 | Rule | Value |
207 |---|---|
208 | Length | One paragraph, 2-5 sentences, replacing A/B/C/D's opening paragraph |
209 | Content | State enough subject count and layout structure to make the composition executable; include breathing room or an SVG-overlay region only when the page composition actually needs it |
210 | Clarity | Describe the actual geometry; a primitive name alone is not a substitute |
211
212 Example opening for a triptych hero:
213
214 > Triptych — three equal vertical bands of canvas, each holding one symbolic object centered in its band; objects share a low horizon line; bands separated by 2px hairline rules; collectively reads as a single composed page. [...rest of prompt continues with rendering paragraph + color behavior + container note...]
215
216 **Fewshot examples per primitive** (one each, deck-context placeholders intact):
217
218 > **A — 3d-isometric + deck-color product reveal, text_policy: none, 600×600**
219 >
220 > 3D isometric illustration in true 30°/30°/30° projection. One dominant product-form subject — a stylized device or sleek tech object — commands the center of the canvas. The subject is rendered in primary electric blue `#0EA5E9` on its lit faces, with 15% darker tonal shift on shadowed faces. A subtle 8%-opacity outer glow halo surrounds the subject. Small supporting context: three thin connecting lines in accent vivid cyan `#06B6D4` arcing from the subject toward the canvas edges (suggesting connectivity), and a soft 8% drop shadow grounding the subject. Background is deep secondary navy `#0A0E27`, including the shadowed plane. The subject is clearly the singular focal element, with deliberate breathing room around it. Composed as a 600×600 hero block. NO text, letters, numbers, or labels anywhere. Color values are rendering guidance only.
221
222 > **B — corporate-photo + deck-color executive headshot, text_policy: none, 600×800**
223 >
224 > Editorial corporate portrait photograph of one professional executive. The person is centered slightly left of canvas center, photographed from chest-up at eye level, looking confidently toward the camera with a relaxed natural expression — not posed-stiff, not over-smiling. Professionally attired in a contemporary business setting (a tailored blazer, neutral palette clothing). Soft natural light from the upper left, gentle shadow on the right side of the face. Diverse, professionally attired subject, photorealistically rendered, contemporary styling. Background is a softly out-of-focus office context — secondary light gray `#F8F9FA` wall with a subtle hint of primary deep navy `#1E3A5F` in a blurred architectural element. Color grading is restrained and professional. Shallow depth of field — subject sharp, background gently blurred. Subject's eyes positioned near the upper-third horizontal line, with comfortable headroom. Composed as a 600×800 bio portrait. NO text, name tags, or captions in the image. Color values are rendering guidance only.
225
226 > **C — ink-notes + deck-color big-number stat, text_policy: embedded, 800×500**
227 >
228 > Professional hand-drawn visual-note style on pure white background. The image's central content is the hand-lettered number "100x" — rendered in bold confident ink strokes as the dominant element, centered with deliberate slight wobble characteristic of hand-lettering. Beneath the number, a thin hand-drawn underline in ink. To the side of the number, one small hand-drawn doodle decoration — a star or upward arrow — adds visual rhythm. Accent coral `#E8655A` (from the deck's accent) appears only as a tiny emphasis dot, totaling under 4% of the canvas. Background is pure white `#FFFFFF`. Composed as an 800×500 typographic hero block with enough breathing room for the letterforms to read clearly. No other text or labels in the image — just the "100x" headline and the small doodle.
229
230 > **D — vector-illustration + deck-color cover background, text_policy: none, 1280×720**
231 >
232 > Clean flat vector illustration backdrop. Atmospheric composition with no central subject — bold geometric shapes arranged along the canvas edges to leave the planned central title field calm. Primary deep navy `#1E3A5F` forms a confident diagonal block across the lower-left area; secondary light gray `#F8F9FA` provides the breathing field; accent gold `#D4AF37` appears only as one thin geometric line near the lower right corner, under 5% of the canvas. Crisp 2px outlines, no gradients, a single 8% soft drop shadow under the navy block. The intended SVG title region is deliberately calm and unbusy. Composed as a 1280×720 full-bleed PPT background. NO text, letters, numbers, signs, watermarks, or written symbols anywhere in the image. Color values are rendering guidance only — do not display HEX codes or color names as text. Simplified geometric shapes only.
233
234 ### 4.2 Prompt depth — expand for subject-domain accuracy
235
236 **Hard rule**: For images whose deck purpose calls for subject-domain accuracy (scientific figures, academic paper figures, engineering schematics, medical / legal / regulated content), expand the prompt without budget ceiling — 500-1000+ words is normal. The §4 word budget (150-300) is the routine-illustration default, not a cap.
237
238 **Forbidden — pre-emptive shortening**: never trim a subject-domain prompt to fit §4's budget. Name the field's visual conventions explicitly in the prompt.
239
240 **Detail to name in the prompt** (illustrative, not an enumeration to match):
241
242 | Domain | Conventions to spell out |
243 |---|---|
244 | chemistry / materials | IUPAC atom colors, bond conventions, lattice type, Å / ps units, subplot labeling (A / B / C circles), view angle |
245 | biology | cell compartment colors, scale bars, organelle conventions, staining palette |
246 | physics | axis labels with proper symbols, signature curve shapes, unit annotations, peak labeling format |
247 | engineering | schematic notation, dimension callouts, section-cut conventions |
248
249 **When uncertain about field conventions**: read `sources/` before drafting the prompt.
250
251 ### 4.3 Illustration sheets — one generation, many spot elements
252
253 An illustration sheet can produce several small **spot illustrations** in one generation and preserve closely matched rendering, deck-color treatment, and line quality before slicing.
254
255 **Default — one sheet for a compatible spot family (may override when separate generation serves the assets better)**: Prefer a sheet when several elements share similar proportions, detail, quality, and semantic precision. Generate elements separately when those needs differ materially; quantity alone neither requires nor forbids a sheet. A single hero/local image stays with the normal one-row-per-image flow (§4.1).
256
257 **Hard rule**: a spot sheet is a generation source, not a slide asset. In Default Generate, keep the sheet row out of `spec_lock.md images`; in Quick Generate, retain its generation-only status in active context and the operational manifest. The sheet is never referenced from SVG. Only sliced element rows are placed.
258
259 **Sheet prompt convention** (one manifest item, `page_role: local`, `text_policy: none`, `image_size` chosen from final placement size):
260
261 - Choose the sheet `aspect_ratio` and `--grid` from the target element shape. Do not default every sheet to `1:1` + a symmetric grid.
262 - Lay the elements out in an explicit **R×C grid, evenly spaced with clear gutters**, each element **centered in its own cell** and isolated (no element bleeds into a neighbor).
263 - State the intended cell shape in the prompt: compact square object, tall portrait element, or wide landscape vignette. Do not let the model shrink every subject into a centered square sticker.
264 - One **flat single-color background** across the whole sheet, set to the deck's background/secondary HEX — this is what lets the slicer key it out cleanly and lets the cut element sit on the slide without a visible box.
265 - Shared `deck_rendering` + `color_scheme` as always. NO text, labels, or numbers anywhere (§5.1, §5.3).
266
267 **Cell geometry is designed, not assumed.** `slice_images.py --grid RxC` cuts rows first and columns second. The cell ratio is:
268
269 ```text
270 cell_ratio = sheet_ratio * rows / cols
271 ```
272
273 Use that deliberately. On a wide sheet (`16:9`, `21:9`, `4:1`, `8:1`), `1xN` makes each cell tall/portrait because the width is divided by `N` while height is kept; `Nx1` makes each cell wide/landscape because height is divided by `N` while width is kept. A designed `MxN` grid is also valid when the resulting cell ratio matches the intended placements.
274
275 | Target spot shape | Sheet plan | Slice grid |
276 |---|---|---|
277 | Compact objects / badges | `1:1` sheet | `2x2`, `2x3`, or `3x3` |
278 | Tall side accents / upright objects | wide or square sheet | `1xN`, or any `MxN` whose cells are portrait |
279 | Wide banners / horizontal vignettes | wide sheet | `Nx1`, or any `MxN` whose cells are landscape |
280
281 If one deck needs mixed shapes, create separate sheets per shape family unless one carefully designed grid gives every element enough room. Keep the visual family consistent through the same `deck_rendering` and `color_scheme`, not by forcing all cells into one square sheet.
282
283 **Resource contract — the sheet and its elements are different row kinds.** A sliced element can only be placed if it exists in the active placeable-resource authority: `spec_lock.md images` in Default Generate or the current agent's prepared resource decision in Quick Generate. Default Generate keeps both row kinds in §VIII under [`strategist-image.md`](./strategist-image.md); Quick Generate resolves the same distinction in active context and its operational manifest without creating planning artifacts:
284
285 - **Sheet row** — `Acquire Via: ai`, `Type: Illustration Sheet`, the intent prompt, named as the slice source with its intended cell shape and placement purpose (`Reference: landscape footer-vignette spot set`). It is generated in Step 5 but **never placed on a slide** — keep it **out of** `spec_lock.md images`. Image_Generator resolves the exact `aspect_ratio`, grid, and slice command from this intent.
286 - **Element rows** — one per used element, `Acquire Via: slice`, filename matching a `--names` output, `Reference` naming the parent sheet + cell/element. These **are** placed — list every one in the active placeable-resource authority, normally with `crop=no-crop` (a tight-trimmed transparent spot should be fit, not cover-cropped). Their dimensions are filled in after slicing (the preparation pass re-runs `analyze_images.py`). Each row carries an owner-resolved layout recommendation; SVG authoring may realize it as a direct cutout or inside an appropriate container while preserving the resource and crop/content constraints.
287
288 For traceability, add optional `slice_grid` and `slice_names` fields to the sheet item in `image_prompts.json` after choosing the geometry. `image_gen.py` validates, preserves, and displays these metadata fields; it does not run the separate slicing command.
289
290 **Slice** with [`slice_images.py`](../scripts/slice_images.py) — cells are cut row-major into individual files in `images/`. With `--alpha` they become transparent elements suitable for direct cutout placement or for composition inside a card, evidence frame, label, or other container. Recommended flags: `--names` (semantic per-cell filenames matching the element rows; the count **must** equal `rows*cols`), `--trim` (tight-crop each cell so imprecise placement inside a cell doesn't leave lopsided margins), `--alpha` (knock the flat background out to transparency so an element can sit on any slide color or container):
291
292 ```bash
293 python3 scripts/slice_images.py <project>/images/illus_sheet.png --grid 2x3 \
294 --names team,product,customer,growth,risk,vision --trim --alpha
295 ```
296
297 **Three constraints that decide whether it looks good**:
298
299 1. **Flat background, matched to the slide.** `image_gen.py` has no transparent-background mode, so the cut element carries whatever was behind it. A flat sheet background (= deck background HEX) is what `--alpha` keys out and what makes non-keyed pieces blend.
300 2. **Clean grid, or it cuts ugly.** State the exact row/column structure and cell shape so the model does not invent a square matrix; `--trim` absorbs smaller placement variance. Do not generate several sheets or read them back merely to choose a favorite; re-roll only when user/live-preview feedback exposes an unusable slice.
301 3. **Generate only as large as needed.** Each cell is a fraction of the sheet. Pick the smallest sheet size that keeps each sliced cell at least **1.5-2x** the intended display size. `1K` is usually enough for small 80-160px decorative spots; use `2K` for medium 180-320px placements; reserve `4K` for large, cropped, or potentially enlarged elements.
302
303 **Reference — sliced-asset placement is not a constraint**: A transparent slice may remain an unboxed cutout or enter a card, evidence frame, label, panel, or other suitable container. The owner-resolved layout text is an expression recommendation; SVG authoring owns the actual geometry and treatment while preserving the resource role and crop/content constraints.
304
305 **Through-line — one family, many roles.** A spot sheet pays off more when the same motif family also drives the cover and section dividers. A large cover / divider anchor is not a giant sheet cell—generate it as its own `hero_page` image sharing the sheet's `deck_rendering`, `color_scheme`, and subject world. Plan this only when the deck leans into illustration, never as a quota.
306
307 ---
308
309 ## 5. Global Hard Rules
310
311 These rules apply to **every** prompt regardless of dimension choices. Append them as a closing sentence to every assembled prompt.
312
313 ### 5.1 HEX is rendering guidance, not text
314
315 Image generation models occasionally paint color names and HEX values as **visible labels in the image** (a `#1E3A5F` swatch literally drawn as the string "#1E3A5F"). This destroys the image.
316
317 **Append to every prompt**:
318
319 > Color values (HEX codes like #1E3A5F) and color names are rendering guidance only — do NOT display HEX codes, color names, or palette labels as visible text anywhere in the image.
320
321 ### 5.2 Human depiction follows the selected rendering
322
323 When the image contains people:
324
325 > Match facial detail, anatomy, texture, and realism to the selected rendering and the row's Reference. A silhouette, detailed illustration, painterly figure, editorial photograph, or another treatment is valid when it belongs to that rendering.
326
327 **Hard rule — likeness authorization**: Do not request an identifiable real-person or celebrity likeness unless the Reference explicitly names a user-authorized subject/source. Generic or fictional people remain free to follow the selected rendering.
328
329 ### 5.3 Text policy — two-layer ownership
330
331 Every AI-image page carries text in two layers:
332
333 | Layer | Owned by | Examples |
334 |---|---|---|
335 | Layer 1 (image-owned) | the prompt — baked into the raster | figure-internal annotations (axis labels, A / B / C markers, units, scale bars, panel labels); architecture / schematic module names, node labels, signal-path identifiers; stable artistic lettering that *is* the visual |
336 | Layer 2 (SVG-owned) | `<text>` overlay — fully editable | authoritative deck/page/chapter titles; navigation, footer, body bullets, conclusion callout; readable copy, captions |
337
338 `text_policy` controls only Layer 1. AI judges per image; no global default bias.
339
340 **When `embedded` is the right call — positive triggers** (any one match supports `embedded`; the editability rule at the tail of §5.3 still has final say):
341
342 | Trigger | Typical Layer 1 text |
343 |---|---|
344 | Paper-figure panel comparison (A/B/C, before/after) | Panel labels — `A` / `B` / `C`, or short panel descriptors |
345 | Textbook math / signal figure | Curve names (`sin` / `cos`), axis labels, unit symbols |
346 | Architecture / schematic following discipline conventions | Module names (`Self-Attention`, `FFN`, `Add & Norm`), node ids, signal-path tags |
347 | Data figure with stable axes | Axis labels, units, scale bars |
348 | Typographic hero (§4.1 Primitive C) | The designed word / number that *is* the image |
349
350 Defaulting an entire `ai` resource list to `none` because "SVG can always overlay" is the failure mode this table exists to break. When any row matches a trigger, start at `embedded` and verify the editability filter below still holds.
351
352 | `text_policy` | Prompt cue |
353 |---|---|
354 | `none` | "NO text of any kind anywhere in the image — no letters, numbers, signs, watermarks, labels, or written symbols." |
355 | `embedded` | Describe the stable Layer 1 lettering directly inside the visual scene: the exact character(s), how they are rendered, and the artistic treatment. |
356
357 **Hard rule — cross-cutting**: Authoritative titles and Layer 2 chrome stay SVG regardless of `text_policy`. Bake title-like wording only when the approved plan explicitly treats those exact characters as stable artistic lettering that is part of the artwork rather than editable deck/page/chapter copy. Navigation, footer, body bullets, captions, and conclusion callouts always stay SVG.
358
359 **Forbidden — text that may be reworded**: any word that may later change belongs in Layer 2, not Layer 1. Layer 1 is for stable visual identifiers and designed lettering that is part of the image itself.
360
361 **Font choice for in-image text — free description, with the deck typography as one optional reference**
362
363 The font for in-image text is a free natural-language description, not an enum. Pick whatever serves the image: blackletter for a heritage cover, hand-brushed for a manifesto poster, retro chrome 3D for Y2K, art-deco display for a luxury hero, ribbon script for a bookstore zine — any artistic treatment the image earns.
364
365 The table below is **a reference for the one case where stable in-image lettering should read as the same typographic family as the SVG body** (e.g. an artistic cover wordmark should feel like the body Helvetica, not a surprise blackletter). Use it as a starting point, not a constraint.
366
367 | Active typography source contains | Optional descriptor if you want to echo the SVG body |
368 |---|---|
369 | `KaiTi` / `FangSong` / `Georgia` / serif families | "elegant serif lettering, refined letterforms" |
370 | `Microsoft YaHei` / `PingFang SC` / `Arial` / sans-serif families | "clean geometric sans-serif, modern letterforms" |
371 | `SimHei` / `Impact` / `Arial Black` / display families | "bold display lettering, heavy expressive strokes" |
372 | `Consolas` / `Courier New` / monospace families | "monospace technical lettering, fixed-width" |
373 | sketch-notes / ink-notes rendering, or no family specified | "hand-lettered organic strokes, natural variation" |
374
375 **When to ignore the table**:
376
377 - Decorative / background lettering, posters, large mood words → describe the artistic treatment freely
378 - Stable artistic cover lettering that wants its own visual identity (blackletter, retro chrome, art-deco display, brushed script) → describe freely
379 - Sketch-notes / ink-notes / hand-drawn renderings where the lettering is part of the rendering itself → describe freely
380 - Any case where rendering already implies a font character (e.g. `vintage-poster` implies period display lettering) → trust the rendering, no need to echo SVG body
381
382 **When to use the table**: stable artistic lettering on a deck whose visual identity is grounded in the SVG body typography, and where a surprise font choice would feel out of place.
383
384 **In-image text vs SVG text — decide by editability, not by model capability**
385
386 Layer 1 text is rasterized into the artwork — once generated it cannot be edited, corrected, searched, restyled, or reflowed. That is the durable reason to choose where text lives, independent of any backend's rendering ability or the script / length involved:
387
388 | Text | Layer |
389 |---|---|
390 | Part of the artwork and stable — decorative lettering, artistic wordmark, hand-lettered keyword, figure-internal identifiers (axis labels, panel letters, units) | Layer 1 (image) OK |
391 | Authoritative titles, page chrome, body copy, captions, data values — anything that must stay exact, searchable, editable, or may be reworded | Layer 2 (SVG) |
392
393 Generation is non-deterministic on every backend, but **do not pre-judge by script or length** — never push text to SVG, shorten a headline, or downgrade `embedded` to `none` on the assumption that a particular script or a long string "won't render". Decide where text lives by the editability rule above, not by guessed rendering ability. Name the exact characters to bake literally in the prompt; do not re-read the generated image to verify them.
394
395 **Prefer in-image**: text that is genuinely part of the artwork and will not be edited — a designed word, a stat lettering, a figure-internal label.
396
397 **Push to SVG overlay instead**: page chrome, captions, data values, or any copy that must stay exact or editable. When the headline must remain editable, switch to **Primitive D (atmospheric backdrop)** and overlay it as SVG text.
398
399 ### 5.4 No brand names or trademarks in the subject
400
401 > The image must not depict identifiable brand logos, trademarks, or product likenesses unless the row's Reference explicitly names a real brand asset the user owns.
402
403 ---
404
405 ## 6. Manifest Schema
406
407 Write `project/images/image_prompts.json` with this shape:
408
409 ```json
410 {
411 "project": "{project_name}",
412 "generated_at": "{ISO-8601 date}",
413 "deck_rendering": "vector-illustration",
414 "color_scheme": {
415 "background": "#FFFFFF",
416 "secondary_bg": "#F8F9FA",
417 "primary": "#1E3A5F",
418 "accent": "#D4AF37",
419 "secondary_accent": "#4A7BB5",
420 "body_text": "#1D2430"
421 },
422 "items": [
423 {
424 "filename": "cover_bg.png",
425 "purpose": "Cover background (Slide 01)",
426 "page_role": "hero_page",
427 "text_policy": "none",
428 "aspect_ratio": "16:9",
429 "image_size": "2K",
430 "prompt": "{fully assembled paragraph per §4 — use §4.1 Primitive D for atmospheric cover}",
431 "alt_text": "Modern tech abstract background with deep blue gradient and digital waves",
432 "status": "Pending"
433 },
434 {
435 "filename": "framework_p05.png",
436 "purpose": "Methodology framework (Slide 05)",
437 "type": "framework",
438 "page_role": "local",
439 "text_policy": "none",
440 "aspect_ratio": "4:3",
441 "image_size": "1K",
442 "prompt": "{fully assembled paragraph per §4}",
443 "status": "Pending"
444 }
445 ]
446 }
447 ```
448
449 ### Field reference
450
451 | Field | Required | Source | Description |
452 |---|---|---|---|
453 | `deck_rendering` | yes | Step 2 active authority | Single rendering name shared by all items in this deck |
454 | `color_scheme` | yes | Step 2 active authority | Core deck color anchors shared by every item; prompts may add contextual tonal behavior, but no separate image palette |
455 | `items[].filename` | yes | Active resource authority | Output filename with extension |
456 | `items[].type` | no | Step 3 per-image | Optional one-of-11 internal-composition type for a local structural infographic when a template genuinely fits. Omit it for custom §4.1 E prose, `hero_page`, an Illustration Sheet, and local single-subject/portrait prose. |
457 | `items[].page_role` | yes | Step 3 per-image | `local` (default — region block on SVG page) or `hero_page` (image is page's main voice; SVG overlay minimal or empty) |
458 | `items[].text_policy` | yes | Step 3 per-image | `none` (image carries no text — explicit visual rule) or `embedded` (image contains stable artistic lettering, hand-lettered keywords, or visual identifiers like axis labels / subplot letters / unit symbols). AI judges per image; no global default bias — see §5.3. |
459 | `items[].aspect_ratio` | yes | Container sizing | Passed to `image_gen.py --aspect_ratio` |
460 | `items[].prompt` | yes | §4 assembly | The full assembled paragraph |
461 | `items[].image_size` | no | Container sizing | `512px` / `1K` / `2K` / `4K` |
462 | `items[].model` | no | Per-item execution override | Backend model for this item; otherwise the CLI/backend default wins |
463 | `items[].alt_text` | no | Accessibility | Short caption |
464 | `items[].slice_grid` | paired optional | §4.3 sheet geometry | Illustration sheet only; exact `RxC` grid to pass to `slice_images.py --grid`; requires `slice_names` |
465 | `items[].slice_names` | paired optional | §4.3 sheet geometry | Illustration sheet only; comma-separated safe PNG basenames to pass to `slice_images.py --names`; requires exactly `rows*cols` unique outputs |
466 | `items[].status` | yes | CLI manages | `Pending` initially; CLI updates to `Generated` / `Failed` / `Needs-Manual` |
467
468 > **Back-compat for legacy `type` values**: existing manifests using `background` / `hero` / `portrait` / `typography` (the four removed pseudo-types) remain readable. Read them as: `background` → `page_role: hero_page` + no type; `hero` → `page_role: hero_page` + no type (use §4.1 Primitive A in prompt); `portrait` → `page_role: local` + no type (use §4.1 Primitive B); `typography` → `page_role: hero_page` + `text_policy: embedded` + no type (use §4.1 Primitive C). New manifests also omit `type` for custom §4.1 E prose, hero pages, and local single-subject/portrait prose.
469 >
470 > **Existing manifest compatibility**:
471 >
472 > - **Fixed compatibility defaults**: a missing `page_role` resolves to `local`; a missing `text_policy` resolves to `none`. Emit one aggregate legacy-compatibility warning per manifest.
473 > - **Declared replay procedure**: an existing manifest may lack `deck_rendering`, or an existing local item may lack `type`, because `items[].prompt` is already assembled. Leave that metadata absent, execute the existing prompt verbatim, and do not reconstruct either value. New manifests follow the field table; custom §4.1 E prose, hero pages, and local single-subject/portrait prose omit `type` intentionally.
474 > - A legacy non-empty `deck_style_anchor` string or object remains readable for replay and sidecar display but never overrides a current `deck_rendering`.
475 > - A legacy `deck_palette` field may remain but cannot override `color_scheme`. Read legacy `page_role: full_page` as `hero_page`.
476
477 ---
478
479 ## 7. Generation Execution
480
481 > Prerequisite: §3 Steps 1-3 complete; `images/image_prompts.json` exists and validates. The manifest is the shared audit/source contract for all modes. It does **not** imply that `image_gen.py --manifest` should run; that command is Path A only.
482
483 ### Path Selection (Deterministic)
484
485 C (AI-generated) supports three implementation modes sharing one `image_prompts.json` source:
486
487 | Trigger | Mode | Mechanism |
488 |---|---|---|
489 | **Default** — `IMAGE_BACKEND` configured | **Path A**: `image_gen.py --manifest` | One command runs the whole manifest with concurrency; status writes back per item |
490 | `IMAGE_BACKEND` not configured (or Path A fails) AND host has a native image tool | **Path B**: Host-native tool | Agent invokes the host's image capability; outputs land at `project/images/<filename>` |
491 | **Both Path A and Path B fail/unavailable** | **Offline Manual Mode** | Manifest stays on disk; user generates externally from `items[].prompt` and places files at `project/images/<filename>` |
492
493 **Quick Generate selection**: an explicit user instruction for `api`, `host-native`, or `manual` retained in active context wins. When the user did not specify a path, select `auto` and run the A → B → C chain without asking or creating a planning artifact.
494
495 **Default Generate selection — declared-procedure fallback when no path is confirmed**: the confirmed user choice wins. When neither channel confirmed a specific path, Generate Step 4 records the effective choice as `auto`; that explicit durable value uses the automatic A → B → C chain. A missing/blank/unknown project value is not an implicit API authorization:
496
497 0. **Confirmed override (wins)** — honor `AI Image Acquisition Path` from `design_spec.md §I`. Generate Step 4 already consumed the final confirmation into that durable artifact; do not reopen `result.json` here. If the recorded choice is set and not `auto`, honor it directly, **even when it contradicts `IMAGE_BACKEND`**:
498 - `api` → **Path A** (`image_gen.py --manifest`).
499 - `host-native` → **Path B** (host's native image tool) — skip A and do **not** run `image_gen.py --manifest`, *even if `IMAGE_BACKEND` is configured*.
500 - `manual` → **Offline Manual** (write prompts, render the Markdown sidecar, hand off; do **not** run `image_gen.py --manifest`).
501 If an explicitly chosen path is unavailable or still fails after its retry, mark the affected row `Needs-Manual`; do not switch to another automated provider. Only when the Design Spec records `auto` does the automatic chain decide. A legacy project missing this Design Spec row returns to Step 4 recovery to consume persisted confirmation once and record it; Image_Generator does not inspect the confirmation channel itself.
502 1. **Try Path A** — if `IMAGE_BACKEND` is configured (env or `.env`), run `image_gen.py --manifest`. If it fails twice in a row, fall to Path B.
503 2. **Try Path B** — if `IMAGE_BACKEND` was not configured (A skipped), or A failed, and the host has a native image tool (Codex / Antigravity / Claude Code / similar), the agent invokes the host's image capability directly.
504 3. **Fall to C (Offline Manual)** — if B is also unavailable (no host-native tool) or fails, write prompts to `images/image_prompts.json` and hand off to the user.
505
506 **Hard rule**: this step is execution, not re-decision. Default Generate uses the path locked in Strategist Step 4 h. Quick Generate uses the explicit active-context instruction or `auto`. Never present an interactive choice here.
507
508 > All three modes share one output contract: file at `project/images/<filename>`. Step 6 SVG references are mode-agnostic.
509
510 ### Path A — `image_gen.py --manifest` (Default)
511
512 ```bash
513 python3 scripts/image_gen.py \
514 --manifest project/images/image_prompts.json \
515 --output project/images
516 ```
517
518 The CLI validates the file behind every `Generated` row before skipping it, iterates retryable rows with bounded adaptive concurrency, and atomically writes each status. A missing/corrupt generated file returns to `Failed`; persistent rate limits finish this run as retryable `Failed` instead of looping forever.
519
520 **Parameters**:
521
522 | Parameter | Short | Description | Default |
523 |---|---|---|---|
524 | `--manifest` | - | Path to `image_prompts.json` | — |
525 | `--concurrency` | - | Max concurrent requests; halves on rate-limit, min 1 | `IMAGE_CONCURRENCY` env or `3` |
526 | `--image_size` | - | Default size (`512px`/`1K`/`2K`/`4K`); per-item `image_size` wins | `1K` |
527 | `--output` | `-o` | Output directory | Manifest's parent dir |
528 | `--backend` | `-b` | Override `IMAGE_BACKEND` for this run | env |
529 | `--model` | `-m` | Default model; per-item `model` wins | Backend default |
530 | `--list-backends` | - | Print support tiers and exit | — |
531
532 > The single-image form `image_gen.py "prompt" --filename ...` is preserved for ad-hoc one-offs (re-rolling a single image) but is no longer the primary path.
533
534 **Configuration sources**:
535 - Current process environment variables
536 - First `.env` found in this order: current working directory, skill directory (e.g. `~/.agents/skills/ppt-master/.env`), clone repo root, `~/.ppt-master/.env`
537
538 Precedence:
539 - Current process environment wins
540 - `.env` fills missing values only
541
542 | Variable | Required | Description |
543 |----------|----------|-------------|
544 | `IMAGE_BACKEND` | Required | Backend identifier; run `image_gen.py --list-backends` for the current set |
545 | `IMAGE_CONCURRENCY` | Optional | Manifest-mode default concurrency (CLI `--concurrency` wins) |
546 | `{PROVIDER}_API_KEY` | Required | Provider-specific API key, e.g. `GEMINI_API_KEY`, `ZHIPU_API_KEY` |
547 | `{PROVIDER}_BASE_URL` | Optional | Provider-specific custom endpoint |
548 | `{PROVIDER}_MODEL` | Optional | Provider-specific model override |
549 | `OPENAI_SIZE_PRESET` | Optional | OpenAI-compatible size mapping: `auto`, `legacy`, `gpt-image`, `gpt-image-2`, `dall-e-2` |
550 | `OPENAI_RESPONSE_FORMAT` | Optional | OpenAI-compatible response field: `auto`, `b64_json`, `url`, `omit` |
551 | `OPENAI_QUALITY` | Optional | OpenAI-compatible quality field: `auto`, `omit`, `low`, `medium`, `high`, `standard`, `hd` |
552
553 > Use provider-specific names only (e.g. `GEMINI_API_KEY`, `OPENAI_API_KEY`). See `.env.example` in clone mode or `${SKILL_DIR}/.env.example` in skill-install mode for the full set per backend.
554
555 > Note: OpenAI-compatible platforms that reject OpenAI-specific fields stay under `IMAGE_BACKEND=openai`; configure the `OPENAI_*` compatibility knobs instead of adding a provider-specific backend.
556
557 > `IMAGE_API_KEY`, `IMAGE_MODEL`, and `IMAGE_BASE_URL` are intentionally unsupported.
558
559 > If `.env` or the current environment contains multiple provider configs, `IMAGE_BACKEND` explicitly selects the active one.
560
561 **Support tiers (recommended usage)**: Core / Extended / Experimental. Run `image_gen.py --list-backends` for the current assignments.
562
563 **Concurrency (manifest mode)**:
564 - Default 3 concurrent requests, halves on the first rate-limit response, minimum 1 (= serial fallback)
565 - Rate-limited items requeue automatically; per-item failures are recorded with `last_error` and skipped
566 - Interrupting mid-run is safe — completed items keep `status: Generated` and are skipped on re-run
567 - On normal completion the Markdown sidecar is re-rendered automatically; if the run is interrupted, run `--render-md` manually to refresh the sidecar
568
569 ### Path B — Host-Native Image Tool
570
571 Triggered automatically when `IMAGE_BACKEND` is not configured (or Path A fails) **and** the host provides a native image generation tool (Codex, Antigravity, Claude Code's image tool, and similar). No user prompting required — the agent detects the host capability and proceeds. The user may also explicitly name this path ("use Codex's image tool") to force it even when `IMAGE_BACKEND` is configured.
572
573 - Agent invokes the host's native image tool directly; prompts come from `items[].prompt`
574 - Do **not** run `image_gen.py --manifest` in Path B. That command is Path A and may use configured API/proxy backends even when the user confirmed host-native.
575 - Still run `python3 scripts/image_gen.py --render-md project/images/image_prompts.json` so the human-readable sidecar exists without touching any backend.
576 - **Batch for speed, mind the rate**: when the host can run independent tool calls in parallel (e.g. Claude Code issues independent calls concurrently), fire several generations together in modest groups — a few rows at a time (~3–4), not the whole manifest at once — so their latency overlaps without flooding the host's image quota. When the host only runs tools serially, generate one row at a time. This mirrors Path A's default concurrency of 3.
577 - Outputs **must** land at `project/images/<filename-from-resource-list>`. Match the Image Resource List dimensions when the host supports arbitrary sizes. Hosts with **fixed native resolutions** (common — e.g. ~1672x941 landscape / ~1086x1448 portrait) generate at the closest native size and backfill the actual pixels into the resource list `Dimensions` column — same convention as formula rows ("actual dimensions from formula manifest") and slice rows ("dimensions filled after slicing"). Do **not** upscale the file to fake the requested size (interpolation adds no detail); minor display-side upscaling (up to ~1.3x in practice) may surface as a non-blocking quality-checker warning and requires no acknowledgement.
578 - Mark each item's `status` `Generated` in the manifest the moment its file lands — as each completes, not in one pass at the end (so an interrupted batch leaves accurate state)
579 - Executor downstream is path-agnostic — no spec change required between Path A and Path B
580
581 ### Offline Manual Mode (C's third implementation mode)
582
583 **Trigger**: the automatic chain reaches this point after both Path A and Path B fail or are unavailable, the user explicitly confirmed `manual`, or an explicitly confirmed automated path still fails after its own retry.
584
585 **Workflow** (no user prompting; system enters this mode automatically):
586
587 1. Verify `images/image_prompts.json` was written
588 2. Set `status: "Needs-Manual"` on every affected item per [`image-base.md`](./image-base.md) §6
589 3. Apply the mode boundary:
590 - Default Generate: continue to Step 6; Executor draws a dashed placeholder and Step 7 verifies the supplied file
591 - Quick Generate: retain the prompt and `Needs-Manual` status, and block direct export until every required supplied file is validated and its row is reconciled to `Generated`
592 4. Print one consolidated handoff to the user:
593 - Filenames awaiting manual generation
594 - Pointer to `images/image_prompts.md` (paste-ready `### Image N:` block per item) or `image_prompts.json` (`items[].prompt`)
595 - Target placement: `project/images/<filename>` matching the resource list exactly
596 - Continuation: Default Generate re-runs Step 7; Quick may validate the supplied file, rerun its resource gate and final checker, then use `--quick-generate` only while the original active context remains available — otherwise start a clean Quick run
597
598 **User-initiated**: When Strategist Step 4 captured `manual` in Default Generate, or the user explicitly requested `manual` in the Quick Generate active context, Path A is skipped from the start.
599
600 > Default Generate tolerates `Needs-Manual` rows through authoring and resumes
601 > at Step 7. Quick Generate preserves the same operational manifest and handoff
602 > but does not run `--quick-generate` while a required row still says
603 > `Needs-Manual`. If the original active context remains available, validate a
604 > later supplied file and update it to `Generated`; otherwise start a clean
605 > Quick run rather than treating the manifest as a resumable design record.
606
607 #### AI-specific Failure Handling (extends image-base.md §6)
608
609 When the path is `auto` and Path A's backend fails twice in a row:
610
611 1. Do not halt. Automatically attempt to fall back to **Path B (Host-Native Tool)**.
612 2. If Path B also fails or is unavailable, mark the row `Needs-Manual`.
613 3. Report to user: filename, prompt used, error message.
614 4. Fall through to **Offline Manual Mode** above.
615
616 When `api` or `host-native` was explicitly confirmed, failure or unavailability does not authorize an automated provider switch. Retry the confirmed path once; if it still fails, mark the row `Needs-Manual`, report the filename/prompt/error, and use the manual handoff above.
617
618 > If the alternate platform watermarks outputs (e.g. Gemini web), the repository includes `scripts/gemini_watermark_remover.py`.
619
620 #### Guardrails (All Modes)
621
622 **Hard rule**:
623
624 - Do not claim an image is generated without an actual file at the expected path
625 - `Needs-Manual` is set only when `manual` was confirmed or the selected automated recovery path was attempted and failed — not as a way to skip work that automation could have done
626 - Status transitions are evidence-driven: a file at the expected path permits `Generated`; an exhausted recovery path permits `Needs-Manual`
627
628 ---
629
630 ## 8. Common Issues & Variant Workflow
631
632 ### Reference field is omitted or blank — declared-inference fallback for existing AI rows
633
634 When an existing AI Resource List row omits `Reference` or contains a blank `Reference`, infer a reasonable image from its non-empty `Purpose`. If `Purpose` is also omitted or blank, stop and repair the row. Examples (not prescriptions):
635
636 | Purpose | A reasonable starting point |
637 |---------|-----------------------------|
638 | Cover | `page_role: hero_page` + §4.1 Primitive A (single-subject) or D (atmospheric); choose `text_policy` by what the cover should communicate |
639 | Chapter divider | `page_role: hero_page` + Primitive D (atmospheric) or A (single-subject); keep the authoritative chapter title in SVG, with `embedded` reserved for separate stable artistic lettering |
640 | Methodology / framework illustration | `type: framework`, `page_role: local` |
641 | Process / workflow illustration | `type: flowchart`, `page_role: local` |
642 | Before/After or two-option page | `type: comparison`, `page_role: local` |
643 | Team / lifestyle photo (group) | `type: scene`, `page_role: local`; rendering = `corporate-photo` or `warm-scene` |
644 | Single-person headshot / bio | `page_role: local` + §4.1 Primitive B (portrait); rendering = `corporate-photo` for photo realism |
645 | Big-number / hero quote block | `page_role: hero_page` + §4.1 Primitive C (typographic); `text_policy: embedded` |
646 | Mood transition / atmosphere | `page_role: hero_page` + Primitive D (atmospheric), or `type: scene` if narrative |
647
648 ### When Images Are Unsatisfactory
649
650 Diagnose the failure category, adjust the **one specific dimension** responsible, do not rewrite the whole prompt.
651
652 | Symptom | Most likely cause | Adjustment |
653 |---|---|---|
654 | Image looks generic, model-average | Tag-soup prompt | Rewrite as one coherent paragraph per §4 |
655 | Wrong style family (looks photorealistic when flat was intended) | Rendering mismatch or rendering paragraph diluted | Reaffirm chosen rendering's style paragraph at the top of the prompt |
656 | Colors don't match deck | Core role anchors or their semantic/proportion instructions were diluted | Restate which deck roles own the field, main forms, and sparse accents; remove unrelated hues while preserving context-justified tonal transitions |
657 | Hex code or color name visible as text in image | Missing §5.1 closing sentence | Append the §5.1 hard rule verbatim |
658 | Garbled letters in supposedly text-free image | `text_policy: none` rule too weak | Strengthen with explicit list: "no letters, no numbers, no words, no signs, no labels, no captions, no watermarks" |
659 | SVG text overlay clashes with busy image area | Page design needs negative space the prompt didn't request | Add a composition cue like "leave the {center / left third / lower band} relatively calm for text overlay" — only when the page actually overlays text on top of the image |
660 | Subject vague | Reference field too abstract | Rewrite reference with concrete nouns (verbs + objects) |
661 | Human depiction conflicts with the selected style or intent | §5.2 rendering/Reference cues were diluted | Restate the selected rendering's facial detail, anatomy, texture, and realism cues without changing the locked rendering |
662
663 **Variant workflow**:
664
665 1. Set the unsatisfactory item's `status` back to `Pending` and update its `prompt` in place
666 2. Re-run the same resolved path used for the original item: Path A may re-run `image_gen.py --manifest` (only that item is re-processed); Path B uses the host-native tool again for that item; Offline Manual re-renders the sidecar and hands off
667 3. To try multiple stylistic approaches, append additional items with distinct filenames (e.g. `cover_bg_v2.png`) rather than overwriting
668
669 ---
670
671 ## 9. Forbidden
672
673 - Generating prompts for `web` rows — those go through [`image-searcher.md`](./image-searcher.md)
674 - Brand names or HEX codes inside the subject description (degrades output)
675 - Mixing renderings or introducing an unrelated image-only palette across images in the same deck
676 - Tag-soup prompts (keyword lists separated by commas without a coherent visual scene)
677 - Globbing `image-renderings/*.md` or any subdirectory — read only the chosen preset or exact custom-reference files
678 - Placing an image without updating its `image_prompts.json` `status` and the active resource authority's status
679 - Switching rendering or core deck-color semantics for a single image—`hero_page` is not an exception to deck-wide coherence
680 - Embedding body copy, data points, bullet lists, or long quotes inside an image — those route to SVG
681
681 lines MARKDOWN