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