返回 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, illustrated-icon, and decorative-lettering 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 or transparent element is composed by SVG within the page. It may be boxed, unboxed, repeated as chrome, or become the page's dominant non-full-canvas visual; SVG owns final geometry and carrier combination |
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 words or phrases, 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) — complete rendering catalog + objective selection boundary | 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. Apply one basis under `image_rendering_behavior`, unchanged when that behavior carries it as-is; synthesize several only by their stated line, texture, depth, material, and mood contributions. If absent, 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 plus intended image jobs | Rendering (compare the complete objective catalog; no keyword or paired style decides the result) |
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, choose the strongest
109 whole-deck fit; do not present another choice after confirmation.
110
111 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.
112
113 > **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.
114
115 Then read the **single resolved** rendering file. It gives you:
116
117 - The 80-120 word style paragraph (rendering)
118 - Two ready-to-paste rendering snippets (fewshot)
119
120 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.
121
122 ### Step 3 — Per-image type + assembly
123
124 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.
125
126 `Layout pattern` is a page-realization preference and is not copied wholesale into the bitmap prompt. When page use depends on stable composition, consume the compact contract already owned by the row's `Reference`, matching §IX block, or Quick active context: subject/quiet zones, boundary or direction, intended overlap/seam, and approximate share only when needed. Do not invent or replace page layout here; return a missing required relationship to its owning decision.
127
128 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.
129 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.
130 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.
131 4. `read_file references/image-type-templates/<type>.md` only when a type was selected (and only if not already read).
132 5. **Assemble the prompt** by combining:
133 - The rendering's style paragraph (from Step 2)
134 - Color-role instructions anchored by the deck HEX values and refined for the image context (from Step 2)
135 - The selected type's structural layout, or the no-type composition prose (from Step 3)
136 - The image's specific `Reference` intent (from `design_spec.md §VIII` or the Quick Generate active-context decision)
137 - Container sizing from the selected type file, or the row's Dimensions for no-type prose
138 - The hard rules from §5 below (HEX-not-as-text, rendering-aligned human depiction and likeness authorization, text policy)
139
140 The assembled prompt is **one cohesive paragraph**, not a bulleted list of tags. See §4 for the assembly template.
141
142 ### Step 4 — Write the manifest and execute the selected path
143
144 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.
145
146 ---
147
148 ## 4. Prompt Assembly Template
149
150 Every assembled prompt follows this paragraph structure. **Write prose, not tag soup**.
151
152 ```
153 [Rendering style paragraph — 80-120 words from the chosen rendering file].
154 [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"].
155 [Composition — from the chosen type file or §4.1 no-type prose].
156 [Image-specific subject — translated from the row's Reference intent into concrete visual nouns].
157 [Container note — "composed as a {W}x{H}px image for {page_role} use"; when the owned composition contract exists, carry its subject/quiet zones, boundary/direction, overlap/seam, and optional approximate share into the prose. Reserve an SVG-overlay region for `hero_page`, or for a `local` image only when §VIII `Reference` / §IX `Layout` explicitly plans native labels, hotspots, lenses, or other overlays there. Otherwise an opaque `local` image reserves no interior overlay space; generate a transparent illustration slice as an isolated element for SVG composition].
158 [Hard rules — see §5].
159 ```
160
161 **Word budget**: 150-300 words. Embedded-text prompts skew longer; pure background prompts can be shorter.
162
163 **Forbidden — tag-soup prompts**:
164
165 ```
166 ❌ "modern, flat design, gradient, vibrant, professional, clean, 4K, high quality"
167 ```
168
169 This produces generic, model-average output. The model is not weighting your tags — write **one coherent visual scene** instead.
170
171 ### 4.1 No-type composition primitives
172
173 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.
174
175 **Primitive A — single dominant subject (product / object / concept hero)**
176
177 > 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.
178
179 Use for: product reveal, concept introduction, chapter-opener visual, brand statement, or a local single-object region.
180
181 **Primitive B — single human subject (portrait)**
182
183 > 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.
184
185 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.
186
187 **Primitive C — typographic hero (the text *is* the image)**
188
189 > The image's central content is one large text element — a single word, a phrase, a headline, a big number, or a short multi-line lockup — 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.
190
191 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).
192
193 **Primitive D — atmospheric backdrop (no subject)**
194
195 > 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.
196
197 **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.
198
199 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.
200
201 **Primitive E — custom (escape hatch)**
202
203 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.
204
205 **Default — concise custom composition prose (may override for subject accuracy)**:
206
207 | Rule | Value |
208 |---|---|
209 | Length | One paragraph, 2-5 sentences, replacing A/B/C/D's opening paragraph |
210 | 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 |
211 | Clarity | Describe the actual geometry; a primitive name alone is not a substitute |
212
213 Example opening for a triptych hero:
214
215 > 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...]
216
217 **Fewshot examples per primitive** (one each, deck-context placeholders intact):
218
219 > **A — 3d-isometric + deck-color product reveal, text_policy: none, 600×600**
220 >
221 > 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.
222
223 > **B — corporate-photo + deck-color executive headshot, text_policy: none, 600×800**
224 >
225 > 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.
226
227 > **C — ink-notes + deck-color big-number stat, text_policy: embedded, 800×500**
228 >
229 > 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.
230
231 > **D — vector-illustration + deck-color cover background, text_policy: none, 1280×720**
232 >
233 > 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.
234
235 ### 4.2 Prompt depth — expand for subject-domain accuracy
236
237 **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.
238
239 **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.
240
241 **Detail to name in the prompt** (illustrative, not an enumeration to match):
242
243 | Domain | Conventions to spell out |
244 |---|---|
245 | chemistry / materials | IUPAC atom colors, bond conventions, lattice type, Å / ps units, subplot labeling (A / B / C circles), view angle |
246 | biology | cell compartment colors, scale bars, organelle conventions, staining palette |
247 | physics | axis labels with proper symbols, signature curve shapes, unit annotations, peak labeling format |
248 | engineering | schematic notation, dimension callouts, section-cut conventions |
249
250 **When uncertain about field conventions**: read `sources/` before drafting the prompt.
251
252 ### 4.3 Illustration sheets — one generation, many composable illustration, illustrated-icon, or lettering elements
253
254 An Illustration Sheet generates compatible transparent **illustration**,
255 **illustrated-icon**, or **decorative lettering** elements with shared rendering,
256 deck-color treatment, and finish. Subjects, silhouettes, visual weights, and page
257 jobs may differ; SVG authors the composition after slicing. Lettering remains
258 stable Layer 1 artwork, not page copy converted to an image.
259
260 **Default — batch compatible elements when a shared generation context helps consistency; split when separate generation improves the result**: Plan only useful illustrated-icon cues, normally grouping compatible ones. Group lettering by compatible letterform character and artistic treatment; font name alone does not decide. Split whenever separate generation benefits style, geometry, detail, quality, or semantic precision. A single transparent element may use a keyed `1x1` sheet; full-canvas or nontransparent images use the normal one-row path (§4.1).
261
262 **Hard rule**: a 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.
263
264 **Hard rule — separable treatment before keying**: when the intended slice
265 excludes a supporting surface, choose a treatment whose complete visible
266 geometry can stand alone against the key field. Engraved, etched, debossed,
267 inlaid, bas-relief, or other surface-dependent treatments are valid only when
268 that carrier belongs in the intended slice; otherwise choose a genuinely
269 freestanding treatment. Never define a carrier as necessary to the treatment
270 and ask the same prompt to remove it.
271
272 **Sheet prompt convention** — one `page_role: local` manifest item; choose
273 `image_size` from final placement size. Spot sheets use `text_policy: none`;
274 lettering sheets use `text_policy: embedded`:
275
276 - Derive `aspect_ratio` and `--grid` from the target shape, not a universal `1:1` symmetric grid. State an invisible logical **R×C grid** and the cell shape: compact square object, tall portrait element, wide landscape vignette, or wide lettering mark. Center and isolate each element in its cell with even, clear gutters; never draw cells, panels, dividers, borders, frames, or alternate gutter colors. Do not shrink every subject into a square sticker.
277 - Use one flat chroma key across the sheet: pure `#00FF00`, `#0000FF`, or `#FF0000`, chosen so its active color does not dominate any element or supporting effect. State the exact HEX; keep it unchanged in all gutters and out of reflections or spill. Grain, halftone, vignette, and other texture stay inside the elements. The key is technical, not part of the deck palette.
278 - Shared `deck_rendering` + `color_scheme` as always.
279 - **Illustration / illustrated-icon sheet**: name each element and its page or recurring-reuse job. For an illustrated icon, state the compact semantic cue that must survive at placement size. Apply the §5.3 `none` cue: no text, labels, or numbers.
280 - **Lettering sheet**: exactly one named stable string per cell as the only text; quote each complete sequence literally. Describe the group's compatible letterform character and artistic treatment, then its communication role, placement/background relationship, relative visual weight, and energy. Follow §5.3's controlled artistic-authorship default. Keep artistry glyph-bound through silhouette, stroke structure, material, texture, depth, and contour-bound light/shadow. Add no topic motifs, scene fragments, icons, detached ribbons, particles, or surrounding illustration unless the approved treatment requests a lettering-plus-illustration lockup. Keep each mark and approved glyph-bound effect inside its cell with key-only padding; no scene, unrelated copy, labels, watermark, or mockup surface.
281 - **Delivery floor, not an aesthetic ceiling**: enlarge the cell, change the grid, or use a larger/separate sheet when lettering treatment or effects need more footprint. Never weaken an approved treatment to fit a crop; geometry does not raise the §5.3 expression level.
282
283 **Cell geometry is designed, not assumed.** `slice_images.py --grid RxC` cuts rows first and columns second. The cell ratio is:
284
285 ```text
286 cell_ratio = sheet_ratio * rows / cols
287 ```
288
289 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.
290
291 | Target element shape | Sheet plan | Slice grid |
292 |---|---|---|
293 | Compact objects / badges / illustrated icons | `1:1` sheet | `2x2`, `2x3`, or `3x3` |
294 | Tall side accents / upright objects | wide or square sheet | `1xN`, or any `MxN` whose cells are portrait |
295 | Wide banners / horizontal vignettes | wide sheet | `Nx1`, or any `MxN` whose cells are landscape |
296 | Large page anchors / dominant cutouts | dedicated sheet matching the silhouette | `1x1` |
297 | Decorative words, phrases, or multi-line lettering lockups | wide sheet | `Nx1`, or any `MxN` whose cells fit the planned string shapes |
298
299 Within one visual family, use separate sheets for shape families that cannot share a roomy grid. Preserve coherence through `deck_rendering` and `color_scheme`, not one forced square sheet or effect stack.
300
301 **Resource contract — sheets and elements are different row kinds.** A slice is placeable only from `spec_lock.md images` in Default Generate or the current agent's prepared-resource decision in Quick Generate. Default keeps both row kinds in §VIII under [`strategist-image.md`](./strategist-image.md); Quick keeps the distinction in active context and its operational manifest, without planning artifacts:
302
303 - **Sheet row** — `Acquire Via: ai`, `Type: Illustration Sheet`, named as the slice source with its intent prompt, cell shape, and placement purpose (`Reference: reusable title/corner illustration family`, `illustrated-icon set: cues = ...`, or `decorative lettering set: exact strings = ...`). Step 5 generates it, but it is **never placed** and stays **out of** `spec_lock.md images`. Image_Generator resolves its `aspect_ratio`, grid, and slice command.
304 - **Element rows** — one per used element, `Acquire Via: slice`, filename matching `--names`, and `Reference` naming the parent sheet plus cell/element. List each in the placeable-resource authority, normally with `crop=no-crop`; tight transparent slices use fit, not cover-crop. `Type: Illustrated icon` marks a compact semantic image asset, never an SVG library entry. A row may serve multiple pages. Fill dimensions after slicing by rerunning `analyze_images.py`. Each row carries an owner-resolved layout recommendation; SVG may use a direct cutout or suitable container while preserving resource identity and crop/content constraints.
305
306 For every placeable-element sheet, add `slice_grid` and `slice_names` to its `image_prompts.json` item with the geometry. The comma-separated safe PNG basenames mark the complete required output set. `image_gen.py` validates, preserves, and displays them; slicing remains a separate command.
307
308 **Slice** with [`slice_images.py`](../scripts/slice_images.py). It cuts row-major into `images/`; `--alpha` yields transparent cutouts usable directly or in containers. Use `--names` (semantic filenames matching element rows; count **must** equal `rows*cols`), `--trim`, `--alpha`, `--bg` with the prompt's exact key HEX, and `--strict-alpha`, which writes nothing when deterministic checks find an incomplete cut:
309
310 ```bash
311 SHEET_KEY_HEX="#00FF00" # example only; choose a key absent from every element/effect
312 python3 scripts/slice_images.py <project>/images/illus_sheet.png --grid 2x3 \
313 --names team,product,customer,growth,risk,vision --trim --alpha \
314 --bg "${SHEET_KEY_HEX}" --strict-alpha
315 ```
316
317 **Three quality constraints**:
318
319 1. **Strict key recovery.** The pure-key path removes spill while recovering partial alpha for antialiasing, shadow, and glow. For a visually flat field with bounded pixel drift, measure it and raise `--tolerance` only enough to absorb it; `--strict-alpha` must still pass. If an effect reaches an edge, regenerate or enlarge instead of placing a non-strict slice. Use `--inset` only for an isolated outer gutter.
320 2. **Clean isolated cells.** `--trim` absorbs small placement variance; fused cells, scene backgrounds, or flourishes/effects crossing a cell make the sheet unusable. Do not generate alternatives merely to choose a favorite. Re-roll only after strict keying failure or user/live-preview evidence of an unusable slice, then slice the replacement.
321 3. **Enough source pixels.** Use the smallest sheet that keeps each cell at least **1.5-2x** intended display size. `1K` usually covers small accents, `2K` medium placements, and `4K` large, cropped, or potentially enlarged elements.
322
323 **Placement reference — one family, many page compositions.** A transparent slice may remain unboxed, enter a container, or combine with backgrounds, native shapes, text, photos, other slices, and lettering. Reuse by fit for hierarchy, rhythm, continuity, or character: stable title/corner chrome may repeat exactly; other anchors and accents may vary in scale, position, pairing, and content interaction. Editable copy remains SVG text. Owner-resolved layout text recommends expression; SVG authoring owns geometry and treatment while preserving resource identity and crop/content constraints. A large transparent anchor composed by SVG remains `local` / `slice`; use `hero_page` only when one prepared bitmap owns the page composition. Never apply a quota.
324
325 ---
326
327 ### 4.4 Registered reconstruction groups and shared plates
328
329 Use this preparation when a person, product, creature, effect, or other scene
330 element must cross native titles, panels, frames, cards, or shapes while the
331 original scene remains behind it. A clean base plus one subject/foreground
332 output is the minimum group; add layers only when overlap or independent
333 editing requires them:
334
335 | Output | Required content |
336 |---|---|
337 | Clean base | Full original canvas with every planned removable scene element removed and the hidden background reconstructed |
338 | Optional midground | Full canvas with only the scene content that must sit between the base and primary subjects |
339 | Subject / foreground | Full canvas with one subject or one z-order-compatible set visible on RGBA transparency |
340 | Shared layer plate | Several mutually non-overlapping objects isolated together in one full-canvas or regular-cell output |
341
342 **Mandatory — preserve registration**: derive every full-canvas member
343 independently from the same canonical source. Preserve canvas dimensions,
344 subject pose, scale, position, lighting, and visible style; do not trim or
345 independently crop registered final outputs. Record the shared source and group
346 relationship in the owning §VIII rows or Quick active-context resources.
347
348 **Image to PPTX override — Codex required**: when
349 [`image-to-pptx.md`](../workflows/profiles/image-to-pptx.md) is active, follow
350 its §3 per-region decision. A complete, separable, final-resolution-sufficient
351 region may remain source-derived. Otherwise use Codex's native reference-image
352 capability for required editing or reconstruction. Inspect every prepared
353 member plus the final recomposition. Do not adapt `image_gen.py`, its manifest,
354 or provider backends for this profile. Other hosts are unsupported. The
355 ordinary Path A / Path B procedure below applies outside this profile.
356
357 **Preparation procedure**:
358
359 1. From the canonical reference, remove every planned separate subject,
360 foreground object, source/data graphic, and editable text, then inpaint one
361 clean base without redesigning visible background content.
362 2. From that same reference, prepare the subject/foreground content as an
363 exact source-derived layer or a reference reconstruction according to the
364 selected profile's source-sufficiency decision. Never derive a layer from
365 the generated base or another generated layer.
366 3. Prefer one shared plate when several objects do not overlap and use the same
367 isolation treatment. Their padded bboxes, including visible shadows and
368 effects, must be pairwise disjoint. One object does not imply one generation
369 call.
370 4. For a registered plate, retain the original full-canvas positions and use
371 one nested-SVG picture crop per recorded bbox under
372 [`svg-effects.md`](./svg-effects.md) §6.5. For a rearranged regular-cell
373 plate, follow §4.3 and run
374 `slice_images.py --grid ... --names ... --trim --alpha`; place each
375 resulting asset at its recorded source bbox.
376 5. Prefer direct RGBA. When transparency is unavailable, use one exact flat
377 key color for the whole layer/plate, then run `slice_images.py` once as a
378 `1x1` sheet with `--alpha` and without `--trim` so full-canvas coordinates
379 remain unchanged. Do not generate one keyed image per object.
380 6. Save final files under `<project>/images/`. Mark registered full-canvas
381 members `no-crop`; ordinary trimmed cell slices retain their own measured
382 dimensions.
383
384 Objects that overlap one another or require different z-order use separate
385 plates/layers. A shared output is valid only when every required final object
386 still becomes an independent SVG/PPT picture object.
387
388 **Shared registered-plate prompt core**:
389
390 > Using the supplied canonical page as the only visual reference, isolate the
391 > following foreground objects together on one full-canvas extraction plate:
392 > {stable object ids/descriptions}. Preserve each object's visible identity,
393 > silhouette, pose, scale, rotation, lighting, shadow, and exact original canvas
394 > position. Keep the original aspect ratio and canvas registration. Retain only
395 > those listed objects; remove the background and every unlisted element. Do not
396 > rearrange, resize, merge, duplicate, or let the listed objects touch one
397 > another. Retain an explicitly listed source graphic or wordmark exactly when
398 > it is one of the requested objects; remove editable slide text and every
399 > unlisted logo/source graphic. Return RGBA transparency if supported;
400 > otherwise use one uniform exact {key HEX} matte with no gradient, texture,
401 > spill, or extra marks.
402
403 Outside Image to PPTX, Path A may use the existing single-image edit mode for
404 each registered derivative; Path B may perform the same edits with the
405 host-native image tool:
406
407 ```bash
408 python3 scripts/image_gen.py "Remove the planned foreground subjects and reconstruct the hidden background; preserve the exact canvas" \
409 --reference-image <project>/images/<source>.png -o <project>/images -f <group>_base
410 python3 scripts/image_gen.py "Isolate the planned non-overlapping foreground objects at their exact original positions on one flat #00FF00 plate" \
411 --reference-image <project>/images/<source>.png -o <project>/images -f <group>_plate_key
412 python3 scripts/slice_images.py <project>/images/<group>_plate_key.png --grid 1x1 \
413 --names <group>_plate --alpha --bg "#00FF00"
414 ```
415
416 These positional edit commands remain the declared derivation exception for
417 already-planned group rows. Keep every final member in the ordinary resource
418 authority and operational sidecar. SVG realization follows
419 [`image-layout-patterns.md`](./image-layout-patterns.md) `#A2-03`.
420
421 ---
422
423 ## 5. Global Hard Rules
424
425 These rules apply to **every** prompt regardless of dimension choices. Append them as a closing sentence to every assembled prompt.
426
427 ### 5.1 HEX is rendering guidance, not text
428
429 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.
430
431 **Append to every prompt**:
432
433 > 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.
434
435 ### 5.2 Human depiction follows the selected rendering
436
437 When the image contains people:
438
439 > 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.
440
441 **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.
442
443 ### 5.3 Text policy — two-layer ownership
444
445 Every AI-image page carries text in two layers:
446
447 | Layer | Owned by | Examples |
448 |---|---|---|
449 | 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 |
450 | Layer 2 (SVG-owned) | `<text>` overlay — fully editable | authoritative deck/page/chapter titles; navigation, footer, body bullets, conclusion callout; readable copy, captions |
451
452 `text_policy` controls only Layer 1. AI judges per image; no global default bias.
453
454 **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):
455
456 | Trigger | Typical Layer 1 text |
457 |---|---|
458 | Paper-figure panel comparison (A/B/C, before/after) | Panel labels — `A` / `B` / `C`, or short panel descriptors |
459 | Textbook math / signal figure | Curve names (`sin` / `cos`), axis labels, unit symbols |
460 | Architecture / schematic following discipline conventions | Module names (`Self-Attention`, `FFN`, `Add & Norm`), node ids, signal-path tags |
461 | Data figure with stable axes | Axis labels, units, scale bars |
462 | Typographic hero (§4.1 Primitive C) | The designed word / number that *is* the image |
463
464 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.
465
466 | `text_policy` | Prompt cue |
467 |---|---|
468 | `none` | "NO text of any kind anywhere in the image — no letters, numbers, signs, watermarks, labels, or written symbols." |
469 | `embedded` | Describe the stable Layer 1 lettering directly inside the visual scene: the exact character(s), how they are rendered, and the artistic treatment. |
470
471 **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.
472
473 **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.
474
475 **Default — controlled, deck-aligned artistic authorship (may override when the user explicitly requests high expression or confirms a strongly expressive direction)**: For decorative lettering, give the model the exact intended string, communication role, placement/background relationship, deck identity, relative visual weight, and desired energy. The resolved rendering, semantic colors, mood, and page hierarchy define the envelope. Without the stated override, keep expression controlled and glyph-native: carry identity through the glyph silhouette, stroke construction, internal material/texture, contour-bound depth/light, and letterform composition; do not translate the topic into literal illustrations or detached decoration around the word. A lettering-plus-illustration lockup is a separate treatment and requires an explicit user request or confirmed design direction. Within the chosen treatment, let the model decide and combine—or omit—the calligraphic gesture, material, dimensionality, texture, lighting, internal hierarchy, and composition; such terms are possibility space, not an effect recipe. Do not flatten the art merely to simplify extraction: §4.3's separable-treatment gate, key field, clear padding, and cell isolation protect delivery without raising the chosen intensity. When fit is uncertain, use the lower effect density; never infer high expression or external motifs from the topic, place, or wording alone. Keep a multi-line lockup as one element when its hierarchy is part of the art.
476
477 **Font choice for in-image text — free description, with the deck typography as one optional reference**
478
479 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.
480
481 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.
482
483 | Active typography source contains | Optional descriptor if you want to echo the SVG body |
484 |---|---|
485 | `KaiTi` / `FangSong` / `Georgia` / serif families | "elegant serif lettering, refined letterforms" |
486 | `Microsoft YaHei` / `PingFang SC` / `Arial` / sans-serif families | "clean geometric sans-serif, modern letterforms" |
487 | `SimHei` / `Impact` / `Arial Black` / display families | "bold display lettering, heavy expressive strokes" |
488 | `Consolas` / `Courier New` / monospace families | "monospace technical lettering, fixed-width" |
489 | sketch-notes / ink-notes rendering, or no family specified | "hand-lettered organic strokes, natural variation" |
490
491 **When to ignore the table**:
492
493 - Decorative / background lettering, posters, large mood words → describe the artistic treatment freely
494 - Stable artistic cover lettering that wants its own visual identity (blackletter, retro chrome, art-deco display, brushed script) → describe freely
495 - Sketch-notes / ink-notes / hand-drawn renderings where the lettering is part of the rendering itself → describe freely
496 - 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
497
498 **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.
499
500 **In-image text vs SVG text — decide by editability, not by model capability**
501
502 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:
503
504 | Text | Layer |
505 |---|---|
506 | Part of the artwork and stable — decorative lettering, artistic wordmark, hand-lettered word or phrase, figure-internal identifiers (axis labels, panel letters, units) | Layer 1 (image) OK |
507 | Authoritative titles, page chrome, body copy, captions, data values — anything that must stay exact, searchable, editable, or may be reworded | Layer 2 (SVG) |
508
509 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.
510
511 **Prefer in-image**: text that is genuinely part of the artwork and will not be edited — a designed word or phrase, a stat lettering, a figure-internal label. String length never decides this; a multi-word phrase or two-line lockup qualifies exactly as a single word does.
512
513 **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.
514
515 ### 5.4 No brand names or trademarks in the subject
516
517 > 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.
518
519 ---
520
521 ## 6. Manifest Schema
522
523 Write `project/images/image_prompts.json` with this shape:
524
525 ```json
526 {
527 "project": "{project_name}",
528 "generated_at": "{ISO-8601 date}",
529 "deck_rendering": "vector-illustration",
530 "color_scheme": {
531 "background": "#FFFFFF",
532 "secondary_bg": "#F8F9FA",
533 "primary": "#1E3A5F",
534 "accent": "#D4AF37",
535 "secondary_accent": "#4A7BB5",
536 "body_text": "#1D2430"
537 },
538 "items": [
539 {
540 "filename": "cover_bg.png",
541 "purpose": "Cover background (Slide 01)",
542 "page_role": "hero_page",
543 "text_policy": "none",
544 "aspect_ratio": "16:9",
545 "image_size": "2K",
546 "prompt": "{fully assembled paragraph per §4 — use §4.1 Primitive D for atmospheric cover}",
547 "alt_text": "Modern tech abstract background with deep blue gradient and digital waves",
548 "status": "Pending"
549 },
550 {
551 "filename": "framework_p05.png",
552 "purpose": "Methodology framework (Slide 05)",
553 "type": "framework",
554 "page_role": "local",
555 "text_policy": "none",
556 "aspect_ratio": "4:3",
557 "image_size": "1K",
558 "prompt": "{fully assembled paragraph per §4}",
559 "status": "Pending"
560 }
561 ]
562 }
563 ```
564
565 ### Field reference
566
567 | Field | Required | Source | Description |
568 |---|---|---|---|
569 | `deck_rendering` | yes | Step 2 active authority | Single rendering name shared by all items in this deck |
570 | `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 |
571 | `items[].filename` | yes | Active resource authority | Output filename with extension |
572 | `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. |
573 | `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) |
574 | `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. |
575 | `items[].aspect_ratio` | yes | Container sizing | Passed to `image_gen.py --aspect_ratio` |
576 | `items[].prompt` | yes | §4 assembly | The full assembled paragraph |
577 | `items[].image_size` | no | Container sizing | `512px` / `1K` / `2K` / `4K` |
578 | `items[].model` | no | Per-item execution override | Backend model for this item; otherwise the CLI/backend default wins |
579 | `items[].alt_text` | no | Accessibility | Short caption |
580 | `items[].slice_grid` | required for a placeable-element sheet | §4.3 sheet geometry | Exact `RxC` grid to pass to `slice_images.py --grid`; requires `slice_names` |
581 | `items[].slice_names` | required for a placeable-element sheet | §4.3 sheet geometry | Comma-separated safe PNG basenames to pass to `slice_images.py --names`; requires exactly `rows*cols` unique outputs |
582 | `items[].status` | yes | CLI manages | `Pending` initially; CLI updates to `Generated` / `Failed` / `Needs-Manual` |
583
584 > **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.
585 >
586 > **Existing manifest compatibility**:
587 >
588 > - **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.
589 > - **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.
590 > - A legacy non-empty `deck_style_anchor` string or object remains readable for replay and sidecar display but never overrides a current `deck_rendering`.
591 > - A legacy `deck_palette` field may remain but cannot override `color_scheme`. Read legacy `page_role: full_page` as `hero_page`.
592
593 ---
594
595 ## 7. Generation Execution
596
597 > 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.
598
599 ### Path Selection (Deterministic)
600
601 C (AI-generated) supports three implementation modes sharing one `image_prompts.json` source:
602
603 | Trigger | Mode | Mechanism |
604 |---|---|---|
605 | `api` / `auto` permits Path A and `IMAGE_BACKEND` is configured | **Path A**: `image_gen.py --manifest` | One command runs the whole manifest with concurrency; status writes back per item |
606 | `host-native` / `auto` permits Path B and the host has a native image tool | **Path B**: Host-native tool | Agent invokes the host's image capability; outputs land at `project/images/<filename>` |
607 | Default confirmed `manual`, or Quick explicitly selected `manual` | **Offline Manual Mode** | Manifest stays on disk; user generates externally from `items[].prompt` and places files at `project/images/<filename>` |
608
609 **Planning boundary**: Strategist and Quick decide AI visual jobs from communication need, not current backend configuration. Do not inspect configuration or probe a provider before planning. Resolve actual Path A/B capability only when this section executes the selected path.
610
611 **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 try Path A → Path B without asking or creating a planning artifact. If an automated path exhausts, apply the Quick no-AI replan below; Offline Manual is entered only from an explicit `manual` instruction.
612
613 **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`; in Default, `auto` authorizes Path A → Path B only and never pre-authorizes Offline Manual. A missing/blank/unknown project value is not an implicit API or manual-generation authorization:
614
615 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`**:
616 - `api` → **Path A** (`image_gen.py --manifest`).
617 - `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*.
618 - `manual` → **Offline Manual** (write prompts, render the Markdown sidecar, hand off; do **not** run `image_gen.py --manifest`).
619 If an explicitly chosen automated path is unavailable or still fails after its retry, do not switch provider or presume manual fulfillment; enter the Default recovery decision below. Only when the Design Spec records `auto` may both automated paths be attempted. 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.
620 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.
621 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.
622 3. **Resolve exhausted automation** — Default enters the recovery decision below; Quick applies the no-AI replan below.
623
624 **Hard rule**: normal execution does not reopen path selection. The only Default exception is the one recovery decision after the confirmed automated path or `auto`'s A → B sequence is actually unavailable/exhausted. Quick uses its explicit active-context instruction or automated path, then applies its declared no-AI replan without asking when automation exhausts.
625
626 > All three modes share one output contract: file at `project/images/<filename>`. Step 6 SVG references are mode-agnostic.
627
628 ### Path A — `image_gen.py --manifest` (Default)
629
630 ```bash
631 python3 scripts/image_gen.py \
632 --manifest project/images/image_prompts.json \
633 --output project/images
634 ```
635
636 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.
637
638 **Parameters**:
639
640 | Parameter | Short | Description | Default |
641 |---|---|---|---|
642 | `--manifest` | - | Path to `image_prompts.json` | — |
643 | `--concurrency` | - | Max concurrent requests; halves on rate-limit, min 1 | `IMAGE_CONCURRENCY` env or `3` |
644 | `--image_size` | - | Default size (`512px`/`1K`/`2K`/`4K`); per-item `image_size` wins | Backend default; see `--list-backends` |
645 | `--output` | `-o` | Output directory | Manifest's parent dir |
646 | `--backend` | `-b` | Override `IMAGE_BACKEND` for this run | env |
647 | `--model` | `-m` | Default model; per-item `model` wins | Backend default |
648 | `--list-backends` | - | Print support tiers and exit | — |
649
650 > 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.
651
652 **Configuration sources**:
653 - Current process environment variables
654 - First `.env` found in this order: current working directory, skill directory (e.g. `~/.agents/skills/ppt-master/.env`), clone repo root, `~/.ppt-master/.env`
655
656 Precedence:
657 - Current process environment wins
658 - `.env` fills missing values only
659
660 | Variable | Required | Description |
661 |----------|----------|-------------|
662 | `IMAGE_BACKEND` | Required | Backend identifier; run `image_gen.py --list-backends` for the current set |
663 | `IMAGE_CONCURRENCY` | Optional | Manifest-mode default concurrency (CLI `--concurrency` wins) |
664 | `{PROVIDER}_API_KEY` | Required | Provider-specific API key, e.g. `GEMINI_API_KEY`, `ZHIPU_API_KEY` |
665 | `{PROVIDER}_BASE_URL` | Optional | Provider-specific custom endpoint |
666 | `{PROVIDER}_MODEL` | Optional | Provider-specific model override |
667 | `OPENAI_SIZE_PRESET` | Optional | OpenAI-compatible size mapping: `auto`, `legacy`, `gpt-image`, `gpt-image-2`, `dall-e-2` |
668 | `OPENAI_RESPONSE_FORMAT` | Optional | OpenAI-compatible response field: `auto`, `b64_json`, `url`, `omit` |
669 | `OPENAI_QUALITY` | Optional | OpenAI-compatible quality field: `auto`, `omit`, `low`, `medium`, `high`, `standard`, `hd` |
670
671 > 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.
672
673 > 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.
674
675 > `IMAGE_API_KEY`, `IMAGE_MODEL`, and `IMAGE_BASE_URL` are intentionally unsupported.
676
677 > If `.env` or the current environment contains multiple provider configs, `IMAGE_BACKEND` explicitly selects the active one.
678
679 **Support tiers (recommended usage)**: Core / Extended / Experimental. Run `image_gen.py --list-backends` for the current assignments.
680
681 **Concurrency (manifest mode)**:
682 - Default 3 concurrent requests, halves on the first rate-limit response, minimum 1 (= serial fallback)
683 - Rate-limited items requeue automatically; per-item failures are recorded with `last_error` and skipped
684 - Interrupting mid-run is safe — completed items keep `status: Generated` and are skipped on re-run
685 - On normal completion the Markdown sidecar is re-rendered automatically; if the run is interrupted, run `--render-md` manually to refresh the sidecar
686
687 ### Path B — Host-Native Image Tool
688
689 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.
690
691 - Agent invokes the host's native image tool directly; prompts come from `items[].prompt`
692 - 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.
693 - Still run `python3 scripts/image_gen.py --render-md project/images/image_prompts.json` so the human-readable sidecar exists without touching any backend.
694 - **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.
695 - 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, as slice rows do 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.
696 - 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)
697 - Executor downstream is path-agnostic — no spec change required between Path A and Path B
698
699 ### Offline Manual Mode (C's third implementation mode)
700
701 **Trigger**: Default reaches this mode only after the user confirmed `manual` in final Stage 2 or at the exhausted-automation recovery decision. Quick reaches it only through an explicit `manual` instruction.
702
703 **Workflow** (manual fulfillment is already authorized; do not ask again inside acquisition):
704
705 1. Verify `images/image_prompts.json` was written
706 2. Set `status: "Needs-Manual"` on every affected item per [`image-base.md`](./image-base.md) §6
707 3. Apply the mode boundary:
708 - Default Generate: continue to Step 6; Executor draws a dashed placeholder, but Step 7 blocks every export command until the supplied file is validated and the placeholder is replaced
709 - 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`
710 4. Print one consolidated handoff to the user:
711 - Filenames awaiting manual generation
712 - Pointer to `images/image_prompts.md` (paste-ready `### Image N:` block per item) or `image_prompts.json` (`items[].prompt`)
713 - Target placement: `project/images/<filename>` matching the resource list exactly
714 - 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
715
716 **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.
717
718 #### Default Exhausted-Automation Decision
719
720 When required AI rows remain unresolved after Default's confirmed automated path or `auto`'s eligible A → B sequence, keep them `Failed` and pause once with one consolidated list of filenames, prompts, attempted paths, and concrete errors. Ask the user to choose exactly one outcome:
721
722 1. **Repair and retry** — wait for the user to repair the named key, balance, endpoint, or host capability, then rerun only the same confirmed path; for `auto`, rerun the repaired eligible path and retain the A → B permission. If it fails again, return to this same decision with the new error.
723 2. **Generate manually** — update `design_spec.md §I` to `AI Image Acquisition Path: manual` as the newer explicit override, mark the affected rows `Needs-Manual`, render the handoff above, and continue authoring only up to the Step 7 image-readiness gate.
724 3. **Cancel affected AI images** — return to Generate Step 4 as a post-confirmation override; remove the affected `ai` / dependent `slice` rows and revise their §IX page jobs plus lock rows to native editable text/SVG or already-confirmed non-AI sources. If no AI rows remain, set the path to `not applicable` and remove the AI Image Strategy subsection. Never introduce a new image source or silently drop required communication content.
725
726 Do not create `Needs-Manual` state in Default before manual fulfillment is explicitly confirmed.
727
728 > Default Generate tolerates `Needs-Manual` rows through authoring and resumes
729 > at Step 7. An explicitly manual Quick run preserves the same operational
730 > manifest and handoff but does not run `--quick-generate` while a required row still says
731 > `Needs-Manual`. If the original active context remains available, validate a
732 > later supplied file and update it to `Generated`; otherwise start a clean
733 > Quick run rather than treating the manifest as a resumable design record.
734
735 #### Quick Exhausted-Automation No-AI Replan
736
737 When an automated AI path or required dependent slicing remains unresolved after its allowed attempts in Quick, do not ask the user and do not enter Offline Manual. Retain the affected filename, attempted path, concrete error, and replacement carrier in active context for the final Quick completion report; remove the affected `ai` row plus dependent `slice` rows from the active resource plan and remove the corresponding manifest item. Re-render `images/image_prompts.md` when other AI items remain; when none remain, remove both `images/image_prompts.json` and `images/image_prompts.md` so no stale failed row survives the replan. Preserve the communication job with native editable text/SVG or already prepared non-AI assets and continue the same run. Do not introduce another image source merely to replace the failed AI job. If the user still wants AI imagery, they must repair the generation capability and start a new Quick run.
738
739 #### AI-specific Failure Handling (extends image-base.md §6)
740
741 When the path is `auto` and Path A's backend fails twice in a row:
742
743 1. Do not halt. Automatically attempt to fall back to **Path B (Host-Native Tool)**.
744 2. If Path B also fails or is unavailable, Default enters the three-outcome decision above without changing the row to `Needs-Manual`; Quick applies the no-AI replan above.
745 3. Report the filename, prompt used, and error message through the owning outcome.
746
747 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, Default enters the decision above, while Quick applies the no-AI replan above.
748
749 > If the alternate platform watermarks outputs (e.g. Gemini web), the repository includes `scripts/gemini_watermark_remover.py`.
750
751 #### Guardrails (All Modes)
752
753 **Hard rule**:
754
755 - Do not claim an image is generated without an actual file at the expected path
756 - `Needs-Manual` is set only when manual fulfillment was confirmed in Default or explicitly selected in Quick — not as a way to skip work that automation could have done
757 - Status transitions are evidence-driven: a file at the expected path permits `Generated`; exhausted Default automation remains `Failed` until a retry succeeds or the user chooses manual or cancellation; exhausted Quick AI rows are removed only through the declared no-AI replan
758
759 ---
760
761 ## 8. Common Issues & Variant Workflow
762
763 ### Reference field is omitted or blank — declared-inference fallback for existing AI rows
764
765 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):
766
767 | Purpose | A reasonable starting point |
768 |---------|-----------------------------|
769 | Cover | `page_role: hero_page` + §4.1 Primitive A (single-subject) or D (atmospheric); choose `text_policy` by what the cover should communicate |
770 | 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 |
771 | Methodology / framework illustration | `type: framework`, `page_role: local` |
772 | Process / workflow illustration | `type: flowchart`, `page_role: local` |
773 | Before/After or two-option page | `type: comparison`, `page_role: local` |
774 | Team / lifestyle photo (group) | `type: scene`, `page_role: local`; rendering = `corporate-photo` or `warm-scene` |
775 | Single-person headshot / bio | `page_role: local` + §4.1 Primitive B (portrait); rendering = `corporate-photo` for photo realism |
776 | Big-number / hero quote block | `page_role: hero_page` + §4.1 Primitive C (typographic); `text_policy: embedded` |
777 | Mood transition / atmosphere | `page_role: hero_page` + Primitive D (atmospheric), or `type: scene` if narrative |
778
779 ### When Images Are Unsatisfactory
780
781 Diagnose the failure category, adjust the **one specific dimension** responsible, do not rewrite the whole prompt.
782
783 | Symptom | Most likely cause | Adjustment |
784 |---|---|---|
785 | Image looks generic, model-average | Tag-soup prompt | Rewrite as one coherent paragraph per §4 |
786 | 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 |
787 | 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 |
788 | Lettering feels unrelated, overdecorated, or too dominant for its role | Expression exceeded the deck identity or planned visual weight | Retain the exact string and visual family; lower effect density, ornament, contrast, or lighting energy for the affected item/family instead of shrinking it into submission |
789 | Lettering carries mountains, buildings, animals, icons, ribbons, or other topic decoration around the glyph | The model turned subject context into an unrequested illustration lockup | Remove every external motif and rerun the affected item/family; express the identity through glyph structure, material, texture, depth, and contour-bound light instead |
790 | Hex code or color name visible as text in image | Missing §5.1 closing sentence | Append the §5.1 hard rule verbatim |
791 | 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" |
792 | 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 |
793 | Subject vague | Reference field too abstract | Rewrite reference with concrete nouns (verbs + objects) |
794 | 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 |
795
796 **Variant workflow**:
797
798 1. Set the unsatisfactory item's `status` back to `Pending` and update its `prompt` in place
799 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
800 3. To try multiple stylistic approaches, append additional items with distinct filenames (e.g. `cover_bg_v2.png`) rather than overwriting
801
802 ---
803
804 ## 9. Forbidden
805
806 - Generating prompts for `web` rows — those go through [`image-searcher.md`](./image-searcher.md)
807 - Brand names or HEX codes inside the subject description (degrades output)
808 - Mixing renderings or introducing an unrelated image-only palette across images in the same deck
809 - Tag-soup prompts (keyword lists separated by commas without a coherent visual scene)
810 - Globbing `image-renderings/*.md` or any subdirectory — read only the chosen preset or exact custom-reference files
811 - Placing an image without updating its `image_prompts.json` `status` and the active resource authority's status
812 - Switching rendering or core deck-color semantics for a single image—`hero_page` is not an exception to deck-wide coherence
813 - Embedding body copy, data points, bullet lists, or long quotes inside an image — those route to SVG
814
814 lines MARKDOWN