diff --git a/config/external-sources.lock.json b/config/external-sources.lock.json index 452d5a5d..3977bb62 100644 --- a/config/external-sources.lock.json +++ b/config/external-sources.lock.json @@ -42,8 +42,8 @@ "repo": "https://github.com/JuliusBrussee/caveman.git", "ref": "main", "adapter": "codex-plugin", - "commit": "17f9f2ec2377b0bfe16b52ee03a462e7f0a02bc8", - "syncedAt": "2026-08-27T16:00:00Z" + "commit": "df2ccd85c94ec3c8289cb62ac020d241ccfb0c60", + "syncedAt": "2026-08-30T16:00:00Z" }, { "id": "taste-skill", @@ -60,8 +60,8 @@ "repo": "https://github.com/shadcn-ui/ui.git", "ref": "main", "adapter": "claude-skill", - "commit": "683a5a9b370acdb7785a0529434e6a3b8c7e0441", - "syncedAt": "2026-08-26T16:00:00Z" + "commit": "b4a618b97e35f5dadf3a00d51f410c84a2567d4d", + "syncedAt": "2026-08-30T16:00:00Z" }, { "id": "frontend-slides", @@ -96,8 +96,8 @@ "repo": "https://github.com/hugohe3/ppt-master.git", "ref": "main", "adapter": "claude-skill", - "commit": "bf81f3ece547e769095a6c0b82f40d33be3d2cf7", - "syncedAt": "2026-08-29T16:00:00Z" + "commit": "035fdad700fa38071c46ec698c9d810f6ec103ec", + "syncedAt": "2026-08-30T16:00:00Z" }, { "id": "grill-me", @@ -114,8 +114,8 @@ "repo": "https://github.com/vercel/next.js.git", "ref": "canary", "adapter": "skill-collection", - "commit": "7421a868ad7eb878efcaa27cbc280b39e72ed757", - "syncedAt": "2026-08-29T16:00:00Z" + "commit": "2fe6f962a1982594bdda96a7de16c594677266d2", + "syncedAt": "2026-08-30T16:00:00Z" } ] } diff --git a/plugins/codex/plugins/caveman/THIRD_PARTY_SOURCE.json b/plugins/codex/plugins/caveman/THIRD_PARTY_SOURCE.json index 10aa8fe3..3ee95fa5 100644 --- a/plugins/codex/plugins/caveman/THIRD_PARTY_SOURCE.json +++ b/plugins/codex/plugins/caveman/THIRD_PARTY_SOURCE.json @@ -2,8 +2,8 @@ "sourceId": "caveman", "repo": "https://github.com/JuliusBrussee/caveman.git", "ref": "main", - "commit": "17f9f2ec2377b0bfe16b52ee03a462e7f0a02bc8", + "commit": "df2ccd85c94ec3c8289cb62ac020d241ccfb0c60", "adapter": "codex-plugin", "sourcePath": "plugins/caveman", - "syncedAt": "2026-08-27T16:00:00Z" + "syncedAt": "2026-08-30T16:00:00Z" } diff --git a/plugins/codex/plugins/mcp-playwright/MCP_SOURCE.json b/plugins/codex/plugins/mcp-playwright/MCP_SOURCE.json index e98d006d..f1f2a282 100644 --- a/plugins/codex/plugins/mcp-playwright/MCP_SOURCE.json +++ b/plugins/codex/plugins/mcp-playwright/MCP_SOURCE.json @@ -3,5 +3,5 @@ "name": "playwright浏览器自动化操作", "version": "20260605", "keySource": "none", - "syncedAt": "2026-08-29T16:01:57Z" + "syncedAt": "2026-08-30T16:01:52Z" } diff --git a/plugins/codex/plugins/next-skills/THIRD_PARTY_SOURCE.json b/plugins/codex/plugins/next-skills/THIRD_PARTY_SOURCE.json index a6af0837..cbf92f7f 100644 --- a/plugins/codex/plugins/next-skills/THIRD_PARTY_SOURCE.json +++ b/plugins/codex/plugins/next-skills/THIRD_PARTY_SOURCE.json @@ -2,8 +2,8 @@ "sourceId": "next-skills", "repo": "https://github.com/vercel/next.js.git", "ref": "canary", - "commit": "7421a868ad7eb878efcaa27cbc280b39e72ed757", + "commit": "2fe6f962a1982594bdda96a7de16c594677266d2", "adapter": "skill-collection", "sourcePath": "skills", - "syncedAt": "2026-08-29T16:00:00Z" + "syncedAt": "2026-08-30T16:00:00Z" } diff --git a/plugins/codex/plugins/ppt-master/THIRD_PARTY_SOURCE.json b/plugins/codex/plugins/ppt-master/THIRD_PARTY_SOURCE.json index 5a2226bb..e6474eef 100644 --- a/plugins/codex/plugins/ppt-master/THIRD_PARTY_SOURCE.json +++ b/plugins/codex/plugins/ppt-master/THIRD_PARTY_SOURCE.json @@ -2,8 +2,8 @@ "sourceId": "ppt-master", "repo": "https://github.com/hugohe3/ppt-master.git", "ref": "main", - "commit": "bf81f3ece547e769095a6c0b82f40d33be3d2cf7", + "commit": "035fdad700fa38071c46ec698c9d810f6ec103ec", "adapter": "claude-skill", "sourcePath": "skills/ppt-master", - "syncedAt": "2026-08-29T16:00:00Z" + "syncedAt": "2026-08-30T16:00:00Z" } diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/SKILL.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/SKILL.md index 0ae97994..727d65e7 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/SKILL.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/SKILL.md @@ -2,7 +2,7 @@ name: ppt-master description: "多格式源文档到高质量 SVG 页面再导出 PPTX 的多阶段演示文稿生成工作流。" metadata: - version: "5.1.0" + version: "6.1.0" copyright: "Copyright (c) 2025-2026 Hugo He" license: "MIT" official_repository: "https://github.com/hugohe3/ppt-master" @@ -63,6 +63,18 @@ in the selected runtime authority's construction references. --- +## Phase Frame + +Every route is one Plan → Do·Check·Act cycle: Plan ends when every authoring +input exists as a file or retained decision; Do authors pages, Check runs the +route's gates, Act repairs at the owning layer (discipline 7), and the cycle +ends at export. Step numbers stay as written. + +| Phase | Default | Quick | Edit Native | Create Template | +|---|---|---|---|---| +| **Plan** | Steps 1–5 | §2 | §1–4 | Steps 1–3 | +| **Do·Check·Act** | Steps 6–7 | §3–4 | §5–7 | Steps 4–8 | + ## Global Execution Discipline 1. **Serial execution** — Follow the selected authority's steps in order. A completed non-blocking step may continue directly to the next eligible step. @@ -71,7 +83,7 @@ in the selected runtime authority's construction references. 4. **Gate before entry** — Verify every listed prerequisite before entering a step. 5. **No speculative execution** — Do not prepare later-phase artifacts before their owning step. 6. **Deterministic routing** — Do not add a route-choice question when [`routing.md`](workflows/routing.md) resolves the request. If a route prerequisite is missing, state it and stop that route. -7. **Owning-source recovery** — On failure, repair or regenerate the owning source artifact and resume from the route's declared pointer. Do not silently downgrade a required artifact. +7. **Act at the owning layer** — On failure, repair at the shallowest layer that owns the fault: the page for a page-local issue, the Plan artifact for a roster/spec/resource fault, the owning source artifact for a tool failure; then resume from the route's declared pointer. Do not silently downgrade a required artifact. ## Global Communication Rules diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/animations.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/animations.md index c21baa03..b2c54ded 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/animations.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/animations.md @@ -1,39 +1,26 @@ # Page Transitions & Per-Element Animations -Execution contract for generated-PPTX **page transitions** and **per-element -object animations**, including deterministic Morph object pairing. This file -owns defaults, sidecar semantics, anchor selection, validation, and package -read-back. +Execution contract for generated-PPTX **page transitions** and **per-element object animations**, including deterministic Morph pairing: defaults, sidecar semantics, anchor selection, validation, and package read-back. ## Capability Menu — Open Here -Motion here is several separate capabilities, not one dial. Two of them are -decided **upstream, while pages are still being authored** — read this menu -before the page plan is frozen, not only when a deck is already exported. +Motion is several separate capabilities, not one dial; two of them are decided while pages are still being authored, so read this before the page plan is frozen. | What the deck needs | Reach for | Decided at | |---|---|---| -| A generic deck-wide entrance build | `-a auto`; with the default `after-previous` Start mode, groups use fixed `--animation-stagger` timing rather than narration cues | Post-processing; §2, §4 | -| Explicit object lifecycle choreography | An `animations.json` sidecar for selected enter/emphasize/move/exit/static duties, order, Start mode, and timing | Post-processing; §2, §4, [`customize-animations`](../workflows/stages/customize-animations.md) | -| Object reveals semantically synchronized to recorded narration | Narration-cue sync derives `narration_animations.json` from canonical `animations.json`, page-local SRT, and `narration_timing.json`; `-a auto` alone does not provide this mapping | Audio stage; [`generate-audio`](../workflows/stages/generate-audio.md) | -| A continuous action — slide-in, flip, camera push-in, progressive reveal, camera pan | **Morph: author the action as two static pages, then select Morph and add explicit pairs when identity must be deterministic.** There is no keyframe timeline anywhere in this pipeline; the difference between two ordinary editable slides *is* the animation | **Page authoring (Step 6), then motion post-processing** — §2.1, §3.1 | -| A static full-bleed page that should stop looking frozen | Consider slow `path_*` motion on a visually subordinate image or atmospheric layer; §4.1 gives one starting recipe | Post-processing; §4.1 | -| Carousel, counting numerals, parallax depth, click-to-reveal flip card | Four recurring recipes assembled from the mechanisms above | §4.2 — the carousel and odometer both need paired pages | +| A generic deck-wide entrance build | `-a auto`; with the default `after-previous` Start, groups use fixed `--animation-stagger` timing, not narration cues | Post-processing; §2, §4 | +| Explicit object lifecycle choreography | An `animations.json` sidecar for selected enter/emphasize/move/exit/static duties, order, Start, timing | Post-processing; §2, §4, [`customize-animations`](../workflows/stages/customize-animations.md) | +| Object reveals synchronized to recorded narration | Narration-cue sync derives `narration_animations.json` from `animations.json`, page-local SRT, and `narration_timing.json`; `-a auto` alone does not | Audio stage; [`generate-audio`](../workflows/stages/generate-audio.md) | +| A continuous action — slide-in, flip, camera push-in, progressive reveal, camera pan | **Morph: author the action as two static pages**, then select Morph and add explicit pairs when identity must be deterministic; there is no keyframe timeline anywhere — the difference between two editable slides *is* the animation | **Page authoring (Step 6), then motion post-processing** — §2.1, §3.1 | +| A static full-bleed page that should stop looking frozen | Slow `path_*` motion on a visually subordinate image or atmospheric layer | Post-processing; §4.1 | +| Carousel, counting numerals, parallax depth, click-to-reveal flip card | Four recipes assembled from the mechanisms above; carousel and odometer need paired pages | §4.2 | | Kiosk or unattended playback | `--auto-advance `, optionally with `-t none` | Export; §3 | -| A transition or object animation needs an audible cue | Optional `transition.sound` or object-animation `sound`; select it only after the visual motion solution is complete, then sync the chosen global-library ids into the project. For direct narrated MP4 delivery, [`generate-audio`](../workflows/stages/generate-audio.md) selects either the verified native-export mix or explicit real-time slideshow capture; never combine them | Post-motion; §2.2 | -| Nothing should move | `-t none`, and leave per-element animation at its default `none` | Export; §1 | +| A transition or object animation needs an audible cue | Optional `transition.sound` or object `sound`, selected only after the visual solution is complete and synced from the global library; a narrated MP4 uses either the verified native-export mix or explicit slideshow capture, never both | Post-motion; §2.2 | +| Nothing should move | `-t none` and per-element `none` | Export; §1 | -**Hard rule — Morph geometry is an authoring decision; pairing is a later -execution decision**: export cannot invent the two visible endpoint states. -Author both consecutive pages while `svg_output/` is still being built. For -deterministic identity, expose each endpoint as a compatible direct-root group -and declare the pair in `animations.json` (§2.1); the source and destination ids -and geometry may differ. `-t morph` without explicit pairs leaves matching to -PowerPoint's heuristic and is not proof that the intended objects will tween. +**Hard rule — Morph geometry is an authoring decision; pairing is a later execution decision**: export cannot invent endpoint states. Author both consecutive pages while `svg_output/` is being built; for deterministic identity expose each endpoint as a compatible direct-root group and declare the pair in `animations.json` (§2.1) — ids and geometry may differ. `-t morph` without pairs leaves matching to PowerPoint's heuristic. -**Reference — not a constraint**: per-element animation stays off by default -(§1). Auto-firing element builds on every page are an unsolicited "AI deck" -tell; each capability above earns its place per page, not per deck. +**Reference — not a constraint**: per-element animation stays off by default; auto-firing builds on every page are an unsolicited "AI deck" tell, and each capability earns its place per page. --- @@ -41,56 +28,28 @@ tell; each capability above earns its place per page, not per deck. | Layer | Default | Why | |---|---|---| -| Page transition | CLI: `fade`, 0.4s | Calm baseline that suits most decks; the public Python builder retains its legacy 0.5s default | -| Per-element animation | **`none` (off)** | A page appears as a whole. Auto-firing element builds are an unsolicited "AI deck" tell, so object animation is opt-in. Turn on the content-aware canonical entrance policy with `-a auto`, or select one PowerPoint-native `entrance_*`, `emphasis_*`, `path_*`, or `exit_*` key explicitly | -| Sound effects | **`none` (off)** | No global sound is copied and no `/sounds/` directory is created unless a resolved transition or object-animation cue actually selects one | +| Page transition | CLI `fade`, 0.4s (the public Python builder keeps its legacy 0.5s) | Calm baseline | +| Per-element animation | **`none` (off)** | A page appears as a whole; opt in with `-a auto` or one explicit `entrance_*` / `emphasis_*` / `path_*` / `exit_*` key | +| Sound effects | **`none` (off)** | No global sound is copied and no `/sounds/` exists until a resolved cue selects one | -To regenerate a deck with different settings, rerun the final checker when its current matching report is absent or stale, then rerun `svg_to_pptx.py` against the same `svg_output/`; the content-generation LLM need not rerun unless authored SVG requires repair. `-s final` is reserved for diagnostic comparison and is not a supported release source. To turn per-element animation on for the whole deck, pass `-a auto`. +To regenerate with different settings, rerun the final checker when its report is absent or stale, then rerun `svg_to_pptx.py` on the same `svg_output/`; the authoring LLM reruns only for SVG repair. `-s final` is diagnostic only. --- ## 2. Custom Object-Level Animation -Per-element animation is off by default. To enable generic entrance reveals -deck-wide, pass `-a auto` at export (no config needed). When a deck instead -needs a specific object lifecycle—for example enter, move, emphasize, then -exit—use the optional `animations.json` sidecar. The SVG remains the visual -source; the custom stage may rewrite its grouping hierarchy, ids, and bounds to -create better semantic anchors without changing visible output, while the -sidecar controls PPTX animation behavior. +`-a auto` enables generic entrance reveals deck-wide with no config. A specific lifecycle — enter, move, emphasize, exit — uses the optional `animations.json` sidecar: the SVG stays the visual source, the custom stage may regroup, rename, and re-bound anchors without changing visible output, and the sidecar controls PPTX behavior. Run [`customize-animations`](../workflows/stages/customize-animations.md) when `animations.json` exists, when the user asks to tune order/effects/timing/object reveals, or when the effective Custom Animations outcome in `design_spec.md §I` is enabled; a §IX `Motion suggestion` informs an active pass but never triggers it. -Run the [`customize-animations`](../workflows/stages/customize-animations.md) -post-processing stage when the project already carries `animations.json`, when -the user explicitly asks to tune animation order/effects/timing/object-level -reveals, or when the effective Custom Animations outcome in -`design_spec.md §I` is enabled. A §IX `Motion suggestion` remains Strategist -advice and informs an active pass, but never triggers the stage alone. - -**Hard rule — semantic anchors before object-targeted sidecar entries**: when -object animation is in scope, derive motion units and their lifecycle duties -from page meaning and narration, then regroup coarse/fragmented Slide-local -content without changing its appearance. Only post-regroup top-level ids are -valid object targets. +**Hard rule — semantic anchors before object-targeted entries**: derive motion units and duties from page meaning and narration, regroup coarse or fragmented Slide-local content without changing appearance, and target only post-regroup top-level ids. ```bash -# Inspect the real anchors after the semantic regrouping pass -python3 skills/ppt-master/scripts/animation_config.py list-groups - -# Build a neutral editable scaffold from the post-regroup anchors when useful -python3 skills/ppt-master/scripts/animation_config.py scaffold - -# Validate references before export -python3 skills/ppt-master/scripts/animation_config.py validate - -# Export reads /animations.json automatically when present -python3 skills/ppt-master/scripts/svg_to_pptx.py +python3 skills/ppt-master/scripts/animation_config.py list-groups # real anchors after regrouping +python3 skills/ppt-master/scripts/animation_config.py scaffold # neutral editable scaffold (effect: none, {} placeholders) +python3 skills/ppt-master/scripts/animation_config.py validate # before export +python3 skills/ppt-master/scripts/svg_to_pptx.py # reads /animations.json automatically ``` -The scaffold keeps `defaults.animation.effect: none` and may list untouched -groups as empty `{}` placeholders; creating it does not opt the deck into -object motion. Populate only adopted motion units. - -Sparse sidecar excerpt (unlisted slides inherit resolved defaults): +Sparse sidecar (unlisted slides inherit resolved defaults): ```json { @@ -112,552 +71,137 @@ Sparse sidecar excerpt (unlisted slides inherit resolved defaults): } ``` -Rules: +**Contract**: -- `slides` keys match SVG stems (`03_market.svg` → `03_market`). -- `groups` keys match top-level `` anchors. -- A populated group block chooses exactly one representation: the - backward-compatible single-effect object, or - `{ "effects": [row, ...] }`. `effects` is non-empty and mutually exclusive - with every legacy single-effect field; each row explicitly names `effect`. - An untouched scaffold `{}` remains a neutral placeholder. -- `effect: none` in the legacy form removes that group from the object-animation - sequence and is useful for overriding inherited generic animation. -- `effects[]` permits the same PowerPoint shape to carry several Animation Pane - rows. `order` sorts ordinary rows across the slide; ties retain SVG group - order and then array order. `trigger_shape` rows keep that relative ordering - in separate interactive sequences rather than interleaving with the main - sequence. Ordering never changes slide layering. -- `delay` is seconds added to that row's resolved Start. -- `trigger` may be set per legacy row or `effects[]` row; otherwise it inherits - the resolved slide Start mode. -- `trigger_shape` is a row-specific reference to another unique, triggerable - top-level group. It maps to PowerPoint **Trigger → On Click of**, makes only - that row interactive, and uses `delay` as `TriggerDelayTime`. It implies - `on-click`; an explicit row `trigger` may accompany it only when also - `on-click`. -- `duration` overrides the per-row schedule duration. `entrance_appear` - remains a 1ms visibility flip, and instantaneous native emphasis presets - retain their PowerPoint-authored duration; the configured value still spaces - the next `after-previous` row. -- `effect_options` requires an explicit canonical `effect` in the same legacy - block or `effects[]` row and accepts only parameters PowerPoint exposes for - that effect: +- `slides` keys are SVG stems; `groups` keys are top-level `` anchors. A populated group is either the legacy single-effect object or `{ "effects": [row, …] }` (non-empty, each row naming `effect`, mutually exclusive with legacy fields); `{}` is a neutral placeholder; legacy `effect: none` removes the group from the sequence and overrides inherited generic animation. +- `effects[]` lets one shape carry several Animation Pane rows; `order` sorts rows across the slide (ties keep SVG group order, then array order), `trigger_shape` rows sort within their own interactive sequence, and ordering never changes layering. +- `delay` adds seconds to the resolved Start; `trigger` per row otherwise inherits the slide Start mode; `trigger_shape` references another unique triggerable top-level group (PowerPoint **Trigger → On Click of**), makes only that row interactive, uses `delay` as `TriggerDelayTime`, and implies `on-click`. +- `duration` overrides the row schedule (`entrance_appear` stays a 1 ms flip and instantaneous native emphasis keeps its authored duration, but the configured value still spaces the next `after-previous` row). +- `effect_options` requires an explicit canonical `effect` and accepts only what PowerPoint exposes: `direction` (directional entrance/exit effects), `amount` (wheel spokes `1`/`2`/`3`/`4`/`8`, spin degrees, transparency ratio), `color` (`#RRGGBB` or `theme:`), `font_name` (required for `emphasis_change_font`; one installed face), `size` (grow/shrink), `relative` (motion paths). `python3 skills/ppt-master/scripts/pptx_animations.py --describe ` prints each effect's exact contract. +- Any block or row may set `repeat_count` or `repeat_duration` (exclusive), `auto_reverse`, `rewind`, `accelerate`, `decelerate` (ratios `0..1`; `bounce_end` needs an interpolated behavior and excludes `decelerate`), `restart` (`always` / `when-not-active` / `never`), `after_effect` (`none` / `dim` with `color` / `hide` / `hide-on-next-click`), and `sound` (project-relative or absolute `.m4a` / `.mp3` / `.wav`; new output uses a project-relative path synced under §2.2, never `templates/sounds/`). `Speed` and smooth start/end derive from `duration` and `accelerate`/`decelerate`. +- This is the complete surface for the top-level-group model: no paragraph/text-range builds (grouped SVG is not emitted as paragraph builds), no media commands (audio/video workflows own them). +- `--animation none` overrides the sidecar and disables all per-element animation; a sidecar group may override the legacy chrome-name heuristic but never `data-pptx-layer` or an explicit static role/placeholder; unknown effects, modes, triggers, or invalid numeric/order fields fail validation with no fallback. - | Option | Applies to | - |---|---| - | `direction` | Directional Fly/Crawl/Wipe/Peek/Strips/Split/Stretch/Zoom and related entrance/exit effects | - | `amount` | Wheel spokes (`1`, `2`, `3`, `4`, `8`), emphasis Spin degrees, or Transparency ratio | - | `color` | Color-capable emphasis effects; `#RRGGBB` or `theme:` | - | `font_name` | Change Font; required for `emphasis_change_font`; one installed PowerPoint face, not a CSS list | - | `size` | Grow/Shrink | - | `relative` | Motion paths (`true` = shape-relative, `false` = fixed slide path) | -- Any animation block or effect row may set `repeat_count` or `repeat_duration` - (mutually exclusive), `auto_reverse`, `rewind`, `accelerate`, `decelerate`, - `bounce_end`, `restart`, `after_effect`, and `sound`. Ratios are `0..1`; - `bounce_end` requires an interpolated behavior and cannot combine with - `decelerate`; `restart` is `always`, `when-not-active`, or `never`; - `after_effect` is `none`, `dim` (with `color`), `hide`, or - `hide-on-next-click`; `sound` is a project-relative or absolute `.m4a`, - `.mp3`, or `.wav` path. New generated configurations use a project-relative - path. A bundled library choice first follows §2.2 and resolves to a - project-local `.wav`; never point new output at `templates/sounds/`. -- `Speed` and smooth start/end are not duplicate sidecar fields: they are - derived from `duration` and `accelerate`/`decelerate`. -- This is the complete parameter surface for the generated top-level-group - target model, including multiple ordered effects on one group. PowerPoint - paragraph/text-range build fields are intentionally absent because grouped - SVG content is not emitted as paragraph builds; media play/pause/stop - commands remain in the audio/video workflows. -- Run `python3 skills/ppt-master/scripts/pptx_animations.py --describe - ` for that effect's exact option values and full parameter - contract. -- `--animation none` overrides the sidecar and disables all per-element animation. -- An explicit sidecar group may override the legacy chrome-name heuristic, but it cannot override `data-pptx-layer` or an explicit static role/placeholder marker. -- Unknown effects, modes, or triggers and invalid numeric/order fields fail validation; no fallback effect is substituted. - -**Inheritance**: the sidecar and its `defaults` block are optional. Unlisted -slides and omitted slide fields inherit `defaults.transition` / -`defaults.animation`, then CLI/exporter resolution. Explicit CLI flags override -the corresponding sidecar default/slide fields; explicit group overrides remain -unless `-a none` hard-disables all object motion. Groups inherit the resolved -slide duration, Start mode, timing modifiers, after-effect, and sound into each -legacy or `effects[]` row. `effect_options` remains coupled to an explicit -effect; `trigger_shape` is never inherited; omitted `order`/`delay` use -exporter defaults. +**Inheritance**: sidecar and `defaults` are optional; unlisted slides and omitted fields inherit `defaults.transition` / `defaults.animation`, then CLI resolution. Explicit CLI flags override the corresponding sidecar default/slide fields; explicit group overrides remain unless `-a none`. Groups inherit the resolved slide duration, Start, timing modifiers, after-effect, and sound; `effect_options` stays coupled to an explicit effect; `trigger_shape` is never inherited; omitted `order`/`delay` use exporter defaults. ### 2.1 Deterministic Morph Object Pairing -When one semantic object continues across two adjacent slides, the destination -slide may declare explicit forced-Morph pairs. This is separate from `groups`: -Morph owns cross-slide identity, while `groups` owns Animation Pane rows. -The generated names follow Microsoft's -[forced object-matching convention](https://support.microsoft.com/en-us/powerpoint/morph-transition-tips-and-tricks). +When one semantic object continues across adjacent slides, the destination slide declares forced-Morph pairs — separate from `groups` (Morph owns cross-slide identity; `groups` owns Animation Pane rows) — following Microsoft's [forced object-matching convention](https://support.microsoft.com/en-us/powerpoint/morph-transition-tips-and-tricks): ```json { "version": 1, "slides": { "02_detail": { - "transition": { - "effect": "morph", - "effect_options": { "morph_by": "object" }, - "duration": 0.8 - }, - "morph": { - "from": "01_overview", - "pairs": { - "hero-image": { - "from": "hero-overview", - "to": "hero-detail" - } - } - } + "transition": { "effect": "morph", "effect_options": { "morph_by": "object" }, "duration": 0.8 }, + "morph": { "from": "01_overview", "pairs": { "hero-image": { "from": "hero-overview", "to": "hero-detail" } } } } } } ``` -- `morph` belongs to the destination slide. `morph.from` must be the - immediately preceding SVG stem in export order. -- `animation_config.py scaffold` never guesses cross-slide identity. Add pairs - from the semantic motion plan after inspecting the final direct-root ids. -- Each `pairs` key is a stable identity; its `from` and `to` values are unique - direct-root `` values on the source and destination slides. Supply the - key without `!!`; export writes the PowerPoint Selection Pane name - `!!` on both objects. -- A destination with explicit pairs must explicitly set `effect: morph`. - `morph_by` may be omitted for its `object` default or set to `object`; - `word`/`character` are rejected. A CLI transition override that changes the - resolved effect fails export. -- A middle slide may continue the same object into another Morph transition, - but the same group must retain the same key. One key cannot name two objects - on one slide, and one object cannot carry two keys. Every `!!` key shared by - two adjacent Morph pages must be declared in that destination's `pairs`; - undeclared forced matches are rejected. -- Explicit pairing can coexist with in-slide object animation and remains - active when `-a none` disables Animation Pane rows. `--no-animations` - disables the sidecar and all page/object motion. -- The exporter resolves both group ids to final Slide-local PowerPoint shapes, - writes names only after Master/Layout processing, then reopens the package - and verifies adjacency, Morph by object, one name per slide, and matching - OOXML object types. Missing, structural, moved, ambiguous, or mismatched - targets fail instead of falling back to automatic Morph matching. +`morph` belongs to the destination and `morph.from` is the immediately preceding stem in export order; `scaffold` never guesses identity — add pairs from the motion plan after inspecting final direct-root ids. Each pair key is a stable identity whose `from`/`to` are unique direct-root ids on the two slides, written without `!!` (export writes the Selection Pane name `!!` on both). A destination with pairs sets `effect: morph` explicitly (`morph_by` omitted or `object`; `word`/`character` rejected; a CLI override that changes the effect fails). A middle slide may continue an object into another Morph under the same key; one key never names two objects on a slide, one object never carries two keys, and every `!!` key shared by adjacent Morph pages must be declared. Pairing coexists with in-slide animation and survives `-a none`; `--no-animations` disables everything. The exporter resolves both ids to final Slide-local shapes, writes names after Master/Layout processing, then reopens the package to verify adjacency, Morph by object, one name per slide, and matching object types — missing, structural, moved, ambiguous, or mismatched targets fail rather than falling back. ### 2.2 On-Demand Sound Selection -**Hard rule — select after motion, materialize after selection**: sound is not a -Strategist resource and does not belong in `design_spec.md`, `spec_lock.md`, or -pre-SVG resource preparation. First complete the SVG roster and resolve the -transition/object-motion solution. Only when a specific cue is then selected, -copy its global-library file into the project and reference that local copy. - -| Source | Action | -|---|---| -| Bundled CC0 library | Read the complete objective [`sound-vocabulary.md`](../templates/sounds/sound-vocabulary.md), select one exact id from the resolved auditory job, sync only that selection, then use the corresponding `sounds//.wav` path | -| User-provided audio already inside the project | Reference its existing project-relative `.m4a`, `.mp3`, or `.wav` path for object animation; a transition sound uses `.wav` | -| External absolute file | The low-level object-animation path remains compatible, but new generated projects should copy or sync the intended file into the project and use a relative path | -| No concrete auditory cue job | Keep `sound` omitted; do not create `/sounds/` and do not copy the library | +**Hard rule — select after motion, materialize after selection**: sound is not a Strategist resource and never appears in `design_spec.md`, `spec_lock.md`, or pre-SVG preparation. After the roster and motion solution are final, and only when a specific cue is selected: read the complete [`sound-vocabulary.md`](../templates/sounds/sound-vocabulary.md), choose one exact id for the auditory job, sync only that id, and reference the project-local `sounds//.wav`; user audio already in the project is referenced by its project-relative path (`.m4a` / `.mp3` / `.wav` for objects, `.wav` for transitions); with no concrete cue job omit `sound` and create no `sounds/`. ```bash -# Optional exact filtering only after the complete vocabulary is in context -python3 skills/ppt-master/scripts/sound_sync.py list --query - -# Materialize only the chosen ids -python3 skills/ppt-master/scripts/sound_sync.py \ - / [/ ...] +python3 skills/ppt-master/scripts/sound_sync.py list --query # optional exact filtering after the vocabulary is in context +python3 skills/ppt-master/scripts/sound_sync.py / [...] # materialize only the chosen ids ``` -`sound_sync.py` is the only bundled-library materialization path. Stable ids -include their namespace; copied files remain under -`/sounds//`. The exporter never reads the global -`templates/sounds/` library directly, and sidecars store paths rather than -library ids. - -**Default — silence (may override for a specific cue)**: do not add sound to -demonstrate capability or spread it across a deck for coverage. A sound may -support a named transition, reveal, confirmation, warning, or drawn/moving -gesture after the corresponding visual behavior is already selected. - -**Hard rule — PPTX and MP4 are separate sound deliveries**: sound fields and -package read-back prove the editable PPTX contains the intended native cue; -they do not prove PowerPoint's video encoder placed it in the MP4 audio track. -For direct narrated MP4 delivery with resolved cues, follow `generate-audio` -and choose exactly one branch: mix from the final narrated trace plus final -PPTX after native encoding, or explicitly capture the live PowerPoint Slide -Show with system audio. Never mix the capture again. Keep post-production gain -and limiter settings out of `animations.json`. +`sound_sync.py` is the only library materialization path; the exporter never reads `templates/sounds/`, and sidecars store paths, not ids. **Default — silence**: never add sound to demonstrate capability or for coverage; a sound supports a named transition, reveal, confirmation, warning, or gesture after that visual behavior is selected. **Hard rule — PPTX and MP4 are separate deliveries**: sound fields and read-back prove the PPTX carries the cue, not that PowerPoint's encoder put it in the MP4; a narrated MP4 with cues follows `generate-audio` — mix from the final narrated trace plus final PPTX, or capture the live Slide Show with system audio, never both — and keeps gain/limiter settings out of `animations.json`. --- ## 3. Page Transitions -**Reference — not a constraint**: choose a transition from the relationship -between adjacent pages, not from gallery coverage. Run this playbook before -selecting a canonical key: - -| Pass | Decision | -|---|---| -| Relate | Decide whether the destination continues the same object or space, advances in a meaningful direction, opens a new section, or intentionally breaks continuity. | -| Diagnose | Name the transition's job: neutral continuity, immediate cut, directional progress, object/state continuity, spatial movement, or a deliberate thematic beat. | -| Select | Use the smallest family that performs that job; keep `fade` when no stronger relationship exists. | -| Coordinate | Align direction, duration, and recurrence with reading order, narration, and the deck's established motion language. | -| Stop | Keep `fade` or `none` when another effect adds no meaning; never vary transitions for catalog coverage. | +**Reference — not a constraint**: choose from the relationship between adjacent pages, not gallery coverage — relate (same object or space, directional advance, new section, deliberate break), diagnose the job (continuity, cut, direction, object/state continuity, spatial movement, thematic beat), select the smallest family, coordinate direction, duration, and recurrence with reading order and narration, and keep `fade` or `none` when nothing adds meaning. | Page relationship | Candidate family | |---|---| | Ordinary continuation within one section | `fade` | | Immediate change with no continuity to preserve | `none` or `cut` | -| Directional steps, timeline, or layer progression | `push` / `wipe`; use `cover` / `uncover` when an overlay relationship is visible | -| The same semantic object or scene changes across adjacent pages | `morph`; use §2.1 pairs when identity must be deterministic | +| Directional steps, timeline, or layer progression | `push` / `wipe`; `cover` / `uncover` for a visible overlay relationship | +| The same object or scene changes across adjacent pages | `morph`; §2.1 pairs for deterministic identity | | Section opening, key reveal, or marked state boundary | Selective `split` / `reveal` / `shape` / `flash` / `random_bars` | -| A repeated collection advances through one spatial frame | `pan` / `conveyor` / `ferris_wheel`; use the §4.2 Morph carousel when individual cards need deterministic identity | +| A repeated collection advances through one spatial frame | `pan` / `conveyor` / `ferris_wheel`; the §4.2 Morph carousel for deterministic cards | | The viewpoint travels around or through a continuous space | `rotate` / `window` / `orbit` / `fly_through` | -| The narrative or theme supports a stage, paper, or physical-page metaphor | Selective `fall_over` / `drape` / `curtains` / `wind` / `prestige` / `peel_off` / `page_curl` / `airplane` / `origami` / `doors` | -| A disruptive beat represents breakage, collapse, or dispersal | Selective `fracture` / `crush` / `dissolve` / `vortex` / `shred` | -| A marked reveal benefits from a geometric, timed, or textured pattern | Selective `checkerboard` / `blinds` / `clock` / `ripple` / `honeycomb` / `glitter` / `comb` | -| A card, panel, gallery, or viewpoint visibly turns or changes face | Selective `switch` / `flip` / `gallery` / `cube` / `box` / `zoom` | -| Unpredictability is itself the requested behavior | `random`; never use it merely to create variety | +| A stage, paper, or physical-page metaphor | Selective `fall_over` / `drape` / `curtains` / `wind` / `prestige` / `peel_off` / `page_curl` / `airplane` / `origami` / `doors` | +| Breakage, collapse, or dispersal | Selective `fracture` / `crush` / `dissolve` / `vortex` / `shred` | +| A geometric, timed, or textured reveal | Selective `checkerboard` / `blinds` / `clock` / `ripple` / `honeycomb` / `glitter` / `comb` | +| A card, panel, gallery, or viewpoint visibly turns | Selective `switch` / `flip` / `gallery` / `cube` / `box` / `zoom` | +| Unpredictability itself is requested | `random`; never for variety | ```bash -# Pick a different effect python3 skills/ppt-master/scripts/svg_to_pptx.py -t push --transition-duration 0.6 - -# Remove the visual transition python3 skills/ppt-master/scripts/svg_to_pptx.py -t none - -# Auto-advance every 5 seconds (kiosk-style playback) -python3 skills/ppt-master/scripts/svg_to_pptx.py --auto-advance 5 - -# Auto-advance with no visual transition +python3 skills/ppt-master/scripts/svg_to_pptx.py --auto-advance 5 # kiosk playback python3 skills/ppt-master/scripts/svg_to_pptx.py -t none --auto-advance 5 ``` -The native registry covers PowerPoint's complete Subtle, Exciting, and Dynamic -Content gallery: 48 canonical keys. New selection, sidecars, plans, conversion -traces, and writers use only those keys. Run `pptx_animations.py --list` for -the categorized identifiers. - -Eight old low-level names remain accepted only as compatibility inputs. They -desugar to a native key plus native `effect_options`: for example, `diamond` -becomes `shape` with `shape: diamond`, and `wedge` becomes `clock` with -`style: wedge`. They are never selected for new output. - -Effects expose their real PowerPoint Effect Options through -`transition.effect_options`. Common examples include Push/Wipe direction, -Morph by object/word/character, Reveal through black, Shape geometry, Page -Curl direction/pages, Glitter pattern/direction, and Fly Through bounce. Run -`pptx_animations.py --describe-transition ` for the exact -effect-specific contract; unknown or inapplicable options fail validation. -`none` removes the visual effect. Effects that require newer Office namespaces -carry a real PowerPoint effect in `mc:Choice` and a `fade` fallback for older -consumers; validation requires the requested primary effect and never accepts -the fallback as a silent substitute. - -An optional `transition.sound` adds one `.wav` cue to the transition. It is a -sidecar field rather than a CLI flag. Bundled choices must first be synced by -§2.2 and referenced through their project-relative path. `effect: none` may -still carry a transition sound and/or automatic advance without restoring a -visual effect. A slide-level `transition.sound: null` explicitly clears an -inherited default transition sound for that page. - -Flags: - -- `-t/--transition` — native effect name, compatibility input, or `none` for no visual transition. Default: `fade`. `none` does not remove an explicitly configured automatic advance. -- `--transition-duration` — seconds, default `0.4`. -- `--auto-advance` — seconds; click remains enabled, so the slide advances on click or when the timer expires. Omit for presenter-controlled advance. - -**Hard rule — no silent downgrade**: an unknown transition effect, unsupported Effect Option, or invalid/non-finite duration fails export. It is never replaced by `fade`. Recorded narration keeps the resolved visual transition; `-t none --recorded-narration ...` writes narration-driven advance timing without restoring a visual effect. +The registry covers PowerPoint's complete Subtle, Exciting, and Dynamic Content gallery — 48 canonical keys (`pptx_animations.py --list`); eight old low-level names desugar to a native key plus options (`diamond` → `shape` + `shape: diamond`, `wedge` → `clock` + `style: wedge`) and are never selected for new output. `transition.effect_options` exposes the real Effect Options (Push/Wipe direction, Morph by object/word/character, Reveal through black, Shape geometry, Page Curl direction/pages, Glitter pattern, Fly Through bounce; `pptx_animations.py --describe-transition `); unknown options fail. Effects needing newer namespaces carry a `mc:Choice` plus a `fade` fallback that validation never accepts as a substitute. `transition.sound` (a sidecar field, `.wav`, synced under §2.2) may accompany `effect: none`; a slide-level `transition.sound: null` clears an inherited default transition sound. Flags: `-t/--transition` (native key, compatibility input, or `none`; default `fade`; `none` keeps an explicit auto-advance), `--transition-duration` (default `0.4`), `--auto-advance` (seconds; click still advances). **Hard rule — no silent downgrade**: an unknown effect, unsupported option, or invalid duration fails export and is never replaced by `fade`; `-t none --recorded-narration …` writes narration-driven advance without restoring a visual effect. ### 3.1 Morph — author an action as the difference between two pages -Morph tweens objects it can match across consecutive slides. That makes it a general mechanism, not just a transition: **any continuous action can be authored as two static pages plus a Morph transition**, with no keyframe timeline anywhere. Duplicate the page, change one property on one object, and PowerPoint interpolates the rest. Use §2.1 explicit pairs when the match must be deterministic. +Morph tweens matched objects across consecutive slides, so any continuous action is two static pages plus Morph: duplicate the page, change one property, PowerPoint interpolates. Off-canvas → on-canvas reads as slide-in, drawer, card extending; rotation as flip, turn, hinge; a scaled image container as camera push-in; a dropping scrim or growing cut as progressive reveal; the same wide image at two `x` offsets as camera pan (`#C2-01`). Chain three or more pages for extend–hold–retract. -| Change between the two pages | Reads as | -|---|---| -| Object sits off-canvas, then on-canvas | Slide-in, drawer pull, card extending | -| Object rotates | Flip, turn, hinge | -| Image container scales up | Camera push-in | -| Scrim opacity drops, or a cut contour grows | Progressive reveal | -| Same wide image at two `x` offsets | Camera pan (see image-layout-patterns `#C2-01`) | - -Chain three or more pages to build a sequence — extend, hold, retract — where each page is still an ordinary editable slide. - -**Hard rule — matching needs compatible object identity, not identical SVG -geometry**: for generated decks, prefer §2.1 deterministic pairs. The source -and destination direct-root group ids may differ, and position, size, crop, or -other visible state is expected to change; both endpoints must still resolve to -one compatible top-level PowerPoint object kind. Automatic Morph without pairs -is heuristic and may cross-fade instead of tweening. - -**Give text somewhere to come from.** Morph tweens objects present on both pages; text that only exists on the second page can only fade in. The standard fix is to place the *next* page's copy on the current page just outside the canvas (below), and the *previous* page's copy just outside the opposite edge (above). Each block then slides through the frame instead of blinking, and the deck reads as one continuous surface being scrolled. A wholly off-canvas endpoint must be one direct-root `` with valid `data-pptx-bounds` and `data-pptx-morph-staging="true"`; when Morph remains enabled, pair it explicitly under §2.1. The marker only declares an intentional invisible endpoint; it cannot excuse a partially clipped group or text carrier. - -**When Morph refuses to match**: PowerPoint pairs compatible object kinds; a -shape and a picture will cross-fade instead of tweening. For generated pages, -declare the identity through the destination slide's `morph` block (§2.1). -The exporter writes the shared `!!` name after structure processing and -reads the package back. Do not author `data-pptx-shape-name` for this purpose; -that attribute remains importer metadata for mirror/preserve packages -([`svg-effects.md`](./svg-effects.md) §6.6). - -**Not supported — Slide Zoom / Summary Zoom.** Click-to-jump navigation built on PowerPoint's Zoom objects (the "click a portrait, zoom into that section" pattern) has no exporter path. Build click-driven navigation with `trigger_shape` on ordinary object animations instead, or with plain hyperlinks. - -**No 3D**: perspective rotation, extrusion, and shear are outside the SVG contract — `skewX` / `skewY` and shear matrices fail closed ([`svg-effects.md`](./svg-effects.md) §6.8). Build the same impression with 2D means — offset, scale, overlap, and per-facet lightness — rather than attempting a 3D tilt. +**Hard rule — matching needs compatible identity, not identical geometry**: prefer §2.1 pairs; ids and visible state may differ, but both endpoints must resolve to one compatible top-level PowerPoint object kind — a shape and a picture cross-fade instead of tweening. Automatic Morph is heuristic. **Give text somewhere to come from**: text present only on the second page can only fade in — place the next page's copy just below the canvas and the previous page's just above, so blocks slide through the frame; a wholly off-canvas endpoint is one direct-root `` with valid `data-pptx-bounds` and `data-pptx-morph-staging="true"`, explicitly paired when Morph stays enabled; the marker never excuses a partially clipped group. Declare identity through the destination's `morph` block, never `data-pptx-shape-name` (importer metadata, [`svg-effects.md`](./svg-effects.md) §6.6). **Not supported**: Slide Zoom / Summary Zoom (build click navigation with `trigger_shape` or hyperlinks) and 3D — perspective, extrusion, and shear fail closed ([`svg-effects.md`](./svg-effects.md) §6.8); build the impression with offset, scale, overlap, and per-facet lightness. --- ## 4. Per-Element Animations -Off by default — enable deck-wide with `-a auto` (or another effect). Once enabled, three Start modes are available — these mirror PowerPoint's animation-pane "Start" dropdown: +Off by default; enable with `-a auto` (or another effect), select a canonical effect with `--animation entrance_fade`, and choose Start with `--animation-trigger on-click|with-previous|after-previous` — PowerPoint's Start dropdown: `on-click` (each click reveals the next group; only for a controlled semantic reveal; forbidden with `--recorded-narration`), `with-previous` (one coordinated beat; stagger ignored), `after-previous` (default click-free cascade with `--animation-stagger`). **Default — one dominant deck rhythm and normally one mode per slide (may mix for a distinct simultaneous or presenter-controlled beat)**. Row-specific `trigger_shape` is PowerPoint's separate Trigger → On Click of, not a fourth mode. -- **`on-click`** — each click reveals the next group. Use only for a controlled semantic reveal; live delivery alone is insufficient. Forbidden with `--recorded-narration`. -- **`with-previous`** — groups start together as one coordinated beat. Stagger ignored. -- **`after-previous`** (default) — click-free cascade on slide entry with `--animation-stagger` spacing. Use when controlled reveals are unnecessary. - -**Default — coherent Start rhythm (may override when a semantic beat needs -different control)**: Keep one dominant deck rhythm and normally one mode per -slide. Mix only for a distinct simultaneous or presenter-controlled beat. - -Enable with `-a auto`, select a canonical effect with -`--animation entrance_fade`, and choose Start behavior with -`--animation-trigger on-click|with-previous|after-previous`. - -PowerPoint's separate **Trigger → On Click of** behavior uses row-specific -`trigger_shape`. It links that row to another top-level group while unlinked -rows keep the slide Start mode; it is not a fourth deck-wide Start mode. - -**Mandatory — lifecycle before effect selection**: start from `static`, then -classify semantic `initial → action → end` before choosing an effect. Generic -staged reveals normally use `enter`; narrower communication jobs select their -matching lifecycle instead. +**Mandatory — lifecycle before effect**: start from `static`, classify `initial → action → end`, then choose the effect; generic staged reveals are `enter`, narrower jobs select their lifecycle. | Duty | State contract | Use when | Effect family | |---|---|---|---| -| `static` | present → hold as reference → present | Motion adds no clarity or intended feeling | No row; legacy `effect: none` only suppresses inheritance | -| `enter` | absent → introduce → present | Information should be withheld, ordered, or revealed with narration | `entrance_*`; modes only for generic reveal | -| `emphasize` | present → redirect attention → present/altered | An already visible object must regain attention or show a local change; never substitute for its first reveal | Explicit `emphasis_*` | -| `move` | state/position A → progress → state/position B | The trajectory carries spatial or causal meaning, or §4.1 adopts subordinate ambient motion; use Morph for cross-page continuity | Explicit `path_*`, or endpoint pages + Morph | -| `exit` | present → retire → absent | The same slide must remove, replace, or make room for content; an ordinary page change needs no object exit | Explicit `exit_*` | +| `static` | present → hold → present | Motion adds no clarity or feeling | No row; legacy `effect: none` only suppresses inheritance | +| `enter` | absent → introduce → present | Information is withheld, ordered, or revealed with narration | `entrance_*`; modes only for generic reveal | +| `emphasize` | present → redirect attention → present/altered | A visible object must regain attention or show a local change; never its first reveal | Explicit `emphasis_*` | +| `move` | A → progress → B | The trajectory carries spatial or causal meaning, or §4.1 ambient motion; Morph for cross-page continuity | Explicit `path_*`, or endpoint pages + Morph | +| `exit` | present → retire → absent | The same slide must remove, replace, or make room; a page change needs no exit | Explicit `exit_*` | -**Default — restrained entrance-led choreography (may override for content, -tone, or the request)**: Use entrances for ordinary builds. Add emphasis or -exit sparingly, only for a real duty and fitting effect. Multiple `effects[]` -rows require multiple duties. +**Default — restrained entrance-led choreography (may override for content, tone, or the request)**: entrances for ordinary builds; emphasis or exit only for a real duty; several `effects[]` rows only for several duties. -The registry exposes two layers: - -- **203 PowerPoint-native object presets**: 53 `entrance_*` presets, 33 - `emphasis_*` effects, 64 `path_*` motion paths, and 53 `exit_*` effects. - Examples include `entrance_bounce`, `emphasis_spin`, `path_circle`, and - `exit_faded_zoom`. Each native key carries the complete PowerPoint-authored - behavior tree, not a generic filter approximation. -- **29 legacy compatibility inputs**, listed by `--list`; new output never - selects them. - -Run the registry command for the exact categorized key list: - -```bash -python3 skills/ppt-master/scripts/pptx_animations.py --list -``` - -Compatibility names normalize before selection and writing: for example, -`fade` resolves to `entrance_fade`; every old Fly direction name resolves to -`entrance_fly`; every old Wipe direction name resolves to `entrance_wipe`; and -`cut` resolves to `entrance_appear` because current PowerPoint has no separate -Cut object effect. Directional aliases preserve their old direction through -`effect_options`; legacy `wheel` maps to `entrance_wheel` with four spokes. -These names are accepted only as compatibility inputs. -Automatic selection, new sidecars, conversion traces, and writers use -canonical keys. - -The native keys mirror the object-capable `MsoAnimEffect` surface. The four -media commands—play, pause, stop, and play from bookmark—are not object effects -for SVG groups and remain owned by the audio/video workflows. - -- `auto` handles generic `enter` duties only and maps semantic ids to canonical entrances: charts/tables/timelines use - `entrance_wipe`; cards/steps use `entrance_fly`; titles/takeaways use - `entrance_fade`; image-like ids cycle a richer pool; unmatched ids cycle - fade/wipe/fly/zoom. -- `mixed` (legacy mode name) handles generic `enter` duties only and is - deterministic. The first animated group on each - slide uses `entrance_fade`; later groups cycle through a 16-effect canonical - PowerPoint entrance pool across the deck. The mode name remains compatible; - it no longer selects hand-authored compatibility rows. -- `random` handles generic `enter` duties only and samples from the same - canonical PowerPoint entrance pool. - Resolution is seeded from the effective deck input, so the same input - produces the same choices; `--conversion-trace` records every resolved effect - when diagnostics are enabled. - -`entrance_appear` is excluded from every variation pool because it has no -visible motion. `auto`, `mixed`, and `random` never satisfy an adopted -`emphasize`, `move`, or `exit` duty; those require explicit canonical effects. - -Flags: `-a/--animation` selects effect/mode; `--animation-trigger` selects Start; -`--animation-duration` and `--animation-stagger` control base timing; -`--animation-config` selects a sidecar; `--no-animations` disables page/object -motion but preserves narration audio and recorded advance timing. - -> Note: `--recorded-narration` rejects `on-click` and `trigger_shape`. Narration-cue sync uses `narration_animations.json` and blocks when only canonical `animations.json` exists. Narration-independent custom motion explicitly passes `--animation-config animations.json`, even when a derived sidecar also exists. With no sidecar, pass `--inherit-motion-from `; explicit all-motion-off uses `--no-animations`. +The registry has **203 native object presets** — 53 `entrance_*`, 33 `emphasis_*`, 64 `path_*`, 53 `exit_*` (e.g. `entrance_bounce`, `emphasis_spin`, `path_circle`, `exit_faded_zoom`), each carrying the complete PowerPoint behavior tree — plus 29 legacy compatibility inputs that normalize before selection (`fade` → `entrance_fade`, old Fly/Wipe direction names → `entrance_fly` / `entrance_wipe` with the direction in `effect_options`, `cut` → `entrance_appear`, `wheel` → `entrance_wheel` with four spokes) and are never written. `python3 skills/ppt-master/scripts/pptx_animations.py --list` prints the categorized keys; media play/pause/stop belong to the audio/video workflows. Modes handle generic `enter` only: `auto` maps semantic ids to canonical entrances (charts/tables/timelines `entrance_wipe`, cards/steps `entrance_fly`, titles/takeaways `entrance_fade`, image-like ids a richer pool, others fade/wipe/fly/zoom); `mixed` is deterministic (`entrance_fade` first, then a 16-effect canonical pool); `random` samples the same pool, seeded from the effective deck input so results repeat; `entrance_appear` is excluded from every pool; none satisfies an adopted `emphasize`, `move`, or `exit`. Flags: `-a/--animation`, `--animation-trigger`, `--animation-duration`, `--animation-stagger`, `--animation-config `, `--no-animations` (kills page/object motion, keeps narration audio and recorded advance). `--recorded-narration` rejects `on-click` and `trigger_shape`; narration-cue sync uses `narration_animations.json` and blocks on a bare canonical sidecar; narration-independent custom motion passes `--animation-config animations.json` explicitly; with no sidecar pass `--inherit-motion-from `. ### 4.1 Slow ambient motion — the page that breathes -**Reference — not a constraint**: ambient motion can keep a static page from -feeling frozen when it remains visually subordinate to the message. A common -starting recipe is `path_left` or `path_right` on a background image, started -`with-previous` and paced much more slowly than a content reveal. The same -principle may suit another atmospheric or non-information-bearing layer. Choose -duration, distance, and moving-object count from the composition and delivery -context. - -Keep a full-bleed moving image covering the canvas at both endpoints; exposing -the slide beneath it is a visible failure. - -It pairs naturally with a fixed foreground: with image-layout-patterns `#M1-07`, the scrim and its cut contour stay locked while the world moves behind the cuts, which reads as looking through windows rather than as a sliding photo. The same logic applies to `#M1-10` and `#P1-09`. - -Motion remains subordinate: avoid competing ambient paths or movement that -reduces the readability of body copy or data. Multiple coordinated layers are -valid when they express one intentional depth or atmosphere relationship. +**Reference — not a constraint**: `path_left` / `path_right` on a background image, started `with-previous` and paced far slower than a content reveal, keeps a static page from feeling frozen while staying subordinate; the same applies to any non-information-bearing layer, with duration, distance, and moving-object count from the composition. A full-bleed moving image must cover the canvas at both endpoints. With a fixed foreground (`#M1-07`, also `#M1-10`, `#P1-09`) the scrim and its cuts stay locked while the world moves behind them — windows, not a sliding photo. Coordinated layers are valid for one depth or atmosphere relationship; competing paths or motion that hurts copy or data are not. ### 4.2 Recurring recipes -Four combinations that recur constantly in authored decks. Each is built from -mechanisms already defined above — none needs a new capability. - -**Carousel** (Morph, §2.1 and §3.1) — hold a fixed row of card frames and rotate the *content* through them: on each page every image advances one position, so the card at centre changes while the frames stay put. Explicitly pair each moving content unit across adjacent pages; the fixed frames stay static and need no pair. Scales to any number of images with one page each. - -**Odometer / counting numerals** (morph or motion path) — build a vertical strip of digits 0–9 and show one through a fixed window formed by background-filled rectangles above and below ([`image-layout-patterns.md`](./image-layout-patterns.md) `#M1-08`). Shift the strip so the target digit lands in the window, then either morph between two pages or run a `path_up` motion on the strip. A small stagger, such as `0.1s`, can make digit columns settle in sequence; synchronized motion is also valid when it fits the intended rhythm. - -**Parallax depth** (morph) — move a background layer a *short* distance and a foreground layer a longer one between two pages. The differing travel is read as depth. Keep both layers' z-order identical on both pages; a layer that changes stacking between pages breaks the tween and the transition jumps. - -**Flip-card / click-to-reveal** (`trigger_shape`, §4) — pair a face group and a back group at the same position, give the face an exit and the back an entrance, and set the back's `trigger_shape` to the face's id. Clicking the face plays both. This is the supported route for click-driven interaction; PowerPoint's Zoom objects are not (§3.1). +- **Carousel** (Morph, §2.1/§3.1): hold a fixed row of card frames and rotate the content through them one position per page, pairing each moving content unit; frames stay static and unpaired. +- **Odometer** (Morph or path): a vertical 0–9 strip shown through a window of background-filled rectangles (`#M1-08`); shift the strip so the target digit lands, then morph or `path_up`; a `0.1s` stagger settles columns in sequence, and synchronized motion is also valid when it fits the intended rhythm. +- **Parallax depth** (Morph): move the background a short distance and the foreground a longer one; keep z-order identical on both pages or the tween jumps. +- **Flip-card / click-to-reveal** (`trigger_shape`): a face group and a back group at the same position, face with an exit and back with an entrance whose `trigger_shape` is the face's id — the supported click-driven route (Zoom objects are not, §3.1). --- ## 5. Anchor Logic — Top-Level `` -Per-element animations are anchored on **top-level `` content -groups** in the SVG (e.g. ``, ``). IDs must -be unique within the page. A backward-compatible single-effect group produces -one Animation Pane row; `effects[]` may produce several ordered rows targeting -the same PowerPoint shape. Each row inherits the slide Start mode unless it -declares its own `trigger`. Nested implementation groups may remain anonymous -because the sidecar does not target them. - -**Hard rule — existing groups are not custom-animation intent**: the -pre-existing SVG hierarchy is implementation evidence, not an authoritative -motion plan. During the custom-animation stage, derive one group per logical -motion unit from claims, comparisons, sequence, causality, and narration beats; -split coarse wrappers and merge fragmented atoms when needed, then use -`list-groups` only after that rewrite. This is also the granularity PowerPoint -uses for group-select / group-move. Do not split or merge units to hit a target -count. - -**Chrome stays static.** `data-pptx-layer` and explicit static -role/placeholder markers are absolute. The legacy chrome-like ID heuristic -(background, header/footer, decor, watermark, page number, nav, logo, rule) -applies only to a top-level group that itself lacks `data-pptx-layer`, -`data-pptx-role`, and `data-pptx-placeholder` semantics; an explicit sidecar -entry may override only this name heuristic. Keep wrappers and use -`effect: none` for static content. - -**Fallback for flat SVGs** (no top-level `` wrappers, only raw `` / `` / `` at the root): - -- ≤ 8 visible top-level primitives → each becomes one anchor (capped to avoid 70+ atom cascades on dense pages). -- > 8 → animation is skipped on that slide. The slide still renders, just without object animation. - -Executors should wrap logical sections in `` regardless of whether you plan to animate. [`shared-standards-core.md`](./shared-standards-core.md) requires it. +Animations anchor on unique top-level `` content groups (`cover-title`, `card-1`); a single-effect group yields one Animation Pane row, `effects[]` several, each inheriting the slide Start unless it declares `trigger`; nested groups stay anonymous and untargeted. **Hard rule — existing groups are not custom-animation intent**: during the custom stage derive one group per logical motion unit from claims, comparisons, sequence, causality, and narration — splitting coarse wrappers and merging fragments without changing appearance, never to hit a count — and run `list-groups` only after that rewrite. **Chrome stays static**: `data-pptx-layer` and explicit static role/placeholder markers are absolute; the legacy chrome-name heuristic (background, header/footer, decor, watermark, page number, nav, logo, rule) applies only to unmarked top-level groups and only it may be overridden by a sidecar entry. Flat SVGs with no top-level ``: ≤8 visible root primitives each become an anchor, more skips animation on that slide. Wrap logical sections in `` regardless ([`shared-standards-core.md`](./shared-standards-core.md)). --- ## 6. Validation and Read-Back -Animation configuration is strict. Export fails on an unknown effect, mode, or -trigger; invalid timing/order values; a missing slide/group/`trigger_shape` -reference; a self-trigger; or any attempt to animate or trigger from a -structural layer. These errors never downgrade or silently omit a target. - -Generated export reads each slide's timing tree back and checks row count/order, -including repeated rows on one shape, trigger, trigger shape, shape target, -preset class, resolved effect tuple, native behavior signature, duration, and -timeline offset. Package validation then checks root -timing placement, unique and valid `p:cTn` ids, and every `p:spTgt` reference. -Deterministic Morph additionally checks the final adjacent slide parts for the -requested `!!` names, one-to-one uniqueness, compatible object types, and a -real Morph-by-object transition on the destination. -The writer does not emit `p:bldP` for groups or pictures. Direct-PPTX preserve -mode tolerates unchanged legacy group/picture `p:bldP` rows from earlier PPT -Master exports; new generated packages remain strict. - -Narration injection preserves animation and updates both p14 Choice/Fallback -when bounce timing is present; unsupported nested timing fails safely. -Direct-PPTX routes fingerprint source -object-animation timing before and after their allowed edits, then run -structural package validation; they do not author or normalize animation -effects. - -`pptx_to_svg.py` uses the same generated-transition read-back validator to -project supported source `p:transition` into canonical `animations.json` rows. -It retains the registry effect, effective options, exact duration, automatic -advance, and supported WAV sound; the sidecar defaults to `none` so absent -source transitions remain absent on re-export. Unknown or inexact native -carriers stay diagnosed/direct-preserve. This is a closed PPT Master-owned -contract, not an arbitrary OOXML transition normalizer. - -For source `p:timing`, the importer accepts only current generated behavior -trees whose registry effect/options, pane order, Start trigger, exact duration, -relative delay, and target/optional trigger shape map to unique top-level slide -SVG groups. It emits one group row or `effects[]` in the same sidecar. Rows -without a native duration, advanced timing modifiers, sounds, builds/media -commands, unknown behavior trees, and unmapped targets remain diagnosed/direct- -preserve; no timing value is inferred. - -**Validation boundary**: these checks prove PPTX timing, relationships, and -embedded sound parts. They are not final-video audio acceptance. The -native-export branch requires a triggered `video_sound_mix.py` receipt; the -slideshow-capture branch requires the human picture/audio/all-cue acceptance -owned by `generate-audio` and never claims that receipt. +Export fails on an unknown effect, mode, or trigger; invalid timing or order; a missing slide, group, or `trigger_shape`; a self-trigger; or animating or triggering from a structural layer — never downgrading or omitting a target. It reads each slide's timing tree back (row count and order including repeats on one shape, trigger, trigger shape, target, preset class, effect tuple, behavior signature, duration, offset), validates root timing placement, unique `p:cTn` ids, and every `p:spTgt`, and for deterministic Morph checks the adjacent parts for the `!!` names, one-to-one uniqueness, compatible types, and a real Morph-by-object transition. The writer emits no `p:bldP` for groups or pictures (preserve mode tolerates legacy ones). Narration injection preserves animation and keeps p14 Choice/Fallback in sync; direct-PPTX routes fingerprint source timing before and after their edits and never author effects. `pptx_to_svg.py` projects supported source `p:transition` (registry effect, options, exact duration, auto-advance, WAV sound; sidecar default `none`) and only current generated `p:timing` trees (registry effect, pane order, Start, exact duration, relative delay, unique top-level targets) into `animations.json`; unknown carriers, missing durations, advanced modifiers, sounds, builds, and unmapped targets stay diagnosed/direct-preserve with no inferred value. These checks prove PPTX timing and embedded sound parts, not final-video audio: the native-export branch needs a `video_sound_mix.py` receipt and the capture branch the human acceptance owned by `generate-audio`. --- ## 7. Video Adaptation Contract -Video renderers consume the resolved conversion trace through -`video_motion_plan.py`, never a raw sidecar or delay-only inference. The plan -locks identity, order, effect, direction, and timing; video may refine only its -declared renderer parameters. Unsupported families fail visibly. See -[`video-motion-plan.md`](../scripts/docs/video-motion-plan.md). - -On the native-export mix branch, direct narrated video sound uses the final -resolved trace for cue order and offsets, the final PPTX relationships for the -exact embedded audio bytes, and page-level narration correlation for the -exported-video clock. It never reads sound timing from a raw sidecar or -filename. The explicit slideshow-capture branch records PowerPoint's real-time -playback instead and does not consume the trace for sound mixing. - ---- +Video renderers consume the resolved conversion trace through `video_motion_plan.py` ([`video-motion-plan.md`](../scripts/docs/video-motion-plan.md)), never a raw sidecar or delay inference; the plan locks identity, order, effect, direction, and timing, video refines only its declared renderer parameters, and unsupported families fail visibly. The native-export mix uses the final trace for cue order and offsets, the final PPTX relationships for the embedded bytes, and page-level narration correlation for the clock; the slideshow-capture branch records real-time playback and does not consume the trace. ## 8. Limitations -- Generated animation belongs to the native PPTX built from `svg_output/`. - `svg_final/` is a static preview, and inserting it as one SVG picture does - not create object anchors. -- PowerPoint OOXML is the compatibility target; other presentation apps may - reinterpret individual native behavior trees. -- PowerPoint's native MP4 encoder may omit transition and object-animation - sounds even when the PPTX package is valid. Direct sound-enabled MP4 delivery - therefore uses either the post-export mix or the explicit real-time - slideshow-capture contract owned by `generate-audio`; the branches never - stack. -- Direct-PPTX routes preserve unknown transition `AlternateContent`; timing - edits keep Choice and Fallback advance attributes synchronized. - ---- +Generated animation belongs to the native PPTX built from `svg_output/` (`svg_final/` is static and inserting it creates no anchors); PowerPoint OOXML is the compatibility target and other apps may reinterpret behavior trees; PowerPoint's MP4 encoder may drop transition and object sounds, so sound-enabled MP4 uses the post-export mix or the capture contract; direct-PPTX routes preserve unknown transition `AlternateContent` and keep Choice/Fallback advance attributes synchronized. ## 9. Implementation References -See [`pptx_transitions.py`](../scripts/pptx_transitions.py), -[`svg-pipeline.md`](../scripts/docs/svg-pipeline.md), -[`pptx-transitions.md`](../scripts/docs/pptx-transitions.md), -[`pptx-animations.md`](../scripts/docs/pptx-animations.md), and -[`video-motion-plan.md`](../scripts/docs/video-motion-plan.md). +[`pptx_transitions.py`](../scripts/pptx_transitions.py), [`svg-pipeline.md`](../scripts/docs/svg-pipeline.md), [`pptx-transitions.md`](../scripts/docs/pptx-transitions.md), [`pptx-animations.md`](../scripts/docs/pptx-animations.md), [`video-motion-plan.md`](../scripts/docs/video-motion-plan.md). diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/artifact-ownership.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/artifact-ownership.md index 16d7d52d..921775a2 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/artifact-ownership.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/artifact-ownership.md @@ -1,22 +1,10 @@ # Artifact Ownership Specification -Global artifact ownership rules for PPT Master projects. A selected route or -profile may explicitly omit an artifact without erasing its facts. +Global artifact ownership rules for PPT Master projects. A selected route or profile may explicitly omit an artifact without erasing its facts. -**Hard rule**: Read each fact from its owning artifact. Do not merge multiple channels into a second source of truth. +**Hard rule**: read each fact from its owning artifact; never merge several channels into a second source of truth. -**Quick Generate projection**: Quick omits confirmation, Design Spec, and lock. -Its current main agent reads source/analysis facts, keeps routine decisions in -active context, and prepares the selected images/icons plus required -operational manifests before SVG authoring. It realizes native formulas directly -from exact mathematical content under [`native-formula.md`](./native-formula.md), -and may also realize charts, tables, native shapes, and other ordinary authoring -capabilities directly from that context. Exact template workspace roots supplied for the run are validated and -installed directly; Quick reads only that project-local state and creates no -Confirm UI selection artifacts. Those artifacts retain their factual/provenance -roles. Quick writes the same final SVG quality provenance and package postflight -as the default profile, but it does not create `svg_final/`, a detailed design -history, or resumable planning state. Context loss restarts the Quick run. +**Quick Generate projection**: Quick omits confirmation, Design Spec, and lock. Its main agent reads source/analysis facts, keeps routine decisions in active context, prepares selected images/icons plus required operational manifests before SVG authoring, and realizes formulas, charts, tables, native shapes, and other ordinary capabilities directly from that context. Exact workspace roots supplied for the run are validated and installed directly; Quick reads only project-local state and creates no Confirm UI artifacts. It writes the same final SVG quality provenance and package postflight as Default but no `svg_final/`, design history, or resumable planning state; context loss restarts the run. --- @@ -24,47 +12,46 @@ history, or resumable planning state. Context loss restarts the Quick run. | Artifact | Owner | Role | Read/write contract | |---|---|---|---| -| `sources/` content-type files | Content contract | Main pipeline factual/text origin for tables, chart data values, SmartArt node wording, and presentation content | Default Strategist reads content-type files (`.md` / `.markdown` / `.txt` / `.csv` / `.tsv` / `.json` / `.jsonl` / `.yaml` / `.yml`), judges by content, and resolves approved semantics plus preferred on-slide wording into §IX; Quick's current agent resolves them in active context. Default Executor opens source passages only for explicit verification/resolution. Never replace values with PPTX geometry JSON. | -| `sources/*.facts.json` | Fact provenance contract | Stable external `fact_id` → claim/source mapping created by topic research | Default Strategist cites IDs in §IX and Executor resolves them for attribution; Quick's current agent carries the same IDs into visible attribution. Scenario data never enters this file. | -| `sources/` converted-source originals | Source archive | Imported source files that have a converted content contract (`.pdf` / `.pptx` / `.docx` / `.xlsx` / `.html` / `.epub` / `.tex` / `.rst` / `.ipynb` / `.typ`, etc.) and source-adjacent extracted assets | Read via the converted `.md` in the main pipeline; direct-PPTX workflows read the `.pptx` by route | -| `sources/*.conversion_profile.json`, `sources/*_files/image_manifest.json` | Pipeline sidecar | Conversion audit record / asset index | NOT read as slide content; open only to audit a conversion or resolve assets | -| `sources/` Image to PPTX source containers | Visible-surface source contract | One or more immutable raster inputs that may each contain one page or several visibly bounded page frames | The Codex-supported Quick profile normalizes them into the ordered canonical frame roster without overwriting originals; frame count, not input-file count, owns slide count. | -| `analysis/source_profile.json` | Machine fact index | Compact PPTX intake digest | Default Strategist or Quick's current agent reads it as factual context and recommendation candidates | -| `analysis/.identity.json` | Native deck identity facts | Canvas, theme palette/fonts, observed usage | Read selectively when detailed identity facts are needed | -| `analysis/.slide_library.json` | Native PPTX structure facts | Text slots, geometry, native tables, native chart caches, SmartArt nodes/connections | Direct PPTX workflows use as native fill/structure contract | -| `analysis/beautify_inventory.json` | Beautify frozen validation ledger | Complete self-contained per-slide ledger of frozen content/data and validation exceptions, deterministically inlined from the source extracts | Keep the complete file as the sole Beautify ledger. Models normally consume derived read-only stdout projections from `beautify_inventory.py --summary` or `--page`; add `--with-geometry` only when raw source geometry is required. Never persist a projection or treat it as a second authority. | -| `analysis/image_analysis.csv` | Regenerated image fact view | Measured facts about the current `images/` folder | Re-run `analyze_images.py` before reading image facts after changes | -| `analysis/reconstruction_inventory.json` | Image to PPTX source-evidence ledger | Source-container/frame mapping, hashes, page order/canvas, visible-region bboxes, observed text/graphic/image family, transcription confidence, overlap/z-order observations, and unresolved evidence | The active Codex Quick agent writes it before layer decisions. It contains no final realization, prompts, output filenames, or SVG bindings; those belong to Quick active context plus required operational image evidence. | -| `design_spec.md` | Strategist design authority | Human-readable design intent, page brief, rationale, resources, and production mechanics | Consume final confirmation once, write/audit here, and apply enabled refinement to this same artifact. §I records effective Speaker Notes, Custom Animations, and Narration Audio outcomes plus provenance; a newer explicit user instruction updates only its owning outcome without reopening Confirm UI. After Gate 1 plus conditional approval, later roles read this file instead of `result.json`; §IX owns Executor page content, while its layout/composition/capability/motif recommendations remain References unless an explicit user/template/resource constraint promotes the named property. | -| `spec_lock.md` | Execution anchor and routing contract | Machine-readable stable color/type roles, icons, images, page rhythm, charts, `template_reuse_scope`, and the route's PowerPoint structure mode; mirror/layout template routes additionally own input prototypes, the Master roster, and the complete page-to-Master/Layout mapping | Strategist authors the route-specific anchors from the audited Design Spec plus current project/page/template context. Executor retains the complete lock once per valid execution context; local uncertainty consults that retained copy before the owning Design Spec fragment. Sparse page-local color/font garnish needs no lock row; a recurring semantic role or new adaptive Layout identity requires Strategist repair before reuse. | -| `project_manager.py page-context` stdout | Derived on-demand page context | Read-only model-facing anchor set + current-page delta + fingerprints for large references | Use only for explicit diagnostics/telemetry or an unresolved page/template/chart path-SHA projection. Never edit or persist it as a replacement source of truth, and never run it as a routine pre-page gate. `global` is a bounded anchor set, not a whitelist. `reference_set` carries path/SHA/load policy but never appends reference payloads. | -| `analysis/page-context/P.usage.json` | Derived optional context telemetry | Measured on-demand page-context size plus hashes of owning inputs/references | `page-context --record-usage` deterministically replaces only the invoked page's snapshot; `page-context-report` summarizes existing snapshots. Telemetry may be partial. Use token data to evaluate context cost, never as content or an execution contract. | -| `images/` | Runtime image pool | User, extracted, AI, web, slice, and EMF/WMF assets | Default Step 5 or Quick Generate resource preparation writes here; `analysis/image_analysis.csv` derives from current contents | -| `images/image_prompts.json`, `image_queries.json`, `image_sources.json` | Conditional resource contracts | AI/web execution status and provenance | Create only for a triggered path, including Quick. They guide preparation/attribution, never page design. | -| `icons/` | Prepared project icon pool | Bundled icons copied by `icon_sync.py` plus user-provided, template, imported, or custom icon SVGs | SVG authoring may choose any icon in this project-local pool per page; `spec_lock.icons.inventory` indexes the default plan's curated synced bundled pool rather than assigning page usage or defining an exhaustive whitelist. Preview, finalization, checking, and export resolve only complete `library/name` references under this root. | -| `${SKILL_DIR}/templates/{brands,styles,layouts,decks}/*_index.json` | Library discovery indexes | The complete registered option source for Default Stage-1 template selection and chat listing | The UI server or chat branch reads these indexes only to populate the Stage-1 choice, after the communication recommendation is authored. Never scan kind directories to add options or use index summaries as Stage-1 planning evidence. Derive a library root from kind + entry id. Exact unregistered roots remain explicit inputs. Quick does not read the catalog. | -| `templates/` | Project template reference | Stage-1-confirmed non-free selection or Quick direct-input installed specs, one file per selected workspace, the effective structural SVG roster (Layout when present, otherwise Deck), and non-image assets | Default template-aware Strategist work from Stage 2 onward, Quick's current agent before direct authoring, and every later role read this project-local state only, never the library/external installation root. The active planner reads every installed template Design Spec and the effective structural SVG roster; Brand and Style are intentionally roster-free, and Deck structure is shadowed when Layout is present. Continuous Executor reuses that context; fresh Executor reads the Design Spec once and each selected complete SVG, when any, only before first use or after its SHA changes. | -| `templates/template_execution_manifest.json` (`v1`) + `templates/template_execution/*.text-slots.json` (`v2-min`) | Derived template index | Compact prototype/source-import summary plus per-prototype text-slot diagnostics; the sidecar integrity hash is tool-only | Materialization may publish these deterministic records, but page-context does not inject or require them and models do not read them during page authoring. The complete prototype SVG is the sole visual/template authority; never author from either JSON artifact. | -| `/svg/` | Imported native-payload backing | Complete PPTX-derived metadata, hidden carriers, fallback evidence, and source structure | Keep immutable; create-template materialization may resolve a validated source ref against these files, but models do not edit or bulk-read them | -| `/svg-flat/` | Optional complete-page verification backing | Self-contained visual composition generated only by explicit `--inheritance-mode both` | Keep immutable when requested; never use as authoring or materialization input | -| `/authoring-svg/` | Template-creation author source | Canonical compact layered SVG IR for imported Master, Layout, and Slide objects | The PPTX import transaction publishes it already normalized and decoration-factored; Template_Designer reads and edits it, and final template SVGs are materialized from it rather than copied from lossless backing | -| `/authoring-svg/authoring_summary.json` | Model-readable authoring index | Current SVG roster plus compact per-file canvas, size, text, image, vector, placeholder, and source-ref counts | Models read this before authoring SVGs; regenerate after direct IR edits | -| `/authoring-svg/authoring_manifest.json` | Tool-only authoring provenance contract | Per-document source/authoring hashes and document-local source-ref paths | Generated atomically with the IR; materialization validates it before reusing native payload; never load it into model context or duplicate raw payload here | -| `/authoring-svg-flat/` | Optional complete-page verification IR | Self-contained page composition view with its own summary and provenance manifest | Generate only from an explicitly requested `svg-flat/`; use to verify composition, while layered `authoring-svg/` remains the canonical editable source | -| `/icons/imported/` | Imported vector pool | One canonical copy of every factored vector subtree | Authoring SVGs reference `data-icon="imported/"`; vector inventories retain source refs so expansion re-establishes IR identity | -| `confirm_ui/template_options.json`, `template_selection.json`, `template_handoff.json` | Default UI template-selection sidecar | Agent-authored candidate input, user-confirmed selection written beside the Stage-1 result, and agent-authored installation/free-design completion handoff | Step 3 writes options without launching UI. The Stage-1 submission writes `template_selection.json` alongside `result.json`; template choices never enter the Strategist contract. After installation/free-design closure, `--complete-template-selection` writes the bound handoff. Stage 2 is exposed only after that handoff and a fresh recommendation. Chat/delegated flows retain equivalent state without fabricating UI receipts; Quick creates none. | -| `confirm_ui/recommendations.stage1.json`, `.stage2.json` | Confirmation proposals | Template-independent communication contract, then template-aware complete solution plus production mechanics | Author the Stage-1 communication recommendation without using candidate indexes or workspaces as evidence; candidate display state may be prepared independently. Its page confirms communication plus template mode/selection in one submission. Create Stage 2 only after the selection is installed or free design closes and the handoff/equivalent state is ready. `template_application` decides only how to use installed project-local state. The active unconfirmed stage may be overwritten; normal progression leaves confirmed Stage 1 intact. | -| `confirm_ui/result.json` | Confirmation result | Persisted user-confirmed input evidence | Generate Step 4 reads the final object once into active context; Strategist consumes it completely into `design_spec.md`. Normal downstream work does not reopen it; fresh recovery may read it once when no retained final state exists. | -| `svg_output/` | Page-design author source | Main-agent handwritten SVG pages containing the complete visible design, including each native formula's exact LaTeX marker and ordinary SVG preview | Quality checker and native PPTX export read this as the canonical visual/page-layout source; templates and locks do not add missing visible objects at export. Formula export replaces only its explicit marker subtree under [`native-formula.md`](./native-formula.md). | -| `notes/total.md` | Conditional speaker-note source | Complete notes before splitting | Step 6 writes only when the effective Speaker Notes outcome is enabled; Step 7.1 or Quick §4 splits | -| `notes/slide_*.md` | Conditional split notes | Per-slide notes generated from `total.md` | Derived by `total_md_split.py` only when speaker notes are enabled | -| `svg_final/` | Default-only derived visual preview | Self-contained post-processed SVGs that may be opened directly or inserted as SVG pictures | Default rebuilds it from `svg_output/` with `finalize_svg.py`; Quick omits it. Never use it as a supported PPTX source. | -| `validation/workflow.log` | Cold workflow audit log | Append-only Python command envelopes, material tagged outcomes, bounded warning/OK/stderr samples, per-run omission counts, and selective manual entries for important details with no owning Python output | `project_manager.py init` creates the log and records its milestone. Later project-scoped Python tools find that existing log through the shared CLI bootstrap and record the bounded audit selection without a wrapper command; their full console output is not copied. A helper whose arguments/cwd do not identify the active project receives `PPT_MASTER_PROJECT_PATH=` on the same Python command. A role may run `workflow_log.py` once for a material non-Python stage handoff or rework reason, user-approved exception, or manual recovery choice; never duplicate artifacts, routine progress, or private reasoning. Detached services retain detailed output in their component logs. Never read this log during normal generation/resume or use it as stage, artifact, or quality authority; inspect it only for an explicit user-requested run review. In Quick it remains an incomplete operational audit, not a design history or resume source. | -| `validation/svg_quality_report.json` | Final SVG quality provenance | Final SVG gate split into blocking / introduced / inherited / source-import categories, bound to the checked SVG bytes by SHA-256 | Default runs `svg_quality_checker.py --canonical-authoring --stage final --json`; Quick adds `--quick-generate` so the checker ignores Design Spec/lock and infers flat versus structured validation from the complete SVG roster. Export links the report only when fingerprints match; Quick requires that link to pass before PPTX creation. | -| `validation/.report.json` | Published-package audit | PPTX package/resource postflight status, part counts, and quality-gate linkage | Both Generate profiles write it and emit `[POSTFLIGHT]` after package validation. | -| `exports/` | Delivery artifacts | Native DrawingML PPTX and explicit native-object/narration variants | Default Step 7.3 or Quick direct export writes final deliverables from `svg_output/`. | -| `backup//svg_output/` | Default-path frozen author-source archive | Re-export source without re-running LLM | Both Generate profiles write a snapshot for default-path exports; explicit `-o/--output` skips it. | -| `animations.json` | Optional animation config | Page-transition and object-animation sidecar | Existing files activate intent resolution: final Stage-2 `false` preserves, explicit objects-off exports `-a none`, and all-motion-off bypasses with `--no-animations`. Creation requires explicit instruction or enabled outcome; §IX advice never activates it | +| `sources/` content-type files | Content contract | Factual/text origin for content, tables, chart values, SmartArt wording | Default Strategist reads content-type files (`.md` / `.markdown` / `.txt` / `.csv` / `.tsv` / `.json` / `.jsonl` / `.yaml` / `.yml`), judges by content, and resolves approved semantics plus on-slide wording into §IX; Quick's agent resolves them in active context. Default Executor opens passages only for explicit verification. Never replace values with PPTX geometry JSON | +| `sources/*.facts.json` | Fact provenance contract | Stable external `fact_id` → claim/source mapping from topic research | Strategist cites IDs in §IX and Executor resolves them for attribution; Quick carries the same IDs into visible attribution. Scenario data never enters this file | +| `sources/` converted-source originals | Source archive | Imported originals (`.pdf` / `.pptx` / `.docx` / `.xlsx` / `.html` / `.epub` / `.tex` / `.rst` / `.ipynb` / `.typ`, …) plus extracted assets | Read via the converted `.md`; direct-PPTX workflows read the `.pptx` by route | +| `sources/*.conversion_profile.json`, `sources/*_files/image_manifest.json` | Pipeline sidecar | Conversion audit / asset index | Not slide content; open only to audit a conversion or resolve assets | +| `sources/` Image to PPTX containers | Visible-surface source contract | Immutable raster inputs, each holding one or several bounded page frames | The Codex-supported Quick profile normalizes them into the ordered frame roster without overwriting originals; frame count owns slide count | +| `analysis/source_profile.json` | Machine fact index | Compact PPTX intake digest | Read as factual context and recommendation candidates | +| `analysis/.identity.json` | Native deck identity facts | Canvas, theme palette/fonts, observed usage | Read selectively for detailed identity facts | +| `analysis/.slide_library.json` | Native PPTX structure facts | Text slots, geometry, native tables, chart caches, SmartArt nodes | Direct PPTX workflows use it as the native fill/structure contract; it never owns content values | +| `analysis/beautify_inventory.json` | Beautify frozen validation ledger | Self-contained per-slide ledger of frozen content/data and validation exceptions inlined from source extracts | Sole Beautify ledger; models consume `beautify_inventory.py --summary` / `--page` projections (`--with-geometry` only for raw geometry) and never persist a projection or treat it as a second authority | +| `analysis/image_analysis.csv` | Regenerated image fact view | Measured facts about current `images/` | Re-run `analyze_images.py` after changes; a view, not a durable cache | +| `analysis/reconstruction_inventory.json` | Image to PPTX evidence ledger | Container/frame mapping, hashes, page order/canvas, region bboxes, observed families, transcription confidence, overlap/z-order, unresolved evidence | Written by the Codex Quick agent before layer decisions; holds no final realization, prompts, output filenames, or SVG bindings | +| `design_spec.md` | Strategist design authority | Design intent, page brief, rationale, resources, production mechanics | Consume final confirmation once, write/audit here, apply refinement to this same file. §I records effective Speaker Notes / Custom Animations / Narration Audio outcomes plus provenance; a newer explicit instruction updates only its outcome without reopening Confirm UI. After Gate 1, later roles read this file instead of `result.json`; §IX owns Executor page content and `Relationships`, while its layout/composition/capability/motif recommendations stay References Executor adjusts freely unless labeled `(binding)` | +| `spec_lock.md` | Execution anchor and routing contract | Stable color/type roles, icons, images, page rhythm, visualizations, `template_reuse_scope`, PowerPoint structure mode; mirror/layout routes add input prototypes, Master roster, and page mapping | Strategist authors route-specific anchors from the audited Design Spec plus context. Executor retains the complete lock once per valid context and consults it before the Design Spec fragment on local uncertainty. Sparse page-local garnish needs no row; a recurring role or new adaptive Layout identity requires Strategist repair | +| `project_manager.py page-context` stdout | Derived on-demand page context | Read-only anchor set + current-page delta + fingerprints | Only for explicit diagnostics/telemetry or an unresolved path-SHA projection; never persisted, never a routine pre-page gate; `global` is a bounded anchor set, not a whitelist | +| `analysis/page-context/P.usage.json` | Optional context telemetry | Measured page-context size plus input hashes | `--record-usage` replaces only the invoked page's snapshot; `page-context-report` summarizes; token data evaluates cost, never content | +| `images/` | Runtime image pool | User, extracted, AI, web, slice, EMF/WMF assets | Default Step 5 or Quick resource preparation writes here | +| `images/image_prompts.json`, `image_queries.json`, `image_sources.json` | Conditional resource contracts | AI/web execution status and provenance | Created only for a triggered path; guide preparation/attribution, never page design | +| `icons/` | Prepared project icon pool | Bundled icons copied by `icon_sync.py` plus user, template, imported, or custom icon SVGs | Authoring may use any icon in this pool per page; `spec_lock.icons.inventory` indexes the default plan's curated synced pool, not page usage or a whitelist. Preview, finalization, checking, and export resolve only complete `library/name` references under this root | +| `${SKILL_DIR}/templates/{brands,styles,layouts,decks}/*_index.json` | Library discovery indexes | Complete registered option source for Stage-1 selection and chat listing | Read only to populate the Stage-1 choice after the communication recommendation is authored; never scan kind directories or use index summaries as planning evidence; derive a library root from kind + id; Quick does not read the catalog | +| `templates/` | Project template reference | Stage-1-confirmed or Quick-installed specs, one file per selected workspace, the effective structural SVG roster (Layout when present, otherwise Deck), non-image assets | Read this project-local state only, never the library root. The planner reads every installed Design Spec and the effective roster; Brand and Style are roster-free; Deck structure is shadowed by Layout. Continuous Executor reuses context; fresh Executor reads the Design Spec once and each selected SVG before first use or after its SHA changes | +| `templates/template_execution_manifest.json` (`v1`), `templates/template_execution/*.text-slots.json` (`v2-min`) | Derived template index | Prototype/source-import summary and text-slot diagnostics; integrity hash is tool-only | Never read during page authoring; the prototype SVG is the sole visual authority | +| `/svg/` | Imported native-payload backing | PPTX-derived metadata, hidden carriers, fallback evidence, source structure | Immutable; materialization may resolve a validated source ref against it; models never edit or bulk-read it | +| `/svg-flat/` | Optional verification backing | Self-contained composition from explicit `--inheritance-mode both` | Immutable; never authoring or materialization input | +| `/authoring-svg/` | Template-creation author source | Compact layered SVG IR for imported Master, Layout, and Slide objects | Published normalized and decoration-factored by import; Template_Designer edits it; final template SVGs materialize from it | +| `/authoring-svg/authoring_summary.json` | Model-readable authoring index | SVG roster plus per-file canvas, size, text, image, vector, placeholder, source-ref counts | Read before authoring SVGs; regenerate after direct IR edits | +| `/authoring-svg/authoring_manifest.json` | Tool-only provenance | Per-document hashes and source-ref paths | Generated atomically with the IR; validated by materialization; never loaded into model context | +| `/authoring-svg-flat/` | Optional verification IR | Self-contained page composition with its own summary/manifest | Generated only from an explicitly requested `svg-flat/`; verification only | +| `/icons/imported/` | Imported vector pool | One canonical copy of every factored vector subtree | Referenced as `data-icon="imported/"`; inventories retain source refs | +| `confirm_ui/template_options.json`, `template_selection.json`, `template_handoff.json` | Default UI template-selection sidecar | Agent-authored candidates, user-confirmed selection beside the Stage-1 result, installation/free-design handoff | Step 3 writes options without launching UI; the Stage-1 submission writes `template_selection.json`; `--complete-template-selection` writes the handoff; Stage 2 is exposed only after that handoff and a fresh recommendation. Chat/delegated flows keep equivalent state without fabricating receipts; Quick creates none | +| `confirm_ui/recommendations.stage1.json`, `.stage2.json` | Confirmation proposals | Template-independent communication contract, then template-aware complete solution plus production mechanics | Stage 1 is authored without candidate indexes or workspaces as evidence and confirms communication plus template mode/selection in one submission; Stage 2 is created only after installation or free-design closure; `template_application` decides only how to use installed state; only the active unconfirmed stage may be overwritten | +| `confirm_ui/result.json` | Confirmation result | Persisted user-confirmed evidence | Step 4 reads the final object once; Strategist consumes it completely into `design_spec.md`; downstream never reopens it except a fresh recovery with no retained state | +| `svg_output/` | Page-design author source | Handwritten SVG pages containing the complete visible design, including formula markers | Canonical source for the checker and native export; templates and locks never add missing visible objects at export | +| `notes/total.md`, `notes/slide_*.md` | Conditional speaker-note source / split notes | Complete notes; per-slide split by `total_md_split.py` | Written only when Speaker Notes is enabled; Step 7.1 or Quick §4 splits | +| `svg_final/` | Default-only derived preview | Self-contained post-processed SVGs | Rebuilt from `svg_output/` by `finalize_svg.py`; Quick omits it; never a PPTX source | +| `validation/workflow.log` | Cold workflow audit log | Append-only Python command envelopes, material outcomes, bounded samples, selective manual entries | Created by `project_manager.py init`; later project-scoped tools record automatically (a helper without project-identifying arguments receives `PPT_MASTER_PROJECT_PATH`). A role may run `workflow_log.py` once for a material non-Python handoff, rework reason, approved exception, or manual recovery. Never read during generation/resume or treat as stage/artifact/quality authority; inspect only on explicit user request | +| `validation/svg_quality_report.json` | Final SVG quality provenance | Final gate split into blocking / introduced / inherited / source-import, bound to SVG bytes by SHA-256 | Default: `svg_quality_checker.py --canonical-authoring --stage final --json`; Quick adds `--quick-generate` (ignores Design Spec/lock, infers flat vs structured from the roster). Export links the report only on matching fingerprints | +| `validation/.report.json` | Published-package audit | Package/resource postflight, part counts, quality-gate linkage | Both profiles write it and emit `[POSTFLIGHT]` | +| `exports/` | Delivery artifacts | Native PPTX and explicit native-object/narration variants | Default Step 7.3 or Quick export writes from `svg_output/` | +| `backup//svg_output/` | Frozen author-source archive | Re-export source without re-running the LLM | Snapshot on default-path exports; explicit `-o/--output` skips it | +| `animations.json` | Optional animation config | Page-transition and object-animation sidecar | An existing file activates intent resolution (Stage-2 `false` preserves, explicit objects-off exports `-a none`, all-motion-off uses `--no-animations`); creation requires explicit instruction or an enabled outcome; §IX advice never activates it | --- @@ -72,47 +59,34 @@ history, or resumable planning state. Context loss restarts the Quick run. | Invariant | Rule | |---|---| -| Content authority | Content-type files in `sources/` own the factual/text origin for content, tables, chart values, and SmartArt wording. For Beautify, `sources/.md` remains that origin; `analysis/beautify_inventory.json` only deterministically inlines the frozen values needed by its self-contained validation contract and does not become a second content authority. Default Strategist resolves source content into §IX and Executor realizes that contract without drafting a second outline. Quick's current agent resolves it once in active context before SVG authoring. `slide_library.json` does not own content values. | -| Sources read policy | In `sources/`, read content-type files (`.md` / `.markdown` / `.txt` / `.csv` / `.tsv` / `.json` / `.jsonl` / `.yaml` / `.yml`) and judge by content — a `.json` / `.csv` may be core content or just data. Exclude known sidecars: `*.conversion_profile.json` and `*_files/image_manifest.json`. `analysis/` facts (`source_profile.json`, `.slide_library.json`) are read per Step 4 / direct-PPTX workflow, not in the `sources/` content scan. | -| PPTX structure | `analysis/.slide_library.json` owns native geometry, slot facts, and SmartArt layout/relationships for direct PPTX workflows. The Beautify inventory only deterministically inlines the subset required by its validation contract; neither the full ledger nor its stdout projections replace `slide_library.json` as the native-structure fact source. | -| Design contract | Final confirmation once → audited `design_spec.md` → optional same-file refinement/approval → context-authored lock. Never maintain a parallel draft/lock. Executor may apply `Template Application` prose but never replace identity. Repair divergence from the approved Design Spec/context unless it fails active-decision fidelity. | -| Flat packaging authority | Free-design, brand-only, Style-only, and every plan with `template_reuse_scope: style` declare `pptx_structure.mode: flat` and omit `pptx_masters`, `pptx_layouts`, `page_pptx_layouts`, and `page_layouts`. A Style installed alongside Layout/Deck changes only Direction / method and does not force the non-Style structure plan to flat. `svg_output/` owns the complete Slide-local visual design without root Master/Layout identity, fixed-layer ownership, or placeholder metadata. Export materializes one clean project-owned Master plus one Blank Layout, applies the locked theme defaults, removes stock content placeholders/Layout inventory, and retains only the standard date/footer/slide-number capability hooks. | -| Template structure authority | `template_reuse_scope: mirror|layout` uses `page_layouts` for each page's authoring-input prototype. `pptx_masters` / `pptx_layouts` own the unique reusable output definitions, while `page_pptx_layouts` owns page assignment. Strict keeps the prototype; adaptive Layout choice is authorized by Strategist or Quick's frozen Template Application. A construction-discovered structural change returns upstream for definition and assignment repair before authoring resumes. Mirror additionally preserves ordinary authored visuals/text topology; only a JSON-first Chart/Table's derived preview children may regenerate while its metadata/structure remain fixed. Layout allows project-controlled reflow/re-skinning. Unused definitions may register without a published Slide. Templates validate provenance but never add missing visible page objects during export. | -| Fact classes | External facts resolve through `sources/*.facts.json`; invented demo KPIs/targets/internal ratios are labeled `scenario` in `design_spec.md §IX` and visibly in the page. Never promote scenario data into the external fact registry. | -| Imported-template authoring | Editable SVGs under `authoring-svg/` own create-template edits, `authoring_summary.json` owns model-facing orientation, and `authoring_manifest.json` owns tool-only source-object identity. Lossless `svg/` owns immutable native payload and fallback evidence; optional `svg-flat/` owns only complete-page verification. Materialized `templates/*.svg` own the validated deliverable contract and contain no IR-only source refs. | -| Legacy template input | Old unmapped/distilled/preserve structured projects and incomplete template packages are not migrated in place. [`create-template`](../workflows/create-template.md) authors a new current workspace: original PPTX Type A may preserve existing native topology in mirror; legacy SVG-only Type B is visual reference for `standard` / `fidelity`. Intentional free-design, Brand-only, and Style-only `flat` projects are already current. The exporter does not migrate or visually cluster legacy structure. | -| Image facts | `images/` is live state; `analysis/image_analysis.csv` is a regenerated view, not a durable cache. | -| Image to PPTX | Normalized page frames own visible-surface truth, not literal reuse of their pixel bytes; `analysis/reconstruction_inventory.json` owns only source evidence. Native text restores visible wording. Identity graphics use an exact vector, deterministic redraw, sufficient source asset, or Codex reference-based high-resolution reconstruction; data graphics stay native-and-verified or exact and are never generatively recreated. Scene imagery uses registered clean-base/midground/subject/foreground layers; padded-bbox-disjoint objects may share one generated plate before independent crop/slice realization. Never infer hidden semantics, substitute a merely similar graphic, or use a full-page screenshot skin as the editable result. | -| SVG source | `svg_output/` is the only author source for generated pages. | -| Page-design closure | On SVG-authoring routes, every visible exported-slide object exists in the corresponding page SVG or an explicitly referenced visual asset. | -| Package-behavior separation | Speaker notes, animations, transitions, narration, and direct native-PPTX workflows keep their owning artifacts; do not force them into SVG metadata. | -| Post-processed SVG | In Default Generate, `svg_final/` is an optional disposable preview rebuilt by Step 7.2; it serves only as a self-contained visual preview / manually insertable SVG picture. Quick omits it. | -| Workflow audit log | `validation/workflow.log` automatically records each project-scoped Python command envelope, all explicit error/failure and receipt/report lines, bounded warning/OK/stderr samples, summary context, and omission counts, plus explicitly selected manual audit entries. It does not retain the full console stream or automatically capture direct file-authoring actions, host-native tools, pre-project conversion, binary-buffer writes, hidden child output, or detached-service activity; absence of a detail line proves nothing about those stages. Automatic recording failure is advisory and never changes the owning tool's outcome; a failed explicit manual append reports failure because no entry was recorded. | -| Export source | The only supported generated-PPTX route reads `svg_output/` through the project SVG-to-DrawingML converter. A diagnostic `-s final` override does not change ownership or create a supported release route. | -| Shape-conversion boundary | PowerPoint's manual Convert-to-Shape operation on `svg_final/` is outside the project compatibility contract. | -| Confirmation | Final UI/chat confirmation overrides recommendations and is consumed once into `design_spec.md`. Enabled refinement applies arbitrary revisions there and requires approval; only then may active-decision fidelity release lock authoring. | -| Template selection | Default Step 3 prepares candidates without interaction or template reads. `template_options.default_mode` is `free_design` for ordinary requests and `templates` for explicit template intent or any exact root; Stage 1 keeps the mode switchable and confirms it with communication. Exactly one root may be preselected, while multiple roots remain unselected candidates. Template mode requires at least one selected candidate. Every applied selection becomes one project-local `templates/` state before Stage 2 reads it. Quick bypasses this gate and applies at most one exact root per kind directly. | -| Proactive production outcomes | Resolve notes/animation/narration from explicit instruction → final Stage 2 → defaults, then persist outcomes/provenance only in Design Spec §I. Explicit notes-off/audio-on applies Generate's dependency gate; final Stage-2 animation `false` does not suppress a sidecar. | +| Content authority | `sources/` content-type files own the factual/text origin; for Beautify, `sources/.md` remains that origin and `beautify_inventory.json` only inlines frozen validation values. Strategist resolves content into §IX and Executor realizes it without a second outline; Quick resolves once in active context. `slide_library.json` never owns content values | +| Sources read policy | Read content-type files and judge by content (a `.json` / `.csv` may be core content or just data); exclude `*.conversion_profile.json` and `*_files/image_manifest.json`. `analysis/` facts are read per Step 4 / direct-PPTX workflow, not in the `sources/` scan | +| PPTX structure | `analysis/.slide_library.json` owns native geometry, slot facts, and SmartArt relationships for direct PPTX workflows; the Beautify ledger and its projections never replace it | +| Design contract | Final confirmation once → audited `design_spec.md` → optional same-file refinement/approval → context-authored lock; never a parallel draft/lock. Executor may apply `Template Application` prose but never replaces identity; repair divergence from the approved Design Spec unless it fails active-decision fidelity | +| Packaging authority | Flat and structured routing, lock rows, and the Master/Layout/placeholder contract are owned by [`pptx-structure-interface.md`](./pptx-structure-interface.md) §1–§2 and planned under [`strategist-template.md`](./strategist-template.md) §3. `svg_output/` owns the complete visible design on every route; templates validate provenance but never add visible objects at export. A construction-discovered structural change returns upstream for definition and assignment repair | +| Fact classes | External facts resolve through `sources/*.facts.json`; invented demo KPIs/targets/ratios are labeled `scenario` in §IX and visibly on the page, never promoted into the fact registry | +| Imported-template authoring | `authoring-svg/` owns create-template edits, `authoring_summary.json` model-facing orientation, `authoring_manifest.json` tool-only identity; lossless `svg/` owns immutable payload, optional `svg-flat/` verification only; materialized `templates/*.svg` own the deliverable contract with no IR-only refs | +| Legacy template input | Old unmapped/distilled/preserve projects and incomplete packages are never migrated in place; [`create-template`](../workflows/create-template.md) authors a new workspace (original PPTX Type A may preserve native topology in mirror; legacy SVG-only Type B is visual reference). Intentional `flat` projects are current. The exporter never migrates or clusters legacy structure | +| Image to PPTX | Normalized frames own visible-surface truth, not literal pixel reuse; `reconstruction_inventory.json` owns only evidence. Native text restores wording; identity graphics use an exact vector, deterministic redraw, sufficient source asset, or Codex reference-based reconstruction; data graphics stay native-and-verified or exact; scene imagery uses registered clean-base/midground/subject/foreground layers, and padded-bbox-disjoint objects may share one plate before independent crops. Never infer hidden semantics, substitute a similar graphic, or use a full-page screenshot skin | +| SVG source and closure | `svg_output/` is the only author source; every visible exported object exists in its page SVG or an explicitly referenced asset. The only supported export route reads `svg_output/` through the project converter; diagnostic `-s final` creates no release route; PowerPoint's Convert-to-Shape on `svg_final/` is outside the contract | +| Package-behavior separation | Speaker notes, animations, transitions, narration, and direct native-PPTX workflows keep their owning artifacts, never forced into SVG metadata | +| Workflow audit log | Records command envelopes, error/failure and receipt/report lines, bounded samples, summary context, omission counts, and selected manual entries; it does not capture direct file authoring, host-native tools, pre-project conversion, binary writes, hidden child output, or detached services — absence of a line proves nothing. Automatic recording failure is advisory; a failed explicit manual append reports failure | +| Confirmation and template selection | Final UI/chat confirmation overrides recommendations and is consumed once; enabled refinement requires approval before lock authoring. Step 3 prepares candidates without reads; `template_options.default_mode` is `free_design` for ordinary requests and `templates` for explicit intent or any exact root; exactly one root may be preselected; template mode requires one selected candidate; every applied selection becomes project-local `templates/` state before Stage 2. Quick applies at most one exact root per kind directly | +| Proactive production outcomes | Resolve notes/animation/narration as explicit instruction → final Stage 2 → defaults; persist outcomes/provenance only in Design Spec §I. Explicit notes-off/audio-on applies Generate's dependency gate; a Stage-2 animation `false` does not suppress an existing sidecar | -**Forbidden - mixed ownership**: Do not copy chart values from Markdown into `analysis/` by hand, do not edit `svg_final/` as the source of a fix, do not edit imported lossless SVGs instead of their authoring IR, and do not treat `design_spec.md` prose as a replacement for `spec_lock.md`. +**Forbidden — mixed ownership**: copying chart values from Markdown into `analysis/` by hand, editing `svg_final/` as the source of a fix, editing imported lossless SVGs instead of their authoring IR, treating `design_spec.md` prose as a replacement for `spec_lock.md`. --- ## 3. Regeneration Rules -The table names each owning command. Generate profiles invoke these commands -directly; the bounded project-scoped Python command/outcome audit is recorded -automatically after initialization. Other routes retain their own invocation -contract. - | Derived artifact | Regenerate from | Command / owner | |---|---|---| | `analysis/image_analysis.csv` | Current `images/` | `python3 ${SKILL_DIR}/scripts/analyze_images.py /images` | -| `/authoring-svg/authoring_summary.json` | Current authoring SVGs plus tool-only manifest roster | `python3 ${SKILL_DIR}/scripts/svg_authoring_view.py /authoring-svg --refresh-summary`; in-place vector/picture extraction refreshes it automatically | -| `notes/slide_*.md` | `notes/total.md`, when speaker notes are enabled | `python3 ${SKILL_DIR}/scripts/total_md_split.py ` | +| `/authoring-svg/authoring_summary.json` | Current authoring SVGs plus tool-only manifest | `python3 ${SKILL_DIR}/scripts/svg_authoring_view.py /authoring-svg --refresh-summary`; in-place extraction refreshes it automatically | +| `notes/slide_*.md` | `notes/total.md`, when notes are enabled | `python3 ${SKILL_DIR}/scripts/total_md_split.py ` | | `svg_final/` | `svg_output/` plus project assets | `python3 ${SKILL_DIR}/scripts/finalize_svg.py ` | -| `validation/svg_quality_report.json` | `svg_output/`, plus locks/template provenance in Default Generate | Default: `python3 ${SKILL_DIR}/scripts/svg_quality_checker.py --canonical-authoring --stage final --json`; Quick: append `--quick-generate` | -| Native PPTX + `validation/.report.json` | `svg_output/` plus notes/assets and final quality report | `python3 ${SKILL_DIR}/scripts/svg_to_pptx.py ` | -| Quick native PPTX | `svg_output/`, prepared resources, passing Quick final report | `python3 ${SKILL_DIR}/scripts/svg_to_pptx.py --quick-generate` | +| `validation/svg_quality_report.json` | `svg_output/`, plus locks/template provenance in Default | Default: `python3 ${SKILL_DIR}/scripts/svg_quality_checker.py --canonical-authoring --stage final --json`; Quick: append `--quick-generate` | +| Native PPTX + `validation/.report.json` | `svg_output/` plus notes/assets and the final report | `python3 ${SKILL_DIR}/scripts/svg_to_pptx.py ` (Quick: `--quick-generate`) | -**Default - regenerate derived views**: When a source artifact changes, regenerate the derived artifact at the owning step instead of patching the derived file directly. +**Default — regenerate derived views**: when a source artifact changes, regenerate the derived artifact at the owning step instead of patching it directly. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/canvas-formats.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/canvas-formats.md index eab34629..ee6b88dc 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/canvas-formats.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/canvas-formats.md @@ -1,13 +1,12 @@ # Canvas Format Specification -> See [`shared-standards-core.md`](./shared-standards-core.md) §4.1 for the normative root -> `viewBox` grammar, compatibility spellings, and fail-closed validation rules. +> See [`shared-standards-core.md`](./shared-standards-core.md) §4.1 for the normative root `viewBox` grammar, compatibility spellings, and fail-closed validation rules. ## Format Quick Reference | ID | Format | Size | viewBox | Ratio | Use Case | |----|--------|------|---------|-------|----------| -| `ppt169` | PPT 16:9 | `1280x720` | `0 0 1280 720` | 16:9 | Business presentations, meetings | +| `ppt169` | PPT 16:9 | `1280x720` | `0 0 1280 720` | 16:9 | Business presentations, meetings, modern devices | | `ppt43` | PPT 4:3 | `1024x768` | `0 0 1024 768` | 4:3 | Traditional projectors, academic talks | | `xiaohongshu` | Xiaohongshu (RED) | `1242x1660` | `0 0 1242 1660` | 3:4 | Image-text sharing, knowledge posts | | `moments` | WeChat Moments / IG | `1080x1080` | `0 0 1080 1080` | 1:1 | Square posters, brand showcases | @@ -16,49 +15,20 @@ | `banner` | Landscape Banner | `1920x1080` | `0 0 1920 1080` | 16:9 | Web banners, digital screens | | `a4` | A4 Print | `1240x1754` | `0 0 1240 1754` | 1:sqrt(2) | Print posters, flyers | -The table lists canonical root spellings. New custom canvases likewise use -`0 0 W H` with positive integer pixels. A fractional positive canvas is accepted -only as compatible input for an imported custom PowerPoint slide size; it is not -the default authoring form. All pages and internal Layout prototypes in one -export use the same numeric canvas and stay within PowerPoint's supported slide -range (914,400–51,206,400 EMU per side, approximately 96–5,376 SVG px). +Custom canvases likewise use `0 0 W H` with positive integer pixels; a fractional positive canvas is accepted only as compatible input for an imported custom PowerPoint slide size. All pages and internal Layout prototypes in one export share the same numeric canvas within PowerPoint's supported slide range (914,400–51,206,400 EMU per side, about 96–5,376 SVG px). `ppt169` is exactly `1280x720`; same-ratio canvases such as `banner` are different coordinate systems. -`ppt169` is the canonical PPT wide-screen canvas in this repo: `1280x720`, not any arbitrary 16:9 size. Same-ratio canvases such as `banner` (`1920x1080`) must be treated as different coordinate systems. - -## Format Selection Decision Tree - -``` -Content purpose? -├── Presentation -│ ├── Modern devices → PPT 16:9 (1280x720) -│ └── Traditional devices → PPT 4:3 (1024x768) -├── Social sharing -│ ├── Xiaohongshu (RED) → 1242x1660 -│ ├── WeChat Moments / IG → 1080x1080 -│ └── Story / TikTok → 1080x1920 -└── Marketing materials - ├── WeChat Article Header → 900x383 - ├── Banner → 1920x1080 - └── Print → 1240x1754 +```xml + + ``` ## Platform Keep-clear -Canvas dimensions do not imply a title band, content topology, or recurring -chrome. Reserve space only for a real output obstruction. For `story`, keep -meaning-bearing text, identity, and calls to action within `y=120..1740` by -default because common mobile story controls occupy the top and bottom; images, -backgrounds, and nonessential texture may remain full bleed. An exact target- -platform overlay guide or installed template overrides this advisory band. +Canvas dimensions imply no title band, content topology, or recurring chrome; reserve space only for a real output obstruction. For `story`, keep meaning-bearing text, identity, and calls to action within `y=120..1740` by default because mobile story controls occupy the top and bottom; images, backgrounds, and texture may stay full bleed. An exact target-platform overlay guide or installed template overrides this advisory band. ## Typography Scale Start -**Hard rule — normative owner**: This section owns the initial body-size anchor -and sanity band for every registered or custom canvas. Strategist and Quick -consume it directly. Confirm UI maintains an exact executable mirror and must -not infer alternate canvas classes or values. All values are unitless SVG px. - -**PPT reading modes**: +**Hard rule — normative owner**: this section owns the initial body-size anchor and sanity band for every registered or custom canvas. Strategist and Quick consume it directly; Confirm UI maintains an exact executable mirror and must not infer alternate canvas classes or values. Values are unitless SVG px. | Canvas | Reading mode | Advisory body band | Initial body | |---|---|---:|---:| @@ -66,17 +36,11 @@ not infer alternate canvas classes or values. All values are unitless SVG px. | `ppt169` / `ppt43` | `balanced` | 22–25 | 24 | | `ppt169` / `ppt43` | `presentation` | 28–32 | 32 | -**Non-PPT registered and custom canvases**: derive one effective canvas span -from the canonical or custom `W x H`, then calculate the advisory band and -initial body anchor: +Non-PPT registered and custom canvases derive one effective span from `W x H`: ```text -short = min(W, H) -long = max(W, H) -span = min(long, 3 * short) -low = round(span * 0.025) -start = round(span * 0.029) -high = round(span * 0.033) +short = min(W, H); long = max(W, H); span = min(long, 3 * short) +low = round(span * 0.025); start = round(span * 0.029); high = round(span * 0.033) ``` | Canvas | Effective span | Advisory body band | Initial body | @@ -84,25 +48,7 @@ high = round(span * 0.033) | `wechat` | 900 | 23–30 | 26 | | `moments` | 1080 | 27–36 | 31 | | `xiaohongshu` | 1660 | 42–55 | 48 | -| `story` | 1920 | 48–63 | 56 | -| `banner` | 1920 | 48–63 | 56 | +| `story` / `banner` | 1920 | 48–63 | 56 | | `a4` | 1754 | 44–58 | 51 | -**Default — starting anchor, not a floor (may override when confirmed identity, -source fidelity, or target viewing conditions require it)**: Start from the -table or formula, then resolve the complete role ramp and page density from the -active content and delivery context. The advisory band only surfaces unusual -values; falling outside it is not a validation failure. Apply the -viewing-distance baseline in -[`shared-standards-core.md`](./shared-standards-core.md) instead of silently -shrinking a recurring role to make content fit. - -## ViewBox Examples - -```xml - - - - - -``` +**Default — starting anchor, not a floor (may override when confirmed identity, source fidelity, or target viewing conditions require it)**: start from the table or formula, then resolve the complete role ramp and page density from the content and delivery context. The band only surfaces unusual values; falling outside it is not a validation failure. Apply the viewing-distance baseline in [`shared-standards-core.md`](./shared-standards-core.md) instead of silently shrinking a recurring role to make content fit. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/confirm-surface.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/confirm-surface.md new file mode 100644 index 00000000..89d061fb --- /dev/null +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/confirm-surface.md @@ -0,0 +1,108 @@ +# Confirmation Surface and Payloads + +What the Strategist needs to run the two-stage confirmation: the surface decision, the in-run switch, and the exact shape of the three files it authors or reads. Server lifecycle, port/lock behavior, the template-selection sidecar, catalogs, and the progression guard live in [`confirm_ui.md`](../scripts/docs/confirm_ui.md); the launch/wait/shutdown commands live in [`generate-pptx.md`](../workflows/generate-pptx.md) Step 4. + +## 1. Surface decision + +**Mandatory — before any UI command**: resolve the most recent explicit confirmation-surface instruction for this run. Unrelated later messages do not reset the branch; once confirmation starts in chat or UI switches to chat, keep chat for the rest of the run. + +| Most recent explicit surface instruction | Branch | +|---|---| +| The user explicitly delegates confirmation | Make the combined Stage-1 communication/template decision, install it, then present one complete final summary. Do not launch the page or fabricate UI receipts. | +| The user asks for or agrees to personally confirm in chat, or declines the page | Use chat for both stages; Stage 1 includes the template/free-design choice. Do not launch the page, run `--wait-only`, or require UI-authored results. | +| No explicit instruction | Use the page. | + +Interpret the instruction semantically — "confirm here", "use the chat window", "do not open the confirmation page" are sufficient; a chat-question tool by itself selects nothing. Both branches preserve the same Stage-1 decision, installation handoff, and template-aware Stage 2, and the chat branch records the same `design_spec_depth` in its summary. + +**Chat/delegated Stage-1 listing**: author the communication recommendation before reading the four template indexes, then present it together with an explicit free-design/template-mode choice; only template mode expands registered candidates and supplied exact roots and requires at least one selection. Ordinary requests initialize free design; explicit template intent or any supplied exact root initializes template mode, and exactly one supplied root may seed that candidate. + +**Always-on Stage-1 chat handoff (UI branch)**: after writing `template_options.json` and `recommendations.stage1.json`, launch the daemon, then immediately post its actual URL plus one compact localized summary of the recommendation and template-choice state (audience, communication intent, audience outcome, core message, delivery context, artifact afterlife, `content_divergence`, canvas, free-design vs template default and any sole preselected root; blank prose shown as "not specified"), ending with a localized line that the same items may be confirmed or revised in chat if the page did not open. Only then run `--wait-only --wait-stage stage1`. The handoff is context, not confirmation; silence confirms nothing. + +**In-run UI → chat switch (any stage)**: when the user explicitly selects chat after launch — interrupt an active wait and confirm its process exited (that deliberate interruption is the only expected non-zero return), run `server.py --shutdown` and require it to succeed, re-check the active receipt once (Stage 1: `result.json` plus `template_selection.json` from the same submission; Stage 2: `result.json`; an unsubmitted browser draft is not confirmed), then continue everything remaining in chat without relaunching or waiting again. After launch failure/timeout, re-check the receipts once the same way and present the same items as open chat questions. + +## 2. `recommendations.stage1.json` + +Author before reading any candidate index, spec, prototype, asset, or template canvas. All seven prose values may be blank; `primary_language` is canonical BCP-47 (`und` and Chinese without script/region are rejected); `lang` is the UI language only. The intent paths (inform / explain / persuade / decide / align / teach / report and account / mobilize / record and hand off) are help text, never a `primary_job` field. + +```json +{ + "stage": "stage1", + "lang": "zh", + "primary_language": "zh-CN", + "recommend": { "canvas": "ppt169" }, + "audience": { "value": "公司管理层,包括财务与产品负责人" }, + "communication_intent": { "value": "先汇报进展并暴露交付风险,再推动管理层决定下一阶段投入" }, + "audience_outcome": { "value": "管理层能比较三个选项、接受风险判断,并选定一条获得预算的路径" }, + "core_message": { "value": "现在为方案 B 增加投入,能以可接受的成本守住发布时间" }, + "delivery_context": { "value": "主要为有主讲的 20 分钟管理层现场评审;次要为会后独立阅读的审批材料" }, + "artifact_afterlife": { "value": "作为审批记录、项目交接依据和季度审计材料" }, + "content_divergence": { "value": "" } +} +``` + +## 3. `recommendations.stage2.json` + +Create only after the Stage-1 receipts and the `--complete-template-selection` handoff exist, leaving Stage 1 unchanged. Required: `recommend.generation_mode`, boolean `refine_spec.value`, `design_spec_depth.value` as `brief` or `complete` (`brief` is rejected with `split` mode or `refine_spec: true`), and `recommend.image_ai_path` (`auto` / `api` / `host-native` / `manual`) whenever `image_usage` includes `ai`. `image_usage` is an array of source ids (`ai`, `web`, `provided`, `placeholder`; `none` is exclusive). `design_directions` carries exactly three complete candidates with unique stable ids; `selected` is the zero-based index chosen after all three are complete. Candidate display text is written once in the confirmed UI language using the plain keys (`name`, `note`, `mode_behavior`, `visual_style_behavior`, `visual`, `mood`, `behavior`; a single locale suffix such as `_zh` is accepted). Typography carries concrete heading/body `primary` plus `english` only for non-English decks and a positive `body_size`; color carries the six-role `palette`. For a confirmed templates-mode handoff, add top-level `template_application.value` — one editable prose paragraph on how to use the installed template. Never write `recommend.template_reuse_scope` or `template_adherence`. + +```json +{ + "stage": "stage2", + "lang": "zh", + "recommend": { + "delivery_purpose": "balanced", + "mode": "custom", + "visual_style": "custom", + "image_strategy": "custom", + "image_usage": ["ai", "provided"], + "image_ai_path": "auto", + "generation_mode": "continuous" + }, + "page_count": { "value": "12-15" }, + "image_notes": { "value": "封面和章节页用 AI 主视觉;产品页优先用户素材。" }, + "proactive_speaker_notes": { "value": true }, + "proactive_custom_animations": { "value": false }, + "proactive_narration_audio": { "value": false }, + "refine_spec": { "value": false }, + "design_spec_depth": { "value": "brief" }, + "template_application": { "value": "选用封面、章节页和数据页原型;跳过示例内容页。品牌标识和页脚保留,正文可按当前材料重组。" }, + "design_directions": { + "selected": 1, + "candidates": [ + { + "id": "executive-clarity", + "name": "稳妥专业", + "note": "以瑞士极简为主,融合柔和圆角与编辑出版风格。", + "mode": "custom", + "mode_behavior": "以 pyramid 作为唯一目录基底,为当前风险决策材料定制两次结论闸门;标题保持判断句,每章先给判断,再用证据展开并以可执行结论收束。", + "visual_style": "custom", + "visual_style_behavior": "由 swiss-minimal 负责精确栅格和大留白,soft-rounded 负责少量关键容器的轮廓与轻微抬升,editorial 负责细规则、边注与证据层级;标题锐利,正文中性。", + "icons": "tabler-outline", + "color": { "name": "冷静专业", "palette": { + "background": "#FFFFFF", "secondary_bg": "#F4F6F8", + "primary": "#1A3A6B", "accent": "#E8A317", + "secondary_accent": "#4A7BB5", "body_text": "#1D2430" + } }, + "typography": { + "name": "微软雅黑 + Arial", + "heading": { "primary": "Microsoft YaHei", "english": "Arial", "css": "sans-serif" }, + "body": { "primary": "Microsoft YaHei", "english": "Arial", "css": "sans-serif" }, + "body_size": 24 + }, + "image_strategy": { + "name": "编辑式证据图", + "rendering": "custom", + "visual": "简化矢量主体配合编辑式注释与局部材质对比", + "mood": "审慎、可信,像调查报道中的证据插图", + "behavior": "由 vector-illustration 负责清晰轮廓,minimalist-swiss 负责留白构图,screen-print 负责克制的半调纹理;三者服从同一平面主体和当前演示文稿颜色角色。" + } + } + ] + } +} +``` + +The array repeats that candidate shape exactly three times. `template_application` appears only in templates mode. + +## 4. `result.json` + +Written by the user's submission; Generate Step 4 reads the final object (`stage: final`, `status: confirmed`) exactly once and retains it through Design Spec authoring. It carries the Stage-1 prose fields, `primary_language`, `canvas`, `page_count`, the confirmed `mode` / `visual_style` with their `_behavior` siblings, `color`, `icons`, `typography` (including `body_size`, optional per-role `sizes`), `delivery_purpose`, `image_usage`, `image_notes`, conditional `image_ai_path` and `image_strategy`, the three flat proactive booleans, `generation_mode`, `refine_spec`, and `design_spec_depth`. It contains no template-selection field — `template_selection.json` and the installed project-local state own that decision. Legacy results without `design_spec_depth` read as `complete`; results that omit the proactive booleans resolve to `true / false / false`. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/executor-base.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/executor-base.md index 37591765..197d806c 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/executor-base.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/executor-base.md @@ -1,8 +1,8 @@ # Executor Flat and Shared Core -Always-loaded Executor authority for flat SVG page authoring and behavior shared by every Generate route; Default and Quick both load it. Items marked `Default only` bind to the persisted Design Spec / `spec_lock.md`. Quick applies the same craft to the transient anchors it resolved under [`quick-generate.md`](../workflows/profiles/quick-generate.md) §2, and its own pacing, single final checker, and export steps replace §3 `Generation rhythm`, the first-page gate, §6, and §7. Load conditional branches only when their trigger is present. +Always-loaded Executor authority for flat SVG page authoring, shared by Default and Quick. Executor is the crew that builds the finished pages on the plan's structure: it receives the blueprint (§2), owns every decision judged on the canvas — carrier mix, geometry, composition, hierarchy, treatment — and draws from the expression vocabulary below. Items marked `Default only` bind to the persisted Design Spec / `spec_lock.md`; Quick applies the same craft to the transient anchors from [`quick-generate.md`](../workflows/profiles/quick-generate.md) §2, and its own pacing, single final checker, and export replace the Default gates and §6. -**Conditional branch routing**: +**Conditional branch routing** — evaluate every trigger once over the whole roster before P01 (Default: §IX; Quick: the frozen transient roster) and read the triggered modules then, in one batch, so that reading stays out of the page loop; a page that reaches a capability the sweep did not foresee reads its module at that moment, before that page's first SVG line: | Trigger | Load | |---|---| @@ -11,48 +11,39 @@ Always-loaded Executor authority for flat SVG page authoring and behavior shared | Any value-driven geometry, including a chart-family reference, mini chart, sparkline, inset, or small multiple | [`executor-chart.md`](./executor-chart.md) | | Any semantic cell grid, including a table-family reference | [`executor-table.md`](./executor-table.md) | | A page uses a preset pattern fill, or an independent Chart/Table object is resolved as `=yes` | [`native-data-interface.md`](./native-data-interface.md) before emitting the pattern or replacement metadata | +| The per-page Structure decision is `yes` for the first time | [`executor-structure.md`](./executor-structure.md) + [`topology-assembly.md`](./topology-assembly.md) | +| A page's contour reaches beyond rectangle, rounded rectangle, circle, ellipse, and line — an inflected carrier (snipped or one-sided rounded rectangle, plaque, bevel, polygon, pie / arc / donut, frame, corner, folded corner, trapezoid, parallelogram) as much as a relationship symbol (block arrow, chevron, callout, flowchart node, banner, star, bracket, connector) — or needs a Boolean / freeform decision | [`native-shape-authoring.md`](./native-shape-authoring.md), read completely (the preset vocabulary is already resident) | +| A page's visual job reaches beyond the everyday block below — faux glass, constructed styles (hand-drawn, ink, riso, pixel, halftone, paper-cut, facets, gradient ribbon), gradient stroke, text picture/texture fill, gauge / sunburst / explicit arc geometry, freeform curves, transforms beyond rotate, or an unsupported effect needing a native-safe alternative | [`svg-effects.md`](./svg-effects.md) | | Any image | [`executor-image.md`](./executor-image.md) + [`image-layout-spec.md`](./image-layout-spec.md) + [`image-layout-patterns.md`](./image-layout-patterns.md) + [`svg-image-embedding.md`](./svg-image-embedding.md) | | Any nontrivial mathematical expression | [`native-formula.md`](./native-formula.md) | | Any external or same-deck click hyperlink | [`native-hyperlinks.md`](./native-hyperlinks.md) | | Any placed image is `Status: Sourced` or its filename has an `image_sources.json` record | [`executor-web-image.md`](./executor-web-image.md), after `executor-image.md` | | Effective Speaker Notes outcome is enabled after all SVG pages pass | [`executor-notes.md`](./executor-notes.md) | -Evaluate branches from each object's actual information model, not only from a Chart/Table reference. A catalog family selects construction guidance but never native readiness; `Native-ready` is an independent object-level decision. Page-local qualitative geometry also never implies package-level `pptx_structure.mode: structured`. +Evaluate branches from each object's actual information model, not only from a Chart/Table reference: a catalog family selects construction guidance, never native readiness, and page-local qualitative geometry never implies `pptx_structure.mode: structured`. Narrative skeleton and aesthetic come from the confirmed mode / visual-style values (Default: the lock; Quick: the active context): when a value names a catalog preset, read that one file; when it is `custom` with `*_references`, read only those files (one basis under its behavior, or several by their stated contributions); a `custom` without references reads no catalog file and follows its behavior prose alone; the planning indexes are never reopened. [`shared-standards-core.md`](./shared-standards-core.md) supplies the technical boundary and the fallback visual-quality and leading defaults. -> Narrative skeleton and visual aesthetic come from the locked values selected through the [`modes/`](./modes/_index.md) and [`visual-styles/`](./visual-styles/_index.md) planning indexes. Executor does not reopen those indexes: it reads one locked preset file or only the exact `*_references` of a custom, applying one basis under its behavior or synthesizing several by their stated contributions; an unreferenced custom reads none. [`shared-standards-core.md`](./shared-standards-core.md) supplies the technical boundary plus the fallback visual-quality and leading defaults when those authorities are silent. +**Hard rule — Shape-first page authority**: every visible object of the exported slide exists in the final page SVG or is explicitly referenced by it; templates and `spec_lock.md` guide construction and never supply content at export. Optional native Chart/Table metadata belongs to an independently selected object and never replaces the visible fallback ([`native-data-interface.md`](./native-data-interface.md)); a native formula marker keeps a matching SVG preview that export alone replaces ([`native-formula.md`](./native-formula.md)). -**Hard rule — Shape-first page authority**: Every visible object intended for the exported slide MUST exist in the final page SVG or be explicitly referenced by it. Templates and `spec_lock.md` guide construction; they are not export-time overlays for missing visible content. Optional native Chart/Table metadata belongs to an independently selected object and never replaces this visible fallback during authoring; [`native-data-interface.md`](./native-data-interface.md) alone defines that metadata and its export activation. Native formula markers require a matching SVG preview; export replaces only it under [`native-formula.md`](./native-formula.md). +**Hard rule — flat PowerPoint structure**: free-design, brand-only, Style-only, and `template_reuse_scope: style` projects use `pptx_structure.mode: flat`: no root Master/Layout identity, `data-pptx-layer`, or `data-pptx-placeholder`; every object Slide-local; the root declares exactly one `data-pptx-page-role` (`cover` / `toc` / `section` / `content` / `ending`). A Style supplies direction, rhythm, and expression defaults without prototypes; its identity-adjacent defaults yield to the final Brand/Deck identity and the lock, and beside Layout/Deck it changes only method. Add `data-pptx-role` only to page-frame objects whose package, page-number, or animation behavior no specialized marker expresses, with a stable unique `id` ([`semantic-svg.md`](./semantic-svg.md)). -**Hard rule — flat PowerPoint structure**: Free-design, brand-only, Style-only, and every `template_reuse_scope: style` project use `pptx_structure.mode: flat`: write no root Master/Layout identity, `data-pptx-layer`, or `data-pptx-placeholder`; every visible object remains Slide-local, and the root declares exactly one canonical `data-pptx-page-role` (`cover` / `toc` / `section` / `content` / `ending`). A Style workspace supplies reusable communication/design direction, composition rhythm, and information-expression defaults without page prototypes. Its identity-adjacent color, typography, icon, and image defaults yield to the final Brand/Deck identity and confirmed project lock. When a Style is installed alongside Layout/Deck, it changes only Direction / method and follows the resolved non-Style structure route. Export materializes one clean project-owned Master plus one Blank Layout from the current lock. Add `data-pptx-role` only to structural page-frame objects whose package, page-number, or animation behavior is not already expressed by specialized metadata; the marked element uses a stable unique `id`. See [`semantic-svg.md`](./semantic-svg.md). - -**Hard rule — supported PPTX route**: The only supported generated-PPTX path is `svg_output/` through the project SVG-to-DrawingML converter. Step 7.2 generates `svg_final/` as an optional self-contained visual preview that may be inserted as an SVG picture; its absence never blocks export. Do not treat PowerPoint's manual Convert-to-Shape operation as an authoring target or compatibility requirement. - -> Note: this rule covers page design only. Speaker notes, animations, transitions, narration, and direct native-PPTX workflows retain their separate artifacts and package-level processing. +**Hard rule — supported PPTX route**: `svg_output/` through the project converter is the only generated-PPTX path; `svg_final/` is an optional preview and PowerPoint's manual Convert-to-Shape is not an authoring target ([`shared-standards-core.md`](./shared-standards-core.md) §4.2). Speaker notes, animations, transitions, narration, and native-PPTX workflows keep their own artifacts. --- ## Page Expression Core -Read this before §1. It is the expression vocabulary every page draws from; the -technical contracts below bound how it is written, not whether it is available. +Read this before §1: the expression vocabulary every page draws from — what exists, recalled here so it is available at the moment a page is composed. The contracts below bound how it is written, not whether it is available; the full manuals load on their routing triggers. -**Capability — typographic feature elements**: beyond the structural roles fixed -by `typography` anchors, a page may carry deliberate typographic hierarchy — a -lead-in sentence, an inline emphasis run, a pull quote, a kicker, a hero number, -a takeaway line. Each is its own feature element with its own size and treatment; -a recurring one becomes a named role. +**Capability — typographic feature elements**: beyond the structural roles fixed by `typography` anchors, a page may carry a lead-in sentence, an inline emphasis run, a pull quote, a kicker, a hero number, a takeaway line — each its own feature element with its own size and treatment; a recurring one becomes a named role. -**Capability — inline emphasis is one editable frame**: a `` paragraph may -nest non-positional `` runs carrying their own `fill`, `font-weight`, or -`font-size`. Export walks those nested runs and emits one DrawingML run per -styled segment, so a coloured or bold phrase inside a sentence stays inside the -same editable PowerPoint text frame. Positioned line-break `` children may -themselves contain inline runs. +**Capability — inline emphasis is one editable frame**: a `` paragraph may nest non-positional `` runs with their own `fill`, `font-weight`, or `font-size`; export emits one DrawingML run per styled segment inside the same editable frame, and positioned line-break `` children may themselves contain inline runs. ```xml 腐朽但仍可加固接续的千年木梁,不做整体更换;风化的古墙,只做防风化微创处理。 ``` +**Capability — native contour families**: beyond rectangle, rounded rectangle, circle, ellipse, and line, the complete Office vocabulary is drawable and stays editable in PowerPoint — carrier and field contours that hold content or cut the page (snipped and one-sided rounded rectangles, plaque and bevel, triangles, hexagons and other polygons, trapezoids and parallelograms, pies, arcs, and donuts, frames, corners, stripes, and folded corners), block arrows and chevrons for direction and steps, flowchart symbols for process and decision, callouts, brackets and braces, stars and banners, bent and curved connectors, and equation shapes — each through `preset_shape_svg.py`, with Merge Shapes results through `shape_boolean_svg.py`. [`preset-shape-vocabulary.md`](./preset-shape-vocabulary.md) is the full list; §3.0 owns selection and encoding. + **Reference — everyday device menu (not a constraint, not a quota)**: the pieces most slides are built from. | Device | Typical job | Realization | @@ -69,334 +60,203 @@ themselves contain inline runs. | Framed or shaped picture | Portrait, product, place, evidence photo | Circle / rounded clip on ``, hairline frame, caption | | Quote block | Pull quote, testimonial, source sentence | Oversized quotation mark or accent rule + text at lead size + attribution | | Timeline or step strip | Ordered events or stages | Baseline `` with ticks/nodes, or chevron presets, labels above/below | +| Process or decision diagram | Flow, branch, input → output, cycle | Flowchart / block-arrow / chevron presets as nodes and direction, `` or connector presets between them, labels native | +| Callout or annotation | A remark attached to an object or region | Callout preset, bracket, or leader line + short native text | +| Display text with gradient or glow | Hero number, cover word, or chapter numeral that should read luminous or material | Text `fill="url(#…)"` or `filter="url(#titleGlow)"` on that one element; body copy never ([`svg-effects.md`](./svg-effects.md) §6.7 / §6.4) | +| Accent gradient rule or band | Title underline, section marker, KPI baseline carrying the deck hue with direction | 2–4 px `` / `` filled by a 2-stop primary → accent gradient | +| Elevated primary object | The one card, image, or CTA that sits above the page | `softShadow` at resting opacity on that object; peers stay flat | +| Duotone or brand-wash image | A photo that must join the deck palette instead of fighting it | Wash gradient over the picture, or a prepared duotone derivative ([`svg-effects.md`](./svg-effects.md) §6.5 / §6.12) | -**Reference — page-level recipes**: [`svg-effects.md`](./svg-effects.md) §6.13 -carries a back-to-front layer stack for cover, divider, text-led, process, -evidence, comparison, closing, and cross-page-motif pages. +**Reference — layout structures (starting points; proportion follows information weight)**: 16:9 values for 1280×720 — safe area 1200×640 with 40 px margins; title band ≈ 100 px, content field ≈ 500 px, footer ≈ 40 px. + +| Content relationship | Useful starting structure | Starting geometry | +|---|---|---| +| One focal claim | Centered single column, negative space, or full-bleed field + floating text | Column 800–1000 px wide; a negative-space page leaves 40–60% empty | +| Equal comparison | Symmetric split or a true matrix / four quadrants | 1:1 with a 40–60 px gap; quadrants ≈ 560×250 with 20–30 px gaps | +| Dominant evidence + takeaway | Asymmetric split with one dominant field | 3:7 / 2:8, heavy side 840–1024 px | +| Parallel sequence | Three columns, process line, chevron strip, or Z-pattern / waterfall | Three columns with 30–40 px gaps | +| Core + surrounding forces | Center-radiating or hub-spoke | Hub 200–300 px with 4–6 satellites | +| Wide visual + explanation | Top-bottom split, or figure-text overlap for a hero moment | Visual ≥ 55% of the field | +| Page-field organization | One large surface, outline, aperture, or off-canvas contour organizes the zones instead of a card per unit | Field spans two or more zones | + +Repeating symmetric card grids without a page job is the failure mode these structures exist to avoid; a page-field, outline carrier, nested field, or continuity construction is compared before stacked cards or uniform equal columns ([`native-shape-authoring.md`](./native-shape-authoring.md) §2.1 composition lenses — page field, outline carrier, nested fields, continuity, depth and contrast, deck language). + +**Reference — page-level recipes (back to front; omit every layer without a job)**: cover = hero field → optional scrim/wash → purposeful opening/contour → native title; divider = image band or quiet field → restrained wash → recurring geometry → number/title; text-led explanation = quiet field → recurring material/contour → native hierarchy → local emphasis; process/system = context field → native relation lines → nodes/labels → optional state/direction focus; evidence/metric = context field → local contrast → native leaders/labels/metric → optional focus/elevation; comparison = matched planes → shared wash/divider → matched labels → one difference marker; closing = receded field → echoed contour/gradient → native action → raised accent; cross-page motif = reuse contour, gradient direction, line language, texture, or light logic and vary scale, crop, position by page job. Full stacks and stops: [`svg-effects.md`](./svg-effects.md) §6.13. + +**Reference — image composition families (any image page)**: `P1` single visual (side, band, inset, hero), `P2` image as canvas with native overlay, `P3` multi-visual (grid, collage, sequence, compare); modifiers `M1` reveal / crop / registration, `M2` tone / focus / contrast (scrim, wash, vignette, spotlight), `M3` framing / placement / depth; prepared-asset `A` treatments and cross-page `C` continuity. Catalog and situation router: [`image-layout-patterns.md`](./image-layout-patterns.md); integration decision: [`executor-image.md`](./executor-image.md). + +**Reference — visual job router (recall; the full table is [`svg-effects.md`](./svg-effects.md) §6.1)**: missing direction, continuous value, or center focus → gradient or channel alpha; unclear elevation or boundary → one-light shadow, restrained glow, or hairline; copy and image not integrating → scrim, fade, wash, vignette, spotlight, or faux glass; unclear relationship state → dash for draft/optional, marker for direction, gradient stroke for flow, frame/contour for boundary; a load-bearing figure lost in a scan → inline emphasis run; display text needing silhouette or material → outline, gradient, picture/texture fill, tracking, glow; a style asking for hand, print, pixel, facets, layers, or ribbon → the matching constructed recipe; an unmatched silhouette, radial hierarchy, or gauge → freeform, explicit arc/sector, or calculated arrowhead. + +**Reference — everyday effects and aesthetic defaults (self-contained; the full contract and rarer techniques are [`svg-effects.md`](./svg-effects.md))**: + +- **Color**: 60-30-10 as the starting proportion (dominant field ≈ 60%, support ≈ 30%, accent ≈ 10%), body text contrast ≥ 4.5:1, hue count following encoding and natural assets; cover and chapter pages may use the theme color as a large field; same-hue gradients add depth; the accent color goes on the key number or word to create focus, not everywhere; cool tones read technical, warm tones energetic, dark fields grave; trends use green up / red down / gray flat with the deck's polarity roles. +- **Rhythm and weight**: follow a data-heavy page with a breathing page; balance visual weight — dark or large elements are heavy, light or small ones light — across left/right and top/bottom; a chapter may share one carrier system while chapters vary, provided each repetition has a page job. A content page may add a one-sentence takeaway band under the title and a muted source note at the page bottom (title voice belongs to the locked mode). +- **Depth through restraint**: depth comes from rhythm (flat vs lifted, dense vs spacious), not shadows everywhere — shadow 2–3 genuinely floating objects per page at most (card over a photo or colored panel, the primary CTA, an overlay) and keep peer-grid cards, dividers, and body containers flat; reach for weight, spacing, accent bars, and tints before shadow; pick one weight tool per container (shadow, border, gradient fill, or strong tint — never stacked); one light source per page (`dx="0"`, `dy="4"`–`"8"`); the shadow is felt, not seen — resting `flood-opacity` 0.06–0.10, raised at most 0.20 (above that is the Office 2007 look); on dark fields use a light hairline or a restrained glow instead of black shadow. +- **Image overlays**: a directional scrim darkest beside the text (`0.88 → 0.30 → 0`), a bottom fade under a lower title (`0 → 0.72`), a radial vignette for atmosphere (`0 → 0.58`), or a brand wash (`0.80 → 0.10`); never a uniform flat opacity over the whole image or a solid black plate. +- **Lines**: `stroke-dasharray` `4,4` separator, `2,2` placeholder outline, `8,4` timeline or flow connector, `8,4,2,4` dimension line; `marker-end` for connector arrowheads; divider hairlines at 0.2–0.3 alpha. +- **Inline emphasis**: lift numerical results, before/after contrasts, and one or two load-bearing nouns per sentence as bold runs in the primary color; never connectives, common verbs, every noun, decorative adjectives, or structural text (footer, axis, legend, page number); reserve green/red for real polarity. + +```xml + + + + + + + + + + + + + + + + + + + + + + +``` --- ## 1. Effect Capability Discovery -**Reference — effects vocabulary**: [`svg-effects.md`](./svg-effects.md) §6.1 -lists the visual jobs an effect can serve, with its Visual Job Router as recall, -and §6.13 offers coordinated page recipes. The catalog expands construction -vocabulary. Active cross-page continuous action -additionally loads [`animations.md`](./animations.md) §3.1 before authoring -both endpoints. +**Reference — effects are a triggered module**: the everyday block above covers gradients, cards, shadow, glow, scrims, dashes, and inline emphasis for most pages. Load [`svg-effects.md`](./svg-effects.md) when the pre-P01 sweep or a page's job reaches beyond it (routing table above); once loaded, its §6.1 Visual Job Router recalls candidates and §6.13 offers coordinated page recipes, and it stays in context for the rest of the run. Active cross-page continuous action additionally loads [`animations.md`](./animations.md) §3.1 before authoring both endpoints. -**Hard rule — discovery does not expand compatibility**: Follow -`svg-effects.md` syntax and fallbacks; unsupported source/backdrop blur, blend -mode, SVG `` / per-pixel masking, dense texture, or skew remains -baked/alternative-only. +**Hard rule — discovery does not expand compatibility**: follow `svg-effects.md` syntax and fallbacks; source/backdrop blur, blend mode, `` / per-pixel masking, dense texture, and skew stay baked or alternative-only. -**Default — resolve active cross-page geometry here, while pages are still being authored (may override when the deck has no continuous action to express)**: object effects, page transitions, and Morph pair keys are post-processing decisions, but the two visible endpoint states are not. Apply this preparation only when an explicit user motion instruction, an enabled effective Custom Animations outcome, or an existing `animations.json` activates motion; a §IX Motion suggestion alone remains non-operative advice. An active sequence that should read as one continuous action (slide-in, flip, camera push-in, progressive reveal, camera pan) must be authored as consecutive pages in `svg_output/` now. Give each continuing endpoint a compatible direct-root group; source and destination ids or geometry may differ because the later motion stage can bind them explicitly through `animations.json`. A deck that reaches export without both states cannot gain the motion by adding a flag. Adding pages is a §IX roster change and returns to Strategist for Design Spec repair first. +**Default — author motion endpoints while pages are still being written (may override when the deck has no continuous action)**: effects, transitions, and Morph pair keys are post-processing, but the two visible endpoint states are not. Only an explicit user motion instruction, an enabled Custom Animations outcome, or an existing `animations.json` activates this; a §IX Motion suggestion alone does not. A sequence that should read as one action (slide-in, flip, push-in, progressive reveal, pan) is authored now as consecutive pages, each continuing endpoint in a compatible direct-root group (ids or geometry may differ; `animations.json` binds them later). A deck exported without both states cannot gain the motion by a flag; adding a page is a §IX roster change and returns to Strategist. --- -## 2. Design Parameter Confirmation (Mandatory Step — Default only) +## 2. Blueprint Intake -Before the first SVG page, output a confirmation listing: the compact communication objective, canvas dimensions, body font size, color scheme (primary/secondary/accent HEX), font plan, the measured line capacity of the body and annotation roles (run `python3 ${SKILL_DIR}/scripts/text_measure.py measure` on one representative CJK/Latin line per role and state "≈ N chars per W px"; the checker's module check adds DrawingML wrapping headroom, so a hand count of characters × font size underestimates by roughly 15%), and the live-preview URL reported by the launcher. If the preview launch failed, state that failure before generating SVGs instead of silently proceeding. Prevents purpose/spec/execution drift. +Executor receives the plan and builds on it: Default reads the retained `design_spec.md` and `spec_lock.md`; Quick holds the same decisions as transient §2 anchors. The plan owns what must be true about every page — content, `Relationships`, roster, rhythm, resources, identity; Executor owns how it looks. Pipeline mechanics of the Default run — context validity and rereads, roster invariance, the five-page lock re-read, recovery from a missing artifact, the pre-P01 parameter confirmation, and the gate cadence — are owned by [`generate-pptx.md`](../workflows/generate-pptx.md) Step 6, not restated here. -### 2.1 Execution context validity (Mandatory — Default only) +### 2.1 Execution context and binding -> Quick has no Design Spec or lock: skip the artifact reads, roster, recovery, and lock re-read rules in this section, but apply its reading-mode, authored-texture, `page_rhythm`, and typography-anchor tables to the transient anchors from `quick-generate.md` §2. +> Quick has no Design Spec or lock: apply the binding, Reference, content-vs-expression, reading-mode, `page_rhythm`, and anchor rules here to its transient §2 anchors. -- **Valid**: if the exact complete Design Spec and lock remain in the unchanged, uncompacted active context, reuse both for every page. Do not reread or poll them. The one scheduled exception is the five-page lightweight lock re-read defined below. -- **Invalid**: fresh/resumed/restarted execution, compaction/summary-only recovery, or an external/unknown change requires one complete read of `design_spec.md`, then `spec_lock.md`, plus triggered references/template inputs. Mid-deck recovery also reads the latest completed SVG and, when images are used, current image metadata. -- **Uncertain**: consult the retained lock first, then only the owning Design Spec fragment; use sources only for facts. Design Spec remains upstream on conflict. +**Hard rule — binding selection vs realization**: Strategist-selected content and `Relationships`, roster and `page_rhythm`, resource paths, structured-template routing keys, core fonts, palette and spacing anchors, icon-library/stroke anchors, crop boundaries, and any field labeled `(binding)` bind. Everything else — the carrier mix, geometry, composition, and which prepared icon serves a page — is realization, plus the sparse local garnish allowed below. Missing or unresolved material stops execution and returns upstream; never search, generate, download, sync, invent, or substitute it. -**On-demand page-context diagnostic**: only for explicit telemetry/debugging or an unresolved page/template/visualization path-SHA question; never as a pre-page gate: +**Reference — planning sketches are adjusted freely**: §V/§IX `Layout`, cover/closing composition, capability recommendations, §III motif direction, Chart/Table `family/key` references, §VIII image-layout patterns, and Motion suggestions are starting sketches: adjust or replace each for the page's purpose, with no upstream repair or stated reason; they carry no binding semantics (what must hold is in the binding fields above), and a `(binding)` field is followed literally. Executor owns final carrier choice, page-scale composition, information-preserving visualization, geometry, spacing, coordinates, native construction, and effects. -```bash -python3 ${SKILL_DIR}/scripts/project_manager.py page-context P [--record-usage] -``` +**Hard rule — content vs expression**: §IX owns each page's semantic content — complete preferred wording and block texture at `complete` depth, a short block list at `brief` — and its wording is not verbatim unless marked literal. Executor may paraphrase, condense repetition, regroup or reorder within the page, and switch among prose, bullets, keywords, labels, or visual annotation when fit or readability benefits, provided the result stays information-equivalent: the `Core message`, `Audience move`, and every claim, fact, value, proper name, qualifier, relationship, evidence, and literal requirement survive. Never add a claim, move content across pages, or drop information to fit a layout; quotation marks and first person only for wording the source itself gives as a quote — reported speech stays reported; return an unfit or underspecified block for Design Spec repair. Use named lock roles literally where they apply, apply an optional `Template Application`, and choose page-local values from the Design Spec, style, content, and composition rather than forcing every object into a lock row. Read sources only to resolve listed `Fact IDs` or verify required claims, quotes, names, or data; never to add content. -Consume stdout directly; stop on non-zero exit. The projection is derived, not authoritative. Use `--record-usage` only for measurement. +**Per-page communication trace**: read `communication.objective`, `communication.core_message`, and the page's §IX `Core message` + `Audience move` before composing. The page must advance the objective and make that move; a page that cannot state its move is an outline defect — surface `warning: P has no communication move` rather than decorating around it, and never invent a purpose at execution time. Structural pages advance the contract by establishing relevance, tension, or the decision frame, or by completing the final commitment. -**Same-context repair**: in a valid uncompacted context, a bounded repair that preserves roster/order/identity/communication needs only affected Design Spec/lock fragment readback plus `project_manager.py validate`. Any broader or invalid-context repair requires the complete reads above. +**Mandatory — per-page Structure decision**: before drawing, read the page's §IX `Relationships` (Quick: the transient relationship statement), then `Visualization` and `Content`, and decide whether geometry must carry that qualitative `order`, `link`, `parent`, `membership`, `contrast`, or `overlap` relationship — from the semantic relationship alone; a missing line is a Design Spec defect: repair that §IX block first (continuous run) or return upstream, never infer the relationship at execution — loading [`executor-structure.md`](./executor-structure.md) and [`topology-assembly.md`](./topology-assembly.md) at the first `yes`; a suggested carrier, topology, or composition does not decide it. `no` stays on this base path; `yes` applies that grammar and keeps the relationship statement in active page context with no catalog reference, lock row, or artifact. A Chart/Table reference never substitutes. -**Hard rule — exact page roster**: `design_spec.md §IX` is the ordered queue: one final slide per entry, with the same id/order. Never add, drop, merge, split, or reorder while drawing. In a continuous run the same context may first repair the affected §IX blocks and `page_rhythm` rows and rerun `project_manager.py validate` when the page count stays inside the Stage-1 confirmed range; leaving that range reconfirms Stage 1. +**Per-page reading-mode check**: apply `communication.consumption_mode` with the §IX block texture and `page_rhythm` — `text`: the visible page stands alone (complete prose, explicit labels / captions / sources, tables, necessary detail); `balanced`: the primary claim and its evidence on the page, enabled notes adding interpretation and transitions; `presentation`: one claim and one dominant visual legible at projection distance, concise copy, enabled notes carrying explanation — and with notes disabled never omit required content on the assumption that notes carry it. Never drop or invent facts to force a mode; when the authored texture materially conflicts with the lock, render the least-destructive faithful composition and surface `warning: P content texture conflicts with consumption_mode ` (a judgment, not a checker rule). -**Hard rule — binding selection vs realization**: use Strategist-selected semantic content, resources/paths, structured-template Master/Layout routing keys, core fonts, palette anchors, icon-library/stroke anchors, and crop boundaries. Adapt realization—including which prepared project-local icon, if any, best serves each page—without changing those binding selections, except sparse local font/color garnish allowed below. Missing or unresolved material stops execution and returns to Strategist-owned acquisition/failure recovery; never search, generate, download, sync, invent, or substitute it. Binding selection changes require upstream repair. +**Default — authored texture (may override when information-equivalent)**: start from each §IX block's written texture (`complete`) or expand its block phrasing (`brief`) under the reading mode. Keep prose where continuity carries cause, argument, narrative, qualification, or emphasis; use bullets or keywords only for genuinely parallel or ordered material or a clearer information-equivalent structure — never because a list is easier to lay out or a template exposes a list slot. An inherited slot never overrides the content relationship — widen, reflow, or drop the card before converting prose to fill a list slot; the locked mode shapes voice and register, not §IX's authored titles or page order (a user-authored topic label stays a label even when the mode favors assertions). Block-level phrasing applies *within* the page's `page_rhythm` density, not against it. -**Reference — planning advice, not a layout lock**: treat §V/§IX `Layout`, cover/closing composition, capability recommendations, §III motif direction, Chart/Table `family/key` construction references, and §VIII image-layout patterns as non-binding inputs. Consider each, then adopt, adapt, or decline it without upstream repair when the same semantic job and every binding user/template/resource constraint remain satisfied. Executor owns final carrier choice, page-scale composition, information-preserving visualization realization, geometry, spacing, coordinates, native preset/Boolean/freeform construction, and effects. - -**Hard rule — content vs expression**: `design_spec.md §IX` owns each page's semantic content and supplies either complete preferred wording and block texture (`complete` depth) or a short block list (`brief` depth); written expression choices are not verbatim requirements unless explicitly literal. Executor may paraphrase, condense repetition, regroup or reorder material within the same page, and switch among prose, bullets, keywords, labels, or visual annotation when fit or readability benefits. The result must remain information-equivalent: preserve the `Core message`, `Audience move`, and every substantive claim, fact, data value, proper name, qualifier or caveat, relationship, key argument or evidence, and literal requirement. Never add a claim, move content across pages, or drop information to make the layout fit; return an unfit or underspecified block for Design Spec repair. - -Use named lock roles literally when that role applies, and use optional `Template Application` from the retained Design Spec. Choose contextual page-local values from the Design Spec, style, content, and current composition rather than forcing every object into a lock row. A page-context delta overrides neither facts nor constraints. Deprecated `page-context --bundle` is a compatibility no-op. - -**Source verification**: §IX owns the page brief at its confirmed depth; the page delta does not carry the source corpus. Read sources only to resolve listed `Fact IDs` or verify required claims, quotes, names, or data. Do not add facts, claims, or selected content. Return underspecified blocks for Design Spec repair. - -**Per-page communication trace**: Read `communication.objective`, `communication.core_message`, and the current §IX `Core message` + `Audience move` before choosing composition. The page must advance the compact objective and move the audience as authored in §IX; the global core message remains the deck-wide north star. A page that cannot state this movement is an upstream outline defect — surface `warning: P has no communication move` instead of compensating with decorative layout. Do not invent a new purpose, ask, or outcome at execution time. Structural pages may advance the contract by establishing relevance / tension / decision frame or by completing the final commitment; they are not exempt from having a reason to exist. - -**Mandatory — per-page Structure decision**: Before drawing, read the current §IX `Layout`, `Visualization`, and `Content` and decide whether geometry must carry any qualitative `order`, `link`, `parent`, `membership`, `contrast`, or `overlap` relationship. Derive the result from that semantic relationship with the already-loaded [`executor-structure.md`](./executor-structure.md); a suggested carrier, topology, or macro composition does not decide it. If none applies, continue on this shared base path. If any applies, use that grammar and retain the relationship statement in active page context; do not create a catalog reference, lock row, or new artifact. A Chart/Table reference never substitutes for this decision. - -**Per-page reading-mode check**: Read `communication.consumption_mode` before choosing the page's composition. Apply it together with the authored §IX block texture and `page_rhythm`: - -| `consumption_mode` | Page execution | -|---|---| -| `text` | Make the visible page independently understandable. Preserve complete prose, explicit labels / captions / sources, tables, and necessary detail; use bullets only for genuinely parallel or ordered items. | -| `balanced` | Keep the primary claim and its evidence on the page; when notes are enabled, let them add interpretation and transitions. Mix prose, structured evidence, and necessary lists according to their semantic relationship. | -| `presentation` | Make one claim and one dominant visual expression legible at projection distance. Keep visible copy concise; when notes are enabled, explanation and transitions can live there. When notes are disabled, rely only on the confirmed presenter/page channels and never omit required content on the assumption that notes will carry it. | - -Apply the content-vs-expression contract above within the selected reading mode. Never drop or invent facts to force a mode. When the authored texture materially conflicts with the lock, render the least-destructive faithful composition and surface `warning: P content texture conflicts with consumption_mode ` as an upstream outline issue; do not encode this subjective judgment in the checker. - -**Default — authored texture (may override when information-equivalent)**: at `complete` depth start from each `design_spec.md §IX Content` block's written texture because it is the Strategist's recommended expression; at `brief` depth each block already carries its phrasing; expand it into page copy under the reading mode. Keep prose when its continuity carries causal, argumentative, narrative, qualification, or emphasis relationships; use bullets or keywords when the material is genuinely parallel or ordered, or another information-equivalent structure is clearer. Never convert solely because a list is easier to lay out or an inherited template exposes a list slot. - -- **Hard rule — one paragraph, one text frame**: use one `` per prose paragraph, never sibling `` elements for its visual lines. Keep the first authored line as direct text; later lines use direct `` children that repeat parent `x`, retain effective font size, and use positive relative `dy`. An all-`` form may start at `dy="0"`. Default retains these breaks without PowerPoint wrapping; `--reflow-text` enables reflow. Start from the shared leading ranges in [`shared-standards-core.md`](./shared-standards-core.md) §4.2, then adjust for the typeface, reading distance, explicit user/template requirements, and locked style. -- **Template precedence**: an inherited slot never overrides the content relationship. If faithful expression needs prose, widen or reflow the container, or drop that card; never convert solely to fill a list slot. -- **Mode precedence**: the locked mode shapes voice / register, not §IX's authored titles or page order. When a `§IX` title is a user-authored topic label, keep it — do not upgrade it to an assertion just because the mode (e.g. `pyramid`) favors them; mode title-tendencies apply only to AI-drafted titles. - -> Note: block-level phrasing, applied *within* the page's `page_rhythm` density (below), not against it. - -**Missing `spec_lock.md` or `design_spec.md`** → stop before drawing and report the missing gate artifact. Recover through [`failure-recovery.md`](../workflows/governance/failure-recovery.md) §3; do not silently downgrade. A failed on-demand `page-context` diagnostic is also not evidence that a required planning artifact may be bypassed. - -**Missing field in an existing lock**: follow [`failure-recovery.md`](../workflows/governance/failure-recovery.md) §2. +**Hard rule — one paragraph, one text frame**: one `` per prose paragraph with positioned `` line breaks, never sibling `` elements ([`shared-standards-core.md`](./shared-standards-core.md) §4.2); start from its leading ranges, then adjust for typeface, reading distance, explicit requirements, and locked style. **Execution anchors and contextual values**: -- Base icons may use any SVG already prepared under `/icons/`. `icons.library` records the Strategist's primary bundled style choice and `icons.inventory` indexes its curated synced pool; neither assigns icons to pages or limits other project-local assets. `simple-icons` entries are real brand marks; they are not a separately confirmed library. -- Illustrated icons are prepared transparent slice files under `images/` and follow [`executor-image.md`](./executor-image.md), even when they perform the same compact semantic job as an SVG icon. Never move them into `icons/`, add them to `icons.inventory`, or render them through ``. -- Core color roles retain their meaning. Derive tints, shades, alpha, gradients, and effects; preserve natural asset colors; and use sparse page-local accents for differentiation/ornament. They must not become a competing or recurring palette. -- §V `Spacing anchors` (page margin, block gap, column gutter, corner radius, body leading) are deck-wide identity anchors: reuse them on every page and depart only for a page job, never to make content fit. -- Resolve structural families by role: exact `_family` first, then `title_family` for title roles or `body_family` for other unoverridden roles, then legacy `font_family`. Never flatten declared role overrides. A sparse export-safe accent family may style short non-structural display/ornament only—never title/body/data/annotation. Recurrence requires upstream selection. -- Font sizes use the named `typography` role values as deck-wide anchors. Map every structural text item to a declared role before drawing; never inherit a template placeholder size. Start from the anchor, then use composition and content fit to adjust that occurrence by at most `±2`px. Keep same-page peers consistent and preserve the role hierarchy; bounded adjustment does not create a new role. -- **Text roles**: declared `lead` / `subtitle` carry the page's primary claim; `footnote` / `annotation` carry footnotes, page numbers, and credits. Sizes come from declared roles. -- **Write unitless px, with at most two decimals.** Structural and mapped-role text uses only its anchor or a value within its `±2`px band; the sparse display-size exception is defined separately below. Do not substitute familiar pt-style numbers or emit long precision tails. -- **Sparse display-size exception**: a short non-structural Hero/Display element may use one undeclared size outside all anchor bands at most twice across the deck without a lock row. The third occurrence makes that size recurring: stop and return to Strategist to name the role in the Design Spec and `spec_lock.md`, then read back and validate the affected fragments before reuse. This exception never applies to titles, body copy, subtitles, annotations, footnotes, captions, data labels, or card copy, and nearby sizes must not be introduced to imitate one recurring treatment. -- **Prepared decorative lettering**: When the approved plan selects stable artistic lettering as part of the visual, place its prepared AI/slice file as an image asset and keep the ordinary editable title/subtitle in separate native text frames. Do not recreate the asset with layered glyph copies or native WordArt; when the plan keeps that wording as native text and prepares no lettering asset, use ordinary `` without inventing a missing image. -- **Outside-band recovery**: for structural text, reflow geometry and use the declared role band locally. For a sparse display occurrence, keep the unitless value and verify that its deck-wide count remains at most two. Never flatten a justified distinction or add a role merely to silence the checker. Mirror pages preserve exact source typography as inherited input. -- Images MUST reference files listed under `images`; no invented filenames -- For math, load [`native-formula.md`](./native-formula.md): simple notation stays text; one-line structural prose uses inline only when its native-height envelope fits the reserved row/module space; matrices, multiline derivations, standalone high structure, or vertically expanding math without that clearance use block. Keep exact LaTeX plus preview; never use an image. +- Icons: any SVG prepared under `/icons/` is usable; `icons.library` records the primary bundled style and `icons.inventory` indexes the synced pool without assigning icons to pages or limiting other project-local assets; `simple-icons` entries are real brand marks, not a library. Illustrated icons are transparent slices under `images/` and follow [`executor-image.md`](./executor-image.md) — never moved into `icons/`, added to the inventory, or rendered through ``. +- Colors: core roles keep their meaning; derive tints, shades, alpha, gradients, and effects, preserve natural asset colors, and use sparse page-local accents that never become a competing or recurring palette. +- Spacing: §V anchors (page margin, block gap, column gutter, corner radius, body leading) are deck-wide identity; depart only for a page job, never to make content fit. +- Families: resolve by role — exact `_family`, then `title_family` / `body_family`, then legacy `font_family`; never flatten a declared override. A sparse export-safe accent family may style short non-structural display or ornament only; recurrence needs upstream selection. +- Sizes: map every structural text item to a declared `typography` role and write its anchor or a value within `±2` px, as unitless px with at most two decimals; peers on one page stay consistent, and bounded adjustment creates no new role. Never inherit a template placeholder size. `lead` / `subtitle` carry the page's primary claim; `footnote` / `annotation` carry footnotes, page numbers, and credits. +- **Sparse display-size exception**: a short non-structural Hero/Display element may use one undeclared size at most twice across the deck without a lock row. The third occurrence makes it recurring — stop, return to Strategist to name the role in the Design Spec and lock, then read back and validate before reuse. Never for titles, body, subtitles, annotations, footnotes, captions, data labels, or card copy, and never imitated with nearby sizes. +- **Outside-band recovery**: structural text reflows geometry and uses the declared band; a sparse display occurrence keeps its value while its deck-wide count stays ≤2. Never flatten a justified distinction or add a role to silence the checker; mirror pages keep exact source typography. +- **Prepared decorative lettering**: place the approved AI/slice file as an image and keep the editable title/subtitle in separate native frames; never rebuild it from glyph copies or WordArt, and never invent a missing asset when the plan kept the wording native. +- Images reference only files listed under `images`; math loads [`native-formula.md`](./native-formula.md) — simple notation stays text, one-line structural prose goes inline only when its native height fits the reserved row, matrices and multiline or vertically expanding math go block; exact LaTeX plus preview, never an image. -Return upstream before any derived/accent identity becomes recurring or structural, or when an undeclared display size reaches its third occurrence, then update the retained context under §2.1. Local garnish, same-role `±2`px adjustments, and at most two sparse display-size occurrences need no lock row. Never expand the lock to silence a comparison. New icon acquisition, images, structural fonts, role anchors, and resources keep their preparation/role rules. +Return upstream before a derived or accent identity becomes recurring or structural; garnish, `±2` px adjustments, and two sparse display occurrences need no lock row, and the lock is never expanded to silence a comparison. -**Five-page lightweight lock re-read (Default Generate only)**: after -completing P05, P10, P15, … and only when another page follows, read -`spec_lock.md` in full once before starting the next page. This is a pure -context re-anchor for the locked palette, typography, icon style, and -`page_rhythm` values under long context. No checker runs, no per-page -self-check output, no pause, and no mid-deck repair loop. If the re-read -reveals an external/unknown change, follow the Invalid recovery branch above; -otherwise continue directly. Compaction, resume, or restart still follows the -full recovery reads above. Quick Generate does not read a project-root -`spec_lock.md` and does not use this rule. - -**Per-page layout rhythm — `page_rhythm` section**: - -Before drawing each page, look up its entry in `page_rhythm` (key format `P` matching the page index in §IX of `design_spec.md`) and apply the corresponding layout discipline: +**Per-page layout rhythm — `page_rhythm`**: before drawing, apply the page's tag (key `P` matching §IX): | Tag | Layout discipline | |-----|-------------------| -| `anchor` | Structural page (cover / chapter / TOC / ending). `mirror` follows its prototype; `layout` retains its structure system. `style` / free design preserves the §IX cover hook or closing takeaway but may adopt, adapt, or decline the recommended composition. | -| `dense` | Information-heavy. Card grids, multi-column layouts, KPI dashboards, tables, and charts are all permitted. This is the baseline behavior. | -| `breathing` | Low-density impact page. Naked text blocks, dividers, whitespace, or full-bleed imagery can carry the content structure. Proportions follow information weight (not a preset ratio). Typical forms: hero quote, single large number with one-line interpretation, full-bleed image with floating caption, section transition. | - -> Mechanical repetition comes from reusing the same carrier and topology without a page job—not from semantic cards themselves. Cards remain appropriate when they express real peer grouping, comparison, hierarchy, or capacity; vary rhythm when the content relationship changes. Context recovery follows §2.1. - -**Missing or empty `page_rhythm` section — fixed compatibility default** → emit `warning: spec_lock.md missing/empty page_rhythm — defaulting all pages to dense` once, fall back to `dense` for all pages. - -**Tag not found for current page — fixed compatibility default** → emit `warning: spec_lock.md page_rhythm tag not found for P — falling back to dense` once per deck (aggregate; do not repeat per page), fall back to `dense`. Do not invent a tag. +| `anchor` | Structural page (cover / chapter / TOC / ending). `mirror` follows its prototype; `layout` retains its structure system; `style` / free design preserves the §IX cover hook or closing takeaway; the recommended composition is a Reference. | +| `dense` | Information-heavy: card grids, multi-column layouts, KPI dashboards, tables, and charts are all permitted. The baseline. | +| `breathing` | Low-density impact page: naked text, dividers, whitespace, or full-bleed imagery carry the structure; proportions follow information weight. Hero quote, single large number with one line, full-bleed image with floating caption, section transition. | +Mechanical repetition comes from reusing one carrier and topology without a page job, not from cards themselves; vary rhythm when the content relationship changes. Missing or empty `page_rhythm` → `warning: spec_lock.md missing/empty page_rhythm — defaulting all pages to dense` once, all pages `dense`. Tag missing for a page → `warning: spec_lock.md page_rhythm tag not found for P — falling back to dense` once per deck, `dense`; never invent a tag. --- ## 3. Execution Guidelines -- **Element grouping (Mandatory)**: wrap each logical Slide-local body unit in a descriptive, page-unique top-level ``. Every visible direct root `` except a compact helper-authored preset atom declares root-coordinate `data-pptx-bounds="x y width height"`; that text-free atom stays top-level when standalone, uses `data-pptx-frame`, and never carries bounds. Frame/native coordinates do not replace bounds on any other group, and placeholder bounds also supply the slot frame. Nested groups need no bounds and any such values are ignored. Checker fails ordinary root-group overlap exceeding `1px` on both axes; structured slots, structural-role groups, and off-canvas Morph staging groups are exempt, but structured Slide-local groups are not. Checker compares root bounds with the `viewBox`, recursively checks estimable text—including both shared multiline forms—against its root module with DrawingML wrapping headroom, and independently checks every estimable visible text carrier against the page without that headroom: through `1px` is ignored; module overflow warns through `5%` and fails above it, while larger page overflow always fails. Unestimable visible text receives an advisory warning. Only a wholly off-canvas direct-root Morph endpoint may set `data-pptx-morph-staging="true"`; keep its text inside its own module bounds, use an explicit pair when Morph remains enabled, and never use the marker for partial overflow. Images, shapes, paths, ``, effects, and object frames remain geometrically free. Flat pages use ordinary groups; structured slots already qualify, while titles, direct Master/Layout atoms, and canvas-level static framing may remain root primitives. On flat pages, give a root background image or full-canvas scrim/decoration rectangle a stable `id` plus `data-pptx-role="background"` / `"decoration"`; never wrap it only to silence the advisory. -- **Reference — not a constraint**: top-level groups set semantic and automatic-animation granularity, but they may contain descriptive nested `` edit groups when the page has meaningful internal subunits. Nested groups need no bounds and create no automatic animation step; use or omit them from the page's actual editing semantics, with no default pattern, depth, or quota. -- **Default — size `data-pptx-bounds` as the intended module zone, not a glyph box (may skip when no text is estimable)**: make the zone as generous as the canvas and sibling layout allow, without overlapping another module zone. An untransformed line spans `y - 0.85 × font_size` to `y + 0.35 × font_size`; width uses the shared SVG-to-PPTX per-run estimate and safety headroom. The same estimator is callable before writing: `python3 ${SKILL_DIR}/scripts/text_measure.py measure|wrap|box ...` measures lines, wraps one paragraph to a max width as ready `` rows, and computes a text block's module zone; one calibration per role serves the deck, and later calls are for lines that approach a limit, batched through `--stdin`. If text does not fit, first expand a zone that has unused non-overlapping space; otherwise reflow or adapt. Larger bounds do not repair off-canvas text. -- **Spec adherence**: follow binding color, canvas, typography, identity, resource, and template anchors; apply layout and other Reference directions under §2.1 without turning them into locks -- **Template structure**: inherit the native visual framework only for `template_reuse_scope: mirror|layout`; `style` uses the flat route -- **Main-agent ownership**: SVG generation must run in the main agent (not sub-agents) — pages share upstream context for cross-page visual continuity -- **Generation rhythm (Default only)**: P01 → first-page gate → remaining pages with one page gate per first-exercised `not-exercised` item → final gate, in one context without batches or other mid-run checker calls. -- **Fact provenance**: when a §IX page lists `Fact IDs`, resolve each ID from `sources/*.facts.json` and keep the claim/value unchanged. Render a compact source footnote using the source name and a short URL/domain when space permits; when speaker notes are enabled, state the attribution naturally there too. When §IX says `Data class: scenario`, place a visible localized `Scenario data` / `情景数据` label adjacent to the affected KPI/chart and, when notes are enabled, state naturally there that the number is illustrative. Never attach an external fact ID to scenario data or let an unlabeled invented KPI look factual. -- **Mandatory — resolve the page carrier mix before coordinates**: decide background paint/field, editable text and optional lettering, native geometry/lines, prepared photos/scenes/illustration/icon assets, and applicable visualizations in one page-level composition decision. Use only prepared external resources, preserve every binding resource job and constraint, and choose the actual combination, visual weight, z-order, and local native construction from the page message and hierarchy. The resolved style controls treatment and emphasis, never carrier eligibility, image source, or the complete native construction vocabulary. At this decision, recall the construction vocabulary already loaded: the resolved style's §1 `Composition geometry`, [`svg-effects.md`](./svg-effects.md) §6.1 Visual Job Router, and [`native-shape-authoring.md`](./native-shape-authoring.md) §2.1 composition lenses. -- **Default — stage each page with the style's composition geometry (may override when another page-fit move is stronger)**: an SVG page is a canvas, not a DOM. Resolve the page-scale move from `spec_lock.md`: a preset uses that selected style's §1 `Composition geometry`; `custom` executes `visual_style_behavior` first, then uses §1 geometry only from exact `visual_style_references` that the behavior assigns a shape or composition job. Other bases contribute only their assigned job, and an unreferenced novel custom follows its behavior alone. Treat every listed move as generative vocabulary rather than a finite menu, then apply [`native-shape-authoring.md`](./native-shape-authoring.md) §2.1's shared exact-fit geometry gate. -- **Default — consider the planned motif direction (may override when another coherent expression better serves the deck)**: when §III `Theme` recommends a cross-page motif or element family, decide whether it earns a continuity job. If adopted, keep its reuse coherent while varying scale, crop, density, position, and content interaction by page role; otherwise adapt or decline it and establish a more fitting style-consistent expression. An explicit user/template motif remains binding. -- **Ordinary carriers stay ordinary**: cards, icon-and-label rows, color swatches, soft shadows, and gradient fields are everyday slide carriers. Use them whenever content groups, compares, enumerates, or names a color, material, or sample, and give peers one shared treatment. When the subject itself is a color or material, draw it: a swatch is content, its value comes from the source, and it needs no lock row. -- **Everyday devices**: the device menu in `Page Expression Core` above is the recall list; reach for a device by page job and let the locked style set its treatment. +**Per-page composition (craft; the vocabulary is the Page Expression Core)**: -- **Inherited containers**: preserve meaningful template frames; restyle radius, fill, stroke, and depth from the active Design Spec and `spec_lock.md`. Selected Chart/Table reference adaptation is owned by [`executor-visualization.md`](./executor-visualization.md); preview effects never override project styling or structural roles. -- **Reference — prefer semantic geometry over preset stacks**: for relationships such as ascending, converging, breaking through, or stacking, first compose faithful primitives and exact presets as one page geometry system; use a Boolean only when the contour itself must merge, open, or fragment. Only when neither construction works should one page-specific polygon/path replace a stack of generic arrows. +- **Mandatory — resolve the page carrier mix before coordinates**: in one page-level decision, choose the background field, editable text and optional lettering, native geometry/lines, prepared photos/scenes/illustration/icon assets, and applicable visualizations — their combination, visual weight, z-order, and local construction from the page message and hierarchy, using only prepared resources and preserving every binding resource job. The resolved style controls treatment and emphasis, never carrier eligibility, image source, or the native vocabulary. Recall the vocabulary here: the style's §1 `Composition geometry`, the Page Expression Core above, and — once triggered — [`svg-effects.md`](./svg-effects.md) §6.1 and [`native-shape-authoring.md`](./native-shape-authoring.md) §2.1. +- **Default — stage each page with the style's composition geometry (may override when another page-fit move is stronger)**: an SVG page is a canvas, not a DOM. A preset uses its style's §1 `Composition geometry`; a `custom` executes `visual_style_behavior` first and takes §1 geometry only from the exact `visual_style_references` the behavior assigns a shape or composition job; an unreferenced custom follows its behavior alone. Every listed move is generative vocabulary; when the move reaches beyond basic primitives, [`native-shape-authoring.md`](./native-shape-authoring.md) §2.1's exact-fit gate applies (loading it then). +- **Default — consider the planned motif (may override when another coherent expression serves the deck better)**: when §III `Theme` recommends a cross-page motif, decide whether it earns a continuity job; if adopted, vary scale, crop, density, position, and content interaction by page role. An explicit user/template motif binds. +- **Ordinary carriers stay ordinary**: cards, icon-and-label rows, color swatches, soft shadows, and gradient fields are everyday carriers — use them whenever content groups, compares, enumerates, or names a color, material, or sample, with one shared treatment for peers; reach for a device by page job and let the locked style set its treatment. When the subject is a color or material, draw it: a swatch is content, its value comes from the source, and it needs no lock row. +- **Reference — semantic geometry over preset stacks**: for ascending, converging, breaking-through, or stacking relationships, compose faithful primitives and exact presets as one geometry system; a Boolean only when the contour must merge, open, or fragment; one page-specific path only when neither works. +- **Inherited containers**: keep meaningful template frames and restyle radius, fill, stroke, and depth from the Design Spec and lock; Chart/Table reference adaptation belongs to [`executor-visualization.md`](./executor-visualization.md), and preview effects never override project styling. +- **Fact provenance**: resolve each §IX `Fact ID` from `sources/*.facts.json` and keep the value unchanged; render a compact source footnote (name + short URL/domain) when space permits and state attribution naturally in enabled notes. For `Data class: scenario`, place a visible localized `Scenario data` / `情景数据` label beside the KPI/chart and say in notes that it is illustrative. Never attach a fact ID to scenario data or let an unlabeled invented KPI look factual. An organizing framework, grouping, or label the source does not state is the deck's reading — say so on the page (e.g. `整理` / `our reading`) or in enabled notes, never presented as the source's structure. + +**Technical contract (the exporter's needs; the complete SVG boundary is [`shared-standards-core.md`](./shared-standards-core.md))**: + +- **Element grouping (Mandatory)**: wrap each logical Slide-local body unit in a descriptive, page-unique top-level `` with root-coordinate `data-pptx-bounds="x y width height"`; a helper-authored preset atom stays top-level with `data-pptx-frame` and no bounds; nested groups need none. Give a root background image or full-canvas scrim/decoration rectangle a stable `id` plus `data-pptx-role="background"` / `"decoration"` instead of a wrapper. Thresholds, exemptions, and the Morph staging marker: [`shared-standards-core.md`](./shared-standards-core.md) §4.3. +- **Reference — nested edit groups**: a top-level group may contain descriptive nested `` groups for meaningful subunits; they need no bounds and create no animation step, with no default depth or quota. +- **Default — bounds are the module zone, not a glyph box (may skip when no text is estimable)**: make each zone as generous as the canvas and siblings allow without overlap. An untransformed line spans `y − 0.85 × font_size` to `y + 0.35 × font_size`. **Width is calibrated once, then estimated**: before P01 the route runs `python3 ${SKILL_DIR}/scripts/text_measure.py calibrate` (Default from the lock with `--outline`, Quick with `--role` arguments) and keeps its per-role table — CJK and Latin ≈ chars per 100 px, plus each role's longest planned line — in context; every later page sizes its zones from that arithmetic (characters ÷ the role's chars-per-100-px × 100; the estimator already carries the wrapping headroom) — write the sentence first, then fit the zone to it; no per-page measurement, no line-by-line tool calls, and never trim wording to satisfy an estimate. Reach for `calibrate --role` or `measure|wrap|box` again only for a role or size that was never calibrated. When text does not fit, first expand a zone with unused space, then reflow or switch texture (prose → points) before dropping a qualifier; larger bounds never repair off-canvas text. +- **Spec adherence**: binding color, canvas, typography, identity, resource, and template anchors hold; layout and other References apply under §2.1 without becoming locks. +- **Template structure**: inherit the native framework only for `template_reuse_scope: mirror|layout`; `style` uses the flat route. +- **Main-agent ownership**: SVG generation runs in the main agent, never a sub-agent — pages share upstream context for cross-page continuity. + +**Checkpoints**: + +- **Mandatory — per-page module line**: before drawing each page, write one line `P modules: core[, structure][, native-shape][, effects][, image][, native-data][, chart | table | formula | link | web-image]` naming the triggered modules the page uses; a module the pre-P01 sweep did not read is read completely before that page's first SVG line, and a page whose carrier mix uses a module's capability without naming it is a defect the carrier receipt exposes. - **Phased generation** (recommended): - 1. **Visual Construction Phase**: generate all SVG pages sequentially for visual consistency. Apply every triggered information-model branch while drawing. **MUST embed one object-scoped plot-area marker** per §IX-named or Quick-promoted value-driven chart object under [`executor-chart.md`](./executor-chart.md) §2; coordinate calibration is a post-generation step (see [`verify-charts`](../workflows/stages/verify-charts.md)). Write every `=yes` native marker plus JSON metadata atomically under [`native-data-interface.md`](./native-data-interface.md) §2, then record its fallback baseline before that page's gate with `python3 ${SKILL_DIR}/scripts/stamp_native_fallbacks.py /svg_output/.svg --write`; rerun it after any later visible edit inside the marker group, because a missing or stale baseline blocks the canonical gate and native Chart/Table export. **Reach for native presets** per §3.0 as you draw each page: a block arrow, chevron, banner/ribbon, callout, standard flowchart node, or star is authored through `preset_shape_svg.py` at draw time — decided by the object's intent as you create it, never by scanning finished paths, and never committed to a bare ``/`` when a preset expresses it; several presets selected for one page are generated in one `preset_shape_svg.py render-batch --input -` round (a gradient fill/stroke or a pattern fill is the one paint exception — keep those ordinary SVG; when justified, one registered [`svg-effects.md`](./svg-effects.md) §6.4 shadow/glow stays on the helper-authored shape). **First-page gate (Mandatory — Default only; Quick runs only its one final checker)**: after completing the first page, run `python3 ${SKILL_DIR}/scripts/svg_quality_checker.py --canonical-authoring --stage first-page --json` directly without output filtering. Review the whole P01 issue set, make one consolidated edit pass for every error and any selected warnings, then perform one verification rerun. If it still fails, treat that complete output as the next batch; never check between individual fixes. After it passes, draw P02 through the last page; the only further mid-run checker call is the first-exercise page gate (`--stage page --page `) on the first page that exercises a `not-exercised` item. - 2. **Quality Check Gate**: only after every planned SVG exists, run `python3 ${SKILL_DIR}/scripts/svg_quality_checker.py --canonical-authoring --stage final --json` (Quick adds its route flag) directly on `svg_output/` without `tail` / `head` / `grep` filtering. One run already reports all pages. Review its complete issue set, fix every `error` plus any selected advisory warnings in one consolidated edit pass, then perform one verification rerun. If it still fails, its complete output begins the next batch cycle; never use checker calls to discover or fix one next issue at a time. Every `warning` is advisory: it never sends the page back for required modification, never authorizes automatic rewriting of compatible user syntax, and needs no acknowledgement/disposition line. Recommendation warnings describe the generated-SVG default; fidelity/quality warnings may be surfaced when material, while the existing input remains releasable. Prototype-identical diagnostics are recorded as `inherited`, source conversion losses as `source-import`, changed/new advisories as `introduced`, and release failures as `blocking` in `validation/svg_quality_report.json`. If release truly depends on a condition, it belongs in `errors`. On success, use the exit status and terminal summary; do not open or `cat` the complete JSON into model context. If terminal output is truncated on failure, read only the relevant issue arrays from the report written by that same run. Do NOT defer error handling to after `finalize_svg.py` — finalize rewrites SVG and masks some violations. - 3. **Logic Construction Phase (conditional)**: after SVGs pass the quality check, batch-generate speaker notes for narrative continuity only when the effective Speaker Notes outcome is enabled. - -**Mandatory — final carrier-receipt review**: The final checker prints one -factual `[CARRIERS]` summary and stores per-page detail under -`files[].info.carrier_receipt`. Compare the summary with the retained page jobs, -chosen resource roles, and running geometry signatures before export. Counts -and diversity never create a quota or prove quality; zero preset use alone -neither proves fit nor establishes a defect. -When the facts contradict an active decision—such as an adopted preset absent -from output, a primary image reduced to a minor frame, or unrelated jobs -collapsing to one neutral construction—read only the affected receipt rows, -repair those pages in one consolidated pass, and rerun the final checker. + 1. **Visual Construction Phase**: generate all pages sequentially, applying every triggered branch while drawing. **MUST embed one object-scoped plot-area marker** per §IX-named or Quick-promoted value-driven chart object ([`executor-chart.md`](./executor-chart.md) §2); calibration follows in [`verify-charts`](../workflows/stages/verify-charts.md). Write every `=yes` native marker plus JSON metadata atomically ([`native-data-interface.md`](./native-data-interface.md) §2) and stamp its baseline before the page's gate — `python3 ${SKILL_DIR}/scripts/stamp_native_fallbacks.py /svg_output/.svg --write`, rerun after any visible edit inside the marker group. **Reach for native presets** per §3.0 as you draw, decided by the object's intent, never by scanning finished paths; several presets for one page go through one `preset_shape_svg.py render-batch --input -` round (gradient/pattern paint stays ordinary SVG; a justified §6.4 shadow/glow stays on the helper-authored shape). + 2. **Quality gates**: owned by the route — [`generate-pptx.md`](../workflows/generate-pptx.md) Step 6 (first-page, final, carrier receipt) or [`quick-generate.md`](../workflows/profiles/quick-generate.md) §4 (one lockless final check). Run each checker unfiltered, review the complete issue set, fix every error plus selected warnings in one consolidated pass, verify once; never check between individual fixes, never `cat` a passing report, never defer errors past `finalize_svg.py` (it rewrites SVG and masks violations). Every `warning` is advisory. + 3. **Logic Construction Phase (conditional)**: after the gates pass, generate speaker notes for narrative continuity only when the effective Speaker Notes outcome is enabled. ### 3.0 Native Shape Selection -**Hard rule — contour before encoding**: choose the page-fit contour from the -full native vocabulary before its authoring form. Rectangle, rounded-rectangle, -circle, and ellipse are preset contours even when authored with short SVG -primitive syntax; never select them because that syntax is easier. After -selection, use [`native-shape-authoring.md`](./native-shape-authoring.md) §1's -simplest exact form, keep atoms independent unless one contour is required, -materialize that contour with Boolean semantics, and use freeform last. Block -arrows, chevrons, banners / ribbons, callouts, flowchart nodes, stars, and other -Office symbols use `preset_shape_svg.py`, not plain paths or fake rectangles. +**Hard rule — contour before encoding**: choose the page-fit contour from the full native vocabulary — [`preset-shape-vocabulary.md`](./preset-shape-vocabulary.md), read completely before the first page — before its authoring form; when the roster sweep or a page reaches beyond rectangle, rounded rectangle, circle, ellipse, and line, read [`native-shape-authoring.md`](./native-shape-authoring.md) completely before choosing. Rectangle, rounded rectangle, circle, and ellipse are preset contours even in short SVG syntax; easier syntax never selects a contour. Every other vocabulary contour — an inflected carrier (snipped, one-sided rounded, plaque, bevel, polygon, pie, frame, folded corner) as much as a block arrow, chevron, banner, callout, flowchart node, or star — comes from `preset_shape_svg.py`, never plain paths or fake rectangles. No Design Spec selection, scorer, or inventory gates this choice. -Before the first page, read -[`preset-shape-vocabulary.md`](./preset-shape-vocabulary.md) completely. Decide -every page-fit contour and its simplest exact authoring form directly from the -page content and visual system; no Design Spec construction selection, scorer, -or material inventory gates this choice. +**Mandatory — independent per-page geometry move**: after the Structure result and any topology, decide the page's geometry before writing coordinates; when it reaches beyond basic primitives, apply [`native-shape-authoring.md`](./native-shape-authoring.md) §2.1 (loading it then); it owns exact-fit comparison, composition lenses, relationship and carrier fit, contour-family choice, the reader effect of a generic or undrawn result, the running geometry signature, and the materialization boundary for both Structure results. Keep the decision in active context; never change the Structure result. -**Mandatory — independent per-page geometry move**: after the Structure result -and any applicable topology resolve, apply -[`native-shape-authoring.md`](./native-shape-authoring.md) §2.1 before writing -coordinates. It owns the exact-fit geometry comparison, composition lenses, -independent relationship / carrier fit, contour-family / exact-result choice, -reader effect for a generic or undrawn result, running geometry signature, and -materialization boundary for both `Structure=no` and `Structure=yes`. Keep the -current decision in active context and never change the Structure result. +Materialize through [`native-shape-authoring.md`](./native-shape-authoring.md) §1's table: an ordinary primitive when the exporter maps it to the same contour, otherwise the helper fragment; `` for a straight relationship and a `bentConnector*` / `curvedConnector*` preset for a stock bend or curve (both export unconnected); independent siblings for a page-level system; `shape_boolean_svg.py` only when one contour must merge, cut, or fragment; ordinary path/polygon only for geometry none of those express. A directional solid object is a `shape` preset such as `rightArrow` or `chevron`; `actionButton*` presets are geometry only. -| Selected result | Authoring form | -|---|---| -| Selected exact non-Connector stock contour | Use ordinary SVG only when the exporter maps it to that same contour; otherwise call `preset_shape_svg.py render` and paste its complete stdout fragment. | -| Straight relationship / divider / leader | Use ``; add a registered marker under [`shared-standards-core.md`](./shared-standards-core.md) §1.1 only when direction is meaningful. | -| Bent / curved relationship exactly expressed by a stock Connector contour, with no required endpoint attachment | Use the matching `bentConnector*` / `curvedConnector*` preset through the helper as an unconnected native Connector shape. | -| Selected text/content boundary needs no filled surface | Use its exact authoring form with `fill="none"` and a visible stroke; keep text and other content independent. | -| Two or more native shapes should form one page-level geometry system | Follow [`native-shape-authoring.md`](./native-shape-authoring.md) §2.1: compose faithful primitives and presets as independent siblings first, then materialize only contours that require Boolean semantics. | -| Supported closed-shape / resolvable-text operands need union, cutout, overlap, symmetric difference, or fragmentation | Use `shape_boolean_svg.py` when Boolean materialization is the clearest faithful construction; follow [`native-shape-authoring.md`](./native-shape-authoring.md) §6. | -| Stock shape that needs a gradient fill/stroke or a pattern fill | Keep ordinary SVG — the helper paints `none` or a solid HEX on both fill and stroke only ([`native-shape-authoring.md`](./native-shape-authoring.md) §5). | -| Page-specific freeform, organic, branded, icon, data geometry, or relationship contour that primitives, exact presets, their independent composition, and Boolean materialization cannot faithfully express | Keep ordinary SVG path/polygon geometry. | -| Similar-looking contour only | Never infer a preset; continue to the Boolean gate, then use freeform only if no faithful construction exists. | - -**Hard rule — freeform is the last construction tier**: before hand-authoring a -stock-looking `` / ``, complete contour selection, simplest exact -materialization, independent composition, and the required Boolean-result gate. -A freeform is permitted only when those routes cannot faithfully express the -object; avoiding a helper or drawing the browser-visible contour faster is not -a valid exception. Data-defined geometry and a genuinely locked organic / -hand-drawn contour satisfy the exception by semantics, not by convenience. - -This decision applies only while drawing a new object. A suggestion never -triggers retrospective scanning, contour classification, or automatic -upgrading of ordinary SVG during export. - -**Hard rule — helper-written metadata**: `data-pptx-authoring`, `data-pptx-prst`, -`data-pptx-frame`, adjustment metadata, and registry paths are written only by -the preset helper; hand-written values fail the checker. The preset helper -generates one compact atomic `` from the shared 187-shape registry, with -semantic metadata and base paint written once. Rerun that helper when geometry -or paint changes; never edit one of its direct paths. - -**Default — relationship geometry**: use `` for a straight relationship. -When a relationship genuinely needs a bend or curve and a stock Connector -contour fits, prefer the matching `bentConnector*` / `curvedConnector*` preset -over a hand-authored SVG Bézier. Use an open freeform path only when a straight -line and the native Connector families cannot faithfully express the required -route, data geometry, or locked hand-drawn / organic style. A directional solid -object remains an ordinary `shape` preset such as `rightArrow` or `chevron`. - -Authored Connector presets export as unconnected `p:cxnSp` objects: they do not -bind to node sites or follow moved nodes. Never hand-add endpoint/site metadata -or claim attachment semantics. Imported Connector topology stays under the -preserve/mirror contract. `actionButton*` presets provide visual geometry only, -not actions or hyperlinks. - -**Hard rule — narrow helper scope**: Both helpers print only their documented -stdout fragment(s); neither writes a page or chooses layout. Read every returned -fragment and insert it through the normal page edit; never -redirect, loop, or batch helper output into `svg_output/`. +**Hard rule — freeform is the last tier**: before hand-authoring a stock-looking `` / ``, complete contour selection, simplest exact materialization, independent composition, and the Boolean gate; avoiding a helper or drawing faster is not an exception, while data-defined geometry and a genuinely locked organic/hand-drawn contour qualify by semantics. This applies only while drawing a new object; export never scans or upgrades ordinary SVG. +**Hard rule — helper-written metadata and scope**: `data-pptx-authoring`, `data-pptx-prst`, `data-pptx-frame`, adjustment metadata, and registry paths are written only by the preset helper (hand-written values fail the checker); rerun it when geometry or paint changes and never edit a direct path. Both helpers print only their stdout fragment(s): read and insert each through the normal page edit, never redirect, loop, or batch output into `svg_output/`. ### SVG File Naming Convention -Format: `_.svg`. Use one roster-wide zero-padded index width sized for the Design Spec §IX roster, such as `01_cover.svg` through `12_end.svg` or `001_cover.svg` through `120_end.svg`; match the deck language and page title. +`_.svg` with one roster-wide zero-padded width (`01_cover.svg` … `12_end.svg`, or `001_cover.svg` … `120_end.svg`), matching the deck language and page title. --- ## 4. Icon Usage -Strategist chooses at most one primary bundled stylistic library and may select `simple-icons` alone or alongside it; Executor implements from the complete prepared project-local pool. Library details and selection rules: [`../templates/icons/README.md`](../templates/icons/README.md). This section defines placeholder syntax. - -> **Prepared-project boundary.** Any SVG under `/icons//` is valid prepared material. Authoring, preview, finalization, and export resolve only complete case-sensitive `library/name` references there; no global or template-source fallback exists. - -> **Icon identifiers are case-sensitive filenames.** Every `data-icon` value must use the exact project-local relative basename (`tabler-outline/award`, never `tabler-outline/Award`). Strategist records its curated bundled pool in `spec_lock.md`; Executor need not add other already-prepared project-local icons to that inventory. Custom identifiers preserve the custom file's exact case; the pipeline never silently lowercases names. - -**Built-in icons — Placeholder method (recommended)**: +Strategist chooses at most one primary bundled stylistic library and may select `simple-icons` alone or alongside it for real brand marks; Executor draws from the complete prepared project-local pool ([`../templates/icons/README.md`](../templates/icons/README.md)). Any SVG under `/icons//` is prepared material; authoring, preview, finalization, and export resolve only complete case-sensitive `library/name` references there (`tabler-outline/award`, never `Award`; custom files keep their exact case), with no global or template-source fallback. ```xml - - - - - - - - - - - - - - - - + + ``` -> ⚠️ **Color**: ALWAYS use `fill="#HEX"` on ``. NEVER use `stroke` or `fill="none"`, even for stroke-style libraries. -> -> **stroke-width** (stroke-style libraries only, currently `tabler-outline`): allowed values `{1.5, 2, 3}`. If `spec_lock.md icons.stroke_width` is declared, all placeholders MUST use that value deck-wide. Ignored on non-stroke libraries. -> -> **Missing `icons.stroke_width` in an existing stroke-library lock — fixed compatibility default**: use `2`, emit one warning, and continue. New authoring must still declare the field. -> -> Icons are auto-embedded by `finalize_svg.py` — no need to run `svg_finalize/embed_icons.py` manually. +**Hard rule — color and stroke**: always `fill="#HEX"` on ``, never `stroke` or `fill="none"`, even for stroke libraries. `stroke-width` (`tabler-outline` only) is `1.5`, `2`, or `3`; a declared `spec_lock.md icons.stroke_width` applies deck-wide, and new authoring declares it, and a legacy stroke-library lock without it uses `2` with one warning. `finalize_svg.py` embeds placeholders automatically. -**Project-local verification**: verify the exact prepared file before use: -```bash -test -f "/icons//.svg" -``` - -**Missing project-local icon** → return to Strategist's preparation / `icon_sync.py` gate. Do not search the global library, select an alternative, or copy a candidate in Executor. - -**Hard rule — prepared assets**: Executor may freely combine project-local icons, regardless of namespace or style. It may not acquire a new icon or treat a globally resolvable file as prepared material. +**Missing project-local icon** (`test -f "/icons//.svg"`) → return to Strategist's preparation / `icon_sync.py` gate; Executor never searches the global library, picks an alternative, or copies a candidate. Executor may combine project-local icons freely across namespaces and styles but may not acquire a new one or treat a globally resolvable file as prepared. --- ## 5. Font Usage -Default reads typography from `spec_lock.md` (Quick: from its transient §2 typography anchor): `_family` → `title_family` / `body_family` → legacy `font_family`; sparse accents follow §2.1. Under [`native-formula.md`](./native-formula.md), blocks use marker style; inline math inherits size / visible solid fill and exports with the project text language in Cambria Math. +Default reads typography from `spec_lock.md` (Quick: its transient §2 anchor): `_family` → `title_family` / `body_family` → legacy `font_family`; sparse accents follow §2.1. Under [`native-formula.md`](./native-formula.md), blocks use marker style and inline math inherits size and solid fill, exporting in Cambria Math with the project text language. -**Default — locked-stack realization (may vary treatment)**: Express the Design Spec Character Reference through scale, weight, spacing, color, and composition; keep the locked family. Put the common stack on root ``, omit matching descendants, and override at the nearest clear ``, ``, or ``. +**Default — locked-stack realization (may vary treatment)**: express the Design Spec Character Reference through scale, weight, spacing, color, and composition while keeping the locked family; put the common stack on root ``, omit matching descendants, and override at the nearest clear ``, ``, or ``. -**Missing required field — `typography.font_family`** → stop and return to Generate Step 4 / [`strategist.md`](strategist.md) §6.2 to repair `spec_lock.md`; do not infer a stack from `design_spec.md`. - -**Hard rule**: every SVG `font-family` stack MUST resolve to target-installed/approved Latin and EA faces. PPTX writes one face per script from the stack: the first named Latin face fills `latin`, the first named CJK face fills `ea` and also `latin` when no named Latin face exists, and a generic family (`sans-serif`, `serif`) fills `latin` only when it precedes every named face. Fonts are not embedded. Missing-face substitution is viewer-selected—not guaranteed Calibri or a later stack entry. +**Hard rule — target faces**: every `font-family` stack resolves to target-installed/approved Latin and EA faces. PPTX writes one face per script: the first named Latin face fills `latin`, the first named CJK face fills `ea` (and `latin` when no Latin face is named), and a generic family fills `latin` only when it precedes every named face. Fonts are not embedded; missing-face substitution is viewer-selected. **Missing `typography.font_family`** → stop and return to Generate Step 4 / [`strategist.md`](strategist.md) §6.2; never infer a stack from `design_spec.md`. --- -## 6. Completion Routing (Default only) +## 6. Completion and Export (Default only) -After every SVG page passes the final quality check, load -[`executor-notes.md`](./executor-notes.md) and complete its notes contract only -when the effective Speaker Notes outcome in `design_spec.md §I` is enabled. -When disabled, proceed directly to the route's conditional motion handling and -Step 7. - -## 7. Next Steps After Completion (Default only) - -> **Auto-continuation**: After Visual Construction Phase and any enabled Logic Construction Phase are complete, the Executor proceeds directly to the post-processing pipeline. - -**Post-processing & Export**: Follow [`generate-pptx.md`](../workflows/generate-pptx.md) -Step 7. That workflow owns the serial commands, gates, success criteria, and -published artifacts; [`svg-pipeline.md`](../scripts/docs/svg-pipeline.md) owns -tool-specific flags and behavior. - -`svg_final/` may be opened directly or manually inserted into PowerPoint as an SVG picture. It is not a second PPTX route. Use `-s final` only for converter diagnostics; release exports use the default `svg_output/` source. Manual Convert-to-Shape behavior is unsupported. +After every page passes the final quality check, load [`executor-notes.md`](./executor-notes.md) only when the effective Speaker Notes outcome in `design_spec.md §I` is enabled, then proceed to the route's conditional motion handling and [`generate-pptx.md`](../workflows/generate-pptx.md) Step 7, which owns post-processing and export. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/executor-chart.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/executor-chart.md index f09f73e6..2356aa02 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/executor-chart.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/executor-chart.md @@ -1,12 +1,10 @@ -> Default Generate also loads [`executor-base.md`](./executor-base.md); a selected chart-family SVG is adapted through [`executor-visualization.md`](./executor-visualization.md), while independent native readiness and metadata remain exclusively in [`native-data-interface.md`](./native-data-interface.md). +> Default Generate also loads [`executor-base.md`](./executor-base.md); a selected chart-family SVG is adapted through [`executor-visualization.md`](./executor-visualization.md), while native readiness and metadata remain exclusively in [`native-data-interface.md`](./native-data-interface.md). # Executor Chart Branch Conditional Executor authority for value-driven SVG geometry, plot-area markers, and the [`verify-charts`](../workflows/stages/verify-charts.md) handoff. -**Trigger**: load whenever source values determine visible geometry, including bar length/height, point position, arc angle, polygon vertex, connector or flow width/path, bubble center/radius, duration position, area, or another quantitative visual variable. Mini charts, sparklines, insets, and small multiples count even without a catalog reference. - -**Boundary**: +**Trigger**: source values determine visible geometry — bar length/height, point position, arc angle, polygon vertex, connector or flow width/path, bubble center/radius, duration position, area, or another quantitative visual variable. Mini charts, sparklines, insets, and small multiples count even without a catalog reference. | Information model | Route | |---|---| @@ -18,40 +16,17 @@ Conditional Executor authority for value-driven SVG geometry, plot-area markers, ## 1. Value-driven Geometry -**Hard rule — data owns the marks**: derive every quantitative mark from the authoritative values and one explicit scale/encoding. Do not eyeball positions, preserve sample values from a catalog preview, or alter data to improve composition. +**Hard rule — data owns the marks**: derive every quantitative mark from the authoritative values and one explicit scale/encoding. Do not eyeball positions, preserve sample values from a catalog preview, or alter data to improve composition. A schedule is a Gantt chart when dates or durations determine each task bar's `x` and `width`, even if the source was a PowerPoint table; a qualitative stage × lane placement belongs to `executor-structure.md`. -Construct the chart in this order: +Construct in this order: (1) resolve data domain, categories, units, baseline, scale, and any radius/color/bin mapping; (2) establish the plot frame, axes/grid or radial frame, and legend needed to decode them; (3) calculate marks from the values, including cumulative, derived, or hierarchical geometry; (4) add data labels, axis/category labels, annotations, units, source notes, and visible exceptions from the page contract; (5) apply project typography, palette, effects, and container treatment without changing the encoding. -1. Resolve the data domain, categories, units, baseline, scale, and any radius/color/bin mapping. -2. Establish the plot frame, axes/grid or radial frame, and legend needed to decode those mappings. -3. Calculate marks from the values, including cumulative, derived, or hierarchical geometry where the chosen chart requires it. -4. Add data labels, axis/category labels, annotations, units, source notes, and visible exceptions from the active page contract. -5. Apply project typography, palette, effects, and container treatment without changing the encoding. +**Perceptual reading**: choose the least ambiguous presentation of the same data. Preserve source or semantic order when it carries meaning; otherwise sort for the page's comparison task. Prefer direct series labels when legible; keep legends, grid lines, and ticks only when they materially reduce lookup effort. Comparable panels share domain, scale, and category order unless a disclosed difference is the message. Magnitude bars and columns start from zero; interval marks keep their authoritative domain; any non-zero baseline or axis break is explicit and never exaggerates. A dual-axis chart is valid only when both series share the exact time/category domain and units and identities stay unambiguous; otherwise separate the views. -**Perceptual reading**: choose the least ambiguous presentation of the same -authoritative data. Preserve source or semantic order when it carries meaning; -otherwise sort categories for the page's comparison task. Prefer direct series -labels when they remain legible, and keep legends, grid lines, ticks, and other -decoding aids only when they materially reduce lookup or comparison effort. -Comparable panels and small multiples use the same domain, scale, and category -order unless a visibly disclosed difference is itself the message. Bars and -columns whose length compares magnitude start from zero; schedule spans and -other true interval marks retain their authoritative domain. Any non-zero -baseline or axis break must be explicit and must not exaggerate the comparison. -A dual-axis chart is valid only when both series share the exact time/category -domain and the units and visual identities stay unambiguous; otherwise separate -the views. +**Reference — chart color and annotation conventions**: a monochromatic depth scheme reads cleaner than rainbow — the primary series in the full theme color, a comparison series in the same hue at about 60% alpha, baselines as a gray dashed line, the accent color only on the key data points; positive / warning / negative trends use the deck's green / yellow / red polarity roles. Place direct data labels at bar ends or beside points instead of a legend where they stay legible; annotate genuine inflection points in words ("policy change", "product launch"); mark an industry average or target as a gray dashed comparison baseline; keep units and precision consistent within one chart; add a muted source note where attribution or provenance matters. -**Per-object completeness**: preserve every authoritative series, category, point, label, unit, qualifier, source, and scale cue needed to read the chart. For a `=yes` chart, the JSON mirrors the drawn fallback item by item in the same edit: legend labels verbatim, point-level exception colors as `point_colors`, the axis scale, the classic `plot_area` taken from the plot-area marker, visible data labels or summary figures as `data_labels` or companion text, and the actual label / axis / grid colors — omit `text_color` and its siblings rather than guess them. When the source cannot determine a required scale or derived value, return the ambiguity upstream in Default or resolve it from explicit source facts in Quick; never fabricate it at draw time. +**Per-object completeness**: preserve every authoritative series, category, point, label, unit, qualifier, source, and scale cue. For a `=yes` chart, the JSON mirrors the drawn fallback item by item in the same edit — legend labels verbatim, point-level exception colors as `point_colors`, the axis scale, `plot_area` from the plot-area marker, visible data labels or summary figures as `data_labels` or companion text, actual label/axis/grid colors (omit `text_color` and siblings rather than guess). When the source cannot determine a required scale or derived value, return the ambiguity upstream in Default or resolve it from explicit source facts in Quick; never fabricate at draw time. -**Hard rule — schedule geometry**: A schedule is a Gantt chart when dates or -durations determine each task bar's `x` and `width`, even if the source was a -PowerPoint table object. A qualitative stage × lane placement without that -mapping belongs to [`executor-structure.md`](./executor-structure.md). - -**Selected reference**: when the page has a `chart/` primary reference, [`executor-visualization.md`](./executor-visualization.md) owns its resolution and flexible adaptation. This branch still owns the actual value-to-geometry calculation. A chart authored from scratch follows the same geometry contract without loading a catalog SVG. - -**Incidental microvisual**: draw a small value-driven trend or indicator accurately. It enters §2 and the verification handoff only when Default §IX or the Quick active-context decision promotes it to a coordinate-verified data object; do not infer that promotion from its appearance after drawing. +**Selected reference**: with a `chart/` primary reference, [`executor-visualization.md`](./executor-visualization.md) owns resolution and adaptation; this branch still owns the value-to-geometry calculation. A chart authored from scratch follows the same contract. An incidental microvisual (small trend or indicator) is drawn accurately but enters §2 and verification only when Default §IX or the Quick active-context decision promotes it to a coordinate-verified object. --- @@ -59,19 +34,7 @@ mapping belongs to [`executor-structure.md`](./executor-structure.md). ### 2.1 Chart Plot-Area Marker (Mandatory per verified chart object) -> [`verify-charts`](../workflows/stages/verify-charts.md) enumerates Default pages from Design Spec §IX and Quick pages from the still-active authoring decisions. A missing marker invokes that stage's declared fallback and adds avoidable derivation work. - -**Hard rule — object-scoped marker**: every Default chart object given a -semantic key in §IX `Visualization`, and every Quick chart object promoted for -coordinate verification, has one page-local `kebab-case` object key. Wrap that -object in ``; put exactly one marker inside its plot-area -group after the axes and before the first data mark. Use -`id="-chartArea"` so several charts can coexist without duplicate -IDs. New pages prefix the marker payload with `object= |`. A legacy -unscoped marker and `` are accepted only when the page has -exactly one verified chart object. - -**Rectangular plot area**: +**Hard rule — object-scoped marker**: every Default chart object keyed in §IX `Visualization`, and every Quick chart object promoted for coordinate verification, has one page-local `kebab-case` object key. Wrap it in ``; place exactly one marker inside its plot-area group `id="-chartArea"`, after the axes and before the first data mark, with payload prefix `object= |`. A legacy unscoped marker with `` is accepted only when the page has exactly one verified chart object. ```xml @@ -83,8 +46,6 @@ exactly one verified chart object. ``` -**Radial plot area**: - ```xml @@ -93,48 +54,21 @@ exactly one verified chart object. | Value | Derivation | |---|---| -| `x_min` | X coordinate of the Y-axis line or leftmost data boundary | -| `y_min` | Y coordinate of the topmost grid line or data boundary | -| `x_max` | X coordinate of the rightmost axis endpoint or data boundary | -| `y_max` | Y coordinate of the X-axis baseline or bottom data boundary | -| `cx, cy` | Absolute center after accounting for containing translate transforms | -| `r`, `r1`, `r2` | Visible outer/inner radii used by the authored radial geometry | +| `x_min` / `x_max` | X of the Y-axis line or leftmost data boundary / rightmost axis endpoint or data boundary | +| `y_min` / `y_max` | Y of the topmost grid line or data boundary / X-axis baseline or bottom data boundary | +| `cx, cy` | Absolute center after containing translate transforms | +| `r`, `r1`, `r2` | Visible outer/inner radii of the authored radial geometry | -Calculator-supported SVGs in `templates/charts/` carry the same comment, and -single-object previews may retain the legacy unscoped payload and -`id="chartArea"`. A qualitative structure or cell-grid table does not gain a -marker merely because it contains numbers. +Calculator-supported SVGs in `templates/charts/` carry the same comment. A qualitative structure or cell-grid table gains no marker merely because it contains numbers. A missing marker invokes the verify stage's declared fallback and adds avoidable derivation work. ### 2.2 Authoring-time Check -After writing each page containing verified charts, confirm marker count and -object ownership before continuing: +After each page containing verified charts: `rg -n "chart-plot-area" /svg_output/.svg` — marker count equals promoted chart objects and each marker sits under its object wrapper. -```bash -rg -n "chart-plot-area" /svg_output/.svg -``` - -The number of markers must equal the number of promoted chart objects, and each -marker must sit under its matching object wrapper. One marker somewhere on a -multi-chart page is insufficient. - -**Native layout handoff**: for a native-ready classic chart whose authored plot -rectangle must remain fixed, copy that final absolute slide rectangle into -metadata `plot_area`; omit it only for PowerPoint automatic layout. The marker -comment alone does not affect export; the closed schema stays in -[`native-data-interface.md`](./native-data-interface.md) §2. - -Technical SVG/PPT constraints remain in [`shared-standards-core.md`](./shared-standards-core.md). +**Native layout handoff**: for a native-ready classic chart whose authored plot rectangle must stay fixed, copy that absolute rectangle into metadata `plot_area`; omit it for PowerPoint automatic layout. The comment alone does not affect export; the closed schema is [`native-data-interface.md`](./native-data-interface.md) §2. --- ## 3. Verification Handoff -Coordinate calibration is a conditional post-generation stage, not part of the page-authoring loop. After all SVG pages exist, run [`verify-charts`](../workflows/stages/verify-charts.md) whenever the active profile declares at least one page with value-driven chart geometry. - -| Active profile | Verification page list | -|---|---| -| Default Generate | Design Spec §IX, with the stage's explicit legacy §VII fallback | -| Quick Generate | Still-active page decisions cross-checked one-for-one against plot-area markers | - -Do not run `svg_position_calculator.py` during the initial draft. The stage calibrates completed SVG geometry against the declared plot area, handles direct/decomposable/formula/manual modes, repairs genuine coordinate mismatches, and then returns to the active profile's checker order. +Coordinate calibration is a conditional post-generation stage. After all SVG pages exist, run [`verify-charts`](../workflows/stages/verify-charts.md) whenever the active profile declares at least one page with value-driven chart geometry: Default enumerates Design Spec §IX (with the stage's legacy §VII fallback); Quick cross-checks still-active page decisions one-for-one against plot-area markers. Do not run `svg_position_calculator.py` during the initial draft; the stage calibrates completed geometry against the declared plot area, repairs genuine mismatches, and returns to the profile's checker order. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/executor-image.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/executor-image.md index 18d7fd35..21c33476 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/executor-image.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/executor-image.md @@ -1,59 +1,40 @@ -> Default Generate also loads [`executor-base.md`](./executor-base.md). Quick -> Generate deliberately does not; this branch supplies its conditional image -> realization rules directly. +> Default Generate also loads [`executor-base.md`](./executor-base.md); Quick loads this branch with its own §2 anchors. # Executor Image Branch Conditional Executor authority for image status handling, placement, crop behavior, and template-bundled images. -**Trigger**: load for any image in §VIII, the lock, Quick Generate's active-context resource decisions, or a selected template. +**Trigger**: any image in §VIII, the lock, Quick's active-context resource decisions, or a selected template. -## 1. Image Handling +**Contract — status handling** (enum and lifecycle in [`svg-image-embedding.md`](svg-image-embedding.md), reference syntax there too). Executor consumes only prepared assets; derivatives already exist and native treatments are SVG work. -Handle images by status; enum and lifecycle: [`svg-image-embedding.md`](svg-image-embedding.md). +| Status | Handling | +|---|---| +| `Existing` (user-provided) | Reference from `../images/` | +| `Generated` (Image_Generator) | Reference from `../images/`; a manifest-backed file also loads [`executor-web-image.md`](./executor-web-image.md) | +| `Sourced` (Image_Searcher) | Reference from `../images/`; read `image_sources.json` for attribution — load [`executor-web-image.md`](./executor-web-image.md) | +| `Needs-Manual` | Default uses a placeholder until Step 7; Quick blocks every required row, file presence notwithstanding | +| `Placeholder` | Dashed `` plus description text | -**Mode boundary**: Default Executor consumes only prepared §VIII/lock assets. Quick enters the same consume-only boundary at SVG authoring from prepared active-context resources. Derivatives already exist; native treatments remain SVG work. +**Template-bundled images**: [`apply-template-workspace.md`](../workflows/stages/apply-template-workspace.md) copies them into project `images/`; every page, including `mirror`, rebases the same bytes to exact `../images/` (a transport rewrite, not a visual edit). Never keep a bare or source-template href. -| Status | Source | Handling | -|--------|--------|----------| -| **Existing** | User-provided | Reference images directly from `../images/` directory | -| **Generated** | Generated by Image_Generator | Reference from `../images/`; manifest-backed files load [`executor-web-image.md`](./executor-web-image.md) | -| **Sourced** | Web-acquired by Image_Searcher | Reference from `../images/`. **Read [`image_sources.json`](image-searcher.md) to decide attribution** — load [`executor-web-image.md`](./executor-web-image.md). | -| **Needs-Manual** | Acquisition or suitability remains unresolved | Default uses a placeholder until Step 7. Quick blocks every required row in this status; file presence alone does not bypass it. | -| **Placeholder** | Not yet prepared | Use dashed border placeholder | +**Contract — crop policy**: read the §VIII row and its lock projection (`source`, `crop`). On every slide that uses a `crop=no-crop` source (or legacy `| no-crop`), keep one visible complete instance with one of the nine legal `meet` anchors — never `none`, `clip-path`, `mask`, overflow clipping, or a nested crop viewport; an auxiliary same-slide detail or lens may crop the source only while that instance stays visible. `crop=adaptive` permits cropping without requiring it: choose `meet` or a focal-safe `slice` from purpose, ratio, focus, and container. A missing or conflicting projection returns upstream; the §VIII `Layout pattern` is a Reference — a starting sketch adjusted freely unless labeled `(binding)`. -**Reference syntax**: see [`svg-image-embedding.md`](svg-image-embedding.md). +**Hard rule — same-source addressable crops, only when adopted**: no layout suggestion (including `#M1-11`) activates this transport, and `#M1-09` is a deliberate-offset treatment with no registered or Morph continuity. Use it only when independent crops must preserve one exact scene map or an explicit editable/Morph requirement needs them: reuse one exact `href` without slice assets, give every independent object a stable page-unique id and its own nested crop wrapper ([`svg-effects.md`](./svg-effects.md) §6.5) — plain rectangles need no crop marker; shaped frames put `data-pptx-crop="1"` on the wrapper and a matching `userSpaceOnUse` clip on the inner `` — and derive every wrapper `viewBox` from one shared source-to-page transform over the union of the visible containers, so different container positions change the source-unit `x`, `y`, `width`, `height` by the same mapping and gaps remove pixels without rescaling. Repeated crops or SVG/PPT drift fail. A compound clip on one `` is `#M1-10`, not a substitute when the objects must stay independently editable or Morphable. -**Template-bundled images**: [`apply-template-workspace.md`](../workflows/stages/apply-template-workspace.md) copies them into project `images/`. Every page, including `mirror`, must rebase the same bytes to exact `../images/`; this transport rewrite is not a visual edit. Never retain a bare or source-template href: preview, validation, and export resolve the written path exactly. +**Hard rule — visible-layer timing**: every crop, lens, scrim, comparison, evidence, or annotation layer an adopted motion plan needs already exists in the final SVG; the motion stage may regroup ordinary Slide-local content but never invents or modifies visible content. When no legal unit can serve a non-binding suggestion, simplify to available units, a page transition, or `none`; an unrepresentable explicit requirement follows failure recovery. -**Default — active image integration (may override when plain placement is -stronger)**: Treat loaded [`image-layout-patterns.md`](./image-layout-patterns.md) -as vocabulary and [`image-layout-spec.md`](./image-layout-spec.md) as math, not -a quota or lock. A `#P...` suggestion is only a skeleton; deepen, simplify, or -combine it through the already-loaded [`svg-effects.md`](./svg-effects.md) and -[`native-shape-authoring.md`](./native-shape-authoring.md). Plain placement or a -regular grid remains valid when it communicates better. Preserve role/source, -must-use, crop/content, and explicit user/template constraints; expression-only -changes need no upstream rewrite. +**Hard rule — narrow visual-inspection scope**: start from §VIII `Reference` plus dimensions; inspect one asset (or its review copy) once only when focal-safe crop, overlay contrast, a quiet region, or the planned subject relationship stays ambiguous — a `Generated` asset only when its intent and dimensions cannot resolve the ambiguity, never routinely. Inspection never reopens selection, changes identity or must-use, infers provenance, substitutes, or invents focus; uncertain `adaptive` focus uses `meet`, and conflicting binding constraints return upstream. -**Mandatory — per-page image composition decision**: Using this already-loaded -branch, decide once immediately before geometry on every page containing an -image and keep the result only in active context: -`role → direction generator → parent contour → slots/rhythm → crop → -image-shape action → labels/overlays → depth/continuity`. Derive the relationship -from the communication job, hierarchy, copy, asset ratio/focus, and deck rhythm; -use `anchor`, `continue`, `bridge`, `overlap`, `reveal`, `echo`, or `register` -only when useful. Compare the resulting candidate with plain/`P`-only placement -and implement the stronger legal composition. Create no artifact or extra pass, -and do not reread the branch while its active context remains valid. +## 1. Image Composition -**Default — preserve the image job at final size (may override when the planned -job is texture only)**: Before accepting a narrow band, small placement, or crop, -keep the subject or relationship named by the image purpose recognizable at its -final on-slide size. If it collapses into color texture, enlarge or recompose it; -treat it as texture only when the upstream job permits that role. +**Mandatory — per-page image composition decision**: on every page with an image, once, immediately before geometry, in active context only: `role → direction generator → parent contour → slots/rhythm → crop → image-shape action → labels/overlays → depth/continuity`, derived from the communication job, hierarchy, copy, asset ratio/focus, and deck rhythm, using `anchor`, `continue`, `bridge`, `overlap`, `reveal`, `echo`, or `register` only when useful. Compare the candidate with plain / `P`-only placement and implement the stronger legal composition; no artifact, no extra pass, no rereading the branch while the context is valid. -**Reference — direction generators, not templates**: +**Default — active image integration (may override when plain placement is stronger)**: [`image-layout-patterns.md`](./image-layout-patterns.md) is vocabulary and [`image-layout-spec.md`](./image-layout-spec.md) is math, neither a quota nor a lock; a `#P…` suggestion is a skeleton to deepen, simplify, or combine through [`svg-effects.md`](./svg-effects.md) and [`native-shape-authoring.md`](./native-shape-authoring.md). Preserve role/source, must-use, crop/content, and explicit constraints; expression-only changes need no upstream rewrite. + +**Default — preserve the image job at final size (may override when the planned job is texture only)**: before accepting a narrow band, small placement, or crop, keep the subject or relationship named by the image purpose recognizable at its on-slide size; if it collapses into color texture, enlarge or recompose, and treat it as texture only when the upstream job permits. + +**Default — one direction generator per image group (may override when deliberate disorder serves the job)**: derive slot positions, crop edges, overlap, and any rotation from one generator; varied angles need a declared rhythm or collision rule. | Generator | Behavior | |---|---| @@ -61,39 +42,6 @@ treat it as texture only when the upstream job permits that role. | `shared-baseline` | Share a baseline while size, offset, or overlap changes systematically | | `curve-spine` | Derive slots and turns from one continuous curve or folded path | | `panel` | Subdivide one coherent tilted, stepped, or polygonal parent panel | -| `none/grid` | Retain calm plain placement or a regular grid | +| `none/grid` | Calm plain placement or a regular grid | -**Default — coherent multi-image direction (may override when deliberate disorder -serves the communication job)**: Within one image group, derive slot positions, -crop edges, overlap, and any rotation from one primary direction generator. -Varied angles need one declared rhythm or collision rule; they are not a shortcut -to variety. - -**Reference — motion-ready image layering, not a constraint**: For adopted §IX or an explicit focus, comparison, evidence, reveal-order, or cross-page requirement, decide during SVG authoring whether the final composition needs separate visible units. Keep ordinary stable framing/background static and wrap each independently revealed or continuing Slide-local unit in a descriptive direct-root ``; structured atoms/slots retain their boundaries. Existing units or a page transition may suffice. The motion stage owns effects, pairing, order, and timing. - -**Hard rule — visible-layer timing**: Any crop, lens, scrim, comparison, evidence, or annotation layer required by an adopted motion plan MUST already exist in the final SVG without violating structural contracts. The later stage may regroup ordinary Slide-local content visual-equivalently, but cannot invent or modify missing visible content. If no legal existing unit can serve a non-binding suggestion, simplify it to available units, a page transition, or `none`; an explicit requirement that cannot be represented follows failure recovery. - -**Hard rule — narrow visual-inspection scope**: Start with §VIII `Reference` plus dimensions. If one asset still leaves focal-safe crop, overlay contrast, a quiet region, or its planned subject relationship ambiguous, inspect only that asset/review copy once for placement. A `Generated` asset qualifies only when final placement depends on an ambiguity that its owned intent and dimensions cannot resolve; never routinely read generated images. Inspection cannot reopen selection, change identity/must-use, infer provenance, substitute the asset, or invent focus. If `adaptive` focus stays uncertain, use `meet`; conflicting binding constraints return upstream. - -**Placeholder**: Dashed border `` + description text - -**Crop policy**: read the §VIII row and its lock projection (`source`, `crop`). On every slide that uses a `crop=no-crop` source (or a legacy trailing `| no-crop`), retain one visible complete instance using one of the nine legal anchors with `meet`, never `none`, and no `clip-path`, `mask`, clipping overflow, or nested `` crop viewport. An auxiliary same-slide detail or lens may crop the same source only while that complete instance remains visible. `crop=adaptive` permits but never requires cropping; choose `meet` or focal-safe `slice` from purpose, ratio, focus, and container. A missing or conflicting `source` / `crop` projection returns upstream instead of being inferred during execution; the §VIII `Layout pattern` remains a preferred expression that may be adopted, adapted, or declined. - -**Hard rule — same-source addressable crops, only when adopted**: A layout -suggestion, including pattern `#M1-11`, never activates this transport. Pattern -`#M1-09` is a separate deliberate-offset treatment and never claims registered -or Morph continuity. Apply this transport only when independent crops must -preserve one exact scene map or an explicit editable/Morph requirement needs -them. Once active, reuse one exact -`href` without slice assets. Give every independent/Morph object a stable -page-unique id and a distinct nested crop wrapper under -[`svg-effects.md`](./svg-effects.md) §6.5. Plain rectangles need no crop marker; -shaped frames put `data-pptx-crop="1"` on the wrapper and a matching -`userSpaceOnUse` clip on its inner ``, never the wrapper. Repeated crops -or SVG/PPT visual drift fail. Derive every wrapper `viewBox` from one shared -source-to-page transform over the union of the visible containers. Never run -`cover` / focal cropping independently per container: different container -positions and heights must change the source-unit `x`, `y`, `width`, and -`height` by the same union-relative mapping, so the gaps remove pixels without -rescaling the scene. A compound clip on one `` is pattern `#M1-10`, not a -substitute when the objects must remain independently editable or Morphable. +**Reference — motion-ready layering**: for an adopted §IX or explicit focus, comparison, evidence, reveal-order, or cross-page requirement, decide during authoring whether the composition needs separate visible units — stable framing stays static, each independently revealed or continuing Slide-local unit gets a descriptive direct-root ``, structured atoms and slots keep their boundaries; existing units or a page transition may suffice. The motion stage owns effects, pairing, order, and timing. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/executor-notes.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/executor-notes.md index a4dd5ee5..5ae652b3 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/executor-notes.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/executor-notes.md @@ -4,56 +4,35 @@ Conditional late-stage authority for generating or validating the complete speaker-notes document. -**Trigger**: Default Generate loads this after the final quality check when the -effective Speaker Notes outcome in `design_spec.md §I` is enabled. Quick -Generate loads it after its final check when the current agent selected notes -or narration in active context. A missing legacy outcome defaults to enabled. -Narration requires notes; when notes are disabled, do not load this branch or -create `notes/total.md`. +**Trigger**: Default loads this after the final quality check when the effective Speaker Notes outcome in `design_spec.md §I` is enabled (a missing legacy outcome defaults to enabled); Quick loads it after its final check when the agent selected notes or narration. Narration requires notes; with notes disabled, do not load this branch or create `notes/total.md`. ## 1. Complete Speaker-notes Document -Write the complete deck to `notes/total.md` in one batch for coherent transitions. Use `# _` per page and `---` between pages; only the heading is stripped before TTS. +Write the whole deck to `notes/total.md` in one batch: `# _` per page, `---` between pages; only the heading is stripped before TTS. `notes_to_audio.py` reads the body verbatim, so write prose only — no list/bullet markup, stage markers, key-point labels, duration lines, or other metadata. Keep one language; spell out digits or symbols when literal TTS would sound wrong (Chinese "百分之六十八" rather than "68%"). -**Pre-SVG narration branch**: when `notes/total.md` already exists because the -user supplied a final/literal script or Quick is directly delivering narrated -video, validate it instead of regenerating it. Retain every word and segment of -a final/literal script. Agent-authored Quick narration may be repaired only for -final-SVG inconsistency and before audio generation. A `# Slide ` -heading remains valid until Generate Step 7.1 resolves the authored roster. +**Pre-SVG narration branch**: when `notes/total.md` already exists from a final/literal script or Quick direct narrated video, validate it instead of regenerating. Retain every word and segment of a final/literal script; agent-authored Quick narration may be repaired only for final-SVG inconsistency and before audio. A `# Slide ` heading remains valid until Generate Step 7.1 resolves the roster. -**Pure spoken narration**: `notes_to_audio.py` reads the body verbatim. Write prose only; never add Markdown list/bullet markup, stage markers, key-point labels, duration lines, or other metadata. - -**Length follows content**: size natural sentences to semantic burden. Two to five is typical, not a cap; anchor pages may use less and dense pages more. Honor the active Design Spec or Quick context plus source rules. Duration is pacing guidance only: never pad, repeat, compress, or omit meaning to hit it. +**Length follows content**: size natural sentences to semantic burden — two to five is typical, not a cap; anchor pages may use less and dense pages more. Duration is pacing guidance only: never pad, repeat, compress, or omit meaning to hit it. ## 2. Final-SVG Grounding and Coverage -**Hard rule — the final SVG is the visible page authority**: read every finalized `svg_output/.svg` in slide order. Use the active plan/context and approved sources; never write from the outline or core message alone. +**Hard rule — the final SVG is the visible page authority**: read every finalized `svg_output/.svg` in slide order with the active plan/context and approved sources; never write from the outline or core message alone. -Before drafting, internally inventory the visible title/subtitle and every information-bearing direct-root ``; structured placeholder content still counts. Coverage requires its unique claim, evidence, example, relationship, qualifier, or implication—not merely its label—to enter the narration. +Before drafting, internally inventory the visible title/subtitle and every information-bearing direct-root `` (structured placeholder content counts). Coverage means its unique claim, evidence, example, relationship, qualifier, or implication — not merely its label — enters the narration. For a pre-SVG script, apply the inventory in reverse: every independent visible claim is supported by its script segment; repair the visual page or return to planning for final/literal input, repair the narration before audio for agent-authored Quick narration, and give every spoken idea needing orientation a visible state or explicit speech-only role. -For a pre-SVG narration branch, apply the same inventory in reverse: every -independent visible claim or relationship must be supported by its script -segment. Repair the visual page or return to planning for final/literal input; -for agent-authored Quick narration, repair the narration before audio without -inventing unsupported claims. Every spoken idea that requires orientation must -likewise have a visible state or an explicit speech-only role in the active plan. +- Text blocks, comparisons, and processes keep every independent fact or relationship; combine related short groups causally or comparatively. +- Charts, tables, and KPIs state the takeaway, decisive values or trend, comparison basis, implication, and material uncertainty — not every axis, row, or cell. +- Quotes keep the decisive clause, material attribution, and relevance. Explain semantic images or text-free diagrams only from the SVG plus plan/source; never infer facts from appearance. +- Speak a source or footer only when attribution, uncertainty, or qualification changes the argument. Omit backgrounds, decoration, chrome, page numbers, and fixed Master/Layout atoms. -- Text blocks, comparisons, and processes retain every independent fact or relationship; combine related short groups causally or comparatively. -- Charts, tables, and KPIs state the takeaway, decisive values or trend, comparison basis, implication, and material uncertainty—not every axis, row, or cell. -- Quotes retain the decisive clause, material attribution, and relevance. Explain semantic images or text-free diagrams only from the SVG plus locked plan/source; never infer facts from appearance. -- Speak a source or page-local footer only when attribution, uncertainty, or qualification changes the argument. Omit backgrounds, decoration, repeated chrome, page numbers, and fixed Master/Layout atoms. - -Form one coherent argument in intended reading/reveal order: proposition → evidence or mechanism → implication or bridge. DOM order need not be speaking order. A sentence may cover related groups and a complex group may need several sentences, but no independent group may disappear to meet a sentence count. Keep the inventory internal: never vocalize IDs, positions, colors, icons, repetitive "this card shows" descriptions, or coverage markers. +Form one coherent argument in intended reading/reveal order — proposition → evidence or mechanism → implication or bridge; DOM order need not be speaking order. A sentence may cover related groups and a complex group may need several sentences, but no independent group disappears to meet a count. Never vocalize IDs, positions, colors, icons, "this card shows" descriptions, or coverage markers. ## 3. Reading Mode and TTS | `consumption_mode` | Notes emphasis | |---|---| -| `text` | Interpret and connect a self-contained page; synthesize every independent SVG information group rather than omitting it. | -| `balanced` | Connect visible claim and evidence, explain the trade-off, and bridge forward. | -| `presentation` | Carry reasoning, context, and supporting detail intentionally omitted from the sparse page. | +| `text` | Interpret and connect a self-contained page; synthesize every independent information group rather than omitting it | +| `balanced` | Connect visible claim and evidence, explain the trade-off, bridge forward | +| `presentation` | Carry reasoning, context, and supporting detail intentionally omitted from the sparse page | -Put transitions naturally in the opening sentence when useful; never label them. Keep one language. Spell out digits or symbols when literal TTS would sound wrong (for example, Chinese "百分之六十八" rather than "68%"). - -After `notes/total.md` is complete, return to Generate Step 7.1 (Default) or `quick-generate.md` §4 (Quick); each route owns splitting and its success criterion. +Put transitions naturally in the opening sentence when useful; never label them. When `notes/total.md` is complete, return to Generate Step 7.1 (Default) or `quick-generate.md` §4 (Quick); each route owns splitting and its success criterion. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/executor-structure.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/executor-structure.md index 0bf901d2..5069735b 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/executor-structure.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/executor-structure.md @@ -2,60 +2,34 @@ # Executor Shape Composition Grammar -Runtime grammar for Slide-local qualitative relationships built from editable shapes; it is not a diagram/template catalog. +Runtime grammar for Slide-local qualitative relationships built from editable shapes; not a diagram catalog. Default and Quick read it once at the first page whose Structure decision is `yes` and reuse it for every later page; loading it selects no `Structure=yes` and creates no geometry quota. -**Load**: Default and Quick read this grammar once with their fixed construction -bundle before all SVG authoring and reuse it for every per-page decision. Loading -the grammar does not select `Structure=yes` or create a geometry quota. +**Hard rule — no Structure catalog**: never recall or resolve `structure/`; compose from authoritative content, §IX relationships, the communication move, and the active visual system. -**Hard rule — no Structure catalog**: never recall or resolve `structure/`. Compose from authoritative content, §IX relationships, the communication move, and the active visual system. +**Hard rule — not structured PPTX**: this branch owns Slide-local geometry. [`executor-structured.md`](./executor-structured.md) independently owns reusable Master/Layout/placeholders under `pptx_structure.mode: structured`. -**Hard rule — not structured PPTX**: this branch owns Slide-local geometry. [`executor-structured.md`](./executor-structured.md) independently owns reusable Master/Layout/placeholders under `pptx_structure.mode: structured`; neither implies the other. +Numbers used only as labels do not create a chart; value-derived position, length, angle, area, radius, width, or color routes to [`executor-chart.md`](./executor-chart.md), row-header × column-header facts to [`executor-table.md`](./executor-table.md). Qualitative lanes use this grammar; date/duration-driven task-bar `x` / `width` is Gantt geometry. --- ## 1. Relationship Atoms -**Mandatory — relationship → topology before contour**: For each active atom, -resolve only the path, junctions, enclosure, field partition, shared region, -scale change, and entry / endpoint that carry meaning. Adapt that topology to -the actual units, text load, page role, and active visual system before -selecting contours. +**Mandatory — relationship → topology before contour**: for each active atom resolve only the path, junctions, enclosure, field partition, shared region, scale change, and entry/endpoint that carry meaning, adapted to the actual units, text load, page role, and visual system, before selecting contours. | Atom | Meaning | Encode with | Generate topology from | |---|---|---|---| -| `order` | Sequence, progression, or rank | Position, numbering, direction, shared path | One reading path: open / closed; straight / bent / stepped / switchback / coiled; level / rising / falling; constant / expanding / contracting; turns, milestones, endpoint | -| `link` | Dependency, exchange, influence, transition | Proximity / alignment when unmistakable; otherwise an edge | Sources, targets, and junctions: direct, hub, chain, split, merge, exchange, or feedback; let the relationship determine the fewest necessary edges | -| `parent` | One unit governs or decomposes into children | Branching, indentation, nesting, scale | Root, depth, and sibling groups: branch, indent, nest, radiate, or scale; let child roles set fan-out and weight | -| `membership` | Units belong to a group, stage, lane, or region | Containment, shared field, band, repetition | Owning fields: enclose, band, lane, cluster, repeat, or nest; let content set field shape and occupancy | -| `contrast` | Peers, states, options, or positions compare | Shared baseline, opposing regions, parallel framing | Shared invariants plus separation: one or more semantic axes / baselines, opposing or parallel fields, counterweight, divergence, or a before / after boundary | -| `overlap` | Units share a meaningful subset or duty | Intersecting regions plus a clear common area | Exact exclusive / shared regions: paired, chained, or layered intersections; keep every owner and common area legible | +| `order` | Sequence, progression, rank | Position, numbering, direction, shared path | One reading path: open / closed; straight / bent / stepped / switchback / coiled; level / rising / falling; constant / expanding / contracting; turns, milestones, endpoint | +| `link` | Dependency, exchange, influence, transition | Proximity / alignment when unmistakable; otherwise an edge | Sources, targets, junctions: direct, hub, chain, split, merge, exchange, feedback; the fewest necessary edges | +| `parent` | One unit governs or decomposes into children | Branching, indentation, nesting, scale | Root, depth, sibling groups: branch, indent, nest, radiate, scale; child roles set fan-out and weight | +| `membership` | Units belong to a group, stage, lane, region | Containment, shared field, band, repetition | Owning fields: enclose, band, lane, cluster, repeat, nest; content sets field shape and occupancy | +| `contrast` | Peers, states, options, positions compare | Shared baseline, opposing regions, parallel framing | Shared invariants plus separation: semantic axes / baselines, opposing or parallel fields, counterweight, divergence, before / after boundary | +| `overlap` | Units share a subset or duty | Intersecting regions plus a clear common area | Exact exclusive / shared regions: paired, chained, layered intersections; every owner and common area legible | -**Reference — not a constraint**: `Generate topology from` names common -transform axes rather than an exhaustive set. Combine, deform, or invent -page-fit topologies from the active atoms; never recall a named diagram or -reproduce a listed form by default. +The last column names common transform axes, not an exhaustive set: combine, deform, or invent page-fit topologies; never recall a named diagram or reproduce a listed form by default. -**Mandatory — combined-atom spatial relation before contour**: Combine atoms as -needed; never force a named business model. When multiple atoms share one -construct, resolve whether their topologies share a field, nest, run in -parallel, cross orthogonally, or intersect. Orthogonal overlay applies when -independent dimensions occupy one field, including but not limited to an -`order` path across `membership` lanes and two independent `contrast` -dimensions; preserve each atom's ownership and reading direction. The overlay -never implies equal partitions. +**Mandatory — combined-atom spatial relation before contour**: when several atoms share one construct, resolve whether their topologies share a field, nest, run in parallel, cross orthogonally, or intersect. Orthogonal overlay applies when independent dimensions occupy one field (an `order` path across `membership` lanes, two independent `contrast` dimensions); preserve each atom's ownership and reading direction. Never force a named business model; the overlay never implies equal partitions. -**Hard rule — no topology from balance alone**: Node count and text fit may -change spacing, route, or wrap. They never justify equal shapes, gaps, or -partitions, mirroring, radial symmetry, or closure that invents peer weight, -centrality, reciprocity, or recurrence. - -Numbers used only as labels do not create a chart. Value-derived position, -length, angle, area, radius, width, or color routes to -[`executor-chart.md`](./executor-chart.md); row-header × column-header facts -route to [`executor-table.md`](./executor-table.md). Qualitative lanes use this -grammar, but date / duration-driven task-bar `x` / `width` is Gantt Chart -geometry. +**Hard rule — no topology from balance alone**: node count and text fit may change spacing, route, or wrap. They never justify equal shapes, gaps, or partitions, mirroring, radial symmetry, or closure that invents peer weight, centrality, reciprocity, or recurrence. --- @@ -67,50 +41,37 @@ geometry. | `node` | Semantic unit, state, actor, item, or group; may punctuate a drawn carrier as a stop, turn, junction, or bridge | | `spine` | Explicit/implied scaffold or continuous carrier establishing reading direction | | `edge` | Necessary semantic connection, branch, dependency, or transition | -| `label` | Text/evidence attached directly or by a non-relational leader/tether to a node, edge, region, or relationship | +| `label` | Text/evidence attached directly or by a non-relational leader/tether to its owner | | `garnish` | Non-semantic accent added after the relationship works | | Operation | Job | |---|---| -| `repeat` | Create peers from one visual family; clone the full contour only when their structural states match | -| `arrange` | Establish order, alignment, rhythm, rank, comparison | +| `repeat` | Peers from one visual family; clone the full contour only when structural states match | +| `arrange` | Order, alignment, rhythm, rank, comparison | | `transform` | Vary scale, rotation, crop, fill, emphasis, or entry/continuation/turn/terminal port state meaningfully | | `connect` | Add an edge when layout/containment is insufficient | | `region` | Partition, contain, intersect, band, or layer fields | | `attach` | Bind labels, badges, annotations, or evidence to an owner | -**Hard rule — realization enters the construction gate**: Decide whether each -role is implicit/direct content or drawn geometry. Every drawn field, spine, -node carrier, or edge follows [`native-shape-authoring.md`](./native-shape-authoring.md) -§§1–2.1: contour before encoding → simplest exact native form → independent -compound → required Boolean → necessary freeform. Text styling cannot replace -required geometry; implicit/direct roles need no container. Decoration cannot -invent a relationship. +**Hard rule — realization enters the construction gate**: decide whether each role is implicit/direct content or drawn geometry. Every drawn field, spine, node carrier, or edge follows [`native-shape-authoring.md`](./native-shape-authoring.md) §§1–2.1: contour before encoding → simplest exact native form → independent compound → required Boolean → necessary freeform. Text styling cannot replace required geometry; implicit/direct roles need no container; decoration cannot invent a relationship. --- ## 3. Construction Order -Choose the field and map required atoms, then follow: - -**Mandatory — spine/topology → nodes → connectors → labels → garnish**: +**Mandatory — spine/topology → nodes → connectors → labels → garnish**, after choosing the field and mapping required atoms: | Layer | Completion evidence | |---|---| | `spine` | Entry, direction, and organizing path are clear; reversal, cycle, split/merge, or stage change reshapes a continuous carrier before node placement | -| `nodes` | Every required unit has one home and intentional weight; each is direct content or a §2-approved carrier; carrier-crossing nodes intentionally continue, stop, turn, join, or bridge its visible path | -| `connectors` (`edge`) | Only unresolved semantic links become edges; route/source/target is clear; every drawn edge passes §2 | -| `labels` | Copy and caveats visibly attach directly or by leader/tether to what they explain; when a node has multiple text roles, cue → claim/value → support → note remains perceptibly descending and absent roles stay absent | +| `nodes` | Every unit has one home and intentional weight as direct content or a §2-approved carrier; carrier-crossing nodes intentionally continue, stop, turn, join, or bridge its path | +| `connectors` | Only unresolved semantic links become edges; route/source/target is clear | +| `labels` | Copy and caveats visibly attach to what they explain; with several text roles on a node, cue → claim/value → support → note stays perceptibly descending and absent roles stay absent | | `garnish` | Removing accents leaves all meaning intact | **Hard rule — relationship before styling**: establish atoms, field, spine, nodes, and necessary edges before palette, type, effects, or containers. Containment, alignment, baselines, and proximity express relationships without edges; lines/Connectors express real edges. -**Structural carriers**: a relationship-bearing field, spine, node carrier, or -directional shape can be the page-scale move; Structure `yes` by itself adds no -geometry. When drawn roles interact, resolve relationship-bearing -parent contour/direction → contact → joint or intentional void → -z-order/occlusion → canvas-edge behavior before labels/garnish. Skip -inapplicable operations; implicit/direct roles remain container-free. +**Structural carriers**: a relationship-bearing field, spine, node carrier, or directional shape can be the page-scale move; Structure `yes` by itself adds no geometry. When drawn roles interact, resolve parent contour/direction → contact → joint or intentional void → z-order/occlusion → canvas-edge behavior before labels/garnish; skip inapplicable operations. --- @@ -118,13 +79,13 @@ inapplicable operations; implicit/direct roles remain container-free. | Check | Pass condition | |---|---| -| Coverage | Every authoritative atom is visible; none was invented | -| Reading path | Entry, progression, hierarchy, and endpoint are unambiguous | +| Coverage | Every authoritative atom is visible; none invented | +| Reading path | Entry, progression, hierarchy, and endpoint unambiguous | | Roles | Nodes/edges have one duty; garnish carries no meaning | | Attachment | Labels/evidence belong to the correct node, edge, or region | | Removal | Without color/effects/icons/garnish, placement still communicates | | Fidelity | All required units, qualifiers, values, and caveats remain | -| Construction | Drawn roles pass §2; implicit/direct roles need no carrier; freeform follows failed exact-native/independent-compound/Boolean routes | -| Composition | Every used contact, void, overlap, cutout, occlusion, or canvas-edge crossing maps to an atom/role or remains removable garnish; none obscures ownership or reading path | +| Construction | Drawn roles pass §2; implicit/direct roles need no carrier; freeform follows failed exact-native/compound/Boolean routes | +| Composition | Every contact, void, overlap, cutout, occlusion, or canvas-edge crossing maps to an atom/role or stays removable garnish | -Load Chart/Table branches independently for embedded objects. Keep one dominant reading path while allowing secondary atoms whose ownership stays clear. +Load Chart/Table branches independently for embedded objects. Keep one dominant reading path while secondary atoms keep clear ownership. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/executor-structured.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/executor-structured.md index 2152f144..b3dacfb2 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/executor-structured.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/executor-structured.md @@ -4,9 +4,9 @@ Conditional Executor authority for `template_reuse_scope: mirror|layout` with `pptx_structure.mode: structured`. -**Trigger**: load only when the lock selects structured template reuse. +**Trigger**: the lock selects structured template reuse. -**Hard rule — package structure, not information structure**: this branch owns reusable PowerPoint Master/Layout atoms, placeholders, slots, and prototype topology. [`executor-structure.md`](./executor-structure.md) independently owns Slide-local qualitative shape composition. Neither one activates or implies the other. +**Hard rule — package structure, not information structure**: this branch owns reusable Master/Layout atoms, placeholders, slots, and prototype topology; [`executor-structure.md`](./executor-structure.md) independently owns Slide-local qualitative composition, and neither implies the other. ## 1. Template Reuse Rules @@ -14,140 +14,61 @@ Conditional Executor authority for `template_reuse_scope: mirror|layout` with `p | Context | Load policy | |---|---| -| `templates/design_spec.md` | Reuse it in a valid active context; after context invalidation, read it once with the project planning artifacts | -| Current page mapping | Read the retained `spec_lock.md page_layouts` row; a page change does not require another file load | -| Selected prototype SVG | Read the complete `templates/.svg` once per valid context and reuse it until a known change or context invalidation | +| `templates/design_spec.md` | Reuse in a valid context; after invalidation read it once with the planning artifacts | +| Current page mapping | The retained `spec_lock.md page_layouts` row; a page change needs no file load | +| Selected prototype SVG | Read the complete `templates/.svg` once per valid context and reuse it until a known change | -**Hard rule**: The complete Slide prototype SVG is authoritative and already resolves its Master + Layout context. Standalone Master/Layout definition SVGs are invalid. An on-demand page-context result may fingerprint the selected Slide prototype but carries no payload; never author from a roster, manifest, sidecar, filename, or summary alone. +**Hard rule**: the complete Slide prototype SVG is authoritative and already resolves its Master + Layout; standalone Master/Layout definition SVGs are invalid; never author from a roster, manifest, sidecar, filename, or summary (manifest/text-slot files are tool metadata whose absence neither invalidates a legacy workspace nor permits text-topology changes). Resolve each page's prototype directly from its `page_layouts` row — `mirror` → §1.1 (the workspace must support `replication_mode: mirror`); `layout` → resolve `P: `, retain the structure system, apply the re-skin/reflow rules below; a missing row stops (adaptive mode still needs one selected input prototype, and there is no filename/page-type fallback). A mapping change stops and returns to Strategist to update the plan, read back and validate, then load the new prototype. -Manifest/text-slot files are derived tool metadata, not model inputs. Missing metadata neither invalidates a legacy workspace nor permits text-topology changes. +**Default — re-skin `layout` (may override when the application plan keeps template visuals and the lock reflects them)**: inherit geometry, label/legend placement, and series encoding; repaint gradients, shadows, fills, and strokes from the current style/lock. `mirror` preserves visuals under §1.1. -**Mapping change**: stop and return to Strategist to update the owning plan, read back and validate the affected planning fragments, then load the new prototype before resuming. - -Resolve the per-page template SVG directly from the owning `spec_lock.md page_layouts` row. There is no filename/page-type fallback. - -**Resolution order (per page):** - -1. `template_reuse_scope: mirror` → see §1.1. The installed workspace must support `replication_mode: mirror`. -2. `template_reuse_scope: layout` → resolve `P: ` from `page_layouts`, retain the structure system, and apply the non-mirror skin/reflow rules below. -3. `mirror` / `layout` with no current-page `page_layouts` row → stop; adaptive mode still requires one selected input prototype. - -> Note: `page_layouts` disambiguates the multiple content variants a template may ship; missing mappings are contract errors. - -**Default — re-skin `layout` (may override when the application plan keeps template visuals and the lock reflects them)**: inherit geometry, label/legend placement, and series encoding; otherwise repaint template gradients, shadows, fills, and strokes from the current style/lock. Template font sizes remain placeholders. `mirror` preserves visuals under §1.1. - -**Font size is skin, not geometry (non-mirror).** A chart / layout template's hardcoded `font-size` values (often 11–16px, sized for the template's own dense placeholder text) are NOT inherited. Structural text and reusable slots start from their `spec_lock.md` role and stay within anchor `±2`px; only a qualifying Slide-local Hero/Display element follows the sparse exception in `executor-base.md`. Template placeholder px supplies neither a role anchor nor a sparse display value. - -**Typography execution order (mandatory):** - -1. Build a per-page text inventory from `design_spec.md §IX` + the current `notes/_*.md`. -2. Classify each text item before drawing. **Structural roles and reusable feature slots** (`title`, `subtitle` / `lead`, `body`, `annotation`, `footnote` / `page_number`, reusable hero or emphasis slots) map to a declared `spec_lock.typography` size role. A missing semantic role returns upstream; do not borrow an unrelated size because it is numerically close. Only a Slide-local, non-slot Hero/Display element may use the sparse-size exception in [`executor-base.md`](./executor-base.md); reusable Layout slots never do. -3. For every mapped role or reusable slot, choose the role anchor or one contextual value within anchor `±2`px before placing the text. A qualifying Slide-local sparse display follows `executor-base.md` directly. Never start from a template `font-size` and then adjust it. -4. Layout from those chosen sizes: compute line-height, wrapped line count, child `y` / `dy`, card padding, card height, column gaps, and available image/chart area. -5. Reflow containers and local geometry together with the bounded role treatment; an inherited template slot never justifies leaving the declared band. - -**Geometry and bounded type co-adapt**: widen or heighten the card, open spacing, recompute child `y` / `dy`, and choose within the mapped role's anchor `±2`px instead of inheriting the template's compact size. Page count and density remain the confirmed Strategist decision: do not repaginate, split, or drop content. If structural text or a reusable slot still needs a value outside the band, return upstream under [`executor-base.md`](./executor-base.md) §2.1; only qualifying Slide-local display text uses its sparse exception. Mirror instead preserves source typography under §1.1. +**Hard rule — font size is skin, not geometry (non-mirror)**: a template's hardcoded `font-size` values are never inherited. Build a per-page text inventory from §IX and the current notes; map every structural role and reusable slot (`title`, `subtitle` / `lead`, `body`, `annotation`, `footnote` / `page_number`, reusable hero or emphasis slots) to a declared `spec_lock.typography` role — a missing role returns upstream, never a numerically close one; choose the anchor or one value within `±2` px before placing text (only a Slide-local, non-slot Hero/Display element may use `executor-base.md`'s sparse exception; reusable slots never do); lay out from those sizes — line height, wrapped lines, child `y` / `dy`, card padding and height, column gaps, image/chart area — and reflow containers and local geometry with the bounded type rather than starting from a template size. Do not repaginate, split, or drop content; a value still outside the band returns upstream under `executor-base.md` §2.1. ### 1.1 Mirror reuse — literal page replacement -When `spec_lock.md` records the AI-derived `template_reuse_scope: mirror`, Executor switches to a literal replacement path. The workspace capability `replication_mode: mirror` is a prerequisite, not the trigger by itself: +When the lock records `template_reuse_scope: mirror` (the workspace's `replication_mode: mirror` is a prerequisite, never the trigger, and never forces mirror when the lock says `layout` or `style`): -1. **Per-page reference selection** — Strategist selects one mirror page per project page via `spec_lock.md page_layouts` (e.g., `P04: 015_content`). The basename is the mirror filename without extension; Strategist made this choice by reading `design_spec.md §V Page Roster` descriptions, not by guessing. -2. **Copy, don't fill** — use the retained full mirror SVG as the starting point, then edit slide-specific text in place. Preserve every ordinary non-text element and every `data-pptx-*` structure attribute verbatim. The sole exception is a direct JSON-first Chart/Table: keep its marker id/kind/authority and metadata unchanged, while derived preview children may be regenerated from that JSON. Do not reopen the same path + SHA merely because another page selects it. -3. **What you may edit** — decide the semantic slot mapping and replacement text only. Change only visible string values already carried by `` and `` nodes that express slide-specific content (title, body, captions, KPI labels, dates, page numbers). Keep the number, order, nesting relationship, and **all attributes** of every `` / `` node unchanged. Never merge or split nodes, move a string between nodes, add a new tspan, or delete an empty carrier. `svg_quality_checker.py` and export validate attributes, topology, and prototype hashes against the complete prototype internally. -4. **What you must not touch** — element positions, sizes, fonts, colors, fills, strokes, gradients, **which image each ordinary `` points at**, `` grouping, sprite-sheet `` wrappers, decoration, `` markers, or authoritative embedded Chart/Table JSON. JSON-first preview images/shapes are derived and excluded from this literal identity rule. **The `href` path is not the image**: normalize a bare `href="cover_bg.png"` to the exact `href="../images/"` when Step 3 relocates those same bytes to `images/`; this required transport rewrite changes nothing visual. Do not leave the bare href or point back into the source template. -5. **Content fit** — if the replacement needs a different number of text segments/items, do not merge/split nodes, drop sourced content, or restructure the grid. Report `warning: P content does not fit mirror reference ; choose another prototype or change template_reuse_scope to layout/style`, then return to Strategist to select the prototype or scope and update the planning mappings. -6. **Visible text editing** — mirror SVGs may keep literal source text rather than `{{...}}` authoring markers. Edit values in place while retaining imported semantic `data-pptx-placeholder` identity and exact text topology. -7. **Output filename** — follow the standard project SVG naming convention (`_.svg` where `` matches the project page index, not the mirror source index). The mirror filename is the *reference*, not the *output*. +1. **Per-page reference**: Strategist selected one mirror page per project page in `page_layouts` (`P04: 015_content`) from `design_spec.md §V` descriptions. +2. **Copy, don't fill**: start from the retained full mirror SVG and edit slide-specific text in place, preserving every ordinary non-text element and every `data-pptx-*` structure attribute verbatim; the sole exception is a JSON-first Chart/Table whose marker id/kind/authority and metadata stay while its derived preview may regenerate from that JSON. Do not reopen the same path + SHA because another page selects it. +3. **Editable**: the semantic slot mapping and visible string values already carried by `` / `` nodes (title, body, captions, KPI labels, dates, page numbers). Keep the number, order, nesting, and all attributes of every text node; never merge, split, move a string between nodes, add a tspan, or delete an empty carrier — checker and export validate topology and prototype hashes. +4. **Untouchable**: positions, sizes, fonts, colors, fills, strokes, gradients, which image each ordinary `` points at, grouping, sprite-sheet `` wrappers, decoration, `` markers, authoritative Chart/Table JSON. The `href` path is not the image: normalize a bare `href="cover_bg.png"` to the exact `href="../images/"` after Step 3 relocates the bytes — a transport rewrite, not a visual edit. +5. **Content fit**: when the replacement needs a different number of segments or items, do not merge, split, drop, or restructure — report `warning: P content does not fit mirror reference ; choose another prototype or change template_reuse_scope to layout/style` and return to Strategist. +6. **Visible text**: mirror SVGs may carry literal source text rather than `{{...}}` markers; edit in place, retaining imported `data-pptx-placeholder` identity and exact topology. +7. **Output filename**: standard `_.svg` with the project page index; the mirror filename is the reference, not the output. -**Detecting mirror mode**: read `template_reuse_scope` from the retained lock. `replication_mode: mirror` in the installed template only determines whether that scope is legal; it must never force mirror behavior when the lock records `layout` or `style`. +Chart, Table, and qualitative topology inside a mirror SVG are already authored: replace only permitted text and never redraw from a catalog or grammar; a JSON-first object may refresh its approximate preview from unchanged JSON without metadata, bounds, marker, slot, or visual drift; a mirror template normally omits `page_visualizations`, and legacy `page_charts` never overrides fidelity. **Legacy template boundary**: a template with missing root Master identity, direct atomic placeholders, `data-pptx-layout-kind`, unmapped `baseline`, `preserve`, or `layout_strategy: distill` is never a fallback input — stop and create a new workspace through [`create-template`](../workflows/create-template.md). -**Mirror + visualization pages**: Chart, Table, and qualitative topology inside a mirror SVG are already authored. Replace only permitted text and do not redraw from a catalog/runtime grammar. A JSON-first Chart/Table may refresh its approximate preview from unchanged authoritative JSON; this never permits metadata, bounds, marker, slot, or ordinary-visual drift. A mirror template normally omits `page_visualizations`, and legacy `page_charts` never overrides fidelity. - -**Legacy template boundary**: A template with missing root Master identity, direct atomic placeholders, `data-pptx-layout-kind`, unmapped `baseline`, `preserve`, or `layout_strategy: distill` is not a fallback input. Stop and create a new current workspace through [`create-template`](../workflows/create-template.md) before generation. - -### Page-Template Mapping Declaration (Required Output) - -Before generating each page, output which template is used: +**Required output before each page**: ``` 📝 **Template mapping**: `templates/03a_content_image_text.svg` (free-design routes may use "None") 🎯 **Adherence rules / application plan**: [specific description] ``` -- **Content pages**: template defines only header/footer; content area is free -- **No template**: allowed only on free-design or brand-only routes +Content pages: the template defines only header/footer and the content area is free. No template is allowed only on free-design or brand-only routes. ### 1.2 PowerPoint Master / Layout Mapping -This section applies only when a deck/layout template's AI-derived lock records `template_reuse_scope: mirror|layout`. `page_layouts` selects the input SVG prototype, `pptx_masters` / `pptx_layouts` declare unique reusable output definitions, and `page_pptx_layouts` assigns every generated page before the first page is drawn. `template_reuse_scope: style`, free-design, and brand-only routes use `pptx_structure.mode: flat`, omit all four sections, skip the rest of §1.2, and keep every SVG object Slide-local. +Applies only when the lock records `template_reuse_scope: mirror|layout`: `page_layouts` selects the input prototype, `pptx_masters` / `pptx_layouts` declare unique reusable output definitions, and `page_pptx_layouts` assigns every page before the first is drawn. `style`, free-design, and brand-only routes use `mode: flat`, omit all four sections, and keep every object Slide-local. -**Hard rule — reuse-scope route**: `template_reuse_scope: mirror|layout` requires `pptx_structure.mode: structured`. `template_reuse_scope: style` requires `mode: flat` even though a template supplied its visual vocabulary. Missing mode or legacy values (`baseline`, `template`, `preserve`), `layout_strategy`, Layout-kind fields, partial mappings, and old direct placeholders stop generation. Create a new template workspace through [`create-template`](../workflows/create-template.md); do not upgrade the active SVG project in place. - -**Hard rule — root identity**: A `page_pptx_layouts` row binds the page to one key in `pptx_layouts`; that unique definition supplies its Master key, Layout picker name, and prototype source. Put the declared Master key/name and Layout key/name on the root SVG. A Layout key belongs to exactly one Master and remains globally unique. - -**Hard rule — atomic fixed layers**: Every `data-pptx-layer="master|layout"` visual is one direct root semantic atom that compiles to one DrawingML object. An ordinary marked `` is forbidden; one validated compact authored-preset `` emitted by `preset_shape_svg.py` is the sole group exception because it compiles to one native shape. When reconstructing source PPTX groups, recursively push supported transforms, paint, opacity, and z-order into atomic children. Repeat the identical ordered Master atom contract on every page using that Master and the identical ordered Layout atom contract on every page sharing that `(master, layout)` pair. - -**Hard rule — PowerPoint paint order**: Direct children appear in this order: Master background atoms, Layout background atoms, optional Slide background, remaining Master atoms, remaining Layout atoms, then slot groups and Slide-local content groups. Backgrounds are the inheritance plane beneath all shapes. - -**Mandatory — slot authoring**: A reusable content slot is one direct root `` carrying `data-pptx-placeholder` and one positive `data-pptx-bounds`; the same design zone is both the reusable Layout default and the slot module boundary. A normal slot contains exactly one compatible direct drawable child marked `data-pptx-carrier="true"`. Export unwraps that child into the real Slide placeholder binding. Decorations do not belong in the slot; move reusable decoration to a root Layout atom and keep page-specific labels/captions in another bounded slot or Slide-local group. - -**Mandatory — slot identity**: Preserve imported `data-pptx-idx` values where available; otherwise omit the title index and assign unique indices only where repeated roles need disambiguation. Pages sharing one Layout key repeat the same slot ids/types/effective indices/default bounds/binding modes. Current text, crop, and Slide-local carrier geometry may differ. - -**Composite proxy fallback**: A genuinely composite region may use a direct `` with positive bounds. Its visible group remains Slide-local and export creates one hidden transparent matching placeholder proxy. This downgrade is valid only for `object`; do not use it for an ordinary title, body, picture, chart, table, or media slot. - -**Forbidden — dummy carriers**: Never satisfy a carrier slot with tiny text, near-transparent glyphs, background-colored punctuation, or other fake content. Leave an intentionally blank text carrier empty/whitespace-only—the exporter emits a legal invisible U+200B run—or use the composite `object` proxy contract. If `strict` prototype binding cannot represent the completed composition, surface the mismatch; select a compatible prototype or create an explicit adaptive Layout instead of hiding the conflict. - -**Zero-slot Layout**: A Layout may have no slot groups. Covers, posters, and fixed visual pages still declare their named Master/Layout and fixed atoms. Do not manufacture a full-page `object` slot or empty `utility` identity. - -**Mandatory — per-page slot coverage**: On every mapped page, declare a slot for each standard role the page actually has: the page heading as `title`, a cover tagline as `subtitle`, the page number as `slide-number`, running footer text as `footer`, a hero / content image as `picture`, and a body block already authored as one merged text frame as `body`. A page shipping zero slots exports a Layout with no insertable placeholders — valid only for a genuinely fixed composition (see Zero-slot Layout above), never as the deck-wide default. Pages sharing one layout key ship the same slot set. - -**Hard rule — variable slot content**: “Per-page headings never stay Slide-local by default” means authoring them as `title` / `subtitle` slots; it never permits page-varying text or images to become fixed Layout atoms. Any such value that varies across pages sharing one Layout key MUST be carried by a slot or remain Slide-local. - -**Mandatory — master/layout layer coverage**: On every mapped page, mark the deck-wide background and every-page chrome (footer bar, running logo) `data-pptx-layer="master"`, and mark the static framing that defines this layout key's composition (header rule, divider band, zone panels — including chrome repeated on every content page but absent from the cover) `data-pptx-layer="layout"`. A mapped page with zero `data-pptx-layer` marks exports a bare Master and an empty Layout — the layer marks, not the slide content, give each Layout its visible design. - -**Layout identity**: Different keys differ in fixed Layout atoms or slot topology/default bounds/binding modes. Identical contracts should share one key. Current wording, imagery, crop, and Slide-local geometry never define identity. - -**Template adherence**: Strict preserves reusable Master/Layout atoms and slot ids/types/indices/default bounds/bindings. Under `layout`, the application plan may still change current text/tspans, line height, crop, and carrier-local geometry inside those bounds; `mirror` remains topology-frozen. Adaptive keeps the prototype Master and realizes only the Layout definition and page assignment already declared in `spec_lock.md`. If reusable atoms or slot topology/default bounds/bindings must change, stop before completing the page and return to Strategist to declare a new Layout key/name, update its definition and affected assignments, then read back and validate those planning fragments before resuming. Changing only content is not a new Layout. - -**Layout-content boundary**: Mark only genuinely reusable fixed framing as a Master/Layout atom. Concrete titles, body copy, metrics, chart marks, images, and page-specific groups remain inside slot groups or ordinary Slide-local content groups. The exporter never infers or clusters structure. - -**Background ownership**: - -| Scope | SVG authoring | -|---|---| -| Deck-wide default | Direct full-canvas solid `` repeated identically on every page | -| Page-type default | Direct full-canvas solid `` repeated on every page sharing that layout key | -| One-page exception | Direct full-canvas solid `` | - -The exporter writes these solid fills as real Master/Layout/Slide `p:bg`, not selectable full-canvas shapes. In structured mode, gradients, preset patterns, images, textures, and overlay panels remain explicit shapes or pictures; the generic background-promotion rule outside structured mode does not expand this ownership contract. +- **Hard rule — reuse-scope route**: `mirror|layout` requires `mode: structured`; `style` requires `flat` even with a template vocabulary. A missing mode, legacy values (`baseline`, `template`, `preserve`), `layout_strategy`, Layout-kind fields, partial mappings, or old direct placeholders stop generation — create a new workspace, never upgrade in place. +- **Hard rule — root identity**: a `page_pptx_layouts` row binds the page to one `pptx_layouts` key, which supplies its Master key, Layout picker name, and prototype source; write the Master key/name and Layout key/name on the root ``. A Layout key belongs to one Master and is globally unique. +- **Hard rule — atomic fixed layers**: every `data-pptx-layer="master|layout"` visual is one direct root atom compiling to one DrawingML object; an ordinary marked `` is forbidden, and one validated compact `preset_shape_svg.py` `` is the sole exception. Push supported transforms, paint, opacity, and z-order of source groups into atomic children. Repeat the identical ordered Master atom contract on every page of that Master and the identical Layout atom contract on every page sharing `(master, layout)`. +- **Hard rule — paint order**: Master background atoms, Layout background atoms, optional Slide background, remaining Master atoms, remaining Layout atoms, then slot groups and Slide-local groups. +- **Mandatory — slots**: a reusable slot is one direct root `` with `data-pptx-placeholder` and one positive `data-pptx-bounds` (the reusable Layout default and the module boundary at once) containing exactly one compatible direct drawable child marked `data-pptx-carrier="true"`, which export unwraps into the real placeholder; decoration goes to a root Layout atom, page-specific labels to another slot or Slide-local group. Preserve imported `data-pptx-idx`; otherwise omit the title index and assign unique indices only where repeated roles need them; pages sharing a Layout key repeat the same slot ids, types, indices, default bounds, and binding modes while current text, crop, and carrier geometry may differ. A genuinely composite region may use `` with positive bounds (Slide-local visuals plus one hidden transparent proxy) — `object` only. **Forbidden — dummy carriers**: never tiny text, near-transparent glyphs, or background-colored punctuation; leave a blank text carrier empty (export emits an invisible U+200B run) or use the proxy; surface a `strict` mismatch instead of hiding it. +- **Zero-slot Layout**: covers, posters, and fixed visual pages still declare Master/Layout and fixed atoms without manufacturing a full-page `object` slot or `utility` identity. +- **Mandatory — per-page slot coverage**: declare a slot for each standard role the page actually has — heading `title`, cover tagline `subtitle`, page number `slide-number`, running footer `footer`, hero/content image `picture`, one merged body frame `body`; zero slots is valid only for a genuinely fixed composition, never as the default; pages sharing a key ship the same slot set. **Hard rule — variable content**: page-varying text or images are carried by a slot or stay Slide-local, never become fixed Layout atoms. +- **Mandatory — layer coverage**: mark the deck-wide background and every-page chrome (footer bar, running logo) `master`, and the static framing that defines this key's composition (header rule, divider band, zone panels, chrome repeated on content pages but absent from the cover) `layout`; a page with zero marks exports a bare Master and empty Layout. +- **Layout identity and adherence**: keys differ in fixed atoms or slot topology/default bounds/binding modes, never in wording, imagery, crop, or Slide-local geometry; identical contracts share one key. Strict preserves atoms and slot ids/types/indices/bounds/bindings (`layout` may still change current text/tspans, line height, crop, and carrier-local geometry inside those bounds; `mirror` is topology-frozen); adaptive keeps the prototype Master and realizes only the Layout definition and assignment already declared in the lock. A needed change to atoms or slot topology stops the page and returns to Strategist to declare a new key, update definition and assignments, and validate; content alone is never a new Layout. Mark only genuinely reusable fixed framing as an atom — titles, body, metrics, chart marks, images, and page-specific groups stay in slots or Slide-local groups; the exporter never infers structure. +- **Background ownership**: deck-wide default = a direct full-canvas solid `` identical on every page; page-type default = `data-pptx-layer="layout"` on every page sharing the key; one-page exception = `data-pptx-layer="slide"`. These export as real `p:bg`; gradients, patterns, images, textures, and overlay panels stay explicit shapes or pictures, and the flat-mode background promotion rule does not apply. --- ## 2. Per-page Structured Lookup -**Per-page template lookup — `page_layouts` section (`mirror` / `layout` only)**: +**`page_layouts` (`mirror` / `layout` only)**: before drawing, take the page's row (`P04: 03a_content_image_text`) and resolve the complete SVG in the selected template directory (§1.0 decides whether to read or reuse it; a `reference_set` fingerprint may diagnose an uncertain path but is not required). The basename must match a real file — otherwise stop and report the invalid mapping; neither strict nor adaptive falls back to free design. A missing row, or a missing section under `mirror|layout`, stops with an upstream contract error; under `style` the section must be absent. Never invent an entry or assume structure because `templates/` exists. -Before drawing each page, use its retained `spec_lock.md page_layouts` row to identify the inherited basename. Resolve the complete SVG from the selected template directory; §1.0 owns whether that file must be read or can be reused from the active context. An on-demand `reference_set` fingerprint may diagnose an uncertain path/SHA but is not required for normal lookup: - -- Entry present (e.g., `P04: 03a_content_image_text`) → inherit the corresponding full SVG. The basename **must match** an actual file in the chosen template directory. If it does not, stop before drawing and report the invalid mapping; neither `strict` nor `adaptive` may fall back to free design inside a structured template deck. -- No entry for this page with `template_reuse_scope: mirror|layout` → stop before drawing and report the missing Strategist mapping. Adaptive mode still requires one selected complete template SVG; flexibility applies to the post-design output Layout, not to whether an input prototype exists. -- Whole section absent while `template_reuse_scope: mirror|layout` is present → stop before drawing; the current template contract is incomplete. -- `template_reuse_scope: style` → the whole section must be absent; do not perform per-page prototype lookup. - -Do **not** invent a prototype entry, and do **not** assume a structured template just because `templates/` exists. For `mirror` / `layout`, a missing or invalid `page_layouts` row is an upstream contract error. `style` is a separate flat deck route, never a per-page fallback. - -**Per-page PowerPoint layout lookup — `template_reuse_scope: mirror|layout` only**: - -- When `pptx_structure.mode` is `flat` (including `template_reuse_scope: style`), skip this lookup and the structured scaffold below. `pptx_masters`, `pptx_layouts`, `page_layouts`, and the corresponding SVG metadata must all be absent; each root still declares its canonical `data-pptx-page-role`. -- With `template_reuse_scope: mirror|layout`, `pptx_structure.mode` must equal `structured`; any other or missing value is rejected. Do not migrate an invalid structured contract in place: create a new current-contract workspace through Create Template before generation resumes. -- Read the current page assignment as `P: `. Resolve the assigned Layout key in `pptx_layouts`, then resolve its Master key in `pptx_masters`. Missing, malformed, or partial mappings stop before drawing. -- Write matching root Master/Layout key and picker names. Do not write `data-pptx-layout-kind` or `data-pptx-page-role`. -- On strict template use, the row and SVG contract match the selected prototype exactly. -- On adaptive template use, retain the prototype Master and realize the Layout key/name already declared for this page. If construction proves that fixed Layout atoms or slot topology/bounds must change, stop before completing the page and return to Strategist to declare, read back, and validate the revised definition and assignment before resuming. -- A Layout key may repeat across non-adjacent pages only when its fixed atoms and slot contracts are identical. - -**Structured template-page scaffold**: +**`page_pptx_layouts` (`mirror|layout` only)**: under `flat` (including `style`) skip this and the scaffold, with `pptx_masters`, `pptx_layouts`, `page_layouts`, and the metadata all absent and each root declaring `data-pptx-page-role`. Otherwise `mode` must be `structured` (any other value is rejected — create a new workspace, never migrate); read `P: `, resolve the key in `pptx_layouts` and its Master in `pptx_masters` (missing or partial mappings stop), write the matching root keys and picker names, and write no `data-pptx-layout-kind` or `data-pptx-page-role`. Strict matches the prototype exactly; adaptive keeps the Master and realizes the declared Layout, stopping and returning upstream when atoms or slots must change. A key may repeat across non-adjacent pages only with identical atoms and slots. ```xml - + - + - + @@ -175,4 +91,4 @@ Do **not** invent a prototype entry, and do **not** assume a structured template ``` -On structured template pages, Master/Layout atoms and slot groups are direct root children and precede ordinary content groups. Structural metadata nested inside an ordinary content group fails export. Flat pages use ordinary top-level semantic groups only. +Master/Layout atoms and slot groups are direct root children preceding ordinary content groups; structural metadata nested inside a content group fails export. Flat pages use ordinary top-level semantic groups only. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/executor-table.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/executor-table.md index ffce2070..716e8f57 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/executor-table.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/executor-table.md @@ -4,7 +4,7 @@ Conditional Executor authority for semantic cell grids whose row/column intersections carry the information. -**Trigger**: load when the page contains an actual cell-grid table or its primary reference uses `table/`. +**Trigger**: the page contains an actual cell-grid table or its primary reference uses `table/`. --- @@ -16,51 +16,22 @@ Conditional Executor authority for semantic cell grids whose row/column intersec | Independent visual zones compare categories without a shared row/column grid | [`executor-structure.md`](./executor-structure.md) | | Values determine marks, positions, lengths, areas, angles, radii, or color bins | [`executor-chart.md`](./executor-chart.md) | -Graphical indicators may appear inside cells without changing the table family, provided the row/column grid still carries their meaning. A row of metric cards or two prose columns is a qualitative structure, not a table. +**Hard rule — physical grid is insufficient**: a PowerPoint table object or rectangular drawing grid does not establish Table semantics. Dates or durations driving task-bar position and length route to `executor-chart.md`; qualitative stage/lane placement routes to `executor-structure.md`. Graphical indicators may sit inside cells while the grid still carries their meaning; a row of metric cards or two prose columns is a qualitative structure, not a table. -**Hard rule — physical grid is insufficient**: A PowerPoint table object or a -rectangular drawing grid does not establish Table semantics. Exact dates or -durations that drive task-bar position and length route to -[`executor-chart.md`](./executor-chart.md); qualitative stage/lane placement -routes to [`executor-structure.md`](./executor-structure.md). - -When a `table/` primary reference exists, [`executor-visualization.md`](./executor-visualization.md) owns resolution and flexible adaptation. A custom cell grid follows this branch without loading a catalog SVG. - -**Reference — not a constraint**: `record_table` covers heterogeneous record × -field grids; `metric_table` covers entity × KPI scanning; -`comparison_matrix` covers heterogeneous criterion × alternative facts; -`feature_matrix` covers capability states; `rating_matrix` covers one repeated -ordinal scale; and `hierarchical_table` covers grouped/indented rows with detail -and totals. These keys separate recurring cell grammars without changing the -shared row/column information-model boundary. +With a `table/` primary reference, [`executor-visualization.md`](./executor-visualization.md) owns resolution and adaptation; a custom grid follows this branch without a catalog SVG. Catalog keys (`record_table` record × field, `metric_table` entity × KPI, `comparison_matrix` criterion × alternative, `feature_matrix` capability states, `rating_matrix` one repeated ordinal scale, `hierarchical_table` grouped rows with detail and totals) separate recurring cell grammars without changing this boundary. --- ## 2. Grid Construction -**Hard rule — grid before decoration**: establish the complete logical grid before drawing fills, borders, badges, or other cell treatment. +**Hard rule — grid before decoration**: establish the complete logical grid before fills, borders, badges, or other cell treatment: (1) resolve column/row counts, header rows, row labels, summaries, and rectangular spans from the content; (2) allocate widths and heights from semantic weight and real text/data fit — no default equal columns when labels or values differ materially; (3) place every value, unit, qualifier, status, and source note in its intersection; (4) align by content role with comparable numeric alignment and stable header/body hierarchy; (5) add rules, fills, banding, highlights, and in-cell indicators only after the grid reads correctly plain; (6) for a `=yes` table, project the finished grid into the JSON in the same edit — `row_heights`, header fill/text/bold/alignment, whole-row or whole-column fills, first-column emphasis, padding, and per-side `borders` mirroring the drawn rules; a font size plus a uniform border is not a projection, and a graphical cell (inset badge, colored chip, mini bar) cannot be expressed by `a:tbl`, so return that object to `Native-ready=no`. -1. Resolve column count, row count, header rows, row labels, summaries, and any rectangular visual spans from the authoritative content. -2. Allocate column widths and row heights from semantic weight and real text/data fit; do not default to equal columns when labels or values differ materially. -3. Place every cell value, unit, qualifier, status, and source-bearing note in its correct intersection. -4. Apply alignment consistently by content role, including comparable numeric alignment and stable header/body hierarchy. -5. Add rules, fills, banding, highlights, and in-cell indicators only after the grid reads correctly in plain form. -6. For a `=yes` table, project the finished grid into the JSON in the same edit: `row_heights`, header fill / text / bold / alignment, whole-row or whole-column fills, first-column emphasis, padding, and per-side `borders` mirroring the drawn rules; a font size plus a uniform border is not a projection. A graphical cell (inset badge, colored chip, mini bar) cannot be expressed by `a:tbl`: return that object to `Native-ready=no`. +**Per-cell completeness**: never drop a row, column, summary, footnote, unit, or qualifier to imitate a lighter catalog preview; reflow text, widen the column, rebalance neighbors, or increase row height within the page's information contract and [`executor-base.md`](./executor-base.md) typography bounds. -**Per-cell completeness**: never drop a row, column, summary, footnote, unit, or qualifier to imitate a lighter catalog preview. Reflow text, widen the affected column, rebalance adjacent columns, or increase row height while preserving the active page's information contract and [`executor-base.md`](./executor-base.md) typography bounds. - -**Visual span discipline**: merge only rectangular regions whose repeated boundaries would obscure an intended shared heading or group. Covered areas must not carry competing visible content. This branch owns the visible SVG geometry only; any native merge fields or payload topology belong exclusively to [`native-data-interface.md`](./native-data-interface.md). - -**Table chrome**: make header/body/summary roles distinguishable with the lightest sufficient combination of weight, fill, rule, and whitespace. Keep comparison scanning stable across the grid; decorative card treatment must not break row or column continuity. +**Spans and chrome**: merge only rectangular regions whose repeated boundaries would obscure an intended shared heading or group, with no competing visible content in covered areas; native merge fields belong exclusively to [`native-data-interface.md`](./native-data-interface.md). Distinguish header/body/summary with the lightest sufficient weight, fill, rule, and whitespace; decorative card treatment must not break row or column continuity. **Reference — table defaults (treatment follows the locked style)**: a header set apart by weight and a rule, or by a fill with reversed text where the style carries fills; zebra rows at `fill-opacity` 0.05, numbers right-aligned and text left-aligned with consistent units and precision, one highlighted row in the accent at `fill-opacity` 0.1, and horizontal rules only — avoid a full grid of lines. --- ## 3. Object Boundary -Treat each semantic table as one independently bounded page object even when it contains nested cell groups. Captions, source notes, and explanatory callouts may sit outside the grid when their ownership is visually explicit. - -Native readiness is decided per independent table object, not by the `table` -family or numeric cells. Reuse its §IX/Quick semantic object key in the -`Native-ready` map; only `=yes` loads and follows -[`native-data-interface.md`](./native-data-interface.md). All others remain -ordinary Shape-first SVG geometry under [`executor-base.md`](./executor-base.md). +Each semantic table is one independently bounded page object even with nested cell groups; captions, source notes, and callouts may sit outside the grid when ownership is visually explicit. Native readiness is decided per table object, not by family or numeric cells: reuse its §IX/Quick semantic object key in the `Native-ready` map; only `=yes` loads [`native-data-interface.md`](./native-data-interface.md), everything else remains Shape-first SVG geometry. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/executor-visualization.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/executor-visualization.md index 5b900be6..7d45b9e1 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/executor-visualization.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/executor-visualization.md @@ -4,7 +4,7 @@ Conditional Executor authority for resolving one page-local Chart/Table `family/key` SVG reference and adapting it without turning the catalog preview into a page specification. -**Trigger**: load only when Default `spec_lock.md page_visualizations` maps the current page to a canonical Chart/Table reference, a legacy `page_charts` row resolves to a live Chart/Table SVG, or Quick already selected one canonical Chart/Table reference in active context. +**Trigger**: Default `spec_lock.md page_visualizations` maps the current page to a canonical Chart/Table reference, a legacy `page_charts` row resolves to a live Chart/Table SVG, or Quick already selected one canonical reference in active context. --- @@ -17,30 +17,27 @@ Conditional Executor authority for resolving one page-local Chart/Table `family/ | Active profile | Resolve from | |---|---| -| Default Generate | Prefer the current `P: family/key` row from retained `spec_lock.md page_visualizations`, then read that page's `Page | Family | Template | Usage` row in Design Spec §VII; use a legacy `page_charts` row and its legacy §VII Usage only when the canonical row is absent | -| Quick Generate | Use the canonical Chart/Table `family/key` and page-local purpose already selected in active context before SVG authoring | +| Default Generate | The current `P: family/key` row in retained `spec_lock.md page_visualizations`, then that page's `Page \| Family \| Template \| Usage` row in Design Spec §VII; a legacy `page_charts` row and its §VII Usage only when the canonical row is absent | +| Quick Generate | The canonical `family/key` and page-local purpose already selected in active context before SVG authoring | -**Hard rule — one primary reference per page**: one page resolves at most one catalog SVG. The reference guides one dominant reusable Chart/Table information structure; secondary objects are authored from their actual content through the applicable branch without loading another catalog SVG. Independent Chart/Table children retain their §IX or Quick semantic object keys for scoped native/verification contracts. - -**Mandatory — shared resolution**: resolve the selected value through `visualization_recall.py validate`; consume its canonical `reference` and `path` instead of guessing a family or constructing a path from the input string. Add `--legacy-bare` only for a value read from legacy `page_charts`. +**Mandatory — shared resolution**: resolve through `visualization_recall.py validate` and consume its canonical `reference` and `path`; never guess a family or build a path from the input string. Add `--legacy-bare` only for a value read from legacy `page_charts`. ```bash python3 ${SKILL_DIR}/scripts/visualization_recall.py validate -python3 ${SKILL_DIR}/scripts/visualization_recall.py validate \ - --legacy-bare +python3 ${SKILL_DIR}/scripts/visualization_recall.py validate --legacy-bare ``` -New `page_visualizations` and Quick selections accept only canonical `chart/` or `table/`. A bare key is read-compatible only from legacy `page_charts`: it must resolve unambiguously to one live Chart/Table entry, otherwise stop for upstream correction. If canonical and legacy rows both exist for one page, stop on the duplicate contract even when both resolve to the same SVG. +**Hard rule — one primary reference per page**: one page resolves at most one catalog SVG, guiding one dominant reusable Chart/Table structure; secondary objects are authored from their content through the applicable branch without another catalog SVG, keeping their §IX or Quick object keys for native/verification contracts. New `page_visualizations` and Quick selections accept only canonical `chart/` or `table/`; a bare key is read-compatible only from legacy `page_charts` and must resolve unambiguously, otherwise stop for upstream correction. Canonical and legacy rows for one page stop on the duplicate contract even when both resolve to the same SVG. -**Legacy Structure boundary**: a retired Structure bare key is semantic intent, not a live visualization reference. Do not resolve it to an SVG or load this branch; recover the qualitative relationship from §IX and apply [`executor-structure.md`](./executor-structure.md) when the mandatory per-page Structure decision is yes. If §IX lacks enough meaning, return upstream for Design Spec repair. +**Legacy Structure boundary**: a retired Structure bare key is semantic intent, not a reference — do not resolve it or load this branch; recover the relationship from §IX and apply [`executor-structure.md`](./executor-structure.md) when the per-page Structure decision is yes, or return upstream when §IX lacks meaning. -Read the resolver-returned SVG once before its first use in the valid active context and reuse that reading until a known file change or context invalidation. Do not manually reopen indexes or scan family directories during Executor realization; the planning owner already reviewed the complete live registries, and the shared resolver owns canonical path resolution here. +Read the resolver-returned SVG once before first use and reuse that reading until a known file change; do not reopen indexes or scan family directories during realization — the planning owner already reviewed the live registries. --- ## 2. Flexible Page-local Adaptation -**Hard rule — reference, not lock**: the selected SVG is a page-local construction reference. The current §IX page block or Quick page decision plus authoritative source content owns the final information structure; the preview does not lock visualization type, geometry, styling, or native replacement. +**Hard rule — reference, not lock**: the selected SVG is a page-local construction reference. The §IX page block or Quick page decision plus authoritative content owns the final information structure; the preview locks no visualization type, geometry, styling, or native replacement. | Preserve | Adapt freely | |---|---| @@ -48,10 +45,6 @@ Read the resolver-returned SVG once before its first use in the valid active con | Selected Usage and valid information encoding | Borrow, recombine, simplify, extend, or depart when another realization preserves the information more faithfully | | Complete page content obligations | Palette, typography, container treatment, effects, background, and page chrome from project authorities | -**Forbidden — preview substitution**: +**Forbidden — preview substitution**: copying sample labels/data as content; omitting authoritative content to fit lighter preview density; spreading one page's reference to another page without its own mapping. -- Do not copy sample labels/data as content. -- Do not omit authoritative content to fit lighter preview density. -- Do not spread one page's reference to another page without its own mapping. - -The namespace selects a reference registry and construction authority only; it does not assert native readiness or mirror a source PowerPoint object type. An imported table used to place duration-driven bars remains Chart semantics. Native eligibility is an independent per-object decision owned by [`native-data-interface.md`](./native-data-interface.md). +The namespace selects a registry and construction authority only; it asserts no native readiness and mirrors no source PowerPoint object type — an imported table used to place duration-driven bars remains Chart semantics. Native eligibility is an independent per-object decision owned by [`native-data-interface.md`](./native-data-interface.md). diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/executor-web-image.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/executor-web-image.md index aa10327e..6844cae6 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/executor-web-image.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/executor-web-image.md @@ -4,22 +4,16 @@ Conditional Executor authority for inline attribution on web-sourced images and their prepared derivatives. -**Trigger**: load for any placed `Status: Sourced` image or any placed prepared derivative whose filename has a copied `image_sources.json` record. Quick Generate uses the same manifest contract without interaction. +**Trigger**: any placed `Status: Sourced` image, or a placed derivative whose filename has a copied `image_sources.json` record; Quick uses the same manifest without interaction. ## 1. Inline Attribution for Sourced Images -Whenever the slide uses a `Status: Sourced` image or a prepared derivative backed by `image_sources.json`, look up the corresponding filename entry and act on `license_tier`: +**Contract**: look up the filename entry and act on `license_tier` — the manifest is the single source of credits, and the credit is rendered in the SVG you author, never by post-processing or export. | `license_tier` | Action on this slide | |---|---| -| `no-attribution` | Embed the `` element only. **No credit element needed.** | -| `attribution-required` | Embed the `` element **plus** a visible inline credit that preserves the asset-specific legal content in [image-searcher.md §7](./image-searcher.md). | -| `manual` | Embed the `` element only. **No credit element** — a user-supplied `--from-url` replacement; verifying usage rights / any required credit is the user's responsibility. | +| `no-attribution` | `` only | +| `attribution-required` | `` plus a visible inline credit preserving that asset's author, source/provider, and CC BY / CC BY-SA license ([image-searcher.md §7](./image-searcher.md)) | +| `manual` | `` only — a user-supplied `--from-url` replacement whose rights and credit are the user's responsibility | -The credit is **not** rendered by post-processing or export — it must be present in the SVG you produce. Preserve that asset's author, source/provider, and CC BY / CC BY-SA license facts. Size, position, color, per-image versus combined treatment, labels, and any contrast scrim/gradient are Executor-owned as long as the credit stays readable and unambiguously bound to the correct image. - -Use `attribution_text` from the manifest entry as the **starting point**. You may omit the filename and full URL when the visible source/provider remains clear, but retain that image's author and CC BY / CC BY-SA license so the quality checker can bind the credit to the referenced asset. For CC0/PD images that landed in the `attribution-required` tier only because of upstream metadata quirks (rare), credits are still safe to render. - -`svg_quality_checker.py` treats a missing image-specific author + license credit as an **error**; one generic CC token does not cover multiple files. An unreadable/missing manifest or missing per-file provenance is also blocking. Fix the manifest or SVG before Default Generate post-processing or Quick Generate direct export. - -**The manifest is the single source of truth for credits.** Do not duplicate license info into speaker notes or any other artifact. +Start from the manifest's `attribution_text`; the filename and full URL may go when the source stays clear, but the author and license stay so the checker can bind the credit to the asset. Size, position, color, per-image versus combined treatment, labels, and any contrast scrim/gradient are Executor's as long as the credit is readable and unambiguously bound. `svg_quality_checker.py` errors on a missing image-specific author + license credit (one generic CC token never covers several files) and on an unreadable manifest or missing per-file provenance; fix before post-processing or Quick export. Never duplicate credits into speaker notes or any other artifact. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/image-base.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/image-base.md index d4857b0b..3516e495 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/image-base.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/image-base.md @@ -2,174 +2,52 @@ # Image Acquisition and Preparation Common Reference -Shared baseline for both acquisition paths. Path-specific behavior lives in the path's own reference. +Shared baseline for both acquisition paths and for prepared derivatives. ---- +**Trigger**: at least one resource row has `Acquire Via: ai` / `web` / `slice`, or any §VIII / Quick active-context resource is a pending prepared derivative (`user` / `placeholder` rows are tracked but skipped) — in Default Generate from `design_spec.md §VIII`, in Quick from the main agent's active-context decisions plus required operational manifests, or standalone against an existing project. -## 1. Trigger Condition +## 1. Resource Row and Path Dispatch -Active when at least one resource row has `Acquire Via: ai` / `web` / `slice`, or when any §VIII / Quick active-context resource is a pending prepared derivative. Canonical rows with `user` / `placeholder` are tracked but skipped by acquisition roles. - -| Mode | Trigger | -|---|---| -| Default Generate | `generate-pptx` workflow, `design_spec.md §VIII` image rows present | -| Quick Generate | [`quick-generate`](../workflows/profiles/quick-generate.md) is active and the current main agent has resolved one or more required images in active context | -| Standalone | Direct request against an existing project | - ---- - -## 2. Image Resource List Format - -Default Generate uses Strategist-owned `design_spec.md §VIII` plus its lock projection. Quick Generate substitutes active-context resource decisions plus required operational manifests; it creates no planning artifact or general resource roster. Status enum: [`svg-image-embedding.md`](svg-image-embedding.md). +Status enum: [`svg-image-embedding.md`](svg-image-embedding.md). Per non-skipped row `Acquire Via` and `Status` are required; `Reference` is required for every `web` / `slice` row, every newly authored `ai` row, and every derivative (an existing `ai` row with a blank `Reference` continues only through [`image-generator.md`](./image-generator.md) §8's declared inference). Quick: explicit user assets, URLs, and path instructions win; otherwise the agent chooses `user` / `ai` / `web` / `slice` rows and AI path `auto` without interaction. | Filename | Dimensions | Purpose / Type | Layout pattern | Crop Policy | Acquire Via | Status | Reference | |---|---|---|---|---|---|---|---| | `` | `` | `` | `` | `adaptive` / `no-crop` | `ai` / `web` / `slice` | Pending | `` | -**Required per non-skipped row**: `Acquire Via` and `Status`. `Reference` is required for every `web` / `slice` row, every newly authored `ai` row, and every prepared derivative regardless of source class. An existing `ai` row whose `Reference` is omitted or blank may continue only through the declared inference in [`image-generator.md`](./image-generator.md) §8; no other path may infer it. +Classify `Reference: Derived from ; treatment=; …` before `Acquire Via`: the parent must be a distinct non-derived `user`, `web`, `ai`, or `slice` row (no placeholder parents, chains, cycles, or self-reference). Then for each Pending row: -**Quick Generate ownership**: explicit user assets, URLs, and path instructions win. Otherwise the main agent chooses required `user` / `ai` / `web` / `slice` rows and AI path `auto`, without interaction. - -**Mandatory — consume the resolved path**: Default consumes Strategist-chosen §VIII rows; Quick resolves once in active context before preparation. This phase never adds or reselects a treatment: - -| Path | Behavior | -|---|---| -| `none` | Use the canonical bitmap unchanged | -| `native` | No new file; SVG owns crop/clip, transform, opacity, frame/shadow/scrim/vignette, and overlap | -| `prepared derivative` | Separate file only for pixel blur, desaturation/grayscale, duotone, brightness/contrast, or existing cutout/registered-layer preparation | - -Choosing `none` is valid. Never bake a native treatment into a derivative. - -**Reference — exact pattern mapping, not activation**: An adopted pattern may use this mapping; its id alone creates nothing. - -| Pattern | Preparation | -|---|---| -| `P*`, `M*`, `C*` | Use existing assets with native SVG/PPT composition; no automatic derivative | -| `A1-02` / `A1-03` | `image_treat.py` blur / duotone | -| `A1-01` / `A1-04` | Existing prepared composite or host/AI path; `image_treat.py` does not blend | -| `A2-01` | Existing/host-prepared RGBA or flat-key AI/slice asset; when source-scene registration is required, use `A2-02` / `A2-03` + [`image-generator.md`](./image-generator.md) §4.4 | -| `A2-02` / `A2-03` | [`image-generator.md`](./image-generator.md) §4.4 registered layers | -| `A2-04` | Existing/host-prepared transparent frame or device asset via the `A2-01` paths, plus an existing content picture registered beneath it; no automatic derivative | -| `A3-01` | Original/subject plus registered `image_treat.py` blur/tone/desaturate derivative | -| `A3-02` | Registered full-canvas `image_treat.py` blur derivative; crop panels natively | -| `A3-03` | `image_treat.py` desaturated base plus existing/§4.4 color subject layer | - ---- - -## 3. Path Dispatch - -Classify `Reference: Derived from ; treatment=; ...` before `Acquire Via`. Its distinct, non-derived parent must be `user`, `web`, `ai`, or `slice`; reject placeholder parents, chains, cycles, and self-reference. For each Pending row: - -| Row kind / Acquire Via | Load reference | Run | Success status | +| Row kind / Acquire Via | Load | Run | Success status | |---|---|---|---| -| Deterministic prepared derivative | This common reference | After parent is usable, run `image_treat.py` to a distinct `.png`; preserve source | Inherit parent: `user → Existing`, `web → Sourced`, `ai/slice → Generated` | -| Registered-layer derivative | [`image-generator.md`](./image-generator.md) §4.4 | After parent is usable, run §4.4 | Supplied final: `user → Existing`; generated/reconstructed: `ai → Generated` | +| Deterministic prepared derivative | this reference | after the parent is usable, `image_treat.py` to a distinct `.png`; preserve the source | inherits the parent: `user → Existing`, `web → Sourced`, `ai/slice → Generated` | +| Registered-layer derivative | [`image-generator.md`](./image-generator.md) §4.4 | after the parent is usable, §4.4 | supplied final `user → Existing`; generated `ai → Generated` | | `ai` | [`image-generator.md`](./image-generator.md) | `image_gen.py` | `Generated` | -| `web` | [`image-searcher.md`](./image-searcher.md) | `image_search.py`; with vision, bounded thumbnail pages then one selected original; without vision, strict metadata-ranked best-only | `Sourced` (`Needs-Selection` is intermediate only) | -| `slice` | [`image-generator.md`](./image-generator.md) §4.3 | `slice_images.py` after parent AI sheet is `Generated` | `Generated` | -| `user` | — | — | (already `Existing`) | -| `placeholder` | — | — | (already `Placeholder`) | +| `web` | [`image-searcher.md`](./image-searcher.md) | `image_search.py`; with vision, bounded thumbnail pages then one selected original; without vision, strict metadata-ranked best-only | `Sourced` (`Needs-Selection` is intermediate) | +| `slice` | [`image-generator.md`](./image-generator.md) §4.3 | `slice_images.py` after the parent sheet is `Generated` | `Generated` | +| `user` / `placeholder` | — | — | already `Existing` / `Placeholder` | -> Lazy load: an all-`web` deck never reads `image-generator.md`, and vice versa. +An all-`web` deck never reads `image-generator.md`, and vice versa. ---- +**Mandatory — consume the resolved treatment path**: this phase never adds or reselects a treatment. `none` uses the canonical bitmap; `native` creates no file (SVG owns crop/clip, transform, opacity, frame/shadow/scrim/vignette, overlap); `prepared derivative` is a separate file only for pixel blur, desaturation/grayscale, duotone, brightness/contrast, or existing cutout/registered-layer preparation. Never bake a native treatment into a derivative. -## 4. Analysis Phase +**Reference — pattern → preparation (an adopted id creates nothing by itself)**: `P*` / `M*` / `C*` use existing assets with native composition; `A1-02` / `A1-03` → `image_treat.py` blur / duotone; `A1-01` / `A1-04` → an existing composite or the host/AI path (`image_treat.py` does not blend); `A2-01` → an existing RGBA or flat-key AI/slice asset (with `A2-02` / `A2-03` + §4.4 when scene registration is required); `A2-02` / `A2-03` → §4.4 registered layers; `A2-04` → an existing transparent frame/device asset plus a content picture registered beneath it; `A3-01` → original/subject plus a registered `image_treat.py` derivative; `A3-02` → a registered full-canvas blur derivative with native crop panels; `A3-03` → a desaturated base plus an existing/§4.4 color subject layer. -1. Read the Default Design Spec/lock, or reuse Quick's active-context resource/page decisions. -2. Separate derivatives before grouping canonical rows by `Acquire Via`; ensure `project/images/` exists. -3. Finish user and triggered ai/web/slice canonical preparation. -4. Materialize only declared derivatives from usable parents, preserve originals, then run `analyze_images.py` once before SVG. +**Intent, not query**: `Reference` is intent (`"Diverse engineering team in modern office, natural light"`, `"Abstract digital waves, deep navy gradient #0A2540"`), owned by Strategist or Quick's agent; the receiving role translates it without reopening it, and a derivative's lineage prefix is metadata, not a query. ---- +## 2. Procedure -## 5. Verification Phase +1. Read the Design Spec/lock or reuse Quick's active-context decisions; separate derivatives, group canonical rows by `Acquire Via`; ensure `project/images/` exists. +2. Finish `user` and triggered `ai` / `web` / `slice` canonical preparation. +3. Materialize only declared derivatives from usable parents, preserving originals, then run `analyze_images.py` once before SVG. +4. Verify: every non-skipped row has `project/images/` or is `Needs-Manual`; each derivative has its distinct file and usable parent, with web provenance copied in `image_sources.json`; every `slice` row has its element file or is `Needs-Manual` because its sheet is unavailable; no `Pending`, `Failed`, or `Needs-Selection` remains; `image_prompts.json` exists when an active `ai` row remains, every entry `Generated` or `Needs-Manual`; `image_sources.json` exists when a web row was processed, every entry with `license_tier ∈ {no-attribution, attribution-required, manual}`. -After all rows reach terminal status: +`Needs-Manual` is terminal for acquisition, not for export: a later supplied file is validated and its row reconciled to `Existing`, `Generated`, or `Sourced`. Quick blocks every required row still in `Needs-Selection` or `Needs-Manual` whatever files happen to exist. -- Every non-skipped row has a file at `project/images/`, or is marked `Needs-Manual` -- Each derivative has its distinct file and usable parent; web provenance is copied in `image_sources.json` -- Every `slice` row has a generated element file, or is marked `Needs-Manual` because its parent sheet is not available -- No `Pending`, `Failed`, or `Needs-Selection` rows remain -- `image_prompts.json` exists when ≥1 active ai row remains; every entry has `status ∈ {Generated, Needs-Manual}` (no `Pending` or `Failed` remaining) -- `image_sources.json` exists when ≥1 web row processed; every entry has `license_tier ∈ {no-attribution, attribution-required, manual}` (`manual` = a user-supplied `--from-url` replacement) +## 3. Failure Handling -> `Needs-Manual` is terminal for acquisition, not export readiness. A later -> supplied/replaced file must be validated and its row reconciled to -> `Existing`, `Generated`, or `Sourced` with matching evidence. -> Quick blocks every required row that still says `Needs-Selection` or -> `Needs-Manual`, regardless of whether a preview or unverified candidate file -> happens to exist. See -> [`image-generator.md`](./image-generator.md) §7. +**Hard rule — automatic exhaustion before blocking**: never open an interactive choice or stop while an untried permitted strategy remains. On a recoverable failure (network, no candidates, license rejection, rate limit) continue through materially different strategies inside the path's permissions without repeating an exhausted one; when the path's variants, ranked pages, providers, license stages, backends, and retries are exhausted, follow its terminal rule — web may set `Needs-Manual`; a Default AI row stays `Failed` until [`image-generator.md`](./image-generator.md) §7's three-outcome recovery decision, and only confirmed manual fulfillment sets `Needs-Manual`; Quick removes exhausted automated AI/slice jobs through §7's no-AI replan, while an explicitly selected manual path may set `Needs-Manual`. Afterwards summarize every `Needs-Manual` row: filename, where the prompt lives (`images/image_prompts.md`, refreshed with `image_gen.py --render-md`), the target path `project/images/`, and for slices the parent sheet and element names (the user places the sheet, the agent reruns `slice_images.py`). `Needs-Manual` is also the entry to Offline Manual Mode, reached only through an explicit `manual` decision; neither profile probes a provider during planning. ---- +## 4. Credits and Handoff -## 6. Failure Handling +License and attribution data live only in `project/images/image_sources.json` — never in `notes/*.md` (TTS would speak them), `total.md`, SVG `` / `` (stripped on export), or a credits appendix slide. Executor renders inline credits per slide under [`executor-web-image.md`](./executor-web-image.md) and [`image-searcher.md`](./image-searcher.md) §7. -**Hard rule — automatic exhaustion before blocking**: acquisition failures MUST NOT open an interactive choice or stop while an untried permitted strategy remains. After exhaustion, follow the owning path's decision policy; Default AI generation uses `image-generator.md` §7's three-outcome recovery gate instead of assuming manual fulfillment. - -1. Run the selected path's initial strategy -2. On recoverable failure (network, no candidates, license rejection, rate limit), continue through materially different strategies that remain inside that path's confirmed permissions; never loop an already exhausted strategy -3. When the path-specific query variants/ranked pages/provider/license-stage or backend/retry strategy is exhausted, follow its owning terminal rule. Web may set `Status: Needs-Manual`; Default AI rows remain `Failed` while its recovery decision or retry is unresolved, and only confirmed manual fulfillment sets `Needs-Manual`; Quick removes exhausted automated AI/dependent-slice jobs through `image-generator.md` §7's declared no-AI replan, while an explicitly selected manual path may set `Needs-Manual` -4. After the phase completes, summarize all `Needs-Manual` rows for the user — list filenames, where prompts live (`images/image_prompts.md` paste-ready blocks for ai rows; refresh via `image_gen.py --render-md` if stale), and where to place generated files (`project/images/`). After supply/replacement, validate the file and reconcile the owning row plus manifest to its usable status. For `slice` rows, list the parent sheet filename and target element names; the user places the sheet, then the agent reruns `slice_images.py`. - -**Quick Generate export gate**: exhaust allowed automation without asking; stop -before `--quick-generate` when a required row is not both backed by its -validated file/provenance and in a usable status. Preview/file presence alone -never bypasses `Needs-Selection` or `Needs-Manual`. - -`Needs-Manual` is also the entry status for **Offline Manual Mode**. Default uses it only when final Stage 2 or the runtime recovery decision explicitly confirmed `manual`; Quick uses it only when the active-context instruction explicitly selected `manual`. Neither profile checks configuration or probes a provider during planning; automated capability is resolved only during [`image-generator.md`](./image-generator.md) §7 execution. - -Path-specific retry policies (provider chain, backend chain) live in the path's own reference. - ---- - -## 7. Credits — Single Source of Truth - -License / attribution data lives **only** in `project/images/image_sources.json`. - -**Forbidden — credits anywhere else**: - -- `notes/*.md` (TTS would speak them in the audio export) -- `total.md` (gets split, then overwritten) -- SVG `` / `<desc>` (stripped by `svg_to_pptx.py`) -- A separate "Image Credits" appendix slide (lost on single-page sharing) - -Executor reads the manifest per slide and renders inline credits when needed — see [`executor-web-image.md`](./executor-web-image.md) §1 and [`image-searcher.md`](./image-searcher.md) §7. - ---- - -## 8. Intent Ownership - -The `Reference` field is **intent**, not a query. Strategist owns it by default; Quick's main agent resolves it in active context. The receiving role translates without reopening it. - -For derivatives, the required lineage/treatment prefix is intent metadata, not a provider query. - -| ✅ Intent | ❌ Pre-processed | -|---|---| -| `"Diverse engineering team in modern office, natural light"` | `"team office light"` | -| `"Abstract digital waves, deep navy gradient #0A2540"` | `"use openverse, search 'waves'"` | - ---- - -## 9. Handoff with SVG Authoring - -SVG authoring consumes the active profile's resource authority plus: - -| Artifact | Path | Purpose | -|---|---|---| -| Image files | `project/images/*.{jpg,png,webp}` | `<image>` references | -| Manifest | `project/images/image_sources.json` | License/provenance for sourced images and their derivatives | - -**Default Generate boundary**: Executor does NOT invoke `image_gen.py` / `image_search.py` / `slice_images.py` / `image_treat.py`; missing material returns to Strategist-owned preparation. - -**Quick Generate boundary**: the main agent finishes acquisition and planned derivation before SVG authoring, then neither acquires, derives, nor reselects while drawing. - ---- - -## 10. Task Completion Checkpoint - -Verify every row, file, triggered manifest/sidecar, and provenance record. -Default proceeds to Executor. Quick proceeds without interaction after -preparation and exports only when every required row has validated evidence and -a usable status. Report only blocking recovery. +SVG authoring consumes `project/images/*.{jpg,png,webp}` and `image_sources.json`. Default Executor never invokes `image_gen.py` / `image_search.py` / `slice_images.py` / `image_treat.py` — missing material returns to Strategist-owned preparation; Quick finishes acquisition and derivation before authoring and neither acquires, derives, nor reselects while drawing. Completion: every row, file, manifest, and provenance record verified; Default proceeds to Executor, Quick exports only with validated evidence and usable statuses; report only blocking recovery. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/image-generator.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/image-generator.md index 09fd919f..c4372e4e 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/image-generator.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/image-generator.md @@ -2,310 +2,120 @@ # Image_Generator Reference Manual -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. +Role definition for the **AI image generation path**: turn each active `Acquire Via: ai` row into one prose prompt, generate the image into `project/images/`, and derive `slice` elements from illustration, illustrated-icon, and lettering sheets. -**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. +**Trigger**: the Default resource list contains `Acquire Via: ai` or `slice`, or Quick has resolved a required AI/sliced image in active context. --- ## 1. Core Principle — Maximize AI Image Capability in Service of the Deck -AI images exist to serve the deck's communication goal. Pick whatever combination of `page_role` and `text_policy` makes the page work best. - -**Two page roles** (orthogonal to type): +Pick whatever `page_role` and `text_policy` make the page work; everything else inside the bitmap is the AI's judgment — no mandated padding, no type-locked text policy, no scenario whitelist. | `page_role` | Use | |---|---| -| `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 | -| `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 | - -**Two text policies** (orthogonal to page_role): +| `local` | Composed by SVG within the page — boxed, unboxed, repeated as chrome, or the dominant non-full-canvas visual; SVG owns geometry and carrier combination | +| `hero_page` | The page's main voice — cover, chapter divider, mood transition, single-number hero, closing quote; SVG above may be minimal or empty | | `text_policy` | Use | |---|---| | `none` | No text inside the image | -| `embedded` | Image contains stable text as part of the artwork — decorative lettering, artistic wordmarks, hand-lettered words or phrases, or figure-internal labels | +| `embedded` | Stable text as part of the artwork — decorative lettering, wordmarks, hand-lettered words, figure-internal labels | -**Hard rule — only what's actually hard**: - -- Same `deck_rendering` + same core deck color anchors/semantic behavior for every image in the deck -- HEX codes and color names are rendering guidance — never visible text in the image -- Long body copy / data points / bulleted lists / long quotes stay in SVG (improving them later means regenerating the image, which is expensive) -- **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. -- Prompts are one coherent prose paragraph, not tag soup (a model-output reality, not an aesthetic choice) - -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. +**Hard rule — only what is actually hard**: one `deck_rendering` and the same core deck color anchors for every image in the deck; HEX codes and color names are rendering guidance, never visible text; long copy, data points, bullet lists, and quotes stay in SVG; in-image text is only for words that will never need editing (one in-image word costs a regeneration, one SVG word a keystroke); prompts are one coherent prose paragraph, not tag soup. --- ## 2. Style and Composition Inputs -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. - | Dimension | Decides | When fixed | |---|---|---| -| **Rendering** | Visual style family (vector / sketch-notes / 3d-isometric / corporate-photo / …) | Once per deck — every AI image in the deck shares one rendering | -| **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 | -| **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 | +| **Rendering** | Visual style family (vector / sketch-notes / 3d-isometric / corporate-photo / …) | Once per deck | +| **Deck colors** | Core background / primary / accent / secondary-accent / text anchors from `spec_lock.md colors` (Default) or the active-context decisions (Quick) | Default after Stage 2; Quick before acquisition | +| **Type** | Optional recall for a local structural infographic's skeleton (infographic / flowchart / framework / matrix / cycle / funnel / pyramid / comparison / timeline / map / scene); omit when no template fits, for single-subject/portrait, and for `hero_page` | Per image | -> 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. +Rendering decides how the image is drawn; color begins from the deck roles — background / secondary background dominate the field, primary carries main forms, accents stay scarce — with context-justified lighting, material, and tint transitions but never an unrelated image-only palette. -### 2.1 Where to find each dimension - -| Reference | Loaded | -|---|---| -| [`image-renderings/_index.md`](./image-renderings/_index.md) — complete rendering catalog + objective selection boundary | Always (Step 1 below) | -| [`image-type-templates/_index.md`](./image-type-templates/_index.md) — type catalog + auto-selection table | Always (Step 1 below) | -| `image-renderings/<chosen>.md` | After Step 2 resolves the rendering — one preset file, or every exact reference listed for `custom` | -| `image-type-templates/<chosen>.md` | After Step 3 picks the type per image — only the types actually used | - -**Hard rule — on-demand loading**: - -- Read the rendering and type `_index.md` files once at role entry. -- After locking inputs, read **only** the specific preset rendering, custom rendering references, and type files selected. -- **Never** glob-read an entire subdirectory (`image-renderings/*.md` is forbidden). Token cost balloons and the AI loses focus. +**Hard rule — on-demand loading**: read [`image-renderings/_index.md`](./image-renderings/_index.md) and [`image-type-templates/_index.md`](./image-type-templates/_index.md) once at role entry; after resolving inputs read only the selected preset rendering file, the exact custom references, and the type files actually used. Never glob a subdirectory. --- ## 3. Workflow -### Step 1 — Load the dimension indices - -Read the two index files that own user-visible image direction and per-image internal composition. - -``` -read_file references/image-renderings/_index.md -read_file references/image-type-templates/_index.md -``` - -### Step 2 — Resolve deck-wide rendering + deck colors - -**Default Generate path — Strategist already recorded rendering and core deck color anchors in `spec_lock.md colors`**: - -``` -image_rendering: vector-illustration -background: #F8F9FA -primary: #1E3A5F -accent: #D4AF37 -``` - -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. - -**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. - -**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. - -**Declared-inference fallback — when an existing `spec_lock.md` omits the `image_rendering` key** (see [`failure-recovery.md`](../workflows/governance/failure-recovery.md) §2): - -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. - -| Signal | Maps to | -|---|---| -| `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) | -| 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 | -| Existing `spec_lock.md icons.library` | Sanity check: chosen rendering should be compatible with the icon library's visual weight | - -If rendering inference surfaces multiple candidates, choose the strongest -whole-deck fit; do not present another choice after confirmation. - -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. - -> **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. - -Then read the **single resolved** rendering file. It gives you: - -- The 80-120 word style paragraph (rendering) -- Two ready-to-paste rendering snippets (fewshot) - -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. - -### Step 3 — Per-image type + assembly - -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. - -`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. - -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. -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. -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. -4. `read_file references/image-type-templates/<type>.md` only when a type was selected (and only if not already read). -5. **Assemble the prompt** by combining: - - The rendering's style paragraph (from Step 2) - - Color-role instructions anchored by the deck HEX values and refined for the image context (from Step 2) - - The selected type's structural layout, or the no-type composition prose (from Step 3) - - The image's specific `Reference` intent (from `design_spec.md §VIII` or the Quick Generate active-context decision) - - Container sizing from the selected type file, or the row's Dimensions for no-type prose - - The hard rules from §5 below (HEX-not-as-text, rendering-aligned human depiction and likeness authorization, text policy) - -The assembled prompt is **one cohesive paragraph**, not a bulleted list of tags. See §4 for the assembly template. - -### Step 4 — Write the manifest and execute the selected path - -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. +1. **Load the indices** above. +2. **Resolve deck rendering + colors.** Default: `spec_lock.md colors` already carries `image_rendering` and the role HEX (`image_rendering: vector-illustration`, `background: #F8F9FA`, `primary: #1E3A5F`, `accent: #D4AF37`) — identity anchors, not a second user-facing choice. Quick: the agent resolves one rendering/color set in context and writes it to `image_prompts.json`. **`custom`**: read every `image_rendering_references` file when the row exists — apply one basis under `image_rendering_behavior`, or synthesize several by their stated line, texture, depth, material, and mood contributions; with no references use the behavior alone; never infer adjacent references. **Missing `image_rendering` key in an existing lock** ([`failure-recovery.md`](../workflows/governance/failure-recovery.md) §2): infer the rendering from `design_spec.md d. Style` plus the intended image jobs against the complete catalog, keep the existing color rows as anchors, sanity-check against `icons.library`, choose the strongest fit without presenting a choice, print "spec_lock.md has no `image_rendering`—inferring `<X>` from design_spec; image colors still use the locked deck roles.", and stop for lock repair if the inference lands on `custom` or the value is empty/invalid; outside Quick, an absent lock stops at Generate Step 5. Then read the single resolved rendering file (an 80–120-word style paragraph plus two fewshot snippets). +3. **Per-image type + assembly.** Explicit row values bind; Quick resolves omissions. `Layout pattern` is never copied into the prompt; when page use depends on stable composition, carry the row's `Reference` / §IX / active-context contract — subject and quiet zones, boundary or direction, overlap/seam, approximate share — without inventing layout. `page_role`: the row's value, else `local` (`hero_page` is Strategist-explicit in Default; Quick may resolve it). `text_policy`: the row's value, else `none` or `embedded` from `Purpose`, `Reference`, and page intent. Type: an Illustration Sheet omits `type` and follows §4.3; another local structural infographic takes one of the 11 types only on a real index match, otherwise §4.1 E prose; a local single-subject/portrait uses §4.1 A/B; a `hero_page` uses §4.1 A–E. Read `image-type-templates/<type>.md` only when selected. Assemble one paragraph from the rendering style paragraph, the deck color behavior, the type layout or composition prose, the `Reference` intent as concrete visual nouns, the container note, and the §5 hard rules. +4. **Write the manifest (§6) and execute the selected path (§7)** — Default's confirmed path, Quick's explicit path or `auto`, without asking. --- ## 4. Prompt Assembly Template -Every assembled prompt follows this paragraph structure. **Write prose, not tag soup**. - ``` -[Rendering style paragraph — 80-120 words from the chosen rendering file]. -[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"]. -[Composition — from the chosen type file or §4.1 no-type prose]. -[Image-specific subject — translated from the row's Reference intent into concrete visual nouns]. -[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]. -[Hard rules — see §5]. +[Rendering style paragraph — 80–120 words from the chosen rendering file]. +[Deck color behavior — 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 stay in the same visual family"]. +[Composition — from the chosen type file or §4.1 prose]. +[Image-specific subject — the row's Reference intent as concrete visual nouns]. +[Container note — "composed as a {W}x{H}px image for {page_role} use"; carry the owned composition contract when one exists. Reserve an SVG-overlay region for `hero_page`, or for a `local` image only when §VIII / §IX explicitly plans native labels, hotspots, lenses, or overlays there; otherwise an opaque local image reserves no interior space, and a transparent slice is an isolated element]. +[Hard rules — §5]. ``` -**Word budget**: 150-300 words. Embedded-text prompts skew longer; pure background prompts can be shorter. - -**Forbidden — tag-soup prompts**: - -``` -❌ "modern, flat design, gradient, vibrant, professional, clean, 4K, high quality" -``` - -This produces generic, model-average output. The model is not weighting your tags — write **one coherent visual scene** instead. +Budget 150–300 words (embedded-text prompts longer, pure backgrounds shorter). **Forbidden — tag soup** (`"modern, flat design, gradient, vibrant, professional, clean, 4K"`): it produces model-average output; write one coherent visual scene. ### 4.1 No-type composition primitives -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. +A/B describe a hero or a local single-subject region; C/D are hero-page compositions; E authors any custom composition, including a structural infographic no type template matches. -**Primitive A — single dominant subject (product / object / concept hero)** +- **A — single dominant subject**: one focal subject placed with intent (centered, thirds, slight offset), scaled to command the container, supporting context subordinate, a deliberate open side only when the page needs it. Product reveal, concept introduction, chapter-opener, brand statement, local object region. +- **B — single human subject (portrait)**: one person, frontal or three-quarter, head and upper body, face as the focal point with eyes near the upper-third line, neutral or softly blurred background, comfortable headroom, framing adapted to the container. Founder, speaker, testimonial, executive, local bio; figure treatment follows the rendering (§5.2). +- **C — typographic hero**: one large text element — a word, phrase, headline, number, or short multi-line lockup — rendered as art with dominant weight, any supporting visual subordinate, breathing room scaled to the text. `text_policy: embedded`; copy that must stay exact or editable goes to SVG (switch to D). +- **D — atmospheric backdrop** (`hero_page` only): gradients, subtle patterns, or restrained color blocks with no dominant subject (a small geometric anchor may sit in a corner or along an edge), activity arranged around the planned SVG overlay region so it stays calm; a `local` image reserves only a named focal/quiet area instead. Cover and divider backgrounds, breathing pages, any page where SVG carries the words. +- **E — custom**: when none of A–D fits (triptych, asymmetric multi-focal, narrative diorama), write the composition directly in the composition sentence — one paragraph of 2–5 sentences stating subject count and layout structure concretely enough to execute, with breathing room or an overlay region only when the page needs it; a primitive name alone is not a description. Example: *Triptych — three equal vertical bands, each holding one symbolic object centered on a shared low horizon; bands separated by 2px hairline rules; reads as one composed page.* -> 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. +**Fewshot per primitive** (deck-context placeholders intact): -Use for: product reveal, concept introduction, chapter-opener visual, brand statement, or a local single-object region. +> **A — 3d-isometric product reveal, `none`, 600×600**: 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, rendered in primary electric blue `#0EA5E9` on its lit faces with a 15% darker tonal shift on shadowed faces and a subtle 8%-opacity outer glow. Small supporting context: three thin connecting lines in accent vivid cyan `#06B6D4` arcing from the subject toward the edges, and a soft 8% drop shadow grounding it. Background is deep secondary navy `#0A0E27`, including the shadowed plane. The subject is the singular focal element with deliberate breathing room. Composed as a 600×600 hero block. NO text, letters, numbers, or labels anywhere. Color values are rendering guidance only. -**Primitive B — single human subject (portrait)** +> **B — corporate-photo executive headshot, `none`, 600×800**: Editorial corporate portrait of one professional executive, centered slightly left, chest-up at eye level, looking confidently toward the camera with a relaxed natural expression. Contemporary business attire in a neutral palette. Soft natural light from the upper left, gentle shadow on the right side of the face. Background a softly out-of-focus office — secondary light gray `#F8F9FA` wall with a hint of primary deep navy `#1E3A5F` in a blurred architectural element. Restrained professional grading, shallow depth of field, eyes near the upper-third line with comfortable headroom. Composed as a 600×800 bio portrait. NO text, name tags, or captions. Color values are rendering guidance only. -> 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. +> **C — ink-notes big-number stat, `embedded`, 800×500**: Professional hand-drawn visual-note style on pure white. The central content is the hand-lettered number "100x" in bold confident ink strokes, centered with the slight wobble of hand-lettering; a thin hand-drawn underline beneath; one small doodle — a star or upward arrow — beside it for rhythm. Accent coral `#E8655A` appears only as a tiny emphasis dot under 4% of the canvas. Background pure white `#FFFFFF`. Composed as an 800×500 typographic hero with enough room for the letterforms. No other text or labels — just "100x" and the doodle. -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. - -**Primitive C — typographic hero (the text *is* the image)** - -> 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. - -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). - -**Primitive D — atmospheric backdrop (no subject)** - -> 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. - -**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. - -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. - -**Primitive E — custom (escape hatch)** - -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. - -**Default — concise custom composition prose (may override for subject accuracy)**: - -| Rule | Value | -|---|---| -| Length | One paragraph, 2-5 sentences, replacing A/B/C/D's opening paragraph | -| 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 | -| Clarity | Describe the actual geometry; a primitive name alone is not a substitute | - -Example opening for a triptych hero: - -> 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...] - -**Fewshot examples per primitive** (one each, deck-context placeholders intact): - -> **A — 3d-isometric + deck-color product reveal, text_policy: none, 600×600** -> -> 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. - -> **B — corporate-photo + deck-color executive headshot, text_policy: none, 600×800** -> -> 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. - -> **C — ink-notes + deck-color big-number stat, text_policy: embedded, 800×500** -> -> 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. - -> **D — vector-illustration + deck-color cover background, text_policy: none, 1280×720** -> -> 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. +> **D — vector-illustration cover background, `none`, 1280×720**: Clean flat vector backdrop with no central subject — bold geometric shapes along the canvas edges leaving the planned central title field calm. Primary deep navy `#1E3A5F` forms a confident diagonal block across the lower left; secondary light gray `#F8F9FA` provides the breathing field; accent gold `#D4AF37` appears only as one thin geometric line near the lower right, 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 stays calm. Composed as a 1280×720 full-bleed background. NO text, letters, numbers, signs, watermarks, or written symbols anywhere. Color values are rendering guidance only — do not display HEX codes or color names as text. ### 4.2 Prompt depth — expand for subject-domain accuracy -**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. +**Hard rule**: for scientific, academic, engineering, medical, legal, or otherwise regulated figures, expand without a ceiling — 500–1000+ words is normal, and §4's budget is a routine-illustration default, never a cap. **Forbidden — pre-emptive shortening.** Name the field's visual conventions explicitly: chemistry/materials (IUPAC atom colors, bond conventions, lattice type, Å / ps units, A/B/C subplot circles, view angle), biology (compartment colors, scale bars, organelle and staining conventions), physics (axis symbols, signature curve shapes, units, peak labeling), engineering (schematic notation, dimension callouts, section cuts) — illustrative, not an enumeration. Read `sources/` when uncertain. -**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. +### 4.3 Illustration sheets — one generation, many composable elements -**Detail to name in the prompt** (illustrative, not an enumeration to match): +A sheet generates compatible transparent **illustration**, **illustrated-icon**, or **decorative lettering** elements sharing rendering, deck-color treatment, and finish; subjects, silhouettes, weights, and jobs may differ, and SVG composes after slicing. Lettering is stable Layer 1 artwork, never page copy turned into an image. -| Domain | Conventions to spell out | -|---|---| -| chemistry / materials | IUPAC atom colors, bond conventions, lattice type, Å / ps units, subplot labeling (A / B / C circles), view angle | -| biology | cell compartment colors, scale bars, organelle conventions, staining palette | -| physics | axis labels with proper symbols, signature curve shapes, unit annotations, peak labeling format | -| engineering | schematic notation, dimension callouts, section-cut conventions | +**Default — batch compatible elements; split when separate generation improves the result**: group illustrated-icon cues normally, group lettering by compatible letterform character and treatment (not font name), and split for style, geometry, detail, quality, or semantic precision. A single element may use a keyed `1x1` sheet; full-canvas or opaque images take the normal §4.1 path. -**When uncertain about field conventions**: read `sources/` before drafting the prompt. +**Hard rule — a sheet is a generation source, not a slide asset**: never referenced from SVG; out of `spec_lock.md images` in Default, generation-only in Quick's context and manifest; only sliced element rows are placed. **Hard rule — separable treatment before keying**: when the slice excludes a supporting surface, choose a treatment whose complete visible geometry stands alone against the key field; engraved, etched, debossed, inlaid, or bas-relief treatments are valid only when their carrier belongs in the slice — never define a carrier as necessary and ask the prompt to remove it. -### 4.3 Illustration sheets — one generation, many composable illustration, illustrated-icon, or lettering elements +**Sheet prompt convention** — one `page_role: local` item with `image_size` from final placement; spot sheets `text_policy: none`, lettering sheets `embedded`: -An Illustration Sheet generates compatible transparent **illustration**, -**illustrated-icon**, or **decorative lettering** elements with shared rendering, -deck-color treatment, and finish. Subjects, silhouettes, visual weights, and page -jobs may differ; SVG authors the composition after slicing. Lettering remains -stable Layer 1 artwork, not page copy converted to an image. +- Derive `aspect_ratio` and `--grid` from the target shape, not a universal square grid. State an invisible logical **R×C grid** and the cell shape (compact square object, tall portrait, wide vignette, wide lettering mark); center and isolate each element with even clear gutters; never draw cells, panels, dividers, borders, frames, or alternate gutter colors; never shrink every subject into a square sticker. +- One flat chroma key across the sheet — pure `#00FF00`, `#0000FF`, or `#FF0000`, chosen so its color dominates no element or effect — stated as exact HEX, unchanged in every gutter, free of reflections or spill; grain, halftone, and vignette stay inside elements. The key is technical, not deck palette. +- Shared `deck_rendering` + `color_scheme`. +- Illustration / illustrated-icon sheet: name each element and its page or reuse job; for an icon, the compact cue that must survive at placement size; the §5.3 `none` cue. +- Lettering sheet: exactly one named stable string per cell as the only text, quoted literally; the group's letterform character and treatment, then role, placement/background relationship, relative weight, and energy under §5.3's controlled-authorship default; artistry glyph-bound (silhouette, stroke structure, material, texture, depth, contour-bound light); no topic motifs, scene fragments, icons, detached ribbons, or particles unless the approved treatment is a lettering-plus-illustration lockup; key-only padding, no scene, unrelated copy, labels, watermark, or mockup surface. +- **Delivery floor, not an aesthetic ceiling**: enlarge the cell, change the grid, or use a larger or separate sheet when a treatment needs footprint; never weaken an approved treatment to fit a crop. -**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). - -**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. - -**Hard rule — separable treatment before keying**: when the intended slice -excludes a supporting surface, choose a treatment whose complete visible -geometry can stand alone against the key field. Engraved, etched, debossed, -inlaid, bas-relief, or other surface-dependent treatments are valid only when -that carrier belongs in the intended slice; otherwise choose a genuinely -freestanding treatment. Never define a carrier as necessary to the treatment -and ask the same prompt to remove it. - -**Sheet prompt convention** — one `page_role: local` manifest item; choose -`image_size` from final placement size. Spot sheets use `text_policy: none`; -lettering sheets use `text_policy: embedded`: - -- 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. -- 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. -- Shared `deck_rendering` + `color_scheme` as always. -- **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. -- **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. -- **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. - -**Cell geometry is designed, not assumed.** `slice_images.py --grid RxC` cuts rows first and columns second. The cell ratio is: - -```text -cell_ratio = sheet_ratio * rows / cols -``` - -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. +**Cell geometry is designed**: `slice_images.py --grid RxC` cuts rows first; `cell_ratio = sheet_ratio × rows / cols`. On a wide sheet `1xN` yields tall cells and `Nx1` wide cells; any `MxN` is valid when its cells match the placements. | Target element shape | Sheet plan | Slice grid | |---|---|---| | Compact objects / badges / illustrated icons | `1:1` sheet | `2x2`, `2x3`, or `3x3` | -| Tall side accents / upright objects | wide or square sheet | `1xN`, or any `MxN` whose cells are portrait | -| Wide banners / horizontal vignettes | wide sheet | `Nx1`, or any `MxN` whose cells are landscape | +| Tall side accents / upright objects | wide or square sheet | `1xN`, or any `MxN` with portrait cells | +| Wide banners / horizontal vignettes | wide sheet | `Nx1`, or any `MxN` with landscape cells | | Large page anchors / dominant cutouts | dedicated sheet matching the silhouette | `1x1` | -| Decorative words, phrases, or multi-line lettering lockups | wide sheet | `Nx1`, or any `MxN` whose cells fit the planned string shapes | +| Decorative words, phrases, multi-line lockups | wide sheet | `Nx1`, or any `MxN` fitting the string shapes | -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. +Shape families that cannot share a roomy grid take separate sheets; coherence comes from rendering and colors, not one forced sheet. -**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: - -- **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. -- **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. - -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. - -**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: +**Resource contract**: a **sheet row** is `Acquire Via: ai`, `Type: Illustration Sheet`, named as the slice source with intent, cell shape, and purpose (`Reference: reusable title/corner illustration family`, `illustrated-icon set: cues = ...`, or `decorative lettering set: exact strings = ...`); Step 5 generates it, it is never placed, and Image_Generator resolves its aspect ratio, grid, and slice command. **Element rows** are one per used element, `Acquire Via: slice`, filename matching `--names`, `Reference` naming the parent and cell, listed in the placeable authority normally with `crop=no-crop` (tight slices use fit, not cover-crop), `Type: Illustrated icon` for a compact cue (never an SVG library entry), reusable across pages, each carrying an owner-resolved layout recommendation, dimensions filled after slicing by `analyze_images.py`. Add `slice_grid` and `slice_names` to the sheet's manifest item — the comma-separated basenames are the complete required output set. ```bash SHEET_KEY_HEX="#00FF00" # example only; choose a key absent from every element/effect @@ -314,95 +124,28 @@ python3 scripts/slice_images.py <project>/images/illus_sheet.png --grid 2x3 \ --bg "${SHEET_KEY_HEX}" --strict-alpha ``` -**Three quality constraints**: +`--names` count equals `rows*cols`; `--strict-alpha` writes nothing on an incomplete cut. Three quality constraints: **strict key recovery** — raise `--tolerance` only enough to absorb measured flat-field drift, `--inset` only for an isolated outer gutter, and regenerate or enlarge when an effect reaches an edge; **clean isolated cells** — fused cells, scene backgrounds, or flourishes crossing a cell make the sheet unusable, and re-rolls follow only a strict keying failure or user/preview evidence, never taste; **enough source pixels** — each cell at least 1.5–2× its display size (`1K` small accents, `2K` medium, `4K` large or enlarged). -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. -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. -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. - -**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. - ---- +**Placement**: a slice is a decorative accessory, not a boxed picture — a spot wasted in a centered rectangle looks cheaper than none; it may stay unboxed at a margin, run off the canvas edge, sit behind or beside text with a slight rotation, vary in size and angle across pages, enter a container, or combine with backgrounds, shapes, text, photos, other slices, and lettering; stable chrome may repeat exactly while anchors and accents vary in scale, position, pairing, and interaction. Editable copy stays SVG; a large SVG-composed anchor remains `local` / `slice`, and `hero_page` applies only when one bitmap owns the page. No quota. ### 4.4 Registered reconstruction groups and shared plates -Use this preparation when a person, product, creature, effect, or other scene -element must cross native titles, panels, frames, cards, or shapes while the -original scene remains behind it. A clean base plus one subject/foreground -output is the minimum group; add layers only when overlap or independent -editing requires them: +Use when a person, product, creature, effect, or scene element must cross native titles, panels, frames, cards, or shapes while the original scene stays behind it. Minimum group: a clean base plus one subject/foreground layer; add layers only for overlap or independent editing. | Output | Required content | |---|---| -| Clean base | Full original canvas with every planned removable scene element removed and the hidden background reconstructed | -| Optional midground | Full canvas with only the scene content that must sit between the base and primary subjects | -| Subject / foreground | Full canvas with one subject or one z-order-compatible set visible on RGBA transparency | +| Clean base | Full original canvas with every planned removable element removed and the hidden background reconstructed | +| Optional midground | Full canvas with only the content that sits between base and primary subjects | +| Subject / foreground | Full canvas with one subject or one z-order-compatible set on RGBA transparency | | Shared layer plate | Several mutually non-overlapping objects isolated together in one full-canvas or regular-cell output | -**Mandatory — preserve registration**: derive every full-canvas member -independently from the same canonical source. Preserve canvas dimensions, -subject pose, scale, position, lighting, and visible style; do not trim or -independently crop registered final outputs. Record the shared source and group -relationship in the owning §VIII rows or Quick active-context resources. +**Mandatory — preserve registration**: derive every full-canvas member independently from the same canonical source, keeping canvas dimensions, pose, scale, position, lighting, and style, never trimming or cropping a registered output; record the shared source and group in the owning rows. **Image to PPTX (Codex required)**: follow its §3 per-region decision — a complete, separable, resolution-sufficient region may stay source-derived, otherwise use Codex's native reference-image capability; inspect every member and the recomposition; do not adapt `image_gen.py` or its backends for that profile; other hosts unsupported. -**Image to PPTX override — Codex required**: when -[`image-to-pptx.md`](../workflows/profiles/image-to-pptx.md) is active, follow -its §3 per-region decision. A complete, separable, final-resolution-sufficient -region may remain source-derived. Otherwise use Codex's native reference-image -capability for required editing or reconstruction. Inspect every prepared -member plus the final recomposition. Do not adapt `image_gen.py`, its manifest, -or provider backends for this profile. Other hosts are unsupported. The -ordinary Path A / Path B procedure below applies outside this profile. +Procedure: (1) from the canonical reference remove every planned subject, foreground object, source graphic, and editable text, then inpaint one clean base without redesigning the background; (2) prepare the subject/foreground as an exact source-derived layer or a reference reconstruction, never from a generated base or layer; (3) prefer one shared plate when objects do not overlap and share an isolation treatment, with padded bboxes (shadows and effects included) pairwise disjoint; (4) a registered plate keeps original positions with one nested-SVG crop per recorded bbox ([`svg-effects.md`](./svg-effects.md) §6.5), a rearranged regular-cell plate is sliced under §4.3 and each asset placed at its recorded bbox; (5) prefer direct RGBA, otherwise one exact flat key over the whole layer and one `1x1` `--alpha` slice without `--trim` so coordinates hold — never one keyed image per object; (6) save under `<project>/images/`, registered full-canvas members `no-crop`. Overlapping or differently ordered objects take separate layers; a shared output is valid only when every final object still becomes an independent picture. -**Preparation procedure**: +> **Shared registered-plate prompt core**: Using the supplied canonical page as the only visual reference, isolate the following foreground objects together on one full-canvas extraction plate: {stable object ids/descriptions}. Preserve each object's visible identity, silhouette, pose, scale, rotation, lighting, shadow, and exact original canvas position; keep the original aspect ratio and registration; retain only the listed objects and remove the background and every unlisted element; do not rearrange, resize, merge, duplicate, or let objects touch; retain an explicitly listed source graphic or wordmark exactly and remove editable slide text and every unlisted logo. Return RGBA if supported; otherwise one uniform exact {key HEX} matte with no gradient, texture, spill, or extra marks. -1. From the canonical reference, remove every planned separate subject, - foreground object, source/data graphic, and editable text, then inpaint one - clean base without redesigning visible background content. -2. From that same reference, prepare the subject/foreground content as an - exact source-derived layer or a reference reconstruction according to the - selected profile's source-sufficiency decision. Never derive a layer from - the generated base or another generated layer. -3. Prefer one shared plate when several objects do not overlap and use the same - isolation treatment. Their padded bboxes, including visible shadows and - effects, must be pairwise disjoint. One object does not imply one generation - call. -4. For a registered plate, retain the original full-canvas positions and use - one nested-SVG picture crop per recorded bbox under - [`svg-effects.md`](./svg-effects.md) §6.5. For a rearranged regular-cell - plate, follow §4.3 and run - `slice_images.py --grid ... --names ... --trim --alpha`; place each - resulting asset at its recorded source bbox. -5. Prefer direct RGBA. When transparency is unavailable, use one exact flat - key color for the whole layer/plate, then run `slice_images.py` once as a - `1x1` sheet with `--alpha` and without `--trim` so full-canvas coordinates - remain unchanged. Do not generate one keyed image per object. -6. Save final files under `<project>/images/`. Mark registered full-canvas - members `no-crop`; ordinary trimmed cell slices retain their own measured - dimensions. - -Objects that overlap one another or require different z-order use separate -plates/layers. A shared output is valid only when every required final object -still becomes an independent SVG/PPT picture object. - -**Shared registered-plate prompt core**: - -> Using the supplied canonical page as the only visual reference, isolate the -> following foreground objects together on one full-canvas extraction plate: -> {stable object ids/descriptions}. Preserve each object's visible identity, -> silhouette, pose, scale, rotation, lighting, shadow, and exact original canvas -> position. Keep the original aspect ratio and canvas registration. Retain only -> those listed objects; remove the background and every unlisted element. Do not -> rearrange, resize, merge, duplicate, or let the listed objects touch one -> another. Retain an explicitly listed source graphic or wordmark exactly when -> it is one of the requested objects; remove editable slide text and every -> unlisted logo/source graphic. Return RGBA transparency if supported; -> otherwise use one uniform exact {key HEX} matte with no gradient, texture, -> spill, or extra marks. - -Outside Image to PPTX, Path A may use the existing single-image edit mode for -each registered derivative; Path B may perform the same edits with the -host-native image tool: +Outside Image to PPTX, Path A uses single-image edit mode and Path B the host tool — the declared derivation exception for already-planned group rows, every member kept in the resource authority and sidecar; SVG realization follows [`image-layout-patterns.md`](./image-layout-patterns.md) `#A2-03`: ```bash python3 scripts/image_gen.py "Remove the planned foreground subjects and reconstruct the hidden background; preserve the exact canvas" \ @@ -413,114 +156,44 @@ python3 scripts/slice_images.py <project>/images/<group>_plate_key.png --grid 1x --names <group>_plate --alpha --bg "#00FF00" ``` -These positional edit commands remain the declared derivation exception for -already-planned group rows. Keep every final member in the ordinary resource -authority and operational sidecar. SVG realization follows -[`image-layout-patterns.md`](./image-layout-patterns.md) `#A2-03`. - --- ## 5. Global Hard Rules -These rules apply to **every** prompt regardless of dimension choices. Append them as a closing sentence to every assembled prompt. +Append these to every assembled prompt. ### 5.1 HEX is rendering guidance, not text -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. - -**Append to every prompt**: - -> 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. +Models occasionally paint color names and HEX values as visible labels. Append: *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.* ### 5.2 Human depiction follows the selected rendering -When the image contains people: - -> 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. - -**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. +Match facial detail, anatomy, texture, and realism to the rendering and the row's Reference — silhouette, detailed illustration, painterly figure, or editorial photograph as that rendering allows. **Hard rule — likeness authorization**: never request an identifiable real-person or celebrity likeness unless the Reference explicitly names a user-authorized subject; generic or fictional people are free. ### 5.3 Text policy — two-layer ownership -Every AI-image page carries text in two layers: - | Layer | Owned by | Examples | |---|---|---| -| 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 | -| Layer 2 (SVG-owned) | `<text>` overlay — fully editable | authoritative deck/page/chapter titles; navigation, footer, body bullets, conclusion callout; readable copy, captions | +| Layer 1 (image-owned) | the prompt, baked into the raster | figure-internal annotations (axis labels, A/B/C markers, units, scale bars, panel labels); schematic module names, node labels, signal-path ids; stable artistic lettering that *is* the visual | +| Layer 2 (SVG-owned) | editable `<text>` overlay | authoritative deck/page/chapter titles; navigation, footer, body bullets, conclusion callouts; readable copy and captions | -`text_policy` controls only Layer 1. AI judges per image; no global default bias. +`text_policy` controls only Layer 1, judged per image with no global bias. Positive triggers for `embedded` — a paper-figure panel comparison (panel labels), a textbook math or signal figure (curve names, axes, units), a discipline-convention schematic (`Self-Attention`, `FFN`, node ids), a data figure with stable axes, a typographic hero (§4.1 C) — start at `embedded` and then apply the editability filter; defaulting a whole `ai` list to `none` because "SVG can always overlay" is the failure mode this table breaks. Prompt cues: `none` → *"NO text of any kind anywhere in the image — no letters, numbers, signs, watermarks, labels, or written symbols."*; `embedded` → describe the exact characters, how they are rendered, and the treatment inside the scene. -**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): +**Hard rule — decide by editability, not model capability**: Layer 1 text can never be edited, corrected, searched, restyled, or reflowed. Text that is part of the artwork and stable — decorative lettering, a wordmark, a hand-lettered phrase, figure-internal identifiers — may be Layer 1; anything that must stay exact, searchable, editable, or may be reworded is Layer 2, whatever `text_policy` says: authoritative titles, chrome, navigation, footer, bullets, captions, data values. Bake title-like wording only when the approved plan treats those exact characters as stable artwork. Never pre-judge by script or length — never push text to SVG, shorten a headline, or downgrade `embedded` to `none` on the assumption that a script or long string "won't render"; a multi-word phrase or two-line lockup qualifies exactly as one word does. Name the exact characters literally; do not re-read the generated image to verify them. When the headline must stay editable, use Primitive D and overlay it. -| Trigger | Typical Layer 1 text | -|---|---| -| Paper-figure panel comparison (A/B/C, before/after) | Panel labels — `A` / `B` / `C`, or short panel descriptors | -| Textbook math / signal figure | Curve names (`sin` / `cos`), axis labels, unit symbols | -| Architecture / schematic following discipline conventions | Module names (`Self-Attention`, `FFN`, `Add & Norm`), node ids, signal-path tags | -| Data figure with stable axes | Axis labels, units, scale bars | -| Typographic hero (§4.1 Primitive C) | The designed word / number that *is* the image | +**Reference — controlled, deck-aligned artistic authorship** (high expression on user request or a confirmed direction): give the model the exact string, communication role, placement/background relationship, deck identity, relative weight, and desired energy; the rendering, semantic colors, mood, and page hierarchy define the envelope. Glyph-native expression carries identity through silhouette, stroke construction, internal material/texture, contour-bound depth and light, and composition; literal topic illustrations or detached decoration compete with the glyph, and a lettering-plus-illustration lockup needs an explicit request or confirmed direction. Within the treatment let the model combine or omit gesture, material, dimensionality, texture, lighting, and hierarchy — possibility space, not a recipe; never flatten the art to ease extraction (§4.3's gates protect delivery); when fit is uncertain use the lower density; keep a multi-line lockup as one element when its hierarchy is part of the art. -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. - -| `text_policy` | Prompt cue | -|---|---| -| `none` | "NO text of any kind anywhere in the image — no letters, numbers, signs, watermarks, labels, or written symbols." | -| `embedded` | Describe the stable Layer 1 lettering directly inside the visual scene: the exact character(s), how they are rendered, and the artistic treatment. | - -**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. - -**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. - -**Reference — controlled, deck-aligned artistic authorship** (the user may request high expression or confirm 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. Controlled, glyph-native expression carries identity through the glyph silhouette, stroke construction, internal material/texture, contour-bound depth/light, and letterform composition; literal topic illustrations or detached decoration around the word compete with the glyph. 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. - -**Font choice for in-image text — free description, with the deck typography as one optional reference** - -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. - -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. - -| Active typography source contains | Optional descriptor if you want to echo the SVG body | -|---|---| -| `KaiTi` / `FangSong` / `Georgia` / serif families | "elegant serif lettering, refined letterforms" | -| `Microsoft YaHei` / `PingFang SC` / `Arial` / sans-serif families | "clean geometric sans-serif, modern letterforms" | -| `SimHei` / `Impact` / `Arial Black` / display families | "bold display lettering, heavy expressive strokes" | -| `Consolas` / `Courier New` / monospace families | "monospace technical lettering, fixed-width" | -| sketch-notes / ink-notes rendering, or no family specified | "hand-lettered organic strokes, natural variation" | - -**When to ignore the table**: - -- Decorative / background lettering, posters, large mood words → describe the artistic treatment freely -- Stable artistic cover lettering that wants its own visual identity (blackletter, retro chrome, art-deco display, brushed script) → describe freely -- Sketch-notes / ink-notes / hand-drawn renderings where the lettering is part of the rendering itself → describe freely -- 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 - -**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. - -**In-image text vs SVG text — decide by editability, not by model capability** - -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: - -| Text | Layer | -|---|---| -| 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 | -| Authoritative titles, page chrome, body copy, captions, data values — anything that must stay exact, searchable, editable, or may be reworded | Layer 2 (SVG) | - -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. - -**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. - -**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. +**Font for in-image text** is a free description, not an enum — blackletter for a heritage cover, hand-brushed for a manifesto, retro chrome for Y2K, art-deco display for luxury, ribbon script for a zine. Echo the SVG body only when stable lettering should read as the same family as the deck's typography: serif families → "elegant serif lettering, refined letterforms"; sans (YaHei / PingFang / Arial) → "clean geometric sans-serif, modern letterforms"; display (SimHei / Impact / Arial Black) → "bold display lettering, heavy expressive strokes"; monospace → "monospace technical lettering, fixed-width"; sketch/ink renderings or no family → "hand-lettered organic strokes, natural variation". Ignore that echo for decorative or background lettering, posters, mood words, cover wordmarks wanting their own identity, hand-drawn renderings, or any rendering that already implies a period letterform. ### 5.4 No brand names or trademarks in the subject -> 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. +The image must not depict identifiable logos, trademarks, or product likenesses unless the Reference explicitly names a real brand asset the user owns. --- ## 6. Manifest Schema -Write `project/images/image_prompts.json` with this shape: +Write `project/images/image_prompts.json`: ```json { @@ -528,12 +201,9 @@ Write `project/images/image_prompts.json` with this shape: "generated_at": "{ISO-8601 date}", "deck_rendering": "vector-illustration", "color_scheme": { - "background": "#FFFFFF", - "secondary_bg": "#F8F9FA", - "primary": "#1E3A5F", - "accent": "#D4AF37", - "secondary_accent": "#4A7BB5", - "body_text": "#1D2430" + "background": "#FFFFFF", "secondary_bg": "#F8F9FA", + "primary": "#1E3A5F", "accent": "#D4AF37", + "secondary_accent": "#4A7BB5", "body_text": "#1D2430" }, "items": [ { @@ -543,7 +213,7 @@ Write `project/images/image_prompts.json` with this shape: "text_policy": "none", "aspect_ratio": "16:9", "image_size": "2K", - "prompt": "{fully assembled paragraph per §4 — use §4.1 Primitive D for atmospheric cover}", + "prompt": "{fully assembled paragraph per §4 — Primitive D for an atmospheric cover}", "alt_text": "Modern tech abstract background with deep blue gradient and digital waves", "status": "Pending" }, @@ -562,252 +232,94 @@ Write `project/images/image_prompts.json` with this shape: } ``` -### Field reference +| Field | Required | Description | +|---|---|---| +| `deck_rendering`, `color_scheme` | yes | One rendering and the core color anchors shared by every item; no separate image palette | +| `items[].filename` | yes | Output filename with extension, from the resource authority | +| `items[].type` | no | One of the 11 internal-composition types for a local structural infographic when a template genuinely fits; omitted for §4.1 E prose, `hero_page`, sheets, and single-subject/portrait | +| `items[].page_role` | yes | `local` (default) or `hero_page` | +| `items[].text_policy` | yes | `none` or `embedded`, judged per image (§5.3) | +| `items[].aspect_ratio` | yes | Passed to `image_gen.py --aspect_ratio` | +| `items[].prompt` | yes | The assembled paragraph | +| `items[].image_size` | no | `512px` / `1K` / `2K` / `4K` | +| `items[].model` | no | Per-item backend model override | +| `items[].alt_text` | no | Short caption | +| `items[].slice_grid`, `items[].slice_names` | for a placeable-element sheet | Exact `RxC` and the comma-separated basenames (`rows*cols` unique outputs) for `slice_images.py` | +| `items[].status` | yes | `Pending` initially; the CLI writes `Generated` / `Failed` / `Needs-Manual` | -| Field | Required | Source | Description | -|---|---|---|---| -| `deck_rendering` | yes | Step 2 active authority | Single rendering name shared by all items in this deck | -| `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 | -| `items[].filename` | yes | Active resource authority | Output filename with extension | -| `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. | -| `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) | -| `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. | -| `items[].aspect_ratio` | yes | Container sizing | Passed to `image_gen.py --aspect_ratio` | -| `items[].prompt` | yes | §4 assembly | The full assembled paragraph | -| `items[].image_size` | no | Container sizing | `512px` / `1K` / `2K` / `4K` | -| `items[].model` | no | Per-item execution override | Backend model for this item; otherwise the CLI/backend default wins | -| `items[].alt_text` | no | Accessibility | Short caption | -| `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` | -| `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 | -| `items[].status` | yes | CLI manages | `Pending` initially; CLI updates to `Generated` / `Failed` / `Needs-Manual` | - -> **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. -> -> **Existing manifest compatibility**: -> -> - **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. -> - **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. -> - A legacy non-empty `deck_style_anchor` string or object remains readable for replay and sidecar display but never overrides a current `deck_rendering`. -> - A legacy `deck_palette` field may remain but cannot override `color_scheme`. Read legacy `page_role: full_page` as `hero_page`. +**Compatibility**: legacy `type` values read as `background` → `hero_page` + no type, `hero` → `hero_page` + Primitive A, `portrait` → `local` + Primitive B, `typography` → `hero_page` + `embedded` + Primitive C; a missing `page_role` is `local`, a missing `text_policy` is `none` (one aggregate warning per manifest); an existing manifest lacking `deck_rendering` or an item lacking `type` replays its assembled `prompt` verbatim without reconstruction; a legacy `deck_style_anchor` or `deck_palette` never overrides `deck_rendering` / `color_scheme`; legacy `page_role: full_page` reads as `hero_page`. --- ## 7. Generation Execution -> 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. - -### Path Selection (Deterministic) - -C (AI-generated) supports three implementation modes sharing one `image_prompts.json` source: +Prerequisite: §3 complete and `images/image_prompts.json` validates. The manifest is the shared contract for every mode; it never implies that `image_gen.py --manifest` runs — that command is Path A only. | Trigger | Mode | Mechanism | |---|---|---| -| `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 | -| `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>` | -| 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>` | +| `api`, or `auto` with `IMAGE_BACKEND` configured | **Path A** `image_gen.py --manifest` | One command runs the manifest with concurrency and writes status per item | +| `host-native`, or `auto` with a host image tool | **Path B** host-native tool | The agent invokes the host capability; outputs land at `project/images/<filename>` | +| Default confirmed `manual`, or Quick explicitly `manual` | **Offline Manual** | Manifest stays on disk; the user generates from `items[].prompt` and places files | -**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. +**Path selection**: planning never inspects configuration or probes a provider — capability is resolved only here. Default honors `AI Image Acquisition Path` from `design_spec.md §I` (already consumed from the confirmation; never reopen `result.json`): `api` → Path A; `host-native` → Path B, skipping A even when `IMAGE_BACKEND` is configured; `manual` → Offline Manual; `auto` → Path A when `IMAGE_BACKEND` is configured (two consecutive failures fall to B), then Path B when the host has a native tool, never Offline Manual by itself; a missing row returns to Step 4 recovery. Quick honors an explicit `api` / `host-native` / `manual` instruction, otherwise `auto` A → B without asking. **Hard rule**: normal execution never reopens selection; a confirmed path that fails after its retry never switches provider — Default enters the recovery decision below, Quick applies its no-AI replan. All modes share one output contract: a file at `project/images/<filename>`. -**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. - -**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: - -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`**: - - `api` → **Path A** (`image_gen.py --manifest`). - - `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*. - - `manual` → **Offline Manual** (write prompts, render the Markdown sidecar, hand off; do **not** run `image_gen.py --manifest`). - 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. -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. -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. -3. **Resolve exhausted automation** — Default enters the recovery decision below; Quick applies the no-AI replan below. - -**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. - -> All three modes share one output contract: file at `project/images/<filename>`. Step 6 SVG references are mode-agnostic. - -### Path A — `image_gen.py --manifest` (Default) +### Path A — `image_gen.py --manifest` ```bash -python3 scripts/image_gen.py \ - --manifest project/images/image_prompts.json \ - --output project/images +python3 scripts/image_gen.py --manifest project/images/image_prompts.json --output project/images ``` -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. +Validates the file behind every `Generated` row before skipping it, iterates retryable rows with bounded adaptive concurrency, and writes each status atomically; a missing or corrupt file returns to `Failed`, and persistent rate limits end the run as retryable `Failed`. Options: `--concurrency` (default `IMAGE_CONCURRENCY` or 3; halves on rate limit, min 1), `--image_size`, `--output`/`-o`, `--backend`/`-b`, `--model`/`-m`, `--list-backends`. Interrupting is safe (completed items stay `Generated`); the Markdown sidecar re-renders on completion, or run `--render-md` after an interruption. Configuration: process environment first, then the first `.env` in cwd, the skill directory, the clone root, `~/.ppt-master/.env` — `IMAGE_BACKEND` (required; `--list-backends` shows the set and support tiers), `IMAGE_CONCURRENCY`, provider-specific `{PROVIDER}_API_KEY` / `_BASE_URL` / `_MODEL` (never `IMAGE_API_KEY` / `IMAGE_MODEL` / `IMAGE_BASE_URL`), and for OpenAI-compatible platforms `OPENAI_SIZE_PRESET` (`auto|legacy|gpt-image|gpt-image-2|dall-e-2`), `OPENAI_RESPONSE_FORMAT` (`auto|b64_json|url|omit`), `OPENAI_QUALITY` (`auto|omit|low|medium|high|standard|hd`) under `IMAGE_BACKEND=openai`; see `.env.example`. The single-image form `image_gen.py "prompt" --filename …` remains for ad-hoc re-rolls. -**Parameters**: +### Path B — host-native image tool -| Parameter | Short | Description | Default | -|---|---|---|---| -| `--manifest` | - | Path to `image_prompts.json` | — | -| `--concurrency` | - | Max concurrent requests; halves on rate-limit, min 1 | `IMAGE_CONCURRENCY` env or `3` | -| `--image_size` | - | Default size (`512px`/`1K`/`2K`/`4K`); per-item `image_size` wins | Backend default; see `--list-backends` | -| `--output` | `-o` | Output directory | Manifest's parent dir | -| `--backend` | `-b` | Override `IMAGE_BACKEND` for this run | env | -| `--model` | `-m` | Default model; per-item `model` wins | Backend default | -| `--list-backends` | - | Print support tiers and exit | — | +Automatic when `IMAGE_BACKEND` is unset or Path A failed and the host (Codex, Antigravity, Claude Code, similar) offers an image tool; the user may also name it explicitly. Prompts come from `items[].prompt`; never run `image_gen.py --manifest` here, but still run `python3 scripts/image_gen.py --render-md project/images/image_prompts.json` for the sidecar. Batch a few rows at a time (~3–4) when the host runs tools in parallel, serially otherwise. Outputs land at the resource-list filename; hosts with fixed native resolutions generate at the closest size and backfill the actual pixels into `Dimensions` — never upscale to fake a size (display-side upscaling up to ~1.3× is a non-blocking warning). Mark each item `Generated` as its file lands. -> 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. +### Offline Manual Mode -**Configuration sources**: -- Current process environment variables -- First `.env` found in this order: current working directory, skill directory (e.g. `~/.agents/skills/ppt-master/.env`), clone repo root, `~/.ppt-master/.env` +Entered only after Default confirmed `manual` (Stage 2 or the recovery decision) or an explicit Quick instruction — never asked again inside acquisition. Verify the manifest, set `status: "Needs-Manual"` on every affected item ([`image-base.md`](./image-base.md) §3), and print one consolidated handoff: filenames, the `images/image_prompts.md` paste-ready blocks (or `items[].prompt`), the exact target `project/images/<filename>`, and the continuation — Default draws dashed placeholders and blocks every Step 7 export command until files are validated and placeholders replaced; Quick blocks direct export until every required row is validated and reconciled to `Generated`, and only while the original context survives (otherwise a clean run). -Precedence: -- Current process environment wins -- `.env` fills missing values only +#### Default exhausted-automation decision -| Variable | Required | Description | -|----------|----------|-------------| -| `IMAGE_BACKEND` | Required | Backend identifier; run `image_gen.py --list-backends` for the current set | -| `IMAGE_CONCURRENCY` | Optional | Manifest-mode default concurrency (CLI `--concurrency` wins) | -| `{PROVIDER}_API_KEY` | Required | Provider-specific API key, e.g. `GEMINI_API_KEY`, `ZHIPU_API_KEY` | -| `{PROVIDER}_BASE_URL` | Optional | Provider-specific custom endpoint | -| `{PROVIDER}_MODEL` | Optional | Provider-specific model override | -| `OPENAI_SIZE_PRESET` | Optional | OpenAI-compatible size mapping: `auto`, `legacy`, `gpt-image`, `gpt-image-2`, `dall-e-2` | -| `OPENAI_RESPONSE_FORMAT` | Optional | OpenAI-compatible response field: `auto`, `b64_json`, `url`, `omit` | -| `OPENAI_QUALITY` | Optional | OpenAI-compatible quality field: `auto`, `omit`, `low`, `medium`, `high`, `standard`, `hd` | +When required rows stay unresolved after the confirmed path or `auto`'s A → B, keep them `Failed`, pause once with one consolidated list (filenames, prompts, attempted paths, concrete errors), and ask for exactly one outcome: **repair and retry** (the same confirmed path; `auto` keeps A → B; a repeat failure returns here with the new error), **generate manually** (record `AI Image Acquisition Path: manual` in `design_spec.md §I`, mark rows `Needs-Manual`, hand off, author up to the Step 7 readiness gate), or **cancel the affected AI images** (return to Step 4 as a post-confirmation override, remove the `ai` and dependent `slice` rows, revise their §IX jobs and lock rows to native text/SVG or confirmed non-AI sources, set the path `not applicable` when no AI rows remain, never add a new source or drop required content). Never create `Needs-Manual` before manual fulfillment is confirmed. -> 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. +#### Quick exhausted-automation no-AI replan -> 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. +Do not ask and do not enter Offline Manual: retain the filename, attempted path, concrete error, and replacement carrier for the completion report; remove the `ai` row, its dependent `slice` rows, and the manifest item; re-render `image_prompts.md` when other items remain, otherwise delete both manifest files; carry the communication job with native text/SVG or prepared non-AI assets; add no other source. Retaining AI imagery means repairing capability and a new Quick run. -> `IMAGE_API_KEY`, `IMAGE_MODEL`, and `IMAGE_BASE_URL` are intentionally unsupported. - -> If `.env` or the current environment contains multiple provider configs, `IMAGE_BACKEND` explicitly selects the active one. - -**Support tiers (recommended usage)**: Core / Extended / Experimental. Run `image_gen.py --list-backends` for the current assignments. - -**Concurrency (manifest mode)**: -- Default 3 concurrent requests, halves on the first rate-limit response, minimum 1 (= serial fallback) -- Rate-limited items requeue automatically; per-item failures are recorded with `last_error` and skipped -- Interrupting mid-run is safe — completed items keep `status: Generated` and are skipped on re-run -- On normal completion the Markdown sidecar is re-rendered automatically; if the run is interrupted, run `--render-md` manually to refresh the sidecar - -### Path B — Host-Native Image Tool - -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. - -- Agent invokes the host's native image tool directly; prompts come from `items[].prompt` -- 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. -- Still run `python3 scripts/image_gen.py --render-md project/images/image_prompts.json` so the human-readable sidecar exists without touching any backend. -- **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. -- 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. -- 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) -- Executor downstream is path-agnostic — no spec change required between Path A and Path B - -### Offline Manual Mode (C's third implementation mode) - -**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. - -**Workflow** (manual fulfillment is already authorized; do not ask again inside acquisition): - -1. Verify `images/image_prompts.json` was written -2. Set `status: "Needs-Manual"` on every affected item per [`image-base.md`](./image-base.md) §6 -3. Apply the mode boundary: - - 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 - - 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` -4. Print one consolidated handoff to the user: - - Filenames awaiting manual generation - - Pointer to `images/image_prompts.md` (paste-ready `### Image N:` block per item) or `image_prompts.json` (`items[].prompt`) - - Target placement: `project/images/<filename>` matching the resource list exactly - - 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 - -**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. - -#### Default Exhausted-Automation Decision - -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: - -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. -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. -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. - -Do not create `Needs-Manual` state in Default before manual fulfillment is explicitly confirmed. - -> Default Generate tolerates `Needs-Manual` rows through authoring and resumes -> at Step 7. An explicitly manual Quick run preserves the same operational -> manifest and handoff but does not run `--quick-generate` while a required row still says -> `Needs-Manual`. If the original active context remains available, validate a -> later supplied file and update it to `Generated`; otherwise start a clean -> Quick run rather than treating the manifest as a resumable design record. - -#### Quick Exhausted-Automation No-AI Replan - -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. - -#### AI-specific Failure Handling (extends image-base.md §6) - -When the path is `auto` and Path A's backend fails twice in a row: - -1. Do not halt. Automatically attempt to fall back to **Path B (Host-Native Tool)**. -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. -3. Report the filename, prompt used, and error message through the owning outcome. - -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. - -> If the alternate platform watermarks outputs (e.g. Gemini web), the repository includes `scripts/gemini_watermark_remover.py`. - -#### Guardrails (All Modes) - -**Hard rule**: - -- Do not claim an image is generated without an actual file at the expected path -- `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 -- 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 +**Failure handling** (extends [`image-base.md`](./image-base.md) §3): on `auto`, two consecutive Path A failures fall to Path B without halting; if B also fails, Default enters the decision above and Quick the replan. A confirmed `api` or `host-native` path is retried once, never switched. If an alternate platform watermarks outputs (e.g. Gemini web), `scripts/gemini_watermark_remover.py` exists. **Guardrails**: never claim an image exists without a file at its path; `Needs-Manual` only on confirmed or explicit manual; status transitions are evidence-driven — a file permits `Generated`, exhausted Default automation stays `Failed` until a retry succeeds or the user chooses, exhausted Quick rows leave only through the replan. --- ## 8. Common Issues & Variant Workflow -### Reference field is omitted or blank — declared-inference fallback for existing AI rows +**Blank `Reference` on an existing AI row — declared inference** from a non-empty `Purpose` (stop and repair when `Purpose` is blank too): cover → `hero_page` + Primitive A or D; chapter divider → `hero_page` + D or A, chapter title in SVG; methodology / framework → `type: framework`, `local`; process → `type: flowchart`, `local`; before/after → `type: comparison`, `local`; team or lifestyle group → `type: scene`, `local`, `corporate-photo` or `warm-scene`; headshot → `local` + Primitive B, `corporate-photo`; big number or hero quote → `hero_page` + Primitive C, `embedded`; mood transition → `hero_page` + D, or `type: scene` when narrative. -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): +**Unsatisfactory images** — adjust the one dimension responsible, never rewrite the whole prompt: -| Purpose | A reasonable starting point | -|---------|-----------------------------| -| Cover | `page_role: hero_page` + §4.1 Primitive A (single-subject) or D (atmospheric); choose `text_policy` by what the cover should communicate | -| 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 | -| Methodology / framework illustration | `type: framework`, `page_role: local` | -| Process / workflow illustration | `type: flowchart`, `page_role: local` | -| Before/After or two-option page | `type: comparison`, `page_role: local` | -| Team / lifestyle photo (group) | `type: scene`, `page_role: local`; rendering = `corporate-photo` or `warm-scene` | -| Single-person headshot / bio | `page_role: local` + §4.1 Primitive B (portrait); rendering = `corporate-photo` for photo realism | -| Big-number / hero quote block | `page_role: hero_page` + §4.1 Primitive C (typographic); `text_policy: embedded` | -| Mood transition / atmosphere | `page_role: hero_page` + Primitive D (atmospheric), or `type: scene` if narrative | - -### When Images Are Unsatisfactory - -Diagnose the failure category, adjust the **one specific dimension** responsible, do not rewrite the whole prompt. - -| Symptom | Most likely cause | Adjustment | +| Symptom | Cause | Adjustment | |---|---|---| -| Image looks generic, model-average | Tag-soup prompt | Rewrite as one coherent paragraph per §4 | -| 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 | -| 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 | -| 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 | -| 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 | -| Hex code or color name visible as text in image | Missing §5.1 closing sentence | Append the §5.1 hard rule verbatim | -| 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" | -| 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 | -| Subject vague | Reference field too abstract | Rewrite reference with concrete nouns (verbs + objects) | -| 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 | +| Generic, model-average | Tag-soup prompt | One coherent paragraph per §4 | +| Wrong style family | Rendering paragraph diluted | Reaffirm the rendering paragraph at the top | +| Colors off-deck | Role anchors or proportions diluted | Restate which roles own field, forms, and accents; remove unrelated hues | +| Lettering unrelated, overdecorated, or too dominant | Expression exceeded the deck identity or planned weight | Keep the string and family; lower effect density, ornament, contrast, or lighting energy | +| Lettering surrounded by mountains, buildings, animals, icons, ribbons | The model turned topic context into an unrequested lockup | Remove every external motif; express identity through glyph structure, material, texture, depth, light | +| HEX or color name visible as text | Missing §5.1 sentence | Append it verbatim | +| Garbled letters in a text-free image | `none` cue too weak | Enumerate: no letters, numbers, words, signs, labels, captions, watermarks | +| SVG overlay clashes with a busy region | No calm-region cue | Add "leave the {center / left third / lower band} calm for text overlay" only when text really overlays | +| Subject vague | Abstract Reference | Concrete nouns (verbs + objects) | +| Human depiction off-style | §5.2 cues diluted | Restate the rendering's facial detail, anatomy, texture, realism | -**Variant workflow**: - -1. Set the unsatisfactory item's `status` back to `Pending` and update its `prompt` in place -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 -3. To try multiple stylistic approaches, append additional items with distinct filenames (e.g. `cover_bg_v2.png`) rather than overwriting +**Variant workflow**: set the item's `status` back to `Pending`, update its `prompt` in place, rerun the same resolved path (Path A reprocesses only that item; Path B regenerates it; Manual re-renders the sidecar); for several stylistic tries append items with distinct filenames (`cover_bg_v2.png`). --- ## 9. Forbidden -- Generating prompts for `web` rows — those go through [`image-searcher.md`](./image-searcher.md) -- Brand names or HEX codes inside the subject description (degrades output) -- Mixing renderings or introducing an unrelated image-only palette across images in the same deck -- Tag-soup prompts (keyword lists separated by commas without a coherent visual scene) -- Globbing `image-renderings/*.md` or any subdirectory — read only the chosen preset or exact custom-reference files -- Placing an image without updating its `image_prompts.json` `status` and the active resource authority's status -- Switching rendering or core deck-color semantics for a single image—`hero_page` is not an exception to deck-wide coherence -- Embedding body copy, data points, bullet lists, or long quotes inside an image — those route to SVG +- Prompts for `web` rows — those go through [`image-searcher.md`](./image-searcher.md) +- Brand names or HEX codes inside the subject description +- Mixing renderings or an unrelated image-only palette within one deck — `hero_page` is no exception +- Tag-soup prompts +- Globbing `image-renderings/*.md` or any subdirectory +- Placing an image without updating `image_prompts.json` `status` and the resource authority +- Embedding body copy, data points, bullet lists, or long quotes in an image diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/image-layout-spec.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/image-layout-spec.md index a02e6588..ec92e96f 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/image-layout-spec.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/image-layout-spec.md @@ -2,35 +2,17 @@ # Image Layout Specification -Neutral geometry and review rules for every image placement. This file calculates the selected composition; it never chooses a resource, pattern, or automatic left/right or top/bottom layout. - -**When to run**: whenever an image will be placed. Use the current page composition to select its region first, then apply the relevant single-item, adjacent, overlay, or multi-item calculation below. +Neutral geometry and review rules for every image placement. This file calculates the selected composition; it never chooses a resource, pattern, or an automatic left/right or top/bottom layout. Whenever an image will be placed, select its region from the current page composition first, then apply the matching single-item, adjacent, overlay, or multi-item calculation. --- ## 1. Ownership and Inputs -| Role | Owns | -|---|---| -| Default Strategist | Resource choice, semantic role, crop boundary, and preferred image/content or image/shape relationship | -| Image_Generator | Composition inside each generated bitmap for its planned container | -| Default Executor | Final SVG regions and geometry; may adapt the preferred relationship while preserving binding resource, content, and crop constraints | -| Quick Generate main agent | The planning and realization decisions above in one active context | - -This specification and [`image-layout-patterns.md`](./image-layout-patterns.md) are the always-read geometry and composition vocabulary; [`svg-image-embedding.md`](./svg-image-embedding.md) owns embedding. Default and Quick SVG authoring also load [`svg-effects.md`](./svg-effects.md) and [`native-shape-authoring.md`](./native-shape-authoring.md) before realization, so apply their contracts directly when a selected construction needs effects, preset geometry, or Boolean geometry. Other routes follow their own documented load triggers. +Default Strategist owns resource choice, semantic role, crop boundary, and the preferred image/content or image/shape relationship; Image_Generator owns composition inside each generated bitmap for its planned container; Default Executor owns final SVG regions and geometry and may adapt the preferred relationship while preserving binding resource, content, and crop constraints; Quick's main agent holds all of these in one context. This specification and [`image-layout-patterns.md`](./image-layout-patterns.md) are the always-read geometry and composition vocabulary; [`svg-image-embedding.md`](./svg-image-embedding.md) owns embedding; [`svg-effects.md`](./svg-effects.md) and [`native-shape-authoring.md`](./native-shape-authoring.md) load on their executor-base triggers — effects beyond the everyday block, a contour beyond basic primitives, or Boolean geometry — so apply them when a construction reaches that far. ### 1.1 Geometry notation -| Symbol | Meaning | -|---|---| -| `(x0, y0, W, H)` | Current selected page region | -| `(ws, hs)` | Measured source width and height | -| `R = ws / hs` | Source aspect ratio | -| `Q = W / H` | Selected-region aspect ratio | -| `g`, `gx`, `gy` | Gap between adjacent regions, columns, or rows | -| `ax`, `ay` | Horizontal and vertical anchor fractions in `[0,1]` | - -All dimensions must be finite and positive. Derive `R` from current measured source data rather than a requested or previously planned size. +`(x0, y0, W, H)` current selected region; `(ws, hs)` measured source size; `R = ws / hs` source aspect; `Q = W / H` region aspect; `g`, `gx`, `gy` gaps between regions, columns, rows; `ax`, `ay` anchor fractions in `[0,1]`. All dimensions are finite and positive; derive `R` from current measured source data, never a requested or previously planned size. --- @@ -38,82 +20,41 @@ All dimensions must be finite and positive. Derive `R` from current measured sou ### 2.1 Contain -Contain keeps the complete source visible inside `(W,H)`: +Keeps the complete source visible inside `(W,H)`; centered contain uses `ax = ay = 0.5` and normally maps to a legal `meet` anchor. ```text -if R >= Q: - w = W - h = W / R -else: - h = H - w = H × R - -x = x0 + ax × (W - w) -y = y0 + ay × (H - h) +if R >= Q: w = W; h = W / R else: h = H; w = H × R +x = x0 + ax × (W - w); y = y0 + ay × (H - h) ``` -Centered contain uses `ax = ay = 0.5`. SVG realization normally maps this to a legal `meet` anchor. - ### 2.2 Fill -Fill covers `(W,H)` without distortion and crops overflow: +Covers `(W,H)` without distortion and crops overflow; centered fill uses `ax = ay = 0.5` and normally maps to a legal `slice` anchor. Use fill only when the active crop boundary permits the computed loss and the anchor protects the declared focal content. ```text -if R >= Q: - h = H - w = H × R -else: - w = W - h = W / R - -overflow_x = w - W -overflow_y = h - H -x = x0 - ax × overflow_x -y = y0 - ay × overflow_y +if R >= Q: h = H; w = H × R else: w = W; h = W / R +overflow_x = w - W; overflow_y = h - H +x = x0 - ax × overflow_x; y = y0 - ay × overflow_y ``` -Centered fill uses `ax = ay = 0.5`. SVG realization normally maps this to a legal `slice` anchor. Use fill only when the active crop boundary permits the computed loss and the anchor protects the declared focal content. - ### 2.3 Mode selection -| Need | Geometry | -|---|---| -| Complete source, evidence, or edge content | Contain | -| Region coverage with a focal-safe crop | Fill | -| Complete source plus a detail view | One contain placement plus a separately justified crop | -| Irregular or repeated source windows | Apply the selected region math first, then load the owning crop/shape reference | +**Reference — narrative intent before geometry**: decide whether the image is the page (hero / full-bleed: image fills the canvas or dominant zone, title floats over a gradient or scrim — covers, dividers, breathing pages), a backdrop (atmosphere: low-contrast image behind text), a coequal block (side-by-side: image and text read together — most content pages), or an accent (small image beside related text, no ratio matching); do not default every image page to side-by-side. For side-by-side, the source ratio shapes the item inside its region (§2–§3), not the page split; on portrait canvases (Xiaohongshu, Story) side columns become narrow, so stacked regions usually serve better. + +Complete source, evidence, or edge content → contain; region coverage with a focal-safe crop → fill; complete source plus a detail view → one contain placement plus a separately justified crop; irregular or repeated source windows → the selected region math first, then the owning crop/shape reference. --- ## 3. Single Image -Place a standalone item by applying §2 to its selected region. The region itself comes from the page hierarchy; source ratio determines the item geometry inside it, not the page structure. - -For an item adjacent to another region, divide only the available selected region. Let `q_item` and `q_other` be positive visual weights for the image and the other content. - -### 3.1 Horizontal adjacency +Apply §2 to the selected region; the region comes from the page hierarchy and the source ratio determines the item geometry inside it, not the page structure. For an item adjacent to another region, divide only the available region by positive visual weights `q_item` and `q_other` — no fixed share is implied, and either region may be placed first: ```text -available = W - g -item_width = available × q_item / (q_item + q_other) -other_width = available - item_width +horizontal: available = W - g; item_width = available × q_item / (q_item + q_other); other_width = available - item_width (both use height H) +vertical: available = H - g; item_height = available × q_item / (q_item + q_other); other_height = available - item_height (both use width W) ``` -Both regions use height `H`. Place either region first according to the selected composition; no fixed share is implied. - -### 3.2 Vertical adjacency - -```text -available = H - g -item_height = available × q_item / (q_item + q_other) -other_height = available - item_height -``` - -Both regions use width `W`. Place either region first according to the selected composition. - -### 3.3 Overlay and inset - -An overlay keeps the image region and overlay region independently measurable. An inset selects a child region `(xi, yi, Wi, Hi)` inside the current region, then reapplies §2 using the same source ratio. Do not derive either region from an assumed percentage; size it from the actual hierarchy, copy, focal content, and required separation. +**Overlay and inset**: an overlay keeps the image region and overlay region independently measurable; an inset selects a child region `(xi, yi, Wi, Hi)` inside the current region and reapplies §2 with the same source ratio. Size either from the actual hierarchy, copy, focal content, and required separation, never an assumed percentage. --- @@ -121,84 +62,35 @@ An overlay keeps the image region and overlay region independently measurable. A ### 4.1 Equal grid -For `c` columns and `r` rows: +For `c` columns and `r` rows — use equal cells when peer comparison is the message, applying contain or fill independently per cell: ```text -cell_width = (W - (c - 1) × gx) / c -cell_height = (H - (r - 1) × gy) / r - -cell_x(col) = x0 + col × (cell_width + gx) -cell_y(row) = y0 + row × (cell_height + gy) +cell_width = (W - (c - 1) × gx) / c; cell_height = (H - (r - 1) × gy) / r +cell_x(col) = x0 + col × (cell_width + gx); cell_y(row) = y0 + row × (cell_height + gy) ``` -Use equal cells when peer comparison is the message. Apply contain or fill independently to each source within its cell. - ### 4.2 Weighted tracks -For column weights `u[1]…u[c]` and row weights `v[1]…v[r]`: +For column weights `u[1…c]` and row weights `v[1…r]` — use when one item is primary; a spanning item receives the sum of its tracks plus the internal gaps it crosses: ```text -available_width = W - (c - 1) × gx -available_height = H - (r - 1) × gy - -column_width[j] = available_width × u[j] / sum(u) -row_height[k] = available_height × v[k] / sum(v) +column_width[j] = (W - (c - 1) × gx) × u[j] / sum(u); row_height[k] = (H - (r - 1) × gy) × v[k] / sum(v) ``` -Use weighted tracks when one item is primary. A spanning item receives the sum of its tracks plus the internal gaps it crosses. - ### 4.3 Free multi-item composition -**Mandatory**: For montage, arc, overlap, or another non-grid arrangement, give -every carrier a finite center and positive size, give every intended overlap an -unambiguous front item, and verify the visible union against `(W,H)`. +**Mandatory**: for montage, arc, overlap, or another non-grid arrangement, give every carrier a finite center `p[i] = (cx[i], cy[i])` and positive size `(w[i], h[i])` (optionally `s[i] × (w0, h0)` for a shared size rhythm), give every intended overlap an unambiguous front item through stacking rank `z[i]` (`area(V[i] ∩ V[j]) > 0` where `V[i]` is the visible carrier after its clip and any parent contour `P`), and verify the visible union against `(W,H)`. `P` must visibly control at least one structural role (outer silhouette, shared seam, reveal, or attachment path); otherwise use the region boundary and omit it. -**Default — shared direction (may override when deliberate disorder serves the -communication job)**: Select one direction generator and derive related carriers -from shared geometry. An override still declares a bounded placement/angle rule -so disorder is authored rather than accidental. Use the following state: - -| State | Definition | -|---|---| -| `p[i] = (cx[i], cy[i])` | Explicit center of item `i` | -| `(w[i], h[i])` | Explicit positive carrier size | -| `s[i] > 0` | Optional shared size rhythm: `(w[i], h[i]) = s[i] × (w0, h0)` | -| `P` (optional) | Parent contour controlling the outer silhouette, shared seam, reveal, or attachment path | -| `V[i]` | Visible carrier after applying its clip and, when `P` is a silhouette, intersecting it with `P` | -| `z[i]` | Stacking rank required for carriers that overlap | - -For a straight shared direction `θ`, calculate centers in its local frame: - -```text -d = (cos(θ), sin(θ)) -n = (-sin(θ), cos(θ)) -p[i] = p0 + t[i] × d + e[i] × n -``` - -Choose `t[i]` and transverse offset `e[i]` as explicit sequences; add `s[i]` -when scale carries the rhythm. Reuse a progression when rhythm is intended; do -not substitute unrelated per-item values. +**Default — shared direction (may override when deliberate disorder serves the communication job)**: select one direction generator and derive related carriers from shared geometry; an override still declares a bounded placement/angle rule so disorder is authored. For a straight direction `θ`: `d = (cos θ, sin θ)`, `n = (-sin θ, cos θ)`, `p[i] = p0 + t[i] × d + e[i] × n`, with `t[i]`, transverse `e[i]`, and optional `s[i]` as explicit sequences that reuse a progression when rhythm is intended. | Generator | Executable rule | |---|---| -| `vector` | Use the straight-frame equation with ordered `t[i]`; set `t[i+1] = t[i] + advance[i]`, where each `advance[i] > 0`. Control overlap through `advance[i]`, not an accidental negative gap. | -| `shared-baseline` | Choose baseline `B(t) = b + t × d`. If `r[i]` is the carrier's half-extent along `n`, place `p[i] = B(t[i]) + r[i] × n`; this keeps one carrier edge on the same baseline while sizes vary. | -| `curve-spine` | Choose ordered parameters `u[i]` on `C(u)` with `||C'(u[i])|| > 0`. Set `d[i] = normalize(C'(u[i]))`, `n[i] = (-d[i].y, d[i].x)`, and `p[i] = C(u[i]) + e[i] × n[i]`; at a zero derivative, use the secant between nearest distinct samples or another generator. | -| `panel` | Define one convex 2D quadrilateral `A,B,C,D` in consistent winding and `F(u,v) = (1-u)(1-v)A + u(1-v)B + uvC + (1-u)vD`. Split monotone `u`/`v` intervals; each cell uses its four `F` corners. | +| `vector` | Straight-frame equation with ordered `t[i+1] = t[i] + advance[i]`, `advance[i] > 0`; overlap is controlled through `advance[i]`, never an accidental negative gap | +| `shared-baseline` | Baseline `B(t) = b + t × d`; with `r[i]` the carrier's half-extent along `n`, `p[i] = B(t[i]) + r[i] × n` keeps one edge on the baseline while sizes vary | +| `curve-spine` | Ordered `u[i]` on `C(u)` with `‖C'(u[i])‖ > 0`; `d[i] = normalize(C'(u[i]))`, `n[i] = (-d[i].y, d[i].x)`, `p[i] = C(u[i]) + e[i] × n[i]`; at a zero derivative use the secant between nearest distinct samples or another generator | +| `panel` | One convex quadrilateral `A,B,C,D` in consistent winding with `F(u,v) = (1-u)(1-v)A + u(1-v)B + uvC + (1-u)vD`; split monotone `u`/`v` intervals, each cell using its four `F` corners | -For each intended overlap, calculate `area(V[i] ∩ V[j]) > 0` and assign the -front item through `z[i]` and `z[j]`. `P` must visibly control at least one -listed structural role; otherwise use the selected region boundary and omit it. - -**Reference — not a constraint**: Use one of these angle mechanisms according to the selected composition: - -| Mechanism | Geometry | -|---|---| -| Clip-shape angle | Keep the bitmap upright and angle only the carrier contour or clip path. | -| Parent-group rotation | Build the complete arrangement first, then rotate its carriers, frames, and attached labels together around one pivot. | -| Tangent rotation | On `curve-spine`, rotate item `i` around `p[i]` by `atan2(d[i].y, d[i].x)` when the carriers should follow the path. | - -**Forbidden — unsupported image deformation**: Do not use shear, skew, or true perspective mapping. A `panel` is a set of 2D quadrilateral clips/crops; it does not warp the image plane. +**Reference — angle mechanisms**: clip-shape angle (bitmap upright, only the carrier contour or clip angled); parent-group rotation (build the arrangement, then rotate carriers, frames, and labels together around one pivot); tangent rotation (on `curve-spine`, rotate item `i` around `p[i]` by `atan2(d[i].y, d[i].x)`). **Forbidden — unsupported deformation**: no shear, skew, or true perspective; a `panel` is a set of 2D quadrilateral clips/crops, never a warped image plane. --- @@ -206,17 +98,17 @@ listed structural role; otherwise use the selected region boundary and omit it. | Check | Required response | |---|---| -| Computed width or height is non-positive | Re-select the page regions or reduce gaps | -| Contain leaves unusable residual space | Recompose the surrounding regions; do not stretch the source | +| Computed width or height non-positive | Re-select the regions or reduce gaps | +| Contain leaves unusable residual space | Recompose the surrounding regions; never stretch | | Fill removes focal or required content | Change anchor, enlarge the region, or use contain | -| Adjacent text/content region cannot carry its material | Reweight or change the selected relationship | -| Equal cells imply equality that the content does not have | Use weighted tracks or a free composition | -| Peer images use inconsistent visual scale without meaning | Normalize their regions or make the hierarchy explicit | -| A free carrier lacks an explicit center or positive size, or an intended overlap lacks stacking order | Supply the missing geometry or z-order before drawing | -| Items intended as one system lack both a shared direction and a deliberate-disorder rule | Derive them from one vector, baseline, curve, panel, or bounded override | -| Per-item angles vary without a shared direction or deliberate-disorder rule | Use one parent-group angle, a shared clip-shape direction, curve tangents, or a bounded angle rhythm | -| The parent contour does not affect silhouette, seam, reveal, or attachment | Remove it or reconstruct the carriers from that contour | -| A panel depends on shear, skew, or perspective warping | Replace it with 2D quadrilateral carriers and focal-safe crops | +| Adjacent content region cannot carry its material | Reweight or change the relationship | +| Equal cells imply an equality the content lacks | Weighted tracks or free composition | +| Peer images use inconsistent scale without meaning | Normalize regions or make the hierarchy explicit | +| A free carrier lacks a center, size, or stacking order for an overlap | Supply it before drawing | +| Items meant as one system lack both a shared direction and a deliberate-disorder rule | Derive them from one vector, baseline, curve, panel, or bounded override | +| Per-item angles vary without a shared direction or disorder rule | One parent-group angle, shared clip direction, curve tangents, or a bounded angle rhythm | +| The parent contour affects no silhouette, seam, reveal, or attachment | Remove it or reconstruct the carriers from it | +| A panel depends on shear, skew, or perspective | Replace with 2D quadrilateral carriers and focal-safe crops | | Gaps, alignments, or overlaps drift without purpose | Recalculate from the shared region and gap values | -The final geometry must express the active page hierarchy, preserve the selected resource relationships, and remain valid under the conditionally loaded technical contracts. +The final geometry expresses the active page hierarchy, preserves the selected resource relationships, and stays valid under the conditionally loaded technical contracts. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/image-renderings/_index.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/image-renderings/_index.md index 25cdaf89..6e5e611e 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/image-renderings/_index.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/image-renderings/_index.md @@ -69,9 +69,7 @@ Every coordinated Stage-2 direction carries one complete `rendering: custom` can - image_rendering_behavior: "Hand-screened poster aesthetic — slightly misregistered halftone overlays, 3 flat ink colors with visible dot pattern at 12% opacity, no gradients, no anti-aliased edges; reads as silkscreen print." ``` -**Hard rule**: three complete rendering candidates are mandatory in every fresh Stage-2 direction set; AI source recommendation remains independent. See [`strategist-image.md`](../strategist-image.md) for the Stage-2 carrier and downstream lock behavior. - -Write `image_rendering_references` only when the confirmed custom direction actually uses catalog material. One rendering may supply the complete treatment unchanged; when several are named, each contributes a distinct executable job across line, texture, depth, material, or mood. Reference count has no fixed cap; count is an outcome, not a target. A four-basis direction may assign `vector-illustration` to silhouette clarity, `minimalist-swiss` to negative-space composition, `screen-print` to restrained halftone texture, and `warm-scene` to light and mood; list all four ids. Omit every rendering whose contribution cannot be stated and never add a second merely to imply synthesis. A custom using no catalog source omits the field and proceeds from its standalone behavior; never invent a reference merely to legitimize `custom`. +Candidate authoring, the three-per-direction rule, and `image_rendering_references` projection are owned by [`strategist-image.md`](../strategist-image.md) §2. --- diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/image-searcher.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/image-searcher.md index cf4554e4..87359916 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/image-searcher.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/image-searcher.md @@ -2,36 +2,29 @@ # Image_Searcher Reference Manual -Role definition for the **web image acquisition path**: translate the active resource owner's intent into keyword queries, search openly-licensed providers, download a license-cleared image into `project/images/`, and record provenance + license metadata into `image_sources.json`. +Role definition for the **web image acquisition path**: translate the resource owner's intent into keyword queries, search openly-licensed providers, download one license-cleared image into `project/images/`, and record provenance and license in `image_sources.json`. -**Trigger**: the Default Generate resource list contains `Acquire Via: web`, or Quick Generate has resolved a required web image in active context. Load only when at least one such resource exists. +**Trigger**: the Default resource list contains `Acquire Via: web`, or Quick has resolved a required web image in active context. --- ## 1. License Tier Discipline -Every **provider-sourced** image is classified into one of two tiers; anything else is rejected outright. A third tier, `manual`, exists **only** for a directly selected replacement from [`--from-url`](#5-running-image_searchpy) or an adopted-page source package — it is never the result of a provider search accepting an unknown license. +Every provider-sourced image lands in one of two tiers; everything else is rejected. `manual` exists only for a directly selected `--from-url` replacement or an adopted-page package image — never for a provider result with an unknown license. Downstream consumers read `license_tier` alone and never interpret raw license strings. | Tier | Licenses | On-slide attribution | |---|---|---| | `no-attribution` | CC0, Public Domain, Pexels License, Pixabay Content License | None | | `attribution-required` | CC BY, CC BY-SA | Inline credit `<text>` on the slide | -| `manual` | Directly selected URL or adopted-page package image (license unverified) | None — verifying rights / any credit is the user's responsibility | +| `manual` | Directly selected URL or adopted-page image, license unverified | None — rights and any credit are the user's responsibility | -**Forbidden — auto-rejected licenses**: - -- CC BY-NC, CC BY-NC-SA (non-commercial) -- CC BY-ND, CC BY-NC-ND (no derivatives) -- All Rights Reserved -- Unknown / missing license - -> `license_tier` is the central abstraction. Downstream consumers (Executor) read this single field and never interpret raw license strings. +**Forbidden — auto-rejected**: CC BY-NC, CC BY-NC-SA, CC BY-ND, CC BY-NC-ND, All Rights Reserved, unknown or missing license. --- ## 2. Search Strategy -Default: quality-first across all allowed license tiers. Do not prefer CC0 / Public Domain over a better CC BY / CC BY-SA image; rely on the manifest's `license_tier` so Executor can add attribution only when needed. +Quality first across all allowed tiers — never prefer CC0 over a better CC BY image; the manifest's `license_tier` lets Executor add credit only when needed. `--strict-no-attribution` (CC0 / PD / Pexels / Pixabay only) is opt-in for decks that cannot carry any on-slide credit. ``` Multimodal Generate: explicit query variants × provider chain + allowed licenses @@ -39,62 +32,33 @@ Multimodal Generate: explicit query variants × provider chain + allowed license → download one original; if none passes, inspect the next 8 first. Non-visual / standalone best-only: explicit query variants × provider chain → strict metadata gate → first downloadable ranked original wins. -Strict: provider chain, license filter = cc0,pdm,pexels,pixabay - → apply the same selected execution mode without CC BY / CC BY-SA. ``` -`--strict-no-attribution` is opt-in. Use it only when the deck cannot tolerate any on-slide credit (corporate template, full-bleed hero). - --- ## 3. Providers | Provider | Config | Strength | |---|---|---| -| Pexels | recommended: `PEXELS_API_KEY` (free, [signup](https://www.pexels.com/api/)) | modern stock photography, people, workplace, lifestyle | -| Pixabay | recommended: `PIXABAY_API_KEY` (free, [signup](https://pixabay.com/api/docs/)) | broad type coverage including photos and illustrations | +| Pexels | `PEXELS_API_KEY` (free, [signup](https://www.pexels.com/api/)) | modern stock photography, people, workplace, lifestyle | +| Pixabay | `PIXABAY_API_KEY` (free, [signup](https://pixabay.com/api/docs/)) | broad coverage including illustrations; its API serves at most a 1280 px long edge, so prefer Wikimedia or Pexels for full-bleed heroes | | Openverse | zero-config | fallback aggregator: Wikimedia + Flickr + museums + rawpixel | -| Wikimedia Commons | zero-config | educational, scientific, geographic, historical | +| Wikimedia Commons | zero-config | educational, scientific, geographic, historical; pin `provider: wikimedia` for murals, manuscripts, artworks, and museum objects, which stock providers tag with tourist snapshots | -Default chain (when `--provider` is unset): - -`pexels` (when keyed) → `pixabay` (when keyed) → `openverse` → `wikimedia`. - -Keyed providers without an API key are silently skipped — not an error. - -**Reference — provider fit by subject**: Pixabay's API serves at most a -1280 px long-edge file even when its metadata reports a much larger original, -so a landscape hero row with the default 1200×800 floors can fail promotion on -height; prefer Wikimedia or Pexels originals for full-bleed use. For murals, -manuscripts, artworks, and museum objects, pin `provider: wikimedia` on that -row: stock providers tag tourist snapshots with the place name, and those pass -`required_terms` while showing no artwork at all. - -**Default — keyed providers for broader stock coverage (may override when zero-config sources fit)**: Configure Pexels or Pixabay when their stock-photo coverage serves the brief. Their absence is not a validation failure; Openverse and Wikimedia remain valid zero-config acquisition paths. +Default chain: `pexels` → `pixabay` (each when keyed) → `openverse` → `wikimedia`; a keyed provider without a key is silently skipped. Configure Pexels or Pixabay when stock coverage serves the brief; their absence is never a failure. --- ## 4. Intent → Query Translation -Keep two layers distinct: - | Layer | Owner and grammar | |---|---| -| Default Generate `design_spec.md §VIII Reference` | Strategist's complete visual intent: exact subject, desired view/mood, focal or quiet region, and crop-safety constraints. Positive quality cues are valid here. | -| Quick Generate active `Reference` | Current main agent's active-context intent after honoring explicit user assets, URLs, subjects, and constraints; unspecified choices are resolved automatically without confirmation. | -| `image_queries.json.items[].query` / positional query | Image_Searcher's concrete entity/identity keyword string. Start with the shortest phrase that preserves identity; keep exact multi-word names and necessary disambiguators even when they exceed four words. Omit mood, quality, composition, HEX, and negative wording. | +| Default `design_spec.md §VIII Reference` / Quick active `Reference` | The owner's complete visual intent — exact subject, view/mood, focal or quiet region, crop safety, positive quality cues — fixed for the run and never rewritten by this role | +| `image_queries.json.items[].query` / positional query | This role's concrete entity keyword string: the shortest phrase that preserves identity, keeping exact multi-word names and disambiguators even beyond four words; no mood, quality, composition, HEX, or negative wording | -Web APIs match metadata, not semantic intent. Providers try each explicit query first, then progressively simplified four/three/two/one-word variants. A pipeline manifest should therefore use a concise primary `query` without pre-truncating exact names, plus `query_variants` for materially different official translations, spellings, aliases, or Chinese names. The tool aggregates and deduplicates their results; do not use variants for cosmetic word-order changes. For Chinese landmarks, pair the precise Chinese name used by Wikimedia with compact English identity terms used by stock providers. +Web APIs match metadata, not intent: providers try each explicit query, then progressively simplified four/three/two/one-word variants, so keep a concise primary `query` plus `query_variants` for materially different official translations, spellings, aliases, or Chinese names (never cosmetic word-order changes); for Chinese landmarks pair the Wikimedia Chinese name with compact English identity terms. A candidate either satisfies the existing intent or the role tries materially different query/provider/license strategies until none remain, then marks `Needs-Manual`; never loosen `required_terms`, the license policy, or the intent to manufacture a match. -Image_Searcher consumes the active Reference and never rewrites its owner. In Default Generate, that means no rewrite of `design_spec.md` or `spec_lock.md`; in Quick Generate, the active-context Reference remains fixed for the run. A candidate either satisfies that existing subject/focal/crop intent, or the role tries materially different query/provider/permitted-license strategies until no untried strategy remains, then marks `Needs-Manual`. Never loosen `required_terms`, the license policy, or the active intent to manufacture a match. - -When the subject is an exact entity (landmark / person / company / product / venue), write `required_terms` at the same time you write the row's `query` and `query_variants`. Use one required group per identity anchor and `|` for aliases / translations, e.g. `["Chongqing|重庆", "Jiefangbei|解放碑|Liberation Monument"]`. This keeps provider queries short while preventing metadata-ranked wrong entities from being accepted automatically. - -Do **not** loosen `required_terms` to generic category words just to improve coverage. Terms like `canyon`, `grand canyon`, `stone pillar`, `ground fissure`, `ancient town`, `bridge`, `temple`, or `village` belong in the search query, not as the only identity gate. For small / Chinese-local attractions, the correct failure mode is `Needs-Manual` or a user-provided `--from-url`, not a visually plausible image of the wrong place. - -**Forbidden — web negative prompts**: `not tourist snapshot`, `no amateur photo`, `avoid low quality`. - -> Note: Keyword APIs search negative words literally. +**Hard rule — `required_terms` for exact entities** (landmarks, people, companies, products, venues, named artworks and institutions): write them with the query — one group per identity anchor, `|` for aliases, e.g. `["Chongqing|重庆", "Jiefangbei|解放碑|Liberation Monument"]`. Never loosen them to category words (`canyon`, `stone pillar`, `ancient town`, `bridge`, `temple`); those belong in the query, and a small or local attraction that metadata cannot prove ends in `Needs-Manual` or a user `--from-url`, never a plausible image of the wrong place. Never use them for generic mood rows ("modern city skyline", "team collaboration"). **Forbidden — negative words** (`not tourist snapshot`, `no amateur photo`): keyword APIs search them literally. | §VIII Reference (intent) | Provider query | |---|---| @@ -107,312 +71,118 @@ Do **not** loosen `required_terms` to generic category words just to improve cov ## 5. Running `image_search.py` ```bash -python3 scripts/image_search.py "<query>" \ - --filename <name>.jpg \ - --slide <slide_id> \ - --orientation landscape \ - --purpose background \ - -o <project_path>/images +python3 scripts/image_search.py "<query>" --filename <name>.jpg --slide <slide_id> \ + --orientation landscape --purpose background -o <project_path>/images ``` -| Parameter | Required | Default | Description | -|---|---|---|---| -| `query` | yes | — | Positional. Pre-simplification not necessary; CLI runs `simplify_query` internally. | -| `--query-variant` | no | — | Repeatable official translation, spelling, alias, or materially different entity phrase; results are aggregated and deduplicated. Batch rows use `query_variants`. | -| `--filename` | yes | — | Output filename matching the resource list | -| `-o / --output` | no | `.` | Output directory; manifest defaults to `<output>/image_sources.json` | -| `--slide` | no | `""` | Slide ID from resource list (recorded in manifest) | -| `--purpose` | no | `""` | `background` / `hero` / `side` / `accent` | -| `--orientation` | no | `any` | `any` / `landscape` / `portrait` / `square` | -| `--min-width / --min-height` | no | `1200 / 800` | Actual downloaded-pixel floors; `--from-url` honors explicit lower overrides | -| `--provider` | no | (chain) | Pin one provider | -| `--strict-no-attribution` | no | off | Restrict to no-attribution licenses; refuse CC BY / CC BY-SA | -| `--require-terms` | no | — | Entity-safety gate for exact subjects. Repeatable; comma separates required groups; `A|B` means aliases within one group. Example: `--require-terms Chongqing --require-terms "Jiefangbei|Liberation Monument"` | -| `--manifest` | no | (default) | Override manifest path | -| `--save-candidates` | no | off | Thumbnail-selection mode: save one ranked page of review-eligible previews and `review_sheet.jpg`, but no original or provenance record. Multimodal Generate enables this; standalone CLI remains best-only by default | -| `--max-candidates` | no | `8` | Thumbnail page size. `0` explicitly requests the complete pool and is reserved for debugging / exceptional review, not normal Generate | -| `--candidate-page` | no | `1` | Ranked thumbnail page to fetch. Page 2 starts at rank 9 with the default page size. Batch rows may override with `candidate_page` | -| `--promote` | no | — | Download exactly one selected candidate original, enforce the request's size/readability gates, and write provenance | -| `--from-url` | no | — | Manual replace: download a directly selected image URL into `--filename` (recorded `license_tier: manual`); works without a multimodal model | +| Parameter | Default | Description | +|---|---|---| +| `query` (positional, required) | — | Simplified internally | +| `--query-variant` | — | Repeatable alias/translation; batch rows use `query_variants` | +| `--filename` (required) | — | Output filename matching the resource list | +| `-o / --output` | `.` | Output directory; manifest defaults to `<output>/image_sources.json` | +| `--slide`, `--purpose`, `--orientation` | `""`, `""`, `any` | Recorded slide id; `background` / `hero` / `side` / `accent`; `landscape` / `portrait` / `square` | +| `--min-width / --min-height` | `1200 / 800` | Downloaded-pixel floors; `--from-url` honors explicit lower overrides | +| `--provider` | chain | Pin one provider | +| `--strict-no-attribution` | off | Refuse CC BY / CC BY-SA | +| `--require-terms` | — | Repeatable identity gate; comma separates groups, `A|B` aliases | +| `--save-candidates` | off | Thumbnail mode: one ranked page of previews plus `review_sheet.jpg`, no original | +| `--max-candidates` | `8` | Page size; `0` = complete pool, debugging only | +| `--candidate-page` | `1` | Ranked page; page 2 starts at rank 9 | +| `--promote <candidate>` | — | Download exactly one selected original, enforce gates, write provenance | +| `--from-url <url>` | — | Manual replacement recorded as `license_tier: manual`; works without vision | +| `--manifest <path>` | `images/image_queries.json` | Override the manifest path | -### Batch mode (≥ 2 web rows) — preferred - -When more than one row is `Acquire Via: web`, do **not** call the CLI once per row. Write all rows into one `image_queries.json` and run a single concurrent batch — the web sister of `image_gen.py --manifest`: +**Batch mode (≥2 web rows) — preferred**: write every row into `image_queries.json` and run one concurrent batch (the web sister of `image_gen.py --manifest`); add `--save-candidates` whenever the agent can inspect images: ```bash -python3 scripts/image_search.py --batch <project_path>/images/image_queries.json \ - -o <project_path>/images \ - --save-candidates +python3 scripts/image_search.py --batch <project_path>/images/image_queries.json -o <project_path>/images --save-candidates ``` -The candidate flag above is the normal Generate invocation when the current -agent can inspect images. It downloads previews only and moves each successful -row to `Needs-Selection`; no target image or `image_sources.json` entry exists -yet. A non-multimodal agent omits it and follows the handoff rules under -Suitability review below: only strict metadata-verified candidates may download -automatically. Standalone CLI use remains best-only unless the caller explicitly -requests thumbnail selection. - -`image_queries.json` schema (one item per web row): - ```json -{ - "items": [ - { - "filename": "jiefangbei.jpg", - "query": "Jiefangbei Chongqing downtown monument", - "query_variants": ["Chongqing Liberation Monument", "重庆 解放碑"], - "slide": "03_landmark", - "purpose": "exact landmark photo", - "orientation": "landscape", - "required_terms": ["Chongqing", "Jiefangbei|Liberation Monument"], - "status": "Pending" - } - ] -} +{ "items": [ { + "filename": "jiefangbei.jpg", + "query": "Jiefangbei Chongqing downtown monument", + "query_variants": ["Chongqing Liberation Monument", "重庆 解放碑"], + "slide": "03_landmark", "purpose": "exact landmark photo", "orientation": "landscape", + "required_terms": ["Chongqing", "Jiefangbei|Liberation Monument"], + "status": "Pending" +} ] } ``` -Required per item: `filename`, `query`, `status` (`Pending`). Optional per-item overrides: `query_variants`, `candidate_page`, `slide`, `purpose`, `orientation`, `provider`, `strict_no_attribution`, `min_width`, `min_height`, `required_terms`. +Required per item: `filename`, `query`, `status`; optional: `query_variants`, `candidate_page`, `slide`, `purpose`, `orientation`, `provider`, `strict_no_attribution`, `min_width`, `min_height`, `required_terms`. The runner revalidates every `Sourced` row against its file, dimensions, and manifest entry (drift → `Failed`), then searches all `Pending` / `Failed` rows concurrently (default concurrency 3, `--concurrency N` or `IMAGE_SEARCH_CONCURRENCY`; `1` for strict pacing on rate-sensitive free providers). Thumbnail mode writes `Needs-Selection` with `candidate_page`, `candidate_count`, `candidate_total`, `has_more_candidates`, `next_candidate_page`, and the `review_sheet` path, creating no image or provenance; to see the next page for one row set its `candidate_page` to `next_candidate_page`, reset only that row to `Pending`, and rerun. Promoting with the same `--batch` manifest moves the row to `Sourced`. Provider failures stay retryable `Failed`; clean exhaustion becomes `Needs-Manual`; status is saved after each completion. -Use `required_terms` for **exact-entity images**: landmarks, people, companies, products, venues, named artworks, and named institutions. Each list item is required; alternatives inside one item use `|`. Example for a Chongqing landmark: `["Chongqing|重庆", "Jiefangbei|解放碑|Liberation Monument"]`. In best-only mode, candidates whose title / author / source URL do not satisfy every group are rejected before ranking, so a visually polished but wrong Rome / Hoi An image cannot win. Thumbnail mode may show a separately labeled near match only for visual identity verification; it never promotes automatically. Do **not** use `required_terms` for generic mood / background rows such as "modern city skyline" or "team collaboration". +**Ranking** orders provider metadata, never pixels, and must not be tuned into a taste engine: hard-reject invalid licenses and zero relevance; in best-only mode reject any candidate missing a `required_terms` group; in thumbnail mode keep strict matches first and admit a near match only when exactly one group is missing and the finding query still has strong relevance (marked `identity_evidence: visual-verification-required`, never auto-promoted); then metadata-verified identity in the title outranks a URL-only match; concrete query tokens match whole ASCII tokens (`office` ≠ `officer`) and dominate generic words; orientation is a small penalty, no-attribution a small bonus, pixel count capped so a huge weak match cannot beat a smaller accurate one. -For less-covered local attractions, keep the strict identity gate rather than progressively deleting location anchors or replacing proper names with category words. If strict metadata cannot prove the entity, mark the row `Needs-Manual` and use the manual URL path when the user supplies a confirmed source. +**Suitability review** — a top hit is downloadable and token-relevant, not visually suitable (the reviewer receives only the locked row intent plus candidate sidecars/sheets, never the full planning or acquisition context): -The runner first revalidates every `Sourced` row against its readable file, requested dimensions, and `image_sources.json` entry; drift returns that row to `Failed`. It then searches all `Pending` / `Failed` rows concurrently. Thumbnail mode writes `Needs-Selection`, `candidate_page`, `candidate_count`, `candidate_total`, `has_more_candidates`, `next_candidate_page`, and the relative `review_sheet` path without creating a target image or provenance. To inspect the next page for one row, set its `candidate_page` to `next_candidate_page`, reset only that row to `Pending`, and rerun the batch. Promoting one candidate with the same `--batch` manifest changes that row to `Sourced`. Provider failures remain retryable `Failed`, while clean provider/stage exhaustion becomes terminal `Needs-Manual`. Status is saved after each completion. A single `web` row may still use single-query mode above. +- **With vision**: `--save-candidates` saves at most the first 8 ranked previews under `candidates/<stem>/review/` and the sheet; run [`web-image-review.md`](../workflows/stages/web-image-review.md) — one isolated reviewer for the batch when available, otherwise local review — then only the image owner promotes the returned filename. Never promote the least-bad candidate; if none passes and `has_more_candidates` is true, fetch `--candidate-page 2` before changing the query. For exact entities, `required_terms` gates metadata and the review image confirms the pixels show the subject and satisfy the focal/crop intent; a generic `required_terms` pass is not acceptance (matching `Ground Fissure` can return an unrelated station named Yunlong). +- **Without vision**: omit `--save-candidates`; the tool excludes near matches, downloads only the first candidate passing every strict metadata, license, and dimension gate, and records `selection_method: metadata-ranked` — never described as visual confirmation. With no strict candidate, or an intent that needs a viewpoint, crop, expression, or fine identity metadata cannot establish, mark `Needs-Manual`; Quick opens no interaction. -**Pacing**: free providers (Wikimedia/Openverse) are rate-sensitive, so batch concurrency defaults to a modest **3** (`--concurrency N`, or `IMAGE_SEARCH_CONCURRENCY` env). Use `--concurrency 1` to restore strict one-at-a-time pacing. Single-query mode is one request at a time by nature. +**Replacement ladder**: (1) with vision, promote the one passing thumbnail; (2) with `has_more_candidates`, fetch the next page (numbering continues globally — page 2 starts at `candidate_09`); (3) after the pool is exhausted, add materially different identity/translation/alias/viewpoint/disambiguation variants and generate a fresh pool; (4) with vision only, after normal search is exhausted, fetch one adopted `source_url` as a Markdown + companion-image package under [`topic-research`](../workflows/stages/topic-research.md) § Hand-off, copy one passing image into `images/`, and reconcile the row and `image_sources.json` from its `image_manifest.json` entry with `license_tier: manual` (never auto-expand facts URLs or promote the whole package); (5) manual URL replace — `python3 scripts/image_search.py --from-url <image-url> --filename <name>.jpg -o <project_path>/images` — recorded `manual`, only with a URL already supplied in Quick; it updates the image and `image_sources.json` but not `image_queries.json`, so validate the file and reconcile the query row and roster to `Sourced` before export ([`executor-web-image.md`](./executor-web-image.md) §1); (6) when variants, pages, providers, license stages, and the package fallback are exhausted, mark `Needs-Manual`. This review never opens an acquisition-time interaction ([`image-base.md`](./image-base.md) §3): Default may continue to Step 6 with a placeholder; Quick blocks direct export when the image is required. -### Ranking model - -`image_search.py` ranks provider metadata, not pixels. The order is deliberately conservative: - -1. common hard reject: invalid license or zero query relevance; -2. strict automatic gate: best-only mode rejects every candidate missing any `required_terms`; this is the only pool available without visual review; -3. visual-review widening: thumbnail mode keeps strict matches first, then may admit a near match only when exactly one required group is absent and the explicit query that found it still has strong metadata relevance. The sidecar marks it `identity_evidence: visual-verification-required`; visual inspection must establish the missing identity before promotion; -4. identity priority: metadata-verified candidates whose title contains the required entity terms outrank candidates that match only via URL; -5. query relevance: concrete query tokens match whole ASCII metadata tokens and dominate generic visual words like "photo", "high quality", "background"; substrings such as `office` inside `officer` do not count; -6. layout fit: requested orientation helps; mismatched orientation is a small penalty, not a hard reject; -7. license / size tie-breakers: no-attribution is a small bonus; pixel count is capped so a huge but weakly relevant image cannot outrank a smaller accurate image. - -Do not tune this into a visual taste engine. The scorer removes obvious metadata failures and orders the thumbnail sheet; visual review still decides whether any candidate fits the slide. - -### Suitability review — with or without a multimodal model - -A metadata-ranked top hit is *downloadable and token-relevant*, not necessarily *visually suitable* — `score_candidate` never sees pixels. Review it against the active Reference and Crop Policy before it is trusted: - -- **Multimodal review available**: run `--save-candidates`. The tool aggregates explicit query variants, deduplicates them, and saves at most the first **8** ranked previews under `candidates/<stem>/review/`; `review_sheet.jpg` contains only that page and no original is downloaded. Run [`web-image-review.md`](../workflows/stages/web-image-review.md): use one isolated vision reviewer for the current batch when available, otherwise review locally. Only the active image owner may use the returned candidate filename with `--promote`. If `has_more_candidates` is true and none passes, fetch `--candidate-page 2` before changing the query. -- **Non-multimodal model (no vision)**: omit `--save-candidates`; the tool excludes every `visual-verification-required` near match, downloads only the first candidate that passes all strict metadata / license / dimension gates, and records `selection_method: metadata-ranked`. Do **not** describe this as visual confirmation. If no strict candidate exists, or the active Reference requires a viewpoint, crop, expression, or fine identity detail that metadata cannot establish, mark the row `Needs-Manual`; Quick does not open an acquisition-time interaction. - -The review stage owns pixel-inspection gates, bounded detail reads, and the compact decision receipt. It receives only the locked row intent plus candidate sidecars/sheets; it never receives the full planning or acquisition context. - -If no thumbnail on the current page passes, download no original. When -`has_more_candidates` is true, advance to `next_candidate_page` first. Only -after the ranked pool is exhausted should you change the query materially — -identity wording, translation, alias, viewpoint, or necessary disambiguator — -reset that row to `Pending`, and generate a fresh pool. Do not promote the -least-bad candidate. - -For exact-entity rows, suitability has two gates: `required_terms` first enforces metadata identity, then the `.review` image confirms the pixels actually show the right subject and satisfy the active focal/crop intent. Passing metadata never authorizes changing that intent downstream. - -Never treat a generic `required_terms` pass as acceptance. For example, matching `Ground Fissure` can return an unrelated transit station named Yunlong, and matching `stone pillar` can return a different scenic area. If the proper name / geography cannot be retained, stop at `Needs-Manual`. - -**Replacement ladder when the first round is not right**: - -1. With vision, promote the one passing thumbnail selected under the review-stage contract; this is the first original-image request. -2. If none passes and `has_more_candidates` is true, fetch the next ranked page (8 by default). Candidate numbers continue globally, so page 2 starts at `candidate_09`; do not repeat page 1 or download an original. -3. After the current pool is exhausted, add materially different query variants for identity wording, official translation, alias, viewpoint, or disambiguation and generate a fresh pool; do not repeat a semantically exhausted query. -4. With vision only, if normal search is exhausted, select one relevant adopted `source_url` and follow [`topic-research`](../workflows/stages/topic-research.md) § Hand-off to fetch its Markdown + companion-image source package. Review that package, copy only one passing image into `<project>/images/`, and reconcile the query row plus `image_sources.json` from the selected `image_manifest.json` entry with `license_tier: manual`. Fetch another page only when the current package has no passing image; never auto-expand facts URLs or promote the whole package. -5. **manual URL replace (universal, model-agnostic)** — use a directly selected URL and swap it in: - ```bash - python3 scripts/image_search.py --from-url <image-url> --filename <name>.jpg -o <project_path>/images - ``` - Recorded with `license_tier: manual` — verifying usage rights is the user's - call. In Quick Generate, use this step only when the URL was already - supplied; never pause to request one. The command updates the image and - `image_sources.json` but does **not** rewrite `image_queries.json`. Validate - the downloaded file and matching manual-provenance entry, then reconcile - that query row and the active roster to `Sourced` before export; a stale - `Needs-Manual` status remains blocking - ([`executor-web-image.md`](./executor-web-image.md) §1); -6. When the query variants, ranked pages, configured provider chain, permitted license stages, and eligible adopted-page package fallback are exhausted, mark the row `Needs-Manual`. - -**This review never opens an acquisition-time interaction** ([`image-base.md`](./image-base.md) §6). Default Generate may build a placeholder and continue to Step 6. Quick Generate finishes all permitted automated strategies, records `Needs-Manual`, and blocks direct export when the unresolved image is required. - -### Visual selection candidates (multimodal Generate; standalone opt-in) - -Candidate-thumbnail saving stays **off by default for standalone CLI use**. -Generate enables it for every web row when the current agent can inspect images, -so the first pass sees a bounded ranked page rather than trusting metadata rank -1 or flooding the reviewer with the complete pool. - -```bash -python3 scripts/image_search.py "<query>" --filename <name>.jpg -o <project_path>/images \ - --save-candidates -``` - -Saves provider previews to `images/candidates/<stem>/review/` with a -thumbnail-only `candidates.json` manifest and an automatically generated -`candidates/<stem>/review_sheet.jpg` containing only the current round. The -default first round is ranks 1–8. The sidecar records `candidate_page`, -`page_size`, `candidate_total`, `has_more_candidates`, each candidate's matched -query, and whether identity is metadata-verified or requires visual -verification. The target filename and `image_sources.json` remain untouched. -Inspect the sheet first, open only plausible individual previews when needed, -then promote the best fit — only that full-resolution original is downloaded -to the target: +**Standalone thumbnail selection** (opt-in outside Generate): ```bash +python3 scripts/image_search.py "<query>" --filename <name>.jpg -o <project_path>/images --save-candidates python3 scripts/image_search.py --promote candidate_03.jpg --filename <name>.jpg -o <project_path>/images - -# No pass on page 1, but candidates.json says has_more_candidates: true -python3 scripts/image_search.py "<same query>" --filename <name>.jpg \ - -o <project_path>/images --save-candidates --candidate-page 2 - -# Batch flow: also reconcile image_queries.json from Needs-Selection to Sourced -python3 scripts/image_search.py --promote candidate_03.jpg --filename <name>.jpg \ - --batch <project_path>/images/image_queries.json -o <project_path>/images +python3 scripts/image_search.py "<same query>" --filename <name>.jpg -o <project_path>/images --save-candidates --candidate-page 2 +python3 scripts/image_search.py --promote candidate_03.jpg --filename <name>.jpg --batch <project_path>/images/image_queries.json -o <project_path>/images ``` -For batch continuation, set only the no-pass row's `candidate_page` to its -`next_candidate_page`, reset that row to `Pending`, and rerun. Use -`--max-candidates 0` only when a complete-pool dump is explicitly useful for -debugging; it is not the Generate default. +Previews land in `images/candidates/<stem>/review/` with a thumbnail-only `candidates.json` (page, size, total, `has_more_candidates`, matched query, identity evidence) and `review_sheet.jpg` for the current round; the target and manifest stay untouched until promotion. --- ## 6. Manifest Format (`image_sources.json`) -Every successful download appends or replaces one entry keyed on `filename`: +Each successful download appends or replaces one entry keyed on `filename`; the file is written atomically and is idempotent, and an unreadable existing manifest blocks the write. ```json { "license_verification": "provider metadata used; manual review recommended for external delivery", "generated_at": "2026-05-01T12:17:59.856275Z", - "items": [ - { - "filename": "team.jpg", - "slide": "03_team", - "purpose": "Leadership photo", - "search_query": "executive boardroom meeting", - "matched_query": "leadership team boardroom", - "selection_method": "metadata-ranked", - "orientation": "landscape", - "provider": "openverse", - "stage": "all", - "title": "Untitled", - "author": "", - "source_page_url": "https://www.rawpixel.com/...", - "download_url": "https://...", - "license_name": "CC0", - "license_url": "https://creativecommons.org/publicdomain/zero/1.0/", - "license_tier": "no-attribution", - "attribution_required": false, - "width": 1024, - "height": 683, - "metadata_dimensions": { - "width": 4800, - "height": 3200, - "note": "upstream-reported size; actual downloaded file is smaller (likely a preview)" - }, - "attribution_text": "team.jpg — \"Untitled\" via Openverse — license: CC0 (...)", - "status": "sourced" - } - ] + "items": [ { + "filename": "team.jpg", "slide": "03_team", "purpose": "Leadership photo", + "search_query": "executive boardroom meeting", "matched_query": "leadership team boardroom", + "selection_method": "metadata-ranked", "orientation": "landscape", + "provider": "openverse", "stage": "all", + "title": "Untitled", "author": "", + "source_page_url": "https://www.rawpixel.com/...", "download_url": "https://...", + "license_name": "CC0", "license_url": "https://creativecommons.org/publicdomain/zero/1.0/", + "license_tier": "no-attribution", "attribution_required": false, + "width": 1024, "height": 683, + "metadata_dimensions": { "width": 4800, "height": 3200, "note": "upstream-reported size; actual downloaded file is smaller (likely a preview)" }, + "attribution_text": "team.jpg — \"Untitled\" via Openverse — license: CC0 (...)", + "status": "sourced" + } ] } ``` -| Field | Notes | -|---|---| -| `matched_query` | Explicit primary query or query variant that discovered the selected asset. | -| `selection_method` | `visual-thumbnail` after promotion from a reviewed preview, or `metadata-ranked` for the strict no-vision / best-only path. It never claims a visual check that did not occur. | -| `width` / `height` | Measured from the file actually saved to disk. Use these for layout. | -| `metadata_dimensions` | Present only when upstream-claimed size differs from the saved file (preview vs original). Informational only. | -| `license_tier` | Drives Executor's attribution decision: `no-attribution` / `attribution-required` for provider-sourced images, or `manual` for a directly selected URL/source-package replacement (embed only; rights/credit are the user's responsibility). | -| `attribution_required` | Boolean alias of `license_tier == "attribution-required"`. | -| `attribution_text` | Canonical credit source. Preserve its author/provider/license facts; compress only through §7's visual grammar rather than inventing or dropping identity. | -| `stage` | `all` by default, or `no-attribution-only` when strict mode is used. | - -> Manifest is **idempotent on `filename`** and written atomically. Rerunning replaces that entry while preserving all others. An existing unreadable/non-object manifest blocks the write instead of being overwritten as fresh state. +`matched_query` is the query or variant that found the asset; `selection_method` is `visual-thumbnail` after a reviewed promotion or `metadata-ranked` for the strict path; `width` / `height` are measured from the saved file (use them for layout) while `metadata_dimensions` appears only when the upstream claim differs; `license_tier` drives Executor's attribution; `attribution_text` is the canonical credit source, compressed only through §7's grammar; `stage` is `all` or `no-attribution-only`. --- ## 7. On-Slide Attribution Contract -Applied by Executor when an image's `license_tier == "attribution-required"`. - -**Hard rule — legal content and binding**: Every slide that uses the asset carries a visible, readable credit bound unambiguously to that asset. Preserve its author, source/provider, and CC BY / CC BY-SA license facts from `attribution_text`; do not invent, merge away, or drop identity. - -**Reference — visual treatment is not a constraint**: Position, size, color, line structure, per-image versus combined credits, labels, and contrast treatment belong to the page composition. Use any treatment that stays readable and preserves the asset-to-credit binding; a scrim or gradient is optional, not required. - -**Reference — attribution treatments, not constraints**: - -| Page situation | Possible treatment | -|---|---| -| One credited image | Place a compact credit near the image edge or in a page footnote area | -| Several credited images | Use per-image credits or one combined source line with labels when needed for unambiguous mapping | -| Hero / full-bleed image | Place the credit in an available quiet region; add a scrim or gradient only when contrast otherwise fails | - -Use `attribution_text` from the manifest as the **starting point**. Compress when the chosen page treatment needs a shorter line, without dropping the required facts: - -| Manifest | Slide credit | -|---|---| -| `team.jpg — "Untitled" via Openverse — license: CC0 (...)` | `via Openverse / CC0` | -| `team.jpg — "Sunset" by Jane Doe via Wikimedia Commons — license: CC BY-SA 4.0 (...)` | `© Jane Doe / Wikimedia / CC BY-SA 4.0` | +For `license_tier: attribution-required`, every slide using the asset carries a visible, readable credit bound unambiguously to it, preserving author, source/provider, and CC BY / CC BY-SA facts from `attribution_text`. Position, size, color, per-image versus combined credits, labels, and contrast treatment belong to the page — a compact credit near the image edge or footnote area for one image, per-image credits or one labeled combined line for several, a quiet region (a scrim or gradient only when contrast fails) on a hero. Compress without dropping required facts: `team.jpg — "Untitled" via Openverse — license: CC0 (...)` → `via Openverse / CC0`; `team.jpg — "Sunset" by Jane Doe via Wikimedia Commons — license: CC BY-SA 4.0 (...)` → `© Jane Doe / Wikimedia / CC BY-SA 4.0`. --- ## 8. Failure Handling (web-specific) -Extends [`image-base.md`](./image-base.md) §6. - -| Situation | Behavior | -|---|---| -| No candidates from any provider in either stage | Mark row `Needs-Manual`. Suggest a more precise query or another configured provider; rerun without `--strict-no-attribution` only when the confirmed page may carry visible credit. | -| Current thumbnail page has no acceptable image and `has_more_candidates` is true | Fetch `next_candidate_page`; do not change the query or download an original yet. | -| Requested thumbnail page is past `candidate_total` | Treat the current pool as exhausted; add a materially different query variant or move to the manual boundary. | -| One or more previews fail while another qualified preview succeeds | Keep the successful thumbnail set; no original has been requested. | -| Every qualified preview fails | Mark row `Failed`; a later batch run retries it. | -| Selected original fails its download/readability/dimension gate | Leave `Needs-Selection`; select another passing thumbnail or materially change the query. Do not commit provenance. | -| Best-only candidate fails to download (HTTP 403/404) | Dispatcher auto-falls through to the next ranked candidate. | -| Provider/network failure remains after dispatch | Mark row `Failed`; a later batch run retries it. | -| Keyed provider has no API key | Silently skipped. Not an error. | - -CLI exit: a successfully prepared `Needs-Selection` thumbnail set returns `0` -as an intermediate success; `Failed` or `Needs-Manual` returns `1`. +Extends [`image-base.md`](./image-base.md) §3. No candidates from any provider or stage → `Needs-Manual` (suggest a more precise query or another provider; rerun without `--strict-no-attribution` only when the page may carry credit). No acceptable image on the current page with `has_more_candidates` → fetch `next_candidate_page` without changing the query or downloading. A page past `candidate_total` → pool exhausted, add a variant or move to the manual boundary. Some previews fail while another qualifies → keep the set. Every preview fails, or a provider/network failure remains → `Failed`, retried by a later batch. A promoted original fails its download/readability/dimension gate → stay `Needs-Selection` and select another or change the query. A best-only download 403/404 → the dispatcher falls to the next ranked candidate. A keyed provider without a key → skipped. CLI exit: a prepared `Needs-Selection` set returns `0`; `Failed` or `Needs-Manual` returns `1`. --- ## 9. Handoff with the Intent Owner -Reference field is **intent description**, not a query. See [`image-base.md`](./image-base.md) §8 for the rule. - -Keep it intact as the acceptance contract. In Default Generate the owner is Strategist; in Quick Generate it is the current main agent's active-context resource decision. Derive a separate concise provider query that preserves exact names and necessary disambiguation; do not pass the Reference verbatim or rewrite it after search. - ---- +`Reference` is intent, not a query ([`image-base.md`](./image-base.md) §1): keep it intact as the acceptance contract, derive a separate concise provider query that preserves exact names and disambiguation, and never pass it verbatim or rewrite it after search. ## 10. Handoff with Executor -Executor reads `image_sources.json` per slide that uses a Sourced image. For each entry: - -| `license_tier` | Slide-level action | -|---|---| -| `no-attribution` | Embed `<image>` only | -| `attribution-required` | Embed `<image>` **and** an inline credit element per §7 | -| `manual` | Embed `<image>` only — directly selected URL or adopted-page package image; verifying usage rights / any required credit is the user's responsibility | - -Executor does not interpret raw license strings — `license_tier` is sufficient. - -`svg_quality_checker.py` verifies this handoff before post-processing: a referenced attribution-required image needs its own visible author + CC BY / CC BY-SA credit; one generic deck-level CC token cannot satisfy several images. - ---- +Executor reads `image_sources.json` per slide and acts on `license_tier` — `no-attribution` and `manual` embed the `<image>` only, `attribution-required` adds the §7 credit — without interpreting license strings. `svg_quality_checker.py` verifies that every referenced attribution-required image has its own visible author + license credit; one deck-level CC token never covers several images. ## 11. Task Completion Checkpoint -In addition to the shared checkpoint in [`image-base.md`](./image-base.md) §10: - -- [ ] Every required web row is `Sourced` with a downloaded original at `project/images/<filename>` OR is marked `Needs-Manual`; `Needs-Selection` remains incomplete -- [ ] Each multimodal `Sourced` web image was selected from a bounded ranked thumbnail page and only its winner original was downloaded; a no-pass page advanced through remaining pages before query replacement. Without vision, only strict metadata candidates may become `Sourced`, with `selection_method: metadata-ranked`; unresolved or visually unprovable intent becomes `Needs-Manual` without pretending a visual check occurred -- [ ] Each `Sourced` row has a manifest entry with valid `license_tier` and non-empty `attribution_text` (except `manual` directly selected rows, which carry no `attribution_text`) -- [ ] Any `attribution-required` image has visible author + license credit in every SVG that references it -- [ ] `metadata_dimensions` warnings surfaced when downloaded preview is much smaller than upstream-claimed size -- [ ] `Needs-Manual` rows include the failure reason +Beyond [`image-base.md`](./image-base.md) §4: every required web row is `Sourced` with its original at `project/images/<filename>` or `Needs-Manual` with a reason (`Needs-Selection` is incomplete); each multimodal `Sourced` image came from a bounded thumbnail page whose winner alone was downloaded, with remaining pages exhausted before any query change; without vision only strict metadata candidates became `Sourced` with `selection_method: metadata-ranked`; each `Sourced` row has a valid `license_tier` and non-empty `attribution_text` (except `manual`); every attribution-required image has its credit in every referencing SVG; `metadata_dimensions` warnings were surfaced when the download was far smaller than claimed. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/modes/_index.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/modes/_index.md index 79b40f69..ddbdb68d 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/modes/_index.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/modes/_index.md @@ -60,16 +60,4 @@ selecting one for the current deck: ## 4. Editable projection and escape hatch — `custom` -`custom` is the editable behavior carrier, not a category defined by how it relates to the catalog. Default uses it for each coordinated direction even when one preset supplies the complete cadence unchanged. In Quick or a lower-level manual choice it remains the escape hatch for **a bespoke narrative direction the five don't give as-is**: a nameable cadence (dialectic 正反合, myth-vs-reality, countdown / Top-N, Socratic), a deliberate multi-act fusion, or the user's own posture shifts. Don't try to taxonomize those bespoke cases. - -**Default candidates**: All three coordinated Stage-2 directions use literal `custom` plus a visible, non-empty `mode_behavior`. A custom may use catalog material in any way or none, including carrying one preset unchanged; it fits any installed template capacity. The three complete directions are plainly different designs, but no single component is required to carry that difference: mode behaviors and bases may coincide when other components express it, while a different name, note, or reference count alone is never a difference. The fixed five remain lower-level single-select alternatives. Strategist crystallizes the confirmed current value in the Design Spec first, then projects its behavior and actual catalog basis to `spec_lock.md`. - -**Quick custom**: do not display a candidate set. Use `custom` only when a project-specific specialization or fusion serves the deck better than one preset; retain the behavior and exact bases in active context and persist nothing. - -**Mandatory — select before detail reading**: Use this index to freeze every catalog source actually used, then read only those exact files before writing the behavior. One source may supply the complete cadence unchanged; when several are named, each owns a distinct executable act, posture, title voice, rhythm, or register. Reference count has no fixed cap; count is an outcome, not a target. A three-basis direction may use `pyramid` for a conclusion-first opening, `narrative` for the risk-tension act, and `instructional` for the closing action sequence; it reads those three files and writes all three ids beside `mode_behavior`. Quick retains its bases only in active context. Omit every source whose contribution cannot be stated, never add a second merely to imply synthesis, and do not open candidates for comparison after this gate. A custom using no catalog source names and reads none. - -> **One value per deck — fusion is *one* `custom`, not several modes.** A deck always resolves a single `mode`. A multi-mode blend is expressed as **one** custom behavior whose paragraph describes the acts — never as several simultaneous modes. -> -> **Default custom need not mean fusion or deviation.** It may project one dominant preset unchanged into an editable behavior, or specialize it when the project actually calls for a delta. Quick or a lower-level manual choice still uses the fixed preset directly when no editable projection is needed. - -**Forbidden — empty behavior**: Single-preset reuse is valid. When a Default direction carries an index row without changing its logic, name and read that exact basis, then state its executable cadence, posture, title voice, page rhythm, or act sequence in the editable behavior; do not add another mode merely to justify `custom`. A bare label with no executable behavior remains invalid. A user-stated direction remains authoritative the same way a user-supplied outline is — see the lens-not-mandate note in §1. +`custom` is the editable behavior carrier: one deck resolves a single `mode`, and a multi-mode blend is one custom behavior whose paragraph states the executable cadence, not several modes. A custom may use catalog material in any way or none — carrying one preset unchanged is valid — and names only the bases it actually uses; freeze those ids from this index, then read only their files before writing the behavior. Default authors it for each Stage-2 direction under [`strategist.md`](../strategist.md) §d; Quick uses it only when a project-specific specialization or fusion serves the deck better than one preset and keeps the behavior in active context. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/native-data-interface.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/native-data-interface.md index 892f5643..759fa2ac 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/native-data-interface.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/native-data-interface.md @@ -2,151 +2,46 @@ # Native Data Interface -Sole conditional interface for preset pattern fills and PowerPoint-native chart/table replacement eligibility, markers, metadata schemas, and export activation. Load only when either feature is selected for the authored SVG. +Sole conditional interface for preset pattern fills and PowerPoint-native chart/table replacement — eligibility, markers, metadata schemas, and export activation. Load only when either feature is selected for the authored SVG. Import-side normalization and the closed PPTX import boundaries live in [`conversion.md`](../scripts/docs/conversion.md#native-table-and-chart-import-claims). ## 1. Pattern Fill — `<pattern>` with PPTX preset annotation -`<pattern>` requests one fixed DrawingML preset; the converter does not render -the tile's arbitrary geometry. Use this interface only when that preset mapping -is intended. - -`data-pptx-pattern="<preset>"` is the generated default for selecting the -intended preset from the enum below. The converter retains an `ltUpDiag` -fallback when the annotation is absent; the checker reports that fallback as a -non-blocking fidelity warning. Invalid explicit preset names remain errors -because they violate the closed OOXML enum. - -Pattern colors may come from importer metadata (`data-pptx-fg` / -`data-pptx-bg`) or from the pattern's child paint. Without metadata, the first -child `<rect>` fill becomes the background and the first stroke (or other fill) -becomes the foreground. A missing background defaults to white; a missing -foreground means no native pattern fill can be emitted. The child geometry -itself is never used as a repeatable tile. - -**Valid `data-pptx-pattern` values** (OOXML `ST_PresetPatternVal` — closed enum, anything outside makes PowerPoint open with "needs to be repaired"): +A `<pattern>` requests one fixed DrawingML preset; the converter never renders the tile's own geometry. Write `data-pptx-pattern="<preset>"` from the closed enum below (absent annotation falls back to `ltUpDiag` with a fidelity warning; an invalid name is an error because PowerPoint opens the file as "needs to be repaired"). Colors come from `data-pptx-fg` / `data-pptx-bg` or the pattern's child paint — the first child `<rect>` fill is the background (default white) and the first stroke or other fill the foreground (required). `patternTransform` is an error. | Category | Values | |---|---| -| Grids | `smGrid` · `lgGrid` · `dotGrid` *(no `ltGrid` — common typo)* | +| Grids | `smGrid` · `lgGrid` · `dotGrid` *(no `ltGrid`)* | | Diagonal lines | `ltUpDiag` · `ltDnDiag` · `dkUpDiag` · `dkDnDiag` · `wdUpDiag` · `wdDnDiag` · `dashUpDiag` · `dashDnDiag` · `diagCross` | | Horizontal / vertical lines | `horz` · `vert` · `ltHorz` · `ltVert` · `dkHorz` · `dkVert` · `narHorz` · `narVert` · `dashHorz` · `dashVert` · `cross` | | Percent fills | `pct5` · `pct10` · `pct20` · `pct25` · `pct30` · `pct40` · `pct50` · `pct60` · `pct70` · `pct75` · `pct80` · `pct90` | | Checks & confetti | `smCheck` · `lgCheck` · `smConfetti` · `lgConfetti` | | Decorative | `horzBrick` · `diagBrick` · `weave` · `plaid` · `trellis` · `zigZag` · `wave` · `sphere` · `divot` · `shingle` · `solidDmnd` · `openDmnd` · `dotDmnd` | -`svg_quality_checker.py` warns when a referenced pattern lacks the annotation; -it errors when the pattern uses `patternTransform` or names a preset outside -this enum. - ## 2. PowerPoint-Native Chart / Table Replacement Markers (Opt-in) -The complete visible SVG fallback remains required for browser preview and -default export. Chart/Table authority is nevertheless object-local rather than -globally Shape-first: +The complete visible SVG fallback stays required for preview and default export; Chart/Table authority is object-local: -- **SVG-first (default)** — free-design, Brand-only, and Style-only authoring - omits `data-pptx-native-authority`. The visible marker subtree is the design - authority; JSON is its derived native projection. Canonical authoring records - `data-pptx-fallback-sha256` only after the fallback and JSON are synchronized. - A later visible edit requires regenerating the JSON and deliberately stamping - a new baseline together. Missing or stale baselines leave default fallback - export available but make `--native-charts-and-tables` fail closed. -- **JSON-first (template/native source)** — a validated PPTX import or a - template-owned Chart/Table writes - `data-pptx-native-authority="json"`. Its inline JSON is the semantic and native - authority; the visible SVG subtree is a derived, compact, and potentially - approximate preview. JSON edits regenerate that preview before template - publication, but preview differences never override the JSON. This marker is - legal only on active `chart` / `table` replacement groups, never formulas or - fallback-only status markers. +- **SVG-first (default)** — free-design, Brand-only, and Style-only authoring omits `data-pptx-native-authority`; the visible subtree is the design authority and JSON its derived projection. Canonical authoring records `data-pptx-fallback-sha256` only after fallback and JSON are synchronized; a later visible edit regenerates the JSON and re-stamps. A missing or stale baseline keeps fallback export available but makes `--native-charts-and-tables` fail closed. +- **JSON-first (template / native source)** — a validated PPTX import or template-owned object writes `data-pptx-native-authority="json"`; inline JSON is the authority and the visible subtree an approximate derived preview regenerated from it. Legal only on active `chart` / `table` replacement groups. -Both forms keep the JSON inside the SVG. `native_payloads.json.gz` is reserved -for supported opaque shape restoration payloads and never replaces semantic -Chart/Table JSON. +Both keep the JSON inside the SVG; `native_payloads.json.gz` is for opaque shape restoration only. -**Hard rule — selected-object authoring**: write the marker and JSON metadata in -the same edit for every supported chart and pure text-grid table; both are -native-ready by default. An unactivated marker changes no export, so never skip -an eligible object because the current request did not ask for native output. -The Default route reads the exact semantic object key from §IX -`Native-ready: <object-key>=yes|no; ...`; Quick assigns the same page-local -`kebab-case` key in active context before drawing. Use that key as the marker -group `id` and metadata `name`. A catalog `family/key`, family name, §VII row, -numeric content, or another ready object on the page never implies eligibility. -A `<object-key>=no` entry and unlisted incidental microvisuals stay on the SVG -fallback route. Canonical rectangular merged text cells may use the narrow -`row_span` / `col_span` contract below; graphical cells stay unmarked. The -marker group supplies visible fallback children for browser rendering and JSON -metadata for `svg_to_pptx` native export. - -A legacy bare `Native-ready: yes|no` maps only to the page's sole eligible -object. Zero or multiple eligible objects make it ambiguous and require -upstream repair. - -**MUST — atomic authoring**: treat one object's visible SVG fallback, parent -`data-pptx-replace-with` marker, and single JSON `<metadata>` child as one -authoring unit. Write all three while that object's data is in context. Do not -defer the marker or metadata to `verify-charts`, the final quality gate, or -export. SVG-first authoring then stamps the completed visible subtree; JSON-first -template authoring instead writes the authority marker and derives its preview -from the inline payload. - -After one SVG-first object's fallback and JSON have been reviewed as the same -authoring transaction, stamp the completed marker explicitly: +**Hard rule — selected-object authoring**: write the marker and JSON for every supported chart and pure text-grid table in the same edit — both are native-ready by default, and an unactivated marker changes no export, so never skip an eligible object. Default reads the key from §IX `Native-ready: <object-key>=yes|no; …`; Quick assigns the same page-local `kebab-case` key before drawing; the key is the marker group `id` and metadata `name`. A catalog `family/key`, §VII row, numeric content, or another ready object never implies eligibility; `=no` entries and incidental microvisuals stay on the fallback route; a legacy bare `Native-ready: yes|no` maps only to the page's sole eligible object. **MUST — atomic authoring**: one object's visible fallback, `data-pptx-replace-with` marker, and single JSON `<metadata>` child are one authoring unit written while the data is in context, never deferred to `verify-charts`, the final gate, or export. Then stamp SVG-first objects: ```bash -python3 skills/ppt-master/scripts/stamp_native_fallbacks.py \ - "<svg-file-or-directory>" --write +python3 skills/ppt-master/scripts/stamp_native_fallbacks.py "<svg-file-or-directory>" --write # read-only without --write; skips JSON-first ``` -Without `--write` the command is read-only. It validates every Chart/Table -payload before changing anything, skips JSON-first markers, and writes only the -current visible-subtree fingerprint. The hash is a synchronization receipt; it -detects later SVG edits but does not itself prove semantic equivalence, so never -stamp independently authored stale JSON merely to satisfy validation. +The hash is a synchronization receipt, not proof of semantic equivalence; never stamp stale JSON to satisfy validation. -**Hard rule — activation is the opt-in, dormant unless exported with `--native-charts-and-tables`**: A marker only declares that a group is eligible for PowerPoint-native Chart/Table replacement. Normal `svg_to_pptx.py` runs keep the fallback SVG children and convert them into independently editable DrawingML shapes. Pass `--native-charts-and-tables` only when the data source and chart/table-specific object model matter more than cross-renderer layout fidelity: it emits the PowerPoint Chart/Table object and skips the fallback children to avoid duplicates. Native styling preserves the core palette, text, axis, grid, and background colors where possible, but it is still a PowerPoint Chart/Table object rather than a pixel-identical SVG drawing. - -The native route is deliberately data-object-first and may be lossy: marker-local labels, callouts, KPIs, guide lines, custom split/bin semantics, or styling that is absent from the payload may disappear or normalize. Export warns about this route-level risk and any narrower issue it can detect. Loss of visual parity is not grounds to remove an active marker that the emitter can otherwise convert; use the default SVG-fallback export when exact authored artwork matters more than a native data source and object-specific controls. +**Hard rule — activation is the opt-in**: a marker only declares eligibility. Normal `svg_to_pptx.py` converts the fallback children into editable DrawingML shapes; `--native-charts-and-tables` emits the PowerPoint Chart/Table object and skips the fallback children — data-object-first and possibly lossy (marker-local labels, callouts, KPIs, guide lines, custom bins, or styling absent from the payload may normalize; export warns). Loss of visual parity is not grounds to remove a convertible marker; use fallback export when exact artwork matters more. | Replacement marker | Native output | Required metadata | |---|---|---| | `<g data-pptx-replace-with="table">` | `<p:graphicFrame>` with `<a:tbl>` | bounds + `columns` or `rows` | | `<g data-pptx-replace-with="chart">` | `<p:graphicFrame>` with `c:chart` / `cx:chart` + chart part + embedded workbook | bounds + `type`, plus chart data | -**Metadata placement**: Put JSON in one child -`<metadata type="application/json">`. The parent group's -`data-pptx-replace-with` value selects the table or chart schema, so the -metadata child does not repeat an object-kind attribute. Attribute JSON -(`data-pptx-json="..."`) remains read-compatible but is harder to XML-escape -correctly and is not canonical authoring. - -**Bounds**: Provide `x`, `y`, `width`, and `height` in metadata, or as -`data-pptx-x` / `data-pptx-y` / `data-pptx-width` / `data-pptx-height` on the -marker group. If any bound is omitted, the exporter infers the object frame -from the visible fallback geometry; this keeps SVG fallback and native object -placement aligned. Complete explicit bounds are absolute slide coordinates; -marker/ancestor `translate` and `scale` transforms apply only when at least one -bound is inferred. `x`, `y`, `width`, and `height` must be finite and resolve -inside PowerPoint's 32-bit DrawingML coordinate range; `width` and `height` -must resolve to at least one EMU. Native table frames must additionally resolve -to at least one EMU per resolved row and column. JSON-first markers require all -four bounds directly in metadata; an approximate preview never supplies their -native frame. - -**Classic plot-area layout**: supported classic charts accept root `plot_area`; -ChartEx rejects it. It contains only finite `x`, `y`, `width`, `height` in -absolute slide px and forms a positive rectangle inside the chart frame. Export -writes `c:manualLayout`; omission keeps automatic layout. - -**Validation**: `svg_quality_checker.py` validates replacement marker kind, JSON -metadata, bounds/fallback availability, table rows/columns, supported chart -type, chart data shape, and the selected authority contract. Canonical -SVG-first authoring requires a fresh fallback baseline; JSON-first markers skip -fallback freshness because their preview is not authoritative. Import -provenance, fallback classification, and legacy spellings remain operational -compatibility fields; use the exact field index in -[`conversion.md`](../scripts/docs/conversion.md#native-table-and-chart-import-claims). +**Metadata placement and bounds**: one child `<metadata type="application/json">` (attribute `data-pptx-json` is read-compatible, not canonical); the marker's `data-pptx-replace-with` selects the schema. Provide `x`, `y`, `width`, `height` in metadata or as `data-pptx-x/y/width/height` on the group; omitted bounds are inferred from the fallback geometry (then marker/ancestor `translate` / `scale` apply), complete explicit bounds are absolute slide coordinates. `x` / `y` are finite and inside the 32-bit DrawingML range; `width` / `height` additionally resolve to at least one EMU (tables: per resolved row and column). JSON-first markers require all four bounds in metadata. Classic charts accept root `plot_area` (`x`, `y`, `width`, `height`, a positive rectangle inside the frame → `c:manualLayout`); ChartEx rejects it. `svg_quality_checker.py` validates marker kind, JSON, bounds/fallback, table rows/columns, chart type and data shape, the authority contract, and (SVG-first) baseline freshness. ```xml <g id="p03-revenue-chart" data-pptx-replace-with="chart"> @@ -167,322 +62,26 @@ compatibility fields; use the exact field index in </g> ``` -**Hard rule — project by the selected authority**: for SVG-first authoring, -metadata is derived from and must describe the same data and visible -chart/table chrome as the fallback drawn in that marker group. For JSON-first -template/native-source objects, the inline metadata is authoritative and the -fallback is only a readable derived preview; approximate preview chrome is not -a contract mismatch. +**Hard rule — project by the selected authority**: SVG-first metadata describes the same data and visible chrome as its fallback — for a chart every category/point and series value, x/y/size data, visible point colors and labels, line/area treatment, title/axis/legend chrome, companion text, bounds, and typography native export cannot infer; for a table every resolved cell, header/summary line, rectangular span, cell style, alignment, bounds, and typography. JSON-first metadata is the authority and its preview may be approximate. Never simplify the artwork to fit the payload: when the closed payload cannot carry required data or topology, Default returns the native-ready decision upstream and Quick revises it before drawing; only the resolved non-native object stays unmarked, and an explicit `=yes` is never silently ignored. **Per-page verification**: every `=yes` key matches exactly one marker with one JSON child, and `=no` / unlisted objects have none — `rg -n 'data-pptx-replace-with="(chart|table)"|<metadata type="application/json">' <project_path>/svg_output/<current_page>.svg`. -| Object | Required projection from the visible fallback | -|---|---| -| Chart | Every category/point and series value, the actual x/y/size data where applicable, visible point colors and labels, line/area treatment needed by the schema, visible title/axis/legend chrome, companion text, bounds, and fallback typography/style values that native export cannot infer unambiguously | -| Table | Every resolved row/column cell, header/summary line, rectangular span, required cell style, alignment, bounds, and visible typography | +### Table schema — `ppt-master.semantic-table.v2` -Do not simplify the SVG artwork to match the native object model. When the -closed payload cannot represent an object without losing required data or cell -topology, Default returns the native-ready decision upstream and Quick revises -that per-object decision before drawing; only the resolved non-native object -stays unmarked on its complete SVG fallback. Never silently ignore an explicit -`<object-key>=yes` declaration. +Every payload carries that exact `schema`. Native tables are rectangular grids: `columns` for the optional header row, `rows` for body rows (shorter rows padded unless `strict_grid: true`; at most 1000 resolved rows and columns); `column_widths` / `row_heights` are finite non-negative relative weights matching the grid with one positive value; `header_rows` is an integer in range; `strict_grid`, `style.band_row`, and `bold` are JSON booleans. Exact repetition may be factored into `defaults.cell` / `defaults.paragraph` / `defaults.run` and kebab-case `cell_styles` selected by `cell_style` (precedence: cell defaults → named style → cell fields; object-valued `padding` merges, everything else replaces; `<style>` and `class` remain forbidden). -**Per-page verification**: enumerate every `<object-key>=yes` on the current -page and confirm a one-to-one key match. Each key identifies one parent marker -and exactly one JSON metadata child; `<object-key>=no` and unlisted incidental -objects have no marker. Finding one marker somewhere on a page is insufficient. +Cells accept `text`, `fill`, `fill_opacity`, `color`, `align` (`l` / `ctr` / `r`), `valign` (`top` / `middle` / `bottom`), `bold`, `font_size`, `padding` and side-specific `padding_*`, `border_color`, `border_width`, `borders`, `lang`, `anchor_center`, `horizontal_overflow`. Multi-paragraph text replaces `text` with a non-empty `paragraphs` list of strings or objects — empty paragraph strings are preserved as blank lines — (`align` plus exactly one of `text` or non-empty `runs`; runs carry required `text` and optional `bold`, `italic`, `underline`, `strike`, `color`, `font_size`, one-typeface `font_family`, `lang`, `alt_lang`); unknown fields, wrong types, empty runs, multi-typeface families, and unsupported colors fail. Per-side borders use `borders.left|right|top|bottom|diagonal_down|diagonal_up` as `{ "style": "none" }` or `{ "style": "solid", "color": "#RRGGBB", "width": <positive-px> }`, overriding a uniform `border_color` / `border_width` on style or cell. A missing `lang` derives `zh-CN` for CJK and `en-US` otherwise. `style.band_row: false` disables banding and materialized alternating fills. Typography mirrors the fallback: `style.font_family` and `style.font_size` from the drawn table text, `style.header_font_size` or per-cell `font_size` only where the fallback differs; with no explicit table font, Default uses the deck body family and anchor, Quick its active-context values. -```bash -rg -n 'data-pptx-replace-with="(chart|table)"|<metadata type="application/json">' <project_path>/svg_output/<current_page>.svg -``` +**Hard rule — the table payload is complete**: a payload holding only `font_size` and a uniform border is not complete when the fallback draws a header band, row or column fills, first-column emphasis, non-uniform row heights, or sparse rules — every row, summary line, value, and cell style that must survive `--native-charts-and-tables` is in `columns` / `rows`, because fallback text is discarded on that route. Numeric or currency columns use cell objects with `align: "r"` (`text-anchor="end"` does not carry). **Merged cells — canonical rectangular contract only**: positive integer `row_span` / `col_span` on the anchor, every covered cell blank as `{"merge_continuation": true}` (a bare `{"text": ""}` is blank only while no `defaults.cell` adds fields), spans inside the grid and non-overlapping; the exporter writes `rowSpan` / `gridSpan` / `hMerge` / `vMerge`. CamelCase aliases, raw OOXML merge fields, top-level merge lists, nonblank covered cells, invalid spans, and overlaps fail. -**Table schema — `ppt-master.semantic-table.v2` only**: Every payload requires -that exact `schema`; unversioned payloads and alternate field spellings fail. -Native tables are rectangular DrawingML grids. Use `columns` for the optional -header row and `rows` for body rows; shorter rows are padded unless -`strict_grid: true`. Tables support at most 1000 resolved rows and columns. -`column_widths` / `row_heights` are finite non-negative relative weights that -match the grid and include one positive value. `header_rows` is an integer in -the resolved row range. `strict_grid`, `style.band_row`, and `bold` are JSON -booleans. +### Chart schemas -PPTX import factors exact repetition into `defaults.cell`, -`defaults.paragraph`, `defaults.run`, and lower-case kebab-case `cell_styles`; -cells select a style with `cell_style`. Precedence is cell defaults → named -style → cell fields. Only object-valued `padding` merges by member; `borders` -and other values replace. Content/topology stays cell-local. This is JSON -inheritance, not SVG CSS: `<style>` and `class` are forbidden. Export expands -the payload in memory before validation and DrawingML construction. +- **Category charts** — `column`, `bar`, `line`, `area`, `pie`, `doughnut`, `pieOfPie`, `barOfPie`, `radar`: `categories` plus `series[].values`. Pie-family charts take exactly one series with per-slice colors; `hole_size` is doughnut-only, integer `10..90`, default `75`; no rotation field. Column/bar may set `series[].point_colors` (camelCase `pointColors` is read-compatible; length = values). `data_labels` is `true` or an object with `show_value`, `position`, `number_format`, `font_size`, `font_family`, `bold`, `color`, per-point `colors`, and `points` (zero-based `idx` plus optional overrides); positions: clustered column/bar `outside_end` / `inside_end` / `inside_base` / `center`, stacked `inside_end` / `inside_base` / `center`, line `above` / `center` / `best_fit`, area none. +- **Combo** — shared `categories` plus `plots[]` (`type: "column" | "line" | "area"`, own `series`, optional `axis: "secondary"`, optionally own `categories` / `category_numeric` when caches genuinely differ, and `series_indices` for imported identity — same-length unique non-negative integers forming one contiguous `0..N-1` range across plots) or typed `series[]` with per-series `type` / `axis` (adjacent compatible series share a plot). Area series may set `fill_opacity` (`0..1`; `fillOpacity` read-compatible); a line plot with `area_fill: true` exports as an area chart; line/area series may set `line_width` in SVG px (`lineWidth` read-compatible). Export layers areas below columns and lines. +- **Axes** — classic `axes` is a closed object of `category`, `value`, `secondary_category`, `secondary_value`, each with only `kind` (`text` / `date` / `value`), `position`, `visible`, `label_position` (`next_to` / `none` / `low` / `high`), `number_format`, `minimum`, `maximum`, `major_unit` (value axes), `reverse`, `major_gridlines`; single-plot `bar` takes `category` left/right and `value` bottom/top; pie-family rejects `axes`. `scatter` / `bubble` use `x` and `y` roles only (`kind: "value"`; `x.position` bottom/top, `y.position` left/right) with the same fields. Logarithmic scales, minor units/gridlines, crossing values, display units, and tick skipping are unsupported. +- **XY** — `scatter` and `bubble` use `series[].x` + `series[].y` (`bubble` adds one `series[].size` / `sizes` per point), or `series[].points` as `[x, y]` / `[x, y, size]` tuples or `{x, y, size}` objects. +- **ChartEx** — `treemap` / `sunburst` (`values` plus `levels[level][point]` or path-style `categories`; treemap `parent_label_layout: "banner" | "overlapping" | "none"` (default `overlapping`), PowerPoint labels only the top level and leaves), `histogram` (`values`), `pareto` / `waterfall` / `funnel` (`categories` + `values`; `waterfall` accepts `subtotals` / `subtotal_indices`), `boxWhisker` (`series[].values`, optional `series[].categories`). ChartEx writes no `<cx:title>` without a payload title (an empty title shows the series name), emits title/subtitle as companion text boxes, and takes `style.colors` / root `colors` into its color-style part. Non-Microsoft renderers show a limited subset. +- **Stock** — numeric Excel date serials in `categories` / `dates` plus exactly four series open / high / low / close (`series` with four entries or top-level `open` / `high` / `low` / `close`). +- **Supported types**: `column`, `bar` (`grouping`: `clustered` / `stacked` / `percentStacked`); `line` (`grouping`: `standard` / `stacked` / `percentStacked`; `line_style`: `line` / `lineMarker`, default `line` with no markers); `area` (`grouping`: `standard` / `stacked` / `percentStacked`); `pie`, `doughnut`, `pieOfPie`, `barOfPie`; `radar`, `radarMarkers`, `radarFilled`; `scatter` (`scatter_style`: `marker` / `lineMarker` / `line` / `smoothMarker` / `smooth`, default `marker`); `bubble`; `combo`; `treemap`, `sunburst`; `histogram`, `pareto`; `boxWhisker`; `waterfall`, `funnel`; `stock`. 3D aliases and `surface` are unsupported; exploded pie/doughnut, `map`, `heatmap`, `bullet`, and `gantt` are deferred and fail fast. -Cells accept `text`, `fill`, `fill_opacity`, `color`, `align`, `valign`, `bold`, -`font_size`, `padding`, canonical side-specific `padding_*`, `border_color`, -`border_width`, `borders`, `lang`, `anchor_center`, and -`horizontal_overflow`. `align` is `l`, `ctr`, or `r`; `valign` is `top`, -`middle`, or `bottom`. Table-wide font/palette/banding/uniform-border policy -lives under `style`; exact imported defaults live under `defaults.cell`. -For multi-paragraph text, replace cell `text` with a non-empty `paragraphs` -list. Each entry is either a string or an object containing optional -`align: "l|ctr|r"` and exactly one of `text` or non-empty `runs`; empty -paragraph strings are preserved, and cell `text` / `paragraphs` are mutually -exclusive. Each run is an object with required string `text` and optional JSON -boolean `bold`, `italic`, `underline`, and `strike`, plus optional `color`, -`font_size`, one-typeface `font_family`, `lang`, and `alt_lang`. Unknown fields, -wrong types, empty run lists, multi-typeface `font_family`, and unsupported -colors fail fast. PPTX import requires exact physical row/grid topology and -normalizes source presentation-only run XML outside this closed schema only -when it contains no non-empty `rPr` / `defRPr` / `endParaRPr` `effectLst` or -`effectDag`. A table-cell run effect follows the blocking effect contract above -instead of entering either the native payload or an effect-free fallback. -Relationship-bearing text, extensions, structural line breaks, fields, tabs, -bullets, malformed run topology, and unsupported text-body structure remain -fallback-only. -Per-side cell borders use -`borders.left|right|top|bottom|diagonal_down|diagonal_up`, where each value is -either `{ "style": "none" }` or -`{ "style": "solid", "color": "#RRGGBB", "width": <positive-px> }`. -Per-side borders are cell-only. Uniform `border_color` / `border_width` may live -on the table style or cell; an explicit side overrides the uniform value. -When `lang` is absent, export derives `zh-CN` for CJK text and `en-US` -otherwise. `style.band_row: false` disables both `<a:tblPr bandRow>` and -materialized alternating row fills. Native table typography mirrors the -visible SVG fallback: put `style.font_family` and `style.font_size` on the -marker from the table text already drawn, then use `style.header_font_size` or -per-cell `font_size` only when the fallback visibly differs. If the fallback -has no explicit table font, Default uses the deck body family and declared body -anchor from `spec_lock.md`; Quick uses its active-context body family and size. +**Chart chrome, typography, and color**: SVG-first metadata matches the fallback chrome; JSON-first owns it. Metadata sizes use SVG px (`1px = 0.75pt`); `style.font_family` and `title_font_size`, `subtitle_font_size`, `axis_font_size`, `axis_title_font_size`, `legend_font_size`, `note_font_size` are required only when native must preserve typography an SVG-first fallback cannot supply unambiguously (JSON-first never infers from its preview). A string or unbounded-object `title` becomes native `c:title` (`subtitle` line two); a title object with complete `x`, `y`, `width`, `height` becomes a companion text box (partial bounds or `subtitle` fail); `name` names the object; `title`, `subtitle`, and axis-title objects accept `text`, `font_size`, `font_family`, `color`; the checker rejects SVG-first title/axis text absent from the fallback. Axis titles are explicit via `axis_titles` (`category`, `value`, `x`, `y`, `secondary_value`) or the root aliases `category_axis_title`, `value_axis_title`, `x_axis_title`, `y_axis_title`, `secondary_value_axis_title`; `show_value_axis_labels: false` hides numeric tick labels (e.g. a radar without radial coordinates); native legends are opt-in via `show_legend: true` and `legend_position` (`bottom` default; `top` / `left` / `right`). SVG-first parity reads the fallback literally — `style.axis_color` equals the dominant axis/grid stroke, numbers match in written form (`286.20` ≠ `286.2`), and marker text that is not a category, data label, axis label, or legend entry needs a companion entry. Companion text (`caption`, `source`, `note`, `notes`, `footnote`, `footnotes`) exports as editable text boxes — strings or objects with `text`, `x`, `y`, `width`, `height` (slide coordinates), `font_size`, `color`, `align`, `bold`; use it for captions, sources, center labels, and annotations, and `data_labels` for point values. `style.colors` sets series colors (treemap/sunburst tile palette in order); the exporter writes explicit chart-area fill, plot-area fill, axis, gridline, and label colors (SVG-first infers them from the largest panel `<rect>`, text, and strokes; JSON-first from JSON or stable defaults), overridable under `style` with `chart_area_fill`, `plot_area_fill`, `text_color`, `axis_color`, `grid_color` (`"none"` for transparent); generated payloads use uppercase `#RRGGBB`, with `#RGB`, `rgb()`, and CSS names normalized. Negative bars keep the series fill. -**Hard rule — table native payload is complete**: A payload holding only `font_size` and a uniform border is not complete when the fallback draws a header band, row or column fills, first-column emphasis, non-uniform row heights, or sparse rules. Every row, summary line, -value, and cell-level style that must survive `--native-charts-and-tables` must -be present in `columns` / `rows`; SVG fallback text is discarded on that route. -For SVG-first objects this payload is a synchronized projection of the visible -table. For JSON-first template/native-source objects it is the table authority -and the preview may be approximate. For numeric or currency columns, use cell -objects with `align: "r"`; SVG `text-anchor="end"` does not carry into the -native table. - -**Merged table cells — canonical rectangular contract only**: Put positive JSON -integer `row_span` / `col_span` values on the merge anchor and keep every -covered grid cell blank: write it as `{"merge_continuation": true}` (a bare -`{"text": ""}` is also blank, but only while no `defaults.cell` expansion adds -other fields to it). Spans must stay within the resolved rectangular grid -and may not overlap. The exporter emits the canonical DrawingML topology -(`rowSpan` on the top edge, `gridSpan` on the left edge, `hMerge` / `vMerge` on -covered cells). CamelCase aliases, raw OOXML merge fields, top-level merge lists, -nonblank covered cells, invalid spans, and overlaps fail fast. The PPTX importer -activates native reconstruction only for that same explicit rectangular topology -with empty merge-slave text bodies; other merge encodings remain fallback-only -with `unsupported-merge-topology`. - -**Category chart schema**: `column`, `bar`, `line`, `area`, `pie`, -`doughnut`, `pieOfPie`, `barOfPie`, and `radar` use `categories` plus -`series[].values`. Pie-family charts (`pie`, `doughnut`, `pieOfPie`, and -`barOfPie`) must have exactly one series; the exporter assigns per-category -slice colors so single-series charts do not collapse into one solid color. -Root `hole_size` is doughnut-only, integer `10..90`, default `75`; -no pie-family rotation or angle field exists. -Column and bar charts may set per-point colors with `series[].point_colors` -or `series[].pointColors`; the list must match `series[].values` length. -Classic category charts may set native PowerPoint data labels with -`data_labels`. Use `data_labels: true` for default value labels, or an object -with `show_value`, `position`, `number_format`, `font_size`, `font_family`, -`bold`, `color`, and optional per-point `colors`. Supported label positions -depend on chart type: clustered column/bar labels may use `outside_end`, -`inside_end`, `inside_base`, or `center`; stacked / percent-stacked column/bar -labels may use `inside_end`, `inside_base`, or `center`; line labels may use -`above`, `center`, or `best_fit`; area labels do not emit a native label -position. To label only selected data points, use `data_labels.points` with -zero-based `idx` plus optional per-point `position`, `number_format`, -`font_size`, `font_family`, `bold`, and `color`. - -**Combo chart schema**: `combo` uses shared `categories` plus either `plots[]` -or typed `series[]`. Each plot supports `type: "column" | "line" | "area"`, -its own `series`, and optional `axis: "secondary"` for a right-side value axis. -When primary and secondary plots genuinely use different category caches, -`plots[]` may also carry its own `categories` and `category_numeric`; the -workbook writer allocates independent category/value ranges. Typed `series[]` -continues to require the shared top-level categories. -Imported `plots[]` may carry `series_indices` so the verified source identity -where each `c:idx` equals its `c:order` survives when physical plot order differs -from legend order. If one plot supplies it, every plot must supply a same-length -list of unique non-negative JSON integers, and the combined values must form one -contiguous `0..N-1` range. Sources whose `idx` and `order` differ stay -fallback-only; typed `series[]` does not accept this plot-scoped field. -Typed `series[]` accepts the same `type` and `axis` fields per series, and -adjacent compatible series are grouped into the same PowerPoint plot. Area -series may set `fill_opacity` / `fillOpacity` as a `0..1` SVG opacity value -when the SVG fallback uses a transparent area fill under an opaque line. A line plot with `area_fill: true` -is exported as a PowerPoint area chart under the hood; `fill_opacity` only sets -the fill style and does not trigger conversion by itself. Combo export layers -area plots below columns and lines while preserving the original series indices. -Line and area series may set `line_width` / `lineWidth` in SVG px units to -match fallback `stroke-width`. - -**Narrow classic-axis schema**: `axes` is a closed object with the roles -`category`, `value`, `secondary_category`, and `secondary_value`. Each role may -set only `kind` (`text`, `date`, or `value`, as appropriate), `position`, -`visible`, `label_position` (`next_to`, `none`, `low`, or `high`), -`number_format`, `minimum`, `maximum`, `major_unit`, `reverse`, and -`major_gridlines`. `major_unit` applies to value axes only. PPTX date-axis -**import** is deliberately narrow: numeric Excel date serials are accepted for -area charts and OHLC stock charts; arbitrary date-axis source families are not. -This contract is not a full `AxisSpec`: logarithmic scales, minor units/gridlines, -crossing values, display units, tick skipping, and other unlisted OOXML semantics -remain unsupported and fail closed on import. -Single-plot `bar` accepts `category` at left/right and `value` at bottom/top; -`pie`, `doughnut`, and `pieOfPie` / `barOfPie` reject `axes`. - -**Narrow XY-axis schema**: `scatter` and `bubble` may use a closed `axes` object -with only `x` and `y` roles. Both roles have `kind: "value"`; `x.position` -is `bottom` or `top`, while `y.position` is `left` or `right`. Each accepts the -same closed fields above, and `major_unit` is valid on both value axes. PPTX -import requires the plot to reference exactly two mutually cross-linked -`c:valAx` nodes and separately enforces the closed field/topology gates. The -native writer emits and the importer reads back every field in this closed -contract. Scatter import derives the effective `scatter_style` from a uniform -per-series line/marker/smooth state; unsupported or nonuniform states remain -fallback-only. The normalized SVG fallback newly consumes only -`axes.x.major_gridlines` and `axes.y.major_gridlines`; the other fields do not -imply full visual-axis parity. - -**XY chart schema**: `scatter` and `bubble` use `series[].x` + `series[].y`; -`bubble` also requires one `series[].size` / `series[].sizes` value per point. -`series[].points` is also accepted as `[x, y]` / `[x, y, size]` tuples or -`{x, y, size}` objects. - -**Chart typography**: Metadata sizes use the same px-style unit as SVG text -(`1px = 0.75pt`). `style.font_family` and the role-specific -`title_font_size`, `subtitle_font_size`, `axis_font_size`, -`axis_title_font_size`, `legend_font_size`, and `note_font_size` fields are -required only when the native object must preserve typography that cannot be -inferred unambiguously from an SVG-first fallback. JSON-first objects do not -infer typography from their approximate preview; put required values in JSON. - -**Chart chrome metadata**: SVG-first metadata MUST match fallback chrome. -JSON-first metadata owns native chrome and may use a simpler preview. For classic -charts, a string or unbounded-object `title` becomes native `c:title`; -`subtitle` is line two. A title object with complete `x`, `y`, -`width`, and `height` becomes a companion editable text box at those absolute -slide-px bounds; partial bounds or `subtitle` fail. Use `name`, not -`title`, for object naming. `title`, `subtitle`, and axis-title objects may set -`text`, `font_size`, `font_family`, and `color`. On SVG-first markers the -checker rejects title/axis text absent from the fallback and export omits it -with a warning; JSON-first keeps it. ChartEx writes no `<cx:title>` unless the payload gives a title — an empty ChartEx title makes PowerPoint show the series name as an automatic title — and emits title/subtitle as companion editable text boxes. Axis -titles are optional and explicit: use `axis_titles` with -`category`, `value`, `x`, `y`, or `secondary_value` keys, or the root aliases -`category_axis_title`, `value_axis_title`, `x_axis_title`, `y_axis_title`, and -`secondary_value_axis_title`; SVG-first must not add semantic axis titles that -are absent from the fallback. Set `show_value_axis_labels: false` when the fallback -keeps category labels but omits numeric value-axis tick labels, such as a radar -chart without radial coordinates. Native legends are metadata-controlled: use -`show_legend: true` and `legend_position` only when the fallback's legend is -meant to be replaced by PowerPoint's native legend. SVG-first parity reads the -fallback literally: `style.axis_color` must equal the dominant stroke among -axis and grid lines, numbers match in written form (`286.20` ≠ `286.2`), and -any marker text that is not a category, data label, axis label, or legend -entry needs its own companion entry (`note`, `caption`, …). -Companion text such as `caption`, `source`, `note`, `notes`, `footnote`, and -`footnotes` is exported as editable PPT text boxes next to the native chart. A -companion entry may be a string or an object with `text`, `x`, `y`, `width`, -`height`, `font_size`, `color`, `align`, and `bold`; explicit bounds are -recommended so the native export matches the SVG fallback placement. Explicit -companion bounds are slide coordinates, not local coordinates inside a -transformed marker group. Use companion text for chart captions, source notes, -center labels, and freeform annotations; use `data_labels` for values that -belong to chart points. - -**Chart color styling**: For classic native charts, `style.colors` sets series -colors. The exporter also writes explicit chart-area fill, plot-area fill, -axis line, gridline, and label text colors so PowerPoint does not substitute a -white/default-theme chart. For SVG-first, omitted values are inferred from -the visible fallback: the largest panel-like `<rect>` becomes the chart -background, fallback text supplies label color, and fallback strokes supply -axis/grid colors. JSON-first uses JSON values or stable exporter defaults, not -its preview. Override any of them explicitly under `style` with -`chart_area_fill`, `plot_area_fill`, `text_color`, `axis_color`, and -`grid_color`; use `"none"` for transparent chart or plot area fill. Generated -payloads default to uppercase `#RRGGBB`. The exporter retains compatibility for -`#RGB`, `rgb(...)` / `rgba(...)`, and common CSS names, normalizing them to -6-digit OOXML RGB. Bar and column series also disable PowerPoint's negative-value -inversion so negative bars keep the same series fill instead of turning into -white/theme fill. - -For treemap and sunburst, `style.colors` projects the visible tile palette in order; aggregate figures drawn inside the marker belong in companion text. For ChartEx native charts, valid payload `style.colors` (or root `colors`) -populate the ChartEx color-style part instead of being replaced by a fixed -accent1–accent6 list. Other ChartEx style semantics remain normalized. - -**PowerPoint chartEx schema**: `treemap`, `sunburst`, `histogram`, `pareto`, -`boxWhisker`, `waterfall`, and `funnel` use Office 2016+ chartEx parts. Use -these input shapes: - -| Type | Required data | -|---|---| -| `treemap`, `sunburst` | `values` plus either `levels` (`levels[level][point]`) or path-style `categories` (`[["Region", "Group", "Leaf"], ...]`) | -| `treemap` display note | Top-level group labels default to `overlapping`; override with `parent_label_layout: "banner" \| "overlapping" \| "none"`. PowerPoint labels only the top level and leaves — intermediate levels group tiles spatially without labels (sunburst shows every ring). | -| `histogram` | `values` | -| `pareto`, `waterfall`, `funnel` | `categories` + `values`; `waterfall` also accepts `subtotals` / `subtotal_indices` point indexes | -| `boxWhisker` | `series[].values`; optional `series[].categories` per value | - -> Note: chartEx files are valid PPTX and editable in PowerPoint; non-Microsoft -> renderers can display a limited subset. - -**Stock chart schema**: `stock` uses numeric Excel date serials in -`categories` or `dates`, plus exactly four series in open / high / low / close -order. Use either `series` with four entries, or top-level `open`, `high`, -`low`, and `close` arrays. PPTX import currently recognizes only canonical OHLC -stock charts with shared numeric date caches, `hiLowLines`, and `upDownBars`. -Safe stock series style may pass the structural gate, but stock series, -`hiLowLines`, and up-down bar local styling can still normalize under the -data-object-first contract. HLC, volume, noncanonical structure, and style XML -outside the safe parsing boundary stay fallback-only. - -**PPTX chart-import boundary**: The importer recognizes conservative classic -single-plot charts plus the verified scatter/bubble XY-axis, column/line/area -combo, area date-axis, canonical OHLC stock, radar, safe `of_pie` `serLines`, -axis/title/legend normalization, and bar/column gap/overlap subsets. Imported -`gapWidth` must be one canonical integer in `0..500`; imported `overlap` must be -one canonical integer in `-100..100`. Both values intentionally normalize to -the native writer contract rather than claiming exact source-style retention. -Malformed, duplicate, or out-of-range values fail closed. - -ChartEx import is closed to seven validated data models: `treemap`, `sunburst`, -`histogram`, `pareto`, `box_whisker`, `waterfall`, and `funnel`. The importer -retains their supported hierarchy/category/value/series/subtotal topology for -native read-back. Numeric cache values must be non-empty and finite, and cache -counts/indexes must be canonical non-negative decimal integers with exact, -contiguous topology; malformed, non-numeric, `NaN`, infinite, sparse, duplicate, -or mismatched caches fail closed. ChartEx style, axis, label, and binning details -outside the payload normalize. Full `AxisSpec`, arbitrary ChartEx families or -presentation fidelity, arbitrary stock variants, and axis/combo/date-axis -semantics outside the closed fields above remain fallback-only. The C4/C5 -import work does not expand the normalized SVG renderer and does not reduce -existing SVG-marker-to-native writer support. - -**Deferred chart types**: Exploded pie / doughnut variants, `map`, `heatmap`, -`bullet`, and `gantt` are intentionally outside the current native-object -support boundary. The exporter fails fast for these types until each mapping is -implemented and validated one by one. - -**Supported chart types**: - -- `column`, `bar`: `clustered`, `stacked`, or `percentStacked` (`grouping`) -- `line`: `standard`, `stacked`, or `percentStacked` (`grouping`); `line` or `lineMarker` (`line_style`, default `line` / no markers) -- `area`: `standard`, `stacked`, or `percentStacked` (`grouping`) -- `pie`: exactly one series, per-slice colors -- `doughnut`: exactly one series, per-slice colors -- `pieOfPie`, `barOfPie`: exactly one series, per-slice colors -- `radar`, `radarMarkers`, `radarFilled` -- `scatter`: `marker` (default), `lineMarker`, `line`, `smoothMarker`, or `smooth` (`scatter_style`) -- `bubble`: x/y/size series -- `combo`: `column`, `line`, and `area` plots, optional secondary value axis -- `treemap`, `sunburst`: hierarchical chartEx charts -- `histogram`, `pareto` -- `boxWhisker` -- `waterfall`, `funnel` -- `stock`: open / high / low / close series - -3D chart aliases (`3DColumn`, `3DBar`, `3DLine`, `3DArea`, `3DPie`, cone, -cylinder, pyramid variants, and `surface`) are unsupported. - -Native legends are opt-in through `show_legend: true`; `legend_position` -defaults to `bottom` and accepts `top`, `left`, or `right`. - -**Forbidden — replacement marker transforms**: Do not rotate, skew, or matrix-transform table/chart replacement groups. Translate / scale is accepted; complex transforms fail export because PowerPoint-native table/chart frames do not preserve arbitrary SVG transforms. +**Forbidden — replacement marker transforms**: no rotate, skew, or matrix on table/chart groups; translate/scale only, because native frames cannot carry arbitrary SVG transforms. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/native-formula.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/native-formula.md index e10986c5..1c9cbd17 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/native-formula.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/native-formula.md @@ -1,30 +1,25 @@ # Native Formula Specification -Shared authoring contract for editable PowerPoint math generated from exact -LaTeX, either inline in Slide-local prose or as a standalone block. +Authoring contract for editable PowerPoint math generated from exact LaTeX, inline in Slide-local prose or as a standalone block. Compiler profile, normalization, reverse import, and compatibility live in [`svg-pipeline.md`](../scripts/docs/svg-pipeline.md#native-formula-compiler). ## 1. Trigger and Ownership -**Trigger**: A page contains structural mathematical notation such as a -fraction, radical, integral, n-ary expression, limit, matrix, delimiter -construction, accent, or complex script. +**Trigger**: a page contains structural mathematical notation — fraction, radical, integral, n-ary expression, limit, matrix, delimiter construction, accent, or complex script. | Layer | Ownership | |---|---| | Default Strategist | Record exact mathematical content as a canonical delimiter-free LaTeX expression body; do not classify its implementation | -| Default Executor | Decide ordinary text versus inline native math versus block native math, then author the selected marker and SVG preview | -| Active Quick context | Perform both content and authoring responsibilities directly | +| Default Executor | Decide ordinary text versus inline versus block native math, then author the marker and SVG preview | +| Active Quick context | Both responsibilities directly | | SVG-to-PPTX exporter | Compile marker LaTeX to editable Office Math and replace only the registered preview | | Content form | Authoring choice | |---|---| -| Short variables, percentages, simple assignments, or notation such as `O(n log n)` | Ordinary editable SVG text | -| One-line structural math embedded in prose whose native-height envelope fits the reserved row/module space | Inline native marker | -| Matrix, `cases`, `aligned`, multiline derivation, standalone high-structure expression, or vertically expanding math that cannot fit its prose row | Block native marker | +| Short variables, percentages, simple assignments, notation such as `O(n log n)` | Ordinary editable SVG text | +| One-line structural math in prose whose native-height envelope fits the reserved row/module space | Inline marker | +| Matrix, `cases`, `aligned`, multiline derivation, standalone high-structure expression, or vertically expanding math that cannot fit its prose row | Block marker | -The Strategist's `Mathematical content` field does not pre-decide this choice. -Formula handling is not a user-confirmed policy, image resource, manifest, or -`spec_lock.md images` entry. +Formula handling is not a user-confirmed policy, image resource, manifest, or `spec_lock.md images` entry. --- @@ -38,32 +33,11 @@ Formula handling is not a user-confirmed policy, image resource, manifest, or </text> ``` -**Hard rule — one leaf run**: Put non-empty LaTeX directly in -`data-pptx-inline-formula` on a leaf `<tspan>`. Canonical authoring omits outer -`$...$`, `$$...$$`, `\(...\)`, and `\[...\]` delimiters, though the compiler -accepts and removes one complete outer pair. Give that `<tspan>` one non-empty -direct preview string with no leading/trailing whitespace, no child element, -and no `x`, `y`, `dx`, `dy`, or paragraph-layout metadata; spacing belongs to -the surrounding text. The marker inherits its computed size and visible solid -fill; exported math uses the project text language and Cambria Math. Local -`\color` / `\textcolor` scopes override the marker fill on both selectable -formula runs and non-selectable structural controls. `\boldsymbol` / `\bm` -also applies its bold-italic style to structural control glyphs. Neither form -changes unrelated marker defaults. +**Hard rule — one leaf run**: non-empty delimiter-free LaTeX in `data-pptx-inline-formula` on a leaf `<tspan>` (the compiler strips one complete outer `$…$` / `$$…$$` / `\(…\)` / `\[…\]` pair) with one non-empty direct preview string, no surrounding whitespace, no child element, and no `x`, `y`, `dx`, `dy`, or paragraph-layout metadata — spacing belongs to the surrounding text. The marker inherits its computed size and visible solid fill; local `\color` / `\textcolor` and `\boldsymbol` / `\bm` scopes apply to formula runs and structural control glyphs. Exported math uses the project text language and Cambria Math. -**Hard rule — Slide-local ordinary text only**: Do not place an inline marker -inside a structured Layout placeholder, a Master/Layout layer, imported -preserved `txBody`, geometry transport subtree, another inline marker, or any -`data-pptx-replace-with` subtree. Export keeps the surrounding text runs in the -same `a:p` and replaces only the marker run with `a14:m > m:oMath`. +**Hard rule — Slide-local ordinary text only**: never inside a structured Layout placeholder, Master/Layout layer, imported preserved `txBody`, geometry transport subtree, another inline marker, or a `data-pptx-replace-with` subtree. Export keeps the surrounding runs in the same `a:p` and replaces only the marker run with `a14:m > m:oMath`. -**Hard rule — reserve native height**: Treat the parsed formula structure, not -its flat SVG preview, as vertical layout truth. Keep adjacent content outside -the native ascent/descent required by fractions, radicals, nested scripts, -n-ary limits, accents, and other stacked structures. The exporter and SVG -checker use the same structural envelope. If the prose row or root module -cannot reserve that space without overlap, isolate the formula line or use the -block marker. +**Hard rule — reserve native height**: the parsed formula structure, not its flat preview, is vertical layout truth. Keep adjacent content outside the native ascent/descent of fractions, radicals, nested scripts, n-ary limits, and accents; exporter and checker use the same envelope. If the prose row or module cannot reserve that space, isolate the formula line or use the block marker. ### 2.2 Block formula @@ -81,95 +55,16 @@ block marker. </g> ``` -**Hard rule — block metadata is truth**: Write one direct -`<metadata type="application/json">` child with non-empty `latex`, `display: -block`, `font_size` in `(0, 400]`, a visible `color`, and `align: -left|center|right`. Use the same canonical delimiter-free form described above. -Give the group finite `data-pptx-x/y`, positive `data-pptx-width/height`, and -matching root-coordinate `data-pptx-bounds`. Export replaces the complete group -with `a14:m > m:oMathPara > m:oMath`. +**Hard rule — block metadata is truth**: one direct `<metadata type="application/json">` child with non-empty `latex`, `display: block`, `font_size` in `(0, 400]`, a visible `color`, and `align: left|center|right`; finite `data-pptx-x/y`, positive `data-pptx-width/height`, and matching root-coordinate `data-pptx-bounds`. Export replaces the whole group with `a14:m > m:oMathPara > m:oMath`. -**Hard rule — preview is SVG, never fallback**: Make every marker preview -semantically equivalent with ordinary SVG text/shapes/lines/paths. Do not use -`<image>`, `<foreignObject>`, visible raw LaTeX, or another runtime renderer. -The exporter discards the registered preview and emits no picture branch. +**Hard rule — preview is SVG, never fallback**: every preview is semantically equivalent ordinary SVG text/shapes/lines/paths — no `<image>`, `<foreignObject>`, visible raw LaTeX, or runtime renderer. The exporter discards the preview and emits no picture branch. --- ## 3. Source, Failure, and Validation -**Forward input profile**: The compiler implements every explicitly named -LaTeX-to-OMML input and behavior in Microsoft's documented -[Microsoft 365 LaTeX profile](https://learn.microsoft.com/en-us/office/math/latex) -(Windows 2606 / Mac 16.110) and -[mhchem profile](https://learn.microsoft.com/en-us/office/math/latex.mhchem) -(Windows 2605 / Mac 16.109). This includes outer delimiters, all listed symbols -and relations, fractions and binomials, roots, right and left scripts, -delimiters and `\middle`, accents, bars and group characters, limits, all 21 -listed n-ary operators, standard/custom functions, matrices and equation-array -environments, CD diagrams, fonts and local colors, boxes and phantoms, spacing, -global 0–9 argument macros, and the documented `\ce` chemistry grammar. The -closed command tables in `scripts/svg_to_pptx/native_objects/formula_profile.py` -are the executable vocabulary; the public compiler facade and OMML structure -gate live in `scripts/svg_to_pptx/native_objects/formula_compiler.py` and -`scripts/svg_to_pptx/native_objects/formula_omml.py`. Microsoft's open-ended -“etc.” wording for additional relation aliases does not define undisclosed -names; only explicitly named commands and retained project aliases are -contractual. +**Accepted input**: every explicitly named command in Microsoft's documented [Microsoft 365 LaTeX profile](https://learn.microsoft.com/en-us/office/math/latex) and [mhchem profile](https://learn.microsoft.com/en-us/office/math/latex.mhchem) — symbols, fractions and binomials, roots, scripts, delimiters and `\middle`, accents, limits, n-ary operators, functions, matrix and equation-array environments, CD diagrams, fonts and local colors, boxes and phantoms, spacing, 0–9 argument macros, `\ce` chemistry. Unknown commands or environments, Microsoft's explicitly unsupported commands, unsupported mhchem arrows, unescaped `%` comments, invalid macros, and resource-limit overflow block conversion: PPT Master never leaks unresolved LaTeX into a released slide. -Implementations: -[`formula.py`](../scripts/svg_to_pptx/native_objects/formula.py), -[`formula_ast.py`](../scripts/svg_to_pptx/native_objects/formula_ast.py), -[`formula_parser.py`](../scripts/svg_to_pptx/native_objects/formula_parser.py), -[`formula_run_properties.py`](../scripts/svg_to_pptx/native_objects/formula_run_properties.py), -[`inline_formula.py`](../scripts/svg_to_pptx/native_objects/inline_formula.py). +**Hard rule — repair LaTeX upstream**: unsupported source or an invalid marker blocks the page. Rewrite within the profile without changing the planned mathematics, or return it to the content owner. Never substitute a PNG, flatten structural math into ordinary text, hand-write OMML, or leave raw LaTeX visible. -**Native normalization**: `\dfrac` / `\tfrac`, `\dbinom` / `\tbinom`, and -continued-fraction alignment normalize to the corresponding OMML structure; -explicit big-delimiter grades become auto-sizing delimiters; `\mathscr` -normalizes to `\mathcal`; `smallmatrix` normalizes to `matrix`; PowerPoint array -columns become centered; style/size commands and equation tags are accepted but -not stored. Color is stored in generated formula runs and structural control -properties. - -**Narrow reverse import**: `pptx_to_svg.py` rebuilds a block formula marker or -same-paragraph inline marker only when one `a14:m` root passes this compiler's -closed OMML validator and its normalized structure can be serialized back to -LaTeX accepted by the same compiler. The reconstructed LaTeX is canonicalized; -it is not the original spelling. A formula-only `m:oMathPara` text shape becomes -one bounded block marker when its carrier also fits the unstyled rectangular -native-formula contract; carrier grouping, paint, effects, rotation, hyperlink, -or placeholder ownership force fallback instead of being silently discarded. -Supported `m:oMath` zones remain inline among their surrounding text runs. Both -forms receive a dependency-free linear SVG preview. This contract covers PPT -Master-emitted vocabulary, not arbitrary third-party OMML. Tolerant import -reports `formula-not-reconstructed`, renders readable formula text, and retains -a relationship-free unchanged source `txBody` as opaque metadata; strict import -stops instead. - -**Fail-closed boundary**: Input containing unknown commands or environments, -Microsoft's explicitly unsupported commands, unsupported mhchem arrows, -unescaped `%` comments, invalid macros, or any resource-limit overflow blocks -conversion. This is stricter than Microsoft 365's literal-text passthrough and -macro-limit behavior: PPT Master never leaks unresolved LaTeX into a released -slide. - -**Hard rule — repair LaTeX upstream**: Unsupported source or an invalid marker -blocks the page. Rewrite within the documented profile without changing the -planned mathematics; otherwise return it to the content owner. Never substitute -a PNG, flatten structural math into ordinary text, hand-write OMML, or leave raw -LaTeX visible. - -**Compatibility boundary**: The generated package uses standard editable Office -Math and retains the PowerPoint 2010+ package target. The executable profile is -pinned to the Microsoft documentation versions above. Repository verification -covers compilation, OMML structure, and PPTX packaging; it is not a complete -Microsoft 365 UI rendering/editability certification. Earlier PowerPoint -versions are not the source-profile baseline. WPS, Keynote, LibreOffice, and -other clients receive no embedded formula fallback and are outside the -rendering/editability contract. - -**Validation**: The first-page/final SVG checker validates every marker, -compiles its LaTeX, and applies the shared native-height envelope to page/module -text bounds before release; native export repeats validation and uses that -envelope for the generated text frame. +**Validation**: the first-page/final SVG checker validates every marker, compiles its LaTeX, and applies the shared native-height envelope to page/module text bounds; native export repeats validation and uses that envelope for the generated text frame. Output is standard editable Office Math for PowerPoint 2010+; WPS, Keynote, and LibreOffice receive no embedded fallback and are outside the rendering/editability contract. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/native-hyperlinks.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/native-hyperlinks.md index dc638f90..ec4fd807 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/native-hyperlinks.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/native-hyperlinks.md @@ -1,23 +1,19 @@ # Native Hyperlink Specification -Shared authoring contract for PowerPoint-native click hyperlinks on complete -objects and inline text runs. +Authoring contract for PowerPoint-native click hyperlinks on complete objects and inline text runs. ## 1. Trigger and Ownership -**Trigger**: A user instruction, source fact, or page plan requires an external -destination or a jump to another slide in the same deck. +**Trigger**: a user instruction, source fact, or page plan requires an external destination or a jump to another slide in the same deck. | Layer | Ownership | |---|---| -| Default Strategist | Record the linked text/object intent and exact target in the applicable §IX page block; never invent or normalize an unknown destination | +| Default Strategist | Record the linked text/object intent and exact target in the §IX page block; never invent or normalize an unknown destination | | Default Executor | Choose the whole-object or inline carrier and author the canonical SVG anchor | -| Active Quick context | Perform both content and authoring responsibilities directly | +| Active Quick context | Both responsibilities directly | | SVG-to-PPTX exporter | Validate the target, create the native relationship, and attach the click action | -**Hard rule — page content only**: Hyperlinks are not a confirmation field, -resource, manifest, or `spec_lock.md` entry. Missing or ambiguous targets return -upstream; do not substitute a search result or guessed URL. +**Hard rule — page content only**: hyperlinks are not a confirmation field, resource, manifest, or `spec_lock.md` entry. Missing or ambiguous targets return upstream; never substitute a search result or guessed URL. --- @@ -30,69 +26,26 @@ upstream; do not substitute a search result or guessed URL. | Same-deck jump | `href="#slide-3"` using the 1-based final slide roster | | Imported shape-plus-run conflict | Importer-only `data-pptx-shape-hyperlink="..."` on the logical `<g>`, with standard inline anchors retained inside | -**Hard rule — one target syntax**: Author SVG 2 `href`. Import may read legacy -`xlink:href`, but generated SVG never writes both. Same-deck destinations use -the exact `#slide-N` form and must resolve inside the final roster. External -destinations are absolute URIs with an explicit scheme; percent-encode spaces. -Relative paths, arbitrary fragments, filesystem paths, and `data:`, `file:`, -`javascript:`, or `vbscript:` destinations fail closed. +**Hard rule — one target syntax**: author SVG 2 `href` (import may read legacy `xlink:href`; generated SVG never writes both). Same-deck destinations use the exact `#slide-N` form inside the final roster. External destinations are absolute URIs with an explicit scheme and percent-encoded spaces; relative paths, arbitrary fragments, filesystem paths, and `data:` / `file:` / `javascript:` / `vbscript:` fail closed. -**Hard rule — inline run**: Put visible text in one or more `<tspan>` children -inside the anchor. The anchor and its descendants own no `x`, `y`, `dx`, or -`dy`; line positioning belongs to the enclosing line `<tspan>`. A linked inline -formula uses one leaf formula `<tspan>` inside the anchor and retains its native -math contract. +**Hard rule — inline run**: visible text sits in one or more `<tspan>` children inside the anchor; the anchor and its descendants own no `x`, `y`, `dx`, or `dy` — line positioning belongs to the enclosing line `<tspan>`. A linked inline formula is one leaf formula `<tspan>` inside the anchor and keeps its native math contract. -**Hard rule — whole-object hit area**: Wrap at least one visible SVG element; -do not put direct text or a bare `<tspan>` in a shape anchor. A multi-object -anchor links each exported leaf object. Include an explicit background shape -when gaps inside a button or card must also be clickable. +**Hard rule — whole-object hit area**: wrap at least one visible SVG element; no direct text or bare `<tspan>` in a shape anchor. A multi-object anchor links each exported leaf object; include an explicit background shape when gaps inside a button or card must also be clickable. Ordinary animation may target an outer top-level `<g>`, but a hyperlink-bearing group cannot also be an interactive `trigger_shape` — one click has one owner. -Ordinary entrance, emphasis, motion-path, exit, and Morph animation may target -an outer top-level `<g>`. A hyperlink-bearing group cannot also serve as an -interactive `trigger_shape`; use a separate trigger so one click has one owner. - -**Forbidden — ambiguous ownership**: Do not nest `<a>` elements or place an -anchor inside `defs`, metadata, geometry-detail, or a native-replacement -subtree. A complete block formula or native Chart/Table marker may be wrapped -as one whole object; its preview descendants may not contain another anchor. - -**Forbidden — authored transport metadata**: Never author -`data-pptx-shape-hyperlink`. PPTX import uses it only when one source shape has -both a whole-shape click and descendant run links, because standard SVG cannot -nest their two anchors. Checker/export accept it only on that logical group -with at least one real inline `<a>` descendant, then restore both native click -levels. Every ordinary whole-object link uses the standard outer `<a href>`. +**Forbidden**: nested `<a>`; an anchor inside `defs`, metadata, geometry-detail, or a native-replacement subtree (a complete block formula or Chart/Table marker may be wrapped as one whole object, but its preview may not contain another anchor); authored `data-pptx-shape-hyperlink`, which PPTX import writes only when one source shape has both a whole-shape click and descendant run links, and which checker/export accept only on that logical group with at least one real inline `<a>` descendant. --- ## 3. Native Result and Preservation -| Carrier / target | Native result | -|---|---| -| Inline external link | `a:rPr/a:hlinkClick` plus an external hyperlink relationship | -| Whole-object external link | `p:cNvPr/a:hlinkClick` on each clickable leaf plus one shared external relationship | -| Inline or whole-object slide jump | The same click carrier plus an internal slide relationship and `ppaction://hlinksldjump` | -| Supported PPTX import | Reconstruct the same canonical SVG `<a href>` form | +Inline links become `a:rPr/a:hlinkClick`, whole-object links `p:cNvPr/a:hlinkClick` on each clickable leaf, each with an external hyperlink relationship; slide jumps add an internal slide relationship and `ppaction://hlinksldjump`. Supported PPTX import reconstructs the same canonical `<a href>` form. -**Hard rule — Edit Native PPTX preservation**: Unchanged round-trip pages keep -their hyperlink XML and relationships byte-for-byte. External links are -preserved. With a `page_plan.json`, a same-deck jump is retargeted only when -its source target maps unambiguously to one output page; omitted or repeated -targets make `svg_to_pptx.py --roundtrip` fail instead of linking to an orphan -or wrong slide. New links on an edited page use this SVG authoring contract. +**Hard rule — Edit Native PPTX preservation**: unchanged round-trip pages keep their hyperlink XML and relationships byte-for-byte; external links are preserved. With a `page_plan.json`, a same-deck jump is retargeted only when its source target maps unambiguously to one output page — omitted or repeated targets make `svg_to_pptx.py --roundtrip` fail rather than link to an orphan or wrong slide. New links on an edited page use this contract. --- ## 4. Exclusions and Validation -**Forbidden — unsupported action settings**: Mouse-over links, custom shows, -first/last/next/previous navigation actions, program or macro execution, OLE or -file actions, and arbitrary `ppaction://` or relationship injection are outside -this contract. An `actionButton*` preset remains visual geometry until wrapped -in an ordinary supported hyperlink anchor. +**Forbidden — unsupported action settings**: mouse-over links, custom shows, first/last/next/previous navigation, program or macro execution, OLE or file actions, and arbitrary `ppaction://` or relationship injection. An `actionButton*` preset stays visual geometry until wrapped in a supported anchor. -**Validation**: The final SVG checker validates carrier structure, target -syntax, and slide range. Export validates relationship type/mode and final -presentation-roster membership. Unsupported PPTX click actions produce an -import diagnostic; strict import fails rather than fabricating an SVG link. +**Validation**: the final SVG checker validates carrier structure, target syntax, and slide range; export validates relationship type/mode and final roster membership. Unsupported PPTX click actions produce an import diagnostic; strict import fails rather than fabricating an SVG link. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/native-shape-authoring.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/native-shape-authoring.md index f6ee0ca4..e63a46f3 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/native-shape-authoring.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/native-shape-authoring.md @@ -1,343 +1,129 @@ -> See [`shared-standards-core.md`](./shared-standards-core.md) §§1.4–1.5 for the native-shape metadata and validation contracts. +> See [`shared-standards-core.md`](./shared-standards-core.md) §1.5 for the authored-preset contract and [`svg-contract.md`](../scripts/docs/svg-contract.md) §1.4–§1.5 for the machine metadata. # Native Shape Authoring Reference -Use this reference during Executor SVG construction or project-owned canonical -template maintenance when native contours or supported shape/text operands can -express the intended object. Choose each contour from its page job before -deciding how to encode it, then use the simplest exact authoring form. Keep -faithful atoms independent unless one contour is required; materialize that -contour with a PowerPoint-style Boolean result, and use hand-authored freeform -only when those constructions fail. Neither helper writes a page. The preset -helper does not create the shape's own `p:txBody`; keep visible text outside the -atomic fragment. +Use during Executor SVG construction or canonical template maintenance whenever a native contour or a supported shape/text operand can express the intended object: choose the contour from the page job, then the simplest exact authoring form; keep atoms independent unless one contour is required; materialize that contour as a PowerPoint-style Boolean result; hand-author freeform last. Neither helper writes a page or a shape's `p:txBody` — visible text stays outside the atomic fragment. -**Mandatory — complete vocabulary before contour selection**: In Create -Template, load this reference and -[`preset-shape-vocabulary.md`](./preset-shape-vocabulary.md) completely and -retain both as soon as `replication_mode` resolves to `standard` or `fidelity`, -before selecting any newly authored page or template contour. Do not load this -authored-construction bundle for `mirror`; it preserves source-owned geometry. -In every other valid authoring context, read the preset vocabulary completely -at authoring entry before selecting the first newly authored contour. It exposes -all 187 exact preset names under the Office gallery and objective contour -families. This is authoring-side capability knowledge, never a Strategist task -or Design Spec field. Reread only after context invalidation or a known file -change; a filtered query cannot replace the complete read. +**Contract — the two helpers** (`${SKILL_DIR}` is the retained absolute Skill root; invoke each command once per argument set, read stdout directly, never change CWD, loop, encode the executable or flag list in a scalar shell string, merge stderr, or add a downstream parser when `--compact` exists; `list --search <term>` and `list --grouped --search <term>` are optional spelling/location helpers): -**Hard rule — direct structured calls**: `${SKILL_DIR}` below is the retained -absolute Skill root. After choosing a concrete lookup or authoring operation, -invoke that command once per argument set and read stdout directly. Do not -change CWD, encode executables or flag lists in scalar shell strings, batch -these calls through shell loops, merge stderr, or add a downstream parser when -`--compact` exists. +```bash +python3 ${SKILL_DIR}/scripts/preset_shape_svg.py render rightArrow \ + --id p03-growth-arrow --frame 160 210 320 112 \ + --fill "#2563EB" --stroke none --adjust "adj1=val 50000" # optional --filter-id softShadow (one §6.4 filter id already in <defs>) +python3 ${SKILL_DIR}/scripts/preset_shape_svg.py render bentConnector3 \ + --id p03-flow-connector --object-kind connector \ + --frame 420 180 220 140 --fill none --stroke "#475569" --stroke-width 2 +python3 ${SKILL_DIR}/scripts/preset_shape_svg.py render-batch --input - # JSON array of the same fields for several already-selected objects +python3 ${SKILL_DIR}/scripts/preset_shape_svg.py describe chevron --compact # objective identity/adjustment/connector/path facts, only for a serious candidate +python3 ${SKILL_DIR}/scripts/shape_boolean_svg.py render <svg-file> \ + --operation subtract --source body --source cutout --id result +``` -`list --search` and `list --grouped --search` are optional spelling/location -helpers. Run `describe <name> --compact` only when a serious candidate needs -objective identity, adjustment, connector, path, connection-site, or -text-rectangle facts. Executor makes the final comparison through §§1–2.1; -filtered lookup cannot narrow the already-loaded vocabulary. +- `render` prints one compact atomic `<g data-pptx-authoring="preset">` with preset, frame, adjustments, and base paint written once and registry-generated visible paths as children; **Hard rule — batch after selection**: after selecting two or more objects for one page or template, use `render-batch --input -` so their independent fragments are validated and emitted in one stdout round. `--frame x y w h` is in the coordinate space where the fragment is inserted (group-local inside a `<g transform>`). Insert the fragment unchanged through the normal page edit; never redirect helper output into `svg_output/`. +- Paint accepted: `none` or six-digit solid HEX fill/stroke, optional channel opacity, stroke width, cap, join, and one shape-only filter id. Gradient or pattern paint stays ordinary SVG. Connector-family presets require `--object-kind connector`, `--fill none`, and a visible stroke, and export as unconnected `p:cxnSp`. +- **Hard rule — atomic and helper-owned**: never write `data-pptx-prst`, frame, adjustment, or registry paths by hand, never edit a direct path, and rerun the helper when preset, frame, adjustment, paint, or filter changes. Keep the fragment top-level without `data-pptx-bounds` when standalone (its `data-pptx-frame` owns geometry); put labels or decorations beside it in a separate bounded parent group, never inside. Moving, scaling, rotating, or flipping the whole group is fine; zero-scale and shear are not, the transformed frame stays inside DrawingML's coordinate range, and stroke width stays inside its line-width range. Keep the helper's exact space-separated ordinary-decimal `data-pptx-frame` spelling; compact authoring accepts no alternate numeric spelling. Keep paint and opacity off ancestor groups (the checker warns). +- `shape_boolean_svg.py` consumes closed `path` / `polygon` / `rect` / `circle` / `ellipse`, one unfiltered compact preset, or supported horizontal direct `<text>` with a resolvable OpenType face (`--font-dir` adds roots; text becomes glyph geometry). The first `--source` supplies result paint and explicit paint flags override only their named channels; for `subtract` every later operand is removed from it. Coordinates are baked into root space: insert the stdout paths at the primary operand's z-order with no extra transform. `union` / `combine` / `intersect` / `subtract` emit one `<path>`; `fragment` emits `<id>-1`, `<id>-2`, … in top/left/bottom/right/area order, each a separate shape. Results use nonzero winding and never `fill-rule`, `clip-rule`, `clip-path`, `mask`, or Merge Shapes metadata; operands that depend on even-odd fill, clipping, or masking fail closed. Never use it on mirror/preserve source structure. + +**Mandatory — complete vocabulary before contour selection**: [`preset-shape-vocabulary.md`](./preset-shape-vocabulary.md) is read completely before contour work (Generate: with the executor core before the first page; Create Template: as soon as `replication_mode` resolves to `standard` or `fidelity`; never for `mirror`); a filtered lookup cannot replace it. Reread only after context invalidation or a known file change. ## 1. Contour Selection and Materialization Gate -**Hard rule — contour before encoding**: choose the page-fit contour from the -intended job and active visual system across the full native vocabulary before -considering authoring syntax. Rectangle, rounded-rectangle, circle, and ellipse -contours are not an earlier visual tier merely because SVG has short primitive -syntax for them. Easier syntax is never the reason to select a contour. +**Hard rule — contour before encoding**: choose the page-fit contour from the intended job and active visual system across the full vocabulary before any syntax. Rectangle, rounded rectangle, circle, and ellipse are not an earlier tier because SVG spells them short; easier syntax never selects a contour. -**Default — exact page-fit geometry before generic neutrality (may override when -neutrality itself communicates the page)**: Resolve relationship fit when the -content carries direction, sequence, membership, hierarchy, convergence, reveal, -or contrast. Independently resolve page-field / carrier fit from ownership, -focal hierarchy, boundary strength, and the active deck's edge / opening -language; `Structure=no` removes only relationship topology. Choose a plain -primitive, uniform grid, or no drawn carrier only when that lack of inflection -gives the reader a concrete benefit or avoids a false inference. Retain that -reader effect through authoring. Before that neutral result wins, name the -strongest fitting native / compound alternative and retain why its inflection -would add no reader benefit, create a false inference, weaken hierarchy, or -conflict with the page job. Quick speed, restrained style, readability, equal -importance, precedent, and shorter syntax alone do not qualify. +**Default — exact page-fit geometry before generic neutrality (may override when neutrality itself communicates the page)**: resolve relationship fit when the content carries direction, sequence, membership, hierarchy, convergence, reveal, or contrast; independently resolve page-field / carrier fit from ownership, focal hierarchy, boundary strength, and the deck's edge / opening language (`Structure=no` removes only relationship topology). Choose a plain primitive, uniform grid, or no drawn carrier only when that lack of inflection gives the reader a concrete benefit or avoids a false inference — and before it wins, name the strongest fitting native or compound alternative and why its inflection would add nothing, mislead, weaken hierarchy, or conflict with the job. Quick speed, restrained style, readability, equal importance, precedent, and shorter syntax alone never qualify. -**Hard rule — style does not narrow capability**: the active visual system may -weight contour fit and control paint, stroke, texture, density, and recurrence. -It never removes primitives, Office presets, independent composition, Boolean, -or necessary freeform from consideration. Style-specific syntax guidance -applies only to the named style-defining mark, not every functional page -contour. - -After contour selection, use the simplest exact materialization below. Do not -hand-author a freeform merely because an SVG path is convenient. +**Hard rule — style does not narrow capability**: the visual system weights contour fit and controls paint, stroke, texture, density, and recurrence; it never removes primitives, presets, composition, Boolean, or necessary freeform from consideration. Style-specific syntax guidance applies only to the named style-defining mark. | Selected result | Authoring form | |---|---| -| Mirror/preserve input already owns native-shape metadata | Keep the existing object and metadata; never reselect its preset. | -| One exact non-Connector stock contour | Use an ordinary SVG primitive only when the exporter maps it to that same contour; otherwise run `preset_shape_svg.py render` and insert its complete stdout fragment. | -| A stock `bentConnector*` / `curvedConnector*` contour exactly expresses a bent or curved relationship and endpoint attachment is not required | Run `preset_shape_svg.py render --object-kind connector`; the result is an unconnected native Connector shape. | -| A straight relationship, divider, or leader | Write `<line>`; use a registered marker under [`shared-standards-core.md`](./shared-standards-core.md) §1.1 only when direction is meaningful. | -| A selected text/content boundary needs no filled surface | Use its exact authoring form with `fill="none"` and a visible stroke; keep its content as independent siblings. | -| Two or more selected native contours form the page construction but do not need one contour | Keep them as independently editable siblings in one ordinary semantic group; use §2.1 to compose the page-level geometry system. | -| Two or more supported closed-shape / resolvable-text operands require Union, Combine, Fragment, Intersect, or Subtract | Run `shape_boolean_svg.py render`, then replace the operands with every stdout path; the result remains ordinary editable custom geometry. | -| Exact native contours, their independent composition, and Boolean materialization cannot faithfully express the visual meaning or contour | Write ordinary `<path>` / `<polygon>` geometry; export keeps it as editable custom geometry. | -| The shape only resembles a preset | Never infer a preset; continue to the Boolean gate, then use freeform only if no faithful construction exists. | - -**Hard rule**: `preset_shape_svg.py` is the only authoring entry for -`data-pptx-authoring="preset"`. Never add `data-pptx-prst`, frame, adjustment, -or registry path data by hand. Insert the helper's complete compact `<g>` and -rerun the helper whenever its geometry, paint, or filter reference changes. -After selecting two or more objects for one current page or template -construction, use `render-batch --input -` to validate and emit their -independent fragments in one stdout round; the batch never chooses those -objects or their composition. +| Mirror/preserve input already owns native-shape metadata | Keep the object and metadata; never reselect its preset | +| One exact non-Connector stock contour | Ordinary SVG primitive only when the exporter maps it to that same contour; otherwise `render` and insert the fragment | +| A stock `bentConnector*` / `curvedConnector*` contour expresses a bend or curve with no endpoint attachment | `render --object-kind connector`; an unconnected native Connector | +| A straight relationship, divider, or leader | `<line>`, with a §1.1 marker only when direction is meaningful | +| A boundary that needs no filled surface | The exact form with `fill="none"` and a visible stroke; content stays an independent sibling | +| Two or more native contours form the construction without needing one contour | Independent siblings in one semantic group, composed under §2.1 | +| Operands require Union, Combine, Fragment, Intersect, or Subtract | `shape_boolean_svg.py`; replace the operands with its paths (editable custom geometry) | +| Nothing above expresses the meaning or contour faithfully | Ordinary `<path>` / `<polygon>` (editable custom geometry) | +| The shape only resembles a preset | Never infer a preset; continue to the Boolean gate, then freeform only if no faithful construction exists | --- ## 2. Vocabulary-Guided Preset Selection -[`preset-shape-vocabulary.md`](./preset-shape-vocabulary.md) follows the Office -gallery taxonomy: Lines, Rectangles, Basic Shapes, Block Arrows, Equation -Shapes, Flowchart, Stars and Banners, Callouts, and Action Buttons. Its family -labels and objective identities expose the available contours without deciding -their page use. The optional semantic helper data does not redefine the -DrawingML registry or override Executor judgment. - -Apply this page-local sequence before drawing: +[`preset-shape-vocabulary.md`](./preset-shape-vocabulary.md) follows the Office gallery taxonomy (Lines, Rectangles, Basic Shapes, Block Arrows, Equation Shapes, Flowchart, Stars and Banners, Callouts, Action Buttons); its families and objective identities expose what exists without deciding page use. | Pass | Action | Result | |---|---|---| -| Job | State what the object must do for the reader before naming a shape. | Page role plus any real relationship, direction, aspect, text load, or literal scope. | -| Browse | Compare that job against the complete loaded vocabulary; move from Office category to contour family to exact name. | A small candidate set chosen by meaning, not syntax convenience. | -| Inspect | When exact facts could change the decision, run `describe --compact` directly for those candidates and compare identity, scope, adjustments, connector status, paths, text rectangle, and connection sites. | Objective geometry evidence without prescribed use. | -| Select | Choose the contour whose inference and visual character fit the page, including a neutral primitive when neutrality is useful. | One page-fit contour; no syntax decision yet. | -| Encode | Apply §1's materialization gate. | Ordinary SVG primitive, helper-authored preset, Boolean result, or necessary freeform. | +| Job | State what the object must do for the reader before naming a shape | Page role plus any real relationship, direction, aspect, text load, or literal scope | +| Browse | Compare that job against the complete vocabulary: category → family → exact name | A small candidate set chosen by meaning | +| Inspect | `describe --compact` only when exact facts could change the decision | Objective geometry evidence | +| Select | The contour whose inference and character fit the page | One contour; no syntax yet | +| Encode | §1's materialization gate | Primitive, helper preset, Boolean result, or necessary freeform | -Example location and inspection commands: +**Hard rule — semantic fit, not name association**: a preset name, topic word, or metaphor is not evidence of use; respect `literal_only` and `scope`. A scroll is not a generic playbook carrier, a lightning bolt is not price tension, `chartX` / `chartStar` / `chartPlus` are partition symbols not charts, a flowchart symbol belongs only in an actual flowchart, an `actionButton*` creates no action or link, and logos, icon glyphs, illustrations, brand contours, and data marks are never presets. The vocabulary exposes contours; Executor chooses them; §1 chooses syntax. Export never scans or upgrades existing geometry. -```bash -python3 "${SKILL_DIR}/scripts/preset_shape_svg.py" describe chevron --compact -python3 "${SKILL_DIR}/scripts/preset_shape_svg.py" list --search connector -``` - -**Hard rule — semantic fit, not name association**: a preset name, topic word, -or metaphor is not evidence of use. Respect `literal_only` and `scope` before -visual preference. For example, a scroll is not a generic playbook carrier, a -lightning bolt is not generic price tension, `chartX` / `chartStar` / -`chartPlus` are partition symbols rather than charts, and a flowchart symbol -belongs only in an actual flowchart. An action-button preset supplies visual -geometry only; it never creates an action or hyperlink. - -The vocabulary exposes contours; Executor chooses them, and §1 chooses syntax. -It never requires `rect`, `ellipse`, `line`, or any other primitive to pass -through the preset helper. Export never scans or upgrades existing geometry. - -**Shape-first diagram rule**: use `<line>` for straight thin relationships; -use an exact connector-family preset for a stock bent or curved contour; use a -block-arrow / chevron preset for a solid direction. Resort to an open freeform -path only when those native constructions cannot faithfully express the -relationship, data geometry, or locked hand-drawn / organic style. Newly -authored connector-family presets remain unconnected and do not gain attachment -semantics. Existing Connector topology imported from a source PPTX remains -owned by the preserve/mirror round-trip contract. - -**Forbidden — false native semantics**: - -- a catalog entry with `literal_only=true` when the depicted literal concept is - absent, or a `flowchart` / `navigation` scope outside that real context; -- `actionButton*` when navigation or trigger behavior is expected; the helper - maps its visual preset geometry only and never creates an action or hyperlink; -- `chartX`, `chartStar`, or `chartPlus` as a substitute for native charts; -- logo, icon glyph, illustration, brand contour, or data-chart marks. +**Shape-first diagram rule**: `<line>` for a straight thin relationship; an exact connector preset for a stock bend or curve; a block-arrow or chevron preset for a solid direction; an open freeform only when none of those expresses the relationship, data geometry, or a locked hand-drawn / organic style. Imported Connector topology stays under the preserve/mirror contract. ### 2.1 Topology assembly and compound page geometry -**Trigger**: after the page or prototype's communication / slot job, -composition anchors, and any applicable topology under -[`executor-structure.md`](./executor-structure.md) are resolved, but before -writing coordinates, run this gate at every active granularity. For -`Structure=yes`, assemble each resolved topology without changing it, using -[`topology-assembly.md`](./topology-assembly.md) as assembly and relative -registration material; for every page, resolve the page-scale geometry move -carrying its background field, -content zoning, focal hierarchy, or reading path. Apply §1's exact-fit decision -and compare the useful lenses below. Before repeating stacked rectangles / -rounded cards or uniform equal columns, compare a page-field, outline, nesting, -or continuity construction and the relevant contour family's exact members. -Readability of the first workable arrangement does not close this gate. This -never creates a decoration requirement. +**Trigger**: after the page's communication / slot job, composition anchors, and any [`executor-structure.md`](./executor-structure.md) topology are resolved, before writing coordinates — at every active granularity. For `Structure=yes`, assemble the resolved topology without changing it, with [`topology-assembly.md`](./topology-assembly.md) as material; for every page, resolve the page-scale geometry move carrying its background field, content zoning, focal hierarchy, or reading path. Before repeating stacked cards or uniform equal columns, compare a page-field, outline, nesting, or continuity construction and the relevant family's exact members; the first workable arrangement's readability does not close this gate, and the gate creates no decoration requirement. | Pass | Action | Result | |---|---|---| -| Topology / page job | Retain the resolved topology and state its relationship duties; name the page-scale geometry move and its jobs: surface, boundary, focal mark, shared region, counterweight, or any source-backed direction / reveal. | Required relationship duties plus one composition direction and a small set of functional zones; no shape names yet. | -| Decompose | Partition the resolved topology and visible content. Identify components needing independent editing, movement, paint, animation, or reuse; separately identify contour / region semantics that require one object or independently retained Boolean result paths. | Editable siblings plus any explicit Boolean operand set. | -| Select | For each required component, choose the contour family, then its exact member from the job, full native vocabulary, and edge / corner / opening behavior; retain the reader effect when the result is generic or undrawn. | Page-fit native atoms without syntax bias. | -| Compose | Assemble the resolved topology from its independent atoms, then establish page frame, scale, z-order, and negative space. Keep text, images, icons, data marks, and non-merged accents outside Boolean operands. | Relationship-faithful assembly inside one page-level geometry system, not unrelated decorations. | -| Materialize | Run the preset helper for each adopted preset. Run the Boolean helper only for contours that require Merge Shapes semantics, then replace those operands with its stdout paths. | Valid authoring SVG ready for native export. | - -**Reference — not a constraint**: At topology scale, compare independent pieces, -one body with dividers, overlapping siblings, fitted joints, intentional gaps, -and independently retained `fragment` regions. These are common assembly -strategies rather than an exhaustive set. Choose from component independence -and contour / region semantics; never map a topology name to a shape list or -infer equal size or spacing. +| Topology / page job | Retain the resolved topology and its relationship duties; name the page-scale move and its jobs — surface, boundary, focal mark, shared region, counterweight, or a source-backed direction / reveal | Duties plus one composition direction and a few functional zones; no shape names | +| Decompose | Split components needing independent editing, movement, paint, animation, or reuse; separately identify contour / region semantics that need one object or retained Boolean paths | Editable siblings plus any explicit Boolean operand set | +| Select | For each component choose the family, then the exact member from job, full vocabulary, and edge / corner / opening behavior; retain the reader effect when the result is generic or undrawn | Page-fit atoms without syntax bias | +| Compose | Assemble the topology from its atoms; set page frame, scale, z-order, and negative space; keep text, images, icons, data marks, and non-merged accents outside Boolean operands | One relationship-faithful geometry system | +| Materialize | Preset helper per adopted preset; Boolean helper only for contours needing Merge Shapes semantics | Valid authoring SVG | **Composition lenses — not a checklist**: -| Lens | Use when it strengthens the resolved page | +| Lens | Use when it strengthens the page | |---|---| -| Page field | Let one large surface, outline, aperture, or off-canvas contour organize major zones instead of wrapping every content unit in a card. | -| Outline carrier | Use `fill="none"` plus a coherent stroke on a frame, arc, bracket, band, or other faithful contour when bare text needs ownership without a heavy filled card. | -| Nested fields | Visually nest an inset contour, secondary surface, badge, port, or focal shape inside / across a larger field to create hierarchy; keep them as siblings unless one contour must merge. | -| Continuity | Align or overlap independent shapes across zones so geometry reinforces the intended reading path. | -| Depth and contrast | Combine filled, outlined, offset, and negative-space atoms; use Boolean only when the contour itself must change. | -| Deck language | Reuse a corner, arc, slant, notch, or layering logic with page-fit variation rather than cloning one composition. | +| Page field | One large surface, outline, aperture, or off-canvas contour organizes major zones instead of a card per unit | +| Outline carrier | `fill="none"` plus a coherent stroke on a frame, arc, bracket, or band gives bare text ownership without a heavy card | +| Nested fields | An inset contour, secondary surface, badge, port, or focal shape inside / across a larger field creates hierarchy; siblings unless one contour must merge | +| Continuity | Independent shapes aligned or overlapped across zones reinforce the reading path | +| Depth and contrast | Filled, outlined, offset, and negative-space atoms combine; Boolean only when the contour itself must change | +| Deck language | A corner, arc, slant, notch, or layering logic recurs with page-fit variation rather than a cloned composition | -**Default — running deck geometry check (may override for literal pages or -isolated template prototypes)**: After each generated page, retain -`page job → composition move → contour / edge language`; append `relationship → -topology` only for `Structure=yes`, then compare before the next. Repeat only for -the same page job / relationship or deliberate continuity; section, equal -weight/density, style, and precedent are insufficient. Create no artifact or -second pass. +At topology scale, independent pieces, one body with dividers, overlapping siblings, fitted joints, intentional gaps, and retained `fragment` regions are common strategies, not a set; never map a topology name to a shape list or infer equal size or spacing. + +**Default — running deck geometry check (may override for literal pages or isolated prototypes)**: after each page retain `page job → composition move → contour / edge language` (plus `relationship → topology` for `Structure=yes`) and compare before the next; repeat only for the same job / relationship or deliberate continuity — section, equal weight, style, and precedent are insufficient. No artifact, no second pass. **Boolean decision gate**: | Required result | Construction | |---|---| -| Stock contour already expresses the job | Keep that exact contour and materialize it through §1; do not rebuild it from other shapes or Boolean operands. | -| Shapes overlap or layer but must remain independently editable | Keep separate primitives / presets in one ordinary semantic group; do not merge them. | -| One continuous outer silhouette | `union`; use `combine` only for intentional symmetric negative regions. | -| A true hole, edge cut, or reveal | `subtract`, with the visible body first and cutout operands after it. | -| Only the common covered region should remain | `intersect`. | -| Exclusive and shared regions need separate styling or motion | `fragment`, retaining every required result path as an independent shape. | +| A stock contour already expresses the job | Keep it and materialize through §1; never rebuild it from operands | +| Shapes overlap but must stay independently editable | Separate primitives / presets in one semantic group | +| One continuous outer silhouette | `union` (`combine` only for intentional symmetric negative regions) | +| A true hole, edge cut, or reveal | `subtract`, visible body first | +| Only the common region should remain | `intersect` | +| Exclusive and shared regions need separate styling or motion | `fragment`, each required region retained as its own shape | -**Authoring-to-export map**: +**Hard rule — merge only geometry that must become one contour**: never merge text, images, icons, or independent accents to simplify the tree; Boolean discards editable operand history. | SVG authoring form | Native PPTX result | |---|---| -| Ordinary `<rect>`, rounded `<rect>`, `<circle>`, `<ellipse>`, or `<line>` | Matching editable preset geometry / line shape. | -| Complete `preset_shape_svg.py` fragment | One exact `a:prstGeom` shape, or `p:cxnSp` for an authored connector preset. | -| `shape_boolean_svg.py` result path | Editable `a:custGeom`; the final contour is retained, not replayable Merge Shapes history. | -| Parent semantic group containing independent atoms and content | A grouped page construction whose child shapes remain separately editable. | +| Ordinary `<rect>`, rounded `<rect>`, `<circle>`, `<ellipse>`, `<line>` | Matching editable preset geometry / line | +| Complete `preset_shape_svg.py` fragment | One exact `a:prstGeom` shape, or `p:cxnSp` for a connector preset | +| `shape_boolean_svg.py` result path | Editable `a:custGeom`; the contour, not replayable Merge Shapes history | +| Semantic group of independent atoms and content | A grouped construction whose children stay separately editable | -**Reference — not a constraint**: derive the operand count, preset choices, -geometry, paint, rotation, and grouping from the current page. A strong compound -construction may use only independent presets, only one Boolean result, or a mix; -there is no Boolean quota and no catalog of allowed combinations. - -**Hard rule — merge only geometry that must become one contour**: never merge -text, images, icons, or otherwise independent accents merely to simplify the -SVG tree. Boolean materialization discards editable operand history; preserve -siblings whenever one-object contour semantics are unnecessary. +Operand count, preset choice, geometry, paint, rotation, and grouping come from the page; there is no Boolean quota and no catalog of allowed combinations. --- ## 3. Fragment Generation -`render` emits one selected object. `render-batch` atomically emits multiple -already-selected objects for one current page or template construction. Its -`--input` is a JSON array of objects with the same fields as the `render` -flags: required `preset`, `id`, and `frame` (`[x, y, width, height]`); -optional `object_kind`, `name`, `fill`, `fill_opacity`, `stroke`, -`stroke_width`, `stroke_opacity`, `stroke_linecap`, `stroke_linejoin`, -`filter_id`, and `adjustments` (an object such as `{"adj": "val 42000"}`). -Generated project pages choose each object's solid paint from the current page -context, using `spec_lock.md` roles as reusable anchors rather than an exhaustive -palette; `create-template` takes colors from the confirmed brief and template -`design_spec.md`. Mirror/preserve input keeps the source object's paint instead -of regenerating this authored form. - -```bash -python3 ${SKILL_DIR}/scripts/preset_shape_svg.py render rightArrow \ - --id p03-growth-arrow \ - --frame 160 210 320 112 \ - --fill "#2563EB" \ - --stroke none \ - --adjust "adj1=val 50000" -``` - -When one native effect is justified, append `--filter-id softShadow`. -`softShadow` must already be one direct page-level `<defs><filter>` id under -[`svg-effects.md`](./svg-effects.md) §6.4. Omit the option otherwise. - -For a stock bent / curved contour that does not require endpoint attachment: - -```bash -python3 ${SKILL_DIR}/scripts/preset_shape_svg.py render bentConnector3 \ - --id p03-flow-connector \ - --object-kind connector \ - --frame 420 180 220 140 \ - --fill none \ - --stroke "#475569" \ - --stroke-width 2 -``` - -Every connector-family preset requires `--object-kind connector`, `--fill none`, -and a visible stroke. It exports as an unconnected `p:cxnSp`; a connector -preset can never be authored as an ordinary `shape`. - -**Hard rule — stdout-only exception**: the helper prints one or more -deterministic `<g>` fragments. Read that output and insert it with the normal -page edit. A batch JSON array is transient input for -already-selected objects in the current construction, never a project resource -or multi-page plan. Do not redirect output into `svg_output/`, loop over -pages/templates, or let the helper choose layout. The main Agent still authors -each complete SVG page and reusable template explicitly. +`render` emits one object; `render-batch --input -` emits several already-selected objects for one page or template construction from a JSON array with the `render` fields (required `preset`, `id`, `frame` `[x, y, w, h]`; optional `object_kind`, `name`, `fill`, `fill_opacity`, `stroke`, `stroke_width`, `stroke_opacity`, `stroke_linecap`, `stroke_linejoin`, `filter_id`, `adjustments` such as `{"adj": "val 42000"}`). Paint comes from the page context with `spec_lock.md` roles as anchors (create-template: from the confirmed brief and template Design Spec); mirror/preserve input keeps source paint. The batch is transient input, never a project resource or multi-page plan, and never chooses layout. --- ## 4. Atomic Fragment Contract -The helper emits one compact logical group. Metadata and base paint are written -once on the group; its direct children are the visible paths regenerated from -the locked preset registry. - -| Component | Ownership | -|---|---| -| Logical `<g data-pptx-authoring="preset">` | Stable id, object kind, preset, frame, adjustments, explicit local base paint, and an optional helper-authored shape filter reference. | -| Direct `<path>` children | Ordered browser-visible registry layers. A child writes only a path-specific fill/stroke override when the preset requires one. | -| Deliberately absent transport fields | No hidden carrier, preview wrapper, `data-pptx-part`, or stored fingerprint belongs in project-authored SVG. Those fields remain part of expanded PPTX import/round-trip transport. | - -**Hard rule**: treat the returned group as atomic. Keep it as the content group -without `data-pptx-bounds` when it stands alone; `data-pptx-frame` owns its -object geometry. When it needs labels, icons, or other decorations, put the -preset and those siblings in a separate bounded parent content group; never put -them inside the preset group itself. Do not edit the direct paths; they are -validation evidence generated from the registry, not a freehand contour surface. - -Canonical page/template authoring also keeps paint and opacity off ancestor -groups that contain the preset. Compatible ancestor paint still exports under -the general SVG composition rules, but the checker warns because the atom is no -longer paint-self-contained; rerun the helper with channel alpha instead. - -On a structured template, a validated authored-preset group is one semantic -atom. It may be Slide-local, the single carrier of an `object` slot, or a direct -Master/Layout fixed atom. This narrow exception does not permit ordinary nested -`<g>` structures in Master/Layout layers or placeholder carriers. The template -workflow may add the registered structural ownership attributes to the complete -helper group; it still must not alter preset metadata, paint, the filter -reference, or direct paths. - -**Frame coordinate space**: `--frame x y w h` is expressed in the coordinate -space where you insert the fragment. At the page root that is page coordinates; -inside a `<g transform="translate(…)">` use **group-local** coordinates — the -ancestor transform stacks on top, so page-absolute values would double-offset -the shape off-canvas. Keep the helper's exact space-separated ordinary-decimal -`data-pptx-frame` spelling; compact authoring does not accept alternate numeric -spellings. - -**Regeneration rule**: rerun the helper when preset, frame, adjustment, fill, -stroke, stroke width, or the filter id changes. Moving, scaling, rotating, or -flipping the complete logical group is allowed; zero-scale transforms and -shear/skew are forbidden, and the transformed frame must remain inside -DrawingML's coordinate range. Stroke width must remain inside DrawingML's -line-width range. To freely edit the contour, replace the whole fragment with -ordinary SVG rather than modifying a generated direct path. - -For a canonical reusable template, the complete helper fragment may remain as -an executable exemplar. A final-page adaptation may copy it unchanged only -when all registry metadata, frame, adjustments, paint, and the optional filter -reference remain unchanged; otherwise regenerate the complete compact group. +The logical `<g data-pptx-authoring="preset">` owns id, object kind, preset, frame, adjustments, base paint, and the optional filter reference; its direct `<path>` children are ordered registry layers with only the per-path override a preset requires. No hidden carrier, preview wrapper, `data-pptx-part`, or fingerprint belongs in project-authored SVG. On a structured template the validated group is one semantic atom — Slide-local, the single carrier of an `object` slot, or a direct Master/Layout fixed atom — and the template workflow may add only registered ownership attributes. A canonical template may keep the fragment as an executable exemplar; a page adaptation copies it unchanged only when every field matches, otherwise regenerates it. Full machine contract and validation: [`svg-contract.md`](../scripts/docs/svg-contract.md) §1.5. --- @@ -345,143 +131,52 @@ reference remain unchanged; otherwise regenerate the complete compact group. | Concern | Behavior | |---|---| -| Shape text | Keep visible SVG `<text>` outside the atomic fragment. It remains editable but may export as a grouped text box rather than the preset's own `p:txBody`. | -| Connector attachment | Authoring helper v1 creates an unconnected `p:cxnSp` and does not accept endpoint/site metadata. Do not hand-add it. The imported-shape contract may preserve an attachment that already exists in a source PPTX; creating a new attached connector is currently unsupported. | -| Action button behavior | `actionButton*` presets map visual geometry only. No action, navigation target, or hyperlink is created automatically. | -| Gradient/pattern paint | Authoring helper v1 accepts solid HEX paint only. Use ordinary SVG when a complex paint treatment is essential. | -| Shadow/glow | Shape presets may reference one existing [`svg-effects.md`](./svg-effects.md) §6.4 filter through `--filter-id`; it applies once to the complete native shape. Connector presets, multiple effects, child-path filters, and other effect graphs remain unsupported. | -| Multi-path darken/lighten | Direct visible layers use the shared normalized paint behavior from the PPTX importer. Their registry-derived HEX values are authorized derivatives of the selected base color and need no separate lock row. | -| Expanded compatibility | Existing helper-authored carrier/preview fragments remain readable as ordinary Slide-local input and receive a non-blocking migration warning; they do not become structured fixed atoms or object-slot carriers. Imported expanded fragments remain the lossless mirror/preserve form. | -| External edits | Any registry-path, style, or semantic mismatch fails quality check and export; regenerate the fragment. | - -**Validation**: `svg_quality_checker.py` independently rerenders every compact -authored preset from registry metadata and compares its direct visible paths -and paint. It also validates the optional shape filter through the shared -[`svg-effects.md`](./svg-effects.md) §6.4 contract. The exporter performs the -same validation, then expands the compact group only in memory to reuse the -lossless native-shape conversion path. -Compatible expanded authored input remains under its separate carrier/preview -freshness contract. +| Shape text | Stays outside the fragment; editable, but may export as a grouped text box rather than the preset's own `p:txBody` | +| Connector attachment | v1 authors unconnected `p:cxnSp` and accepts no endpoint/site metadata; imported attachments survive only under preserve/mirror | +| Action buttons | Geometry only; no action, navigation, or hyperlink | +| Gradient/pattern paint | Ordinary SVG | +| Shadow/glow | One existing §6.4 filter via `--filter-id`, shape presets only, applied once to the whole shape | +| Multi-path darken/lighten | Registry-derived derivatives of the base color; no lock row | +| Expanded legacy fragments | Readable as Slide-local input with a migration warning; never structured atoms or slot carriers | +| External edits | Any registry-path, style, or semantic mismatch fails quality check and export; regenerate | --- ## 6. Shape Boolean Materialization -**Trigger**: Current page construction has two or more supported shape/text operands -whose faithful result calls for PowerPoint-style Union, Combine, Fragment, -Intersect, or Subtract. Executor decides this directly from the actual content, -complete native inventory, and explicit user/template constraints; no upstream -suggestion or planning field is required. - -```bash -python3 ${SKILL_DIR}/scripts/shape_boolean_svg.py render <svg-file> \ - --operation subtract \ - --source body \ - --source cutout \ - --id result -``` - -| Concern | Contract | -|---|---| -| Sources | Closed `path`, `polygon`, `rect`, `circle`, `ellipse`, one validated unfiltered compact authored shape preset, or supported horizontal implicit-LTR direct `<text>` with a resolvable exact OpenType weight/style (`--font-dir` adds search roots). Text becomes glyph geometry and is no longer editable text. A filtered preset is not a Boolean operand; materialize the geometry without the effect, then reapply one supported filter to the result. Open geometry, groups, nested text, images, definitions, and nested SVG viewports fail closed. | -| Primary shape | The first `--source` supplies result paint. For `subtract`, all later operands are removed from that primary geometry. Explicit paint flags override only their named channels. | -| Coordinates | Ancestor and local transforms are baked into SVG-root coordinate space. Place stdout in the primary operand's z-order with no additional transform; never reinsert it under an original transformed ancestor. Root-coordinate space does not require each result path to be a direct `<svg>` child. | -| Placement | Ordinary Slide-local results belong in the applicable untransformed direct-root semantic `<g>` with its normal `id` / `data-pptx-bounds`. Master/Layout results remain direct-root path atoms and redeclare `data-pptx-layer`. One non-fragment result may be the direct `data-pptx-carrier="true"` child of an `object` slot. | -| Fragment roles | Fragment paths may share one ordinary Slide-local semantic group, but remain separate shapes and cannot collectively claim one carrier or one Master/Layout atom. Helper output inherits no structural role metadata from its operands; redeclare only the final layer/carrier/role contract. | -| Result | `union`, `combine`, `intersect`, and `subtract` emit one ordinary `<path>`. `fragment` emits stable sibling paths named `<id>-1`, `<id>-2`, ... in top/left/bottom/right/area order. | -| Winding | Results use explicit nonzero contour direction and never emit `fill-rule`, `clip-rule`, `clip-path`, `mask`, or Merge Shapes metadata. Operands that depend on even-odd fill, clipping, or masking fail closed. | -| Preservation | This helper authors new geometry only. Never use it to merge or split mirror/preserve source structure. | - -Operation semantics match PowerPoint's visible Merge Shapes result: `union` -keeps every covered region, `combine` keeps the symmetric difference, -`intersect` keeps only common coverage, `subtract` removes every later source -from the primary, and `fragment` returns each atomic filled region. The PPTX -stores the materialized freeform geometry, not replayable operation history. - -**Hard rule — stdout-only replacement**: The helper never writes the source -page. In one normal page edit, remove every selected operand and insert -every returned path in root coordinate space at the primary operand's z-order, -using the placement contract above. Fragment paths remain separate shapes; an -ordinary semantic group does not turn them into one structural atom. +**Trigger**: the current construction has two or more supported operands whose faithful result calls for Union, Combine, Fragment, Intersect, or Subtract — decided by Executor from the content and inventory, with no upstream field. Operation semantics match PowerPoint's Merge Shapes: `union` keeps every covered region, `combine` the symmetric difference, `intersect` the common coverage, `subtract` removes later sources from the primary, `fragment` returns each atomic region; the PPTX stores the resulting freeform, not history. Ordinary Slide-local results belong in the applicable untransformed direct-root semantic `<g>` with its normal `id` / `data-pptx-bounds`; Master/Layout results stay direct-root atoms that redeclare `data-pptx-layer`; one non-fragment result may be the `data-pptx-carrier="true"` child of an `object` slot; fragment paths may share a group but never collectively claim one carrier or atom, and helper output inherits no structural role from its operands. In one page edit, remove every operand and insert every returned path at the primary operand's z-order. --- ## 7. Shape-Only Modelling Techniques -Applies to any page built from shapes, **with or without images** — a text-only, -data-only, or icon-only deck reaches these the same way. Each technique below is -plain geometry plus gradient paint, so all of it survives native export. +Plain geometry plus gradient paint, so all of it survives native export; reachable from any shape-built page, with or without images. ### 7.1 Alternating light/dark gradient = dimensional form -The single highest-yield shape technique. A cylinder, metallic band, dimensional -numeral, or curved panel is produced by one gradient whose stops **alternate -light and dark** across the shape — light · dark · light for a three-stop ramp, -or light · dark · light · dark · light for a five-stop one. The alternation -imitates a curved surface catching light twice; a plain two-stop ramp always -reads flat no matter how strong the contrast. - -Keep every stop on one hue and vary only lightness, hold one light direction for -the whole page, and remove strokes so adjacent facets meet cleanly. For a -cylinder, apply the alternating ramp across the body and cap it with an ellipse -carrying its own shallower ramp. The same light logic applies across separate -facets of any folded form. +The highest-yield shape technique: a cylinder, metallic band, dimensional numeral, or curved panel comes from one gradient whose stops alternate light · dark · light (three stops) or light · dark · light · dark · light (five). The alternation reads as a curved surface catching light twice; a two-stop ramp always reads flat. Keep every stop on one hue and vary only lightness, hold one light direction per page, and remove strokes so facets meet cleanly. A cylinder takes the ramp across its body and a shallower ramp on its cap ellipse; the same light logic runs across the facets of any folded form. ### 7.2 Reflection without a reflection effect -Native reflection is `Bake-required` ([`svg-effects.md`](./svg-effects.md) §6.12), -so build it from geometry instead: +Native reflection is `Bake-required` (§6.12), so build it: duplicate and flip with `transform="translate(0, 2·y_bottom) scale(1, -1)"`, keep only the top 10–25 % of the copy, lay over it a rectangle whose gradient runs from fully transparent at the object's base to the page background at the cut, and drop the whole reflection to 60–70 % opacity. Seats certificate rows, product shots, logo tiles, and cylinders; no blur. -1. Duplicate the object and flip it with `transform="translate(0, 2·y_bottom) scale(1, -1)"`. -2. Keep only the top **10–25 %** of the flipped copy — that is all a reflection - ever shows. -3. Lay a rectangle over it filled with a gradient running from fully transparent - at the object's base to the page background color at the cut line, so the - copy dissolves into the page. -4. Drop the whole reflection to roughly **60–70 %** opacity. +### 7.3 Fragment as a modelling tool -Seat rows of certificates, product shots, logo tiles, and cylinders this way. Do -not add a blur — it will not survive export, and a short gradient fade already -reads correctly at slide scale. - -### 7.3 Fragment as a modelling tool, not just a boolean - -`fragment` (§6) can build registered layered diagrams from one silhouette: -cross a triangle with topology-derived bars for pyramid tiers; cross a circle -with two topology-derived bars for a quadrant wheel; slice an annulus radially -for ring segments. These are construction examples rather than topology -defaults or an exhaustive set. Every retained piece inherits the parent contour, -so the assembly stays registered without independently redrawing its parts. - -Derive cutter count, position, and piece size from the resolved topology. Use a -constant step and one §7.1 gradient family only when equal tier / segment weight -and one-solid reading are semantic; otherwise preserve the required differences -in geometry and paint. +`fragment` builds registered layered diagrams from one silhouette: a triangle crossed by topology-derived bars gives pyramid tiers, a circle crossed by two bars a quadrant wheel, an annulus sliced radially ring segments — every piece inherits the parent contour, so the assembly stays registered. Derive cutter count, position, and piece size from the resolved topology; use a constant step and one §7.1 gradient family only when equal weight and one-solid reading are semantic. ### 7.4 Soft edges without the soft-edge effect -Feathered edges are `Bake-required` ([`svg-effects.md`](./svg-effects.md) §6.12), -but the four jobs they normally do are all reachable with gradients: +Feathered edges are `Bake-required`, but their four jobs are gradients: | Intent | Build instead | |---|---| -| Contact shadow under an object | Ellipse filled with a `radialGradient` from dark-transparent at the centre to fully transparent at the rim | -| Spotlight / stage pool | Cone or ellipse filled with a gradient fading to transparent at its far end, at low opacity over the scene | -| Object dissolving into the page | Overlay a rectangle whose gradient runs from transparent to the exact page background hex | +| Contact shadow under an object | Ellipse with a `radialGradient` from dark-transparent at the centre to transparent at the rim | +| Spotlight / stage pool | Cone or ellipse fading to transparent at its far end, low opacity over the scene | +| Object dissolving into the page | A rectangle whose gradient runs from transparent to the exact page background hex | | Hiding an object while keeping it live | Full transparency, or a background-registered fill ([`image-layout-patterns.md`](./image-layout-patterns.md) `#M1-08`) | -A radial or linear alpha ramp reads the same as a feathered edge at slide scale -and, unlike a filter, exports intact. Never approximate a soft edge with a stack -of stroked outlines — the banding is visible on projection. +A radial or linear alpha ramp reads as a feathered edge at slide scale and exports intact; never approximate a soft edge with stacked stroked outlines. ### 7.5 Ground plane and staging -An object floating in empty canvas looks pasted on. Give it a surface: a wide -shallow ellipse or trapezoid beneath it, filled with a gradient that fades to the -background at its edges, optionally with a soft dark ellipse directly under the -object as contact shadow. A trapezoid narrowing away from the viewer reads as a -receding floor; a cylinder or slab reads as a pedestal. - -Keep the plane low-contrast — it is staging, not content. This is what makes -certificate rows, product hero shots, and trophy/award pages look composed -rather than floating, and it costs two shapes. +An object floating in empty canvas looks pasted on. Give it a wide shallow ellipse or trapezoid beneath, filled with a gradient fading to the background at its edges, optionally with a soft dark ellipse directly under it as contact shadow; a trapezoid narrowing away reads as a receding floor, a cylinder or slab as a pedestal. Keep the plane low-contrast — staging, not content. Two shapes make certificate rows, product heroes, and award pages look composed. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/pptx-structure-interface.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/pptx-structure-interface.md index 7834430b..162dae78 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/pptx-structure-interface.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/pptx-structure-interface.md @@ -4,210 +4,78 @@ Conditional interface for PowerPoint Master, Layout, fixed-layer, and placeholder authoring. In Generate, load only for Default `spec_lock.md pptx_structure.mode: structured` or Quick structured Slide authoring from an installed Layout/Deck owner. -**Cross-reference map**: unqualified §1.5 and §4.2 references point to [`shared-standards-core.md`](./shared-standards-core.md); this file's own sections are §1–§3. +**Cross-reference map**: unqualified §1.5 and §4.2 references point to [`shared-standards-core.md`](./shared-standards-core.md); this file's own sections are §1–§3. Exporter and read-back mechanics live in [`svg-pipeline.md`](../scripts/docs/svg-pipeline.md#structured-export-mechanics). ## 1. PPTX Structure Routing -Every new SVG project declares one deterministic route. Free-design, brand-only, and `template_reuse_scope: style` projects use `pptx_structure.mode: flat`, omit `pptx_masters` / `pptx_layouts` / `page_pptx_layouts` / `page_layouts`, and author no Master/Layout/layer/placeholder metadata. Export keeps all represented content Slide-local while materializing one clean project-owned Master plus one Blank Layout from the current color/typography lock; stock content placeholders and unused built-in Layouts are removed, while the standard date/footer/slide-number capability hooks remain. Deck/layout template projects whose AI-derived lock records `template_reuse_scope: mirror|layout` use `mode: structured`; `standard` / `fidelity` templates use their authored contract, while mirror templates use the validated source identities and parentage declared by the newly authored compact workspace. +Every new SVG project declares one deterministic route: -**Quick exception**: Lock-row/Strategist statements below are Default-only. Quick keeps free/Brand/Style-only flat; an installed Layout/Deck owner is structured unless visual-only, with identities on SVG roots and title/body anchors inferred from slot carriers. +| Project | `pptx_structure.mode` | Structure metadata | +|---|---|---| +| Free-design, brand-only, `template_reuse_scope: style` | `flat` | none; omit `pptx_masters` / `pptx_layouts` / `page_pptx_layouts` / `page_layouts`; export materializes one clean project-owned Master plus one Blank Layout from the lock and keeps every object Slide-local | +| Layout/Deck template with `template_reuse_scope: mirror\|layout` | `structured` | §2; `standard` / `fidelity` templates use their authored contract, mirror templates use the validated source identities and parentage of the compact workspace | -**Hard rule — no structure inference**: Flat export performs no promotion or deduplication; every object stays Slide-local. Structured template export compiles only declared root identities, atomic fixed layers, and slot groups—it does not assign Layout families, cluster pages, infer placeholders, repair missing metadata, or migrate legacy contracts. Create a new current workspace through [`create-template`](../workflows/create-template.md) before generating structured pages. +**Quick exception**: Lock-row/Strategist statements in this file are Default-only. Quick keeps free/Brand/Style-only flat; an installed Layout/Deck owner is structured unless visual-only, with identities on SVG roots and title/body anchors inferred from slot carriers. -**Layout reuse**: Reuse one Layout key only when its ordered fixed Layout atoms and slot ids/types/effective indices/default bounds/binding modes are identical. Different wording, data, imagery, crop, or Slide-local carrier geometry does not create a new Layout. A genuinely different reusable contract gets a new key even when both pages are semantically `content`. +**Hard rule — no structure inference**: Flat export promotes and deduplicates nothing. Structured export compiles only declared root identities, atomic fixed layers, and slot groups; it never assigns Layout families, clusters pages, infers placeholders, repairs missing metadata, or migrates legacy contracts. Create a current workspace through [`create-template`](../workflows/create-template.md) before generating structured pages. -**Zero-slot Layout**: A named Layout may contain no slots and no fixed Layout atoms. This is valid for a cover, poster, full-visual page, or other fixed composition. Do not manufacture an empty `utility` kind or full-page fake `object` slot. +**Layout reuse**: Reuse one Layout key only when its ordered fixed Layout atoms and slot ids/types/effective indices/default bounds/binding modes are identical. Different wording, data, imagery, crop, or Slide-local carrier geometry does not create a new Layout; a genuinely different reusable contract gets a new key even when both pages are semantically `content`. A Layout may have zero slots and zero fixed atoms — valid for a cover, poster, or full-visual page; do not manufacture an empty `utility` kind or a full-page fake `object` slot. **Adaptive change**: `strict` preserves the prototype. `adaptive` retains its Master and uses only a Layout declared in Default's plan/lock or permitted by Quick's frozen Template Application. Required atom/slot-contract changes return Default for repair/readback/validation; Quick creates a new Layout only under that permission. Never mutate a reused key. ## 2. Explicit PPTX Master / Layout / Placeholder Metadata -**Trigger**: This explicit metadata interface applies only to new pages generated from a current deck/layout template workspace with `template_reuse_scope: mirror|layout`. `spec_lock.md` declares `pptx_structure.mode: structured`, complete unique `pptx_masters` / `pptx_layouts` rosters, one `page_pptx_layouts` assignment per generated page, and `page_layouts` as authoring-prototype provenance. `template_reuse_scope: style`, free-design, and brand-only SVGs use `mode: flat` and none of these metadata fields. +**Trigger**: new pages generated from a current deck/layout workspace with `template_reuse_scope: mirror|layout`. `spec_lock.md` declares `pptx_structure.mode: structured`, complete unique `pptx_masters` / `pptx_layouts` rosters, one `page_pptx_layouts` assignment per generated page, and `page_layouts` as authoring-prototype provenance. -**Project lock**: A Master row is `<master_key>: <PowerPoint picker name>`. A unique Layout row is `<layout_key>: <master_key> | <PowerPoint picker name> | <prototype source>`, where the source is a generated `P<NN>` or installed `template:<basename>`. A page assignment is `P<NN>: <layout_key>` under `page_pptx_layouts`. The SVG root values MUST match the assigned definition. A Layout key belongs to exactly one Master and must be globally unique. Reuse one key only when prototypes share identical ordered Layout atoms and slot ids/types/effective indices/default bounds/binding modes. An unused Layout uses a template SVG source and remains registered without a published carrier slide. Every structured route requires numeric `spec_lock.md` typography `title` / `body` rows. +**Project lock rows**: Master `<master_key>: <PowerPoint picker name>`; unique Layout `<layout_key>: <master_key> | <PowerPoint picker name> | <prototype source>` where the source is a generated `P<NN>` or installed `template:<basename>`; page assignment `P<NN>: <layout_key>` under `page_pptx_layouts`. SVG root values MUST match the assigned definition. A Layout key belongs to exactly one Master and is globally unique; an unused Layout uses a template SVG source and stays registered without a published carrier slide. Every structured route requires numeric `spec_lock.md` typography `title` / `body` rows — they become the Master text styles. -**Template behavior**: Strict preserves the selected prototype's Master/Layout/slot contract. Adaptive realizes only a Layout allowed by §1 and never mutates a reused key. Mirror-created prototypes preserve validated source identity, parentage, slots, meaning, and similar presentation in compact new SVG; paint/geometry nodes need not be isomorphic. `standard` / `fidelity` never make source topology authoritative; mirror does not synthesize replacement topology or fill missing facts. - -Imported inherited-shape visibility remains an immutable analysis fact until a -structured mirror is materialized. The final mirror root carries that fact with -the two optional canonical booleans below so export can write the preserved source -package fields without inferring visibility from which shapes happen to be -present. Authored `standard` / `fidelity` templates normally omit both and use -the default `true`. See -[`conversion.md`](../scripts/docs/conversion.md#import-compatibility-and-recovery-boundary). - -**Master text-style contract**: Default reads title/body anchors from its lock; -structured Quick infers them from semantic slot carriers with deterministic -fallbacks, while flat Quick retains stock defaults. An effective `title` anchor -maps to every `a:defRPr` in Master `p:titleStyle`. Level 1 in both -`p:bodyStyle` and `p:otherStyle` uses the declared `body` anchor; levels 2–9 -use a deterministic descending hierarchy from `15/16` through `8/16` of that -size, rounded to 0.5 pt and floored at the smaller of 8 pt or the body size. -Existing per-level indentation and bullet properties remain unchanged. - -| Master style | Effective source | XML field changed | -|---|---|---| -| `p:titleStyle` | title anchor | Every `a:defRPr@sz` | -| `p:bodyStyle` | body anchor | Level 1 plus derived level 2–9 `a:defRPr@sz` | -| `p:otherStyle` | body anchor | Level 1 plus derived level 2–9 `a:defRPr@sz` | - -**Hard rule — narrow scope**: This Master update changes only Master -`p:txStyles//a:defRPr@sz`; it preserves level indentation, bullet, margin, and -paragraph settings. It does not rewrite direct run sizes on generated slides, -so the initial slide rendering remains controlled by the authored SVG. Missing -Default `title` or `body` rows fail flat or structured export; Quick structured -uses inferred/fallback anchors. - -**Layout level-one text-default contract**: For every text-bearing placeholder -whose first prototype run has a direct `a:rPr@sz`, explicit Layout export copies that -size to the generated Layout prompt run and -`p:txBody/a:lstStyle/a:lvl1pPr/a:defRPr@sz`. It does not rewrite Slide direct -runs or Layout levels 2–9. This preserves the layout-specific size when -level-one placeholder text is inserted or reset; placeholders without a direct -prototype size remain unchanged. +**Template behavior**: Strict preserves the selected prototype's Master/Layout/slot contract. Adaptive realizes only a Layout allowed by §1 and never mutates a reused key. Mirror-created prototypes preserve validated source identity, parentage, slots, meaning, and similar presentation in compact new SVG; paint/geometry nodes need not be isomorphic. `standard` / `fidelity` never make source topology authoritative; mirror does not synthesize replacement topology or fill missing facts. Imported inherited-shape visibility is an analysis fact carried by the two optional root booleans below; authored `standard` / `fidelity` templates normally omit both (see [`conversion.md`](../scripts/docs/conversion.md#import-compatibility-and-recovery-boundary)). | Metadata | Placement | Behavior | |---|---|---| | `data-pptx-master="master-default"` | root `<svg>` | Binds the slide to one generated Slide Master key | -| `data-pptx-master-name="Default Master"` | root `<svg>` | Sets the Master picker/display name | +| `data-pptx-master-name="Default Master"` | root `<svg>` | Master picker/display name | | `data-pptx-layout="content"` | root `<svg>` | Binds the slide to one generated reusable layout key | -| `data-pptx-layout-name="Title and Content"` | root `<svg>` | Sets the PowerPoint layout-picker name; defaults from the layout key | -| `data-pptx-show-master-shapes="false"` | root `<svg>` | Accepts exact lowercase `true` or `false` and writes the assigned Layout's `p:sldLayout@showMasterSp`; every SVG using the same Layout key must repeat the same value; omission means `true` | -| `data-pptx-show-inherited-shapes="false"` | root `<svg>` | Accepts exact lowercase `true` or `false` and writes this Slide's `p:sld@showMasterSp`; `false` hides inherited Layout and Master shapes without removing backgrounds, placeholders, parts, or parent relationships; omission means `true` | -| `data-pptx-layer="master"` | direct semantic atom | Moves one repeated static object/background into the named Slide Master; ordinary `<g>` is forbidden, while one validated compact authored-preset `<g>` (§1.5) is an atomic exception | -| `data-pptx-layer="layout"` | direct semantic atom | Moves one repeated static object/background into the selected Layout; ordinary `<g>` is forbidden, while one validated compact authored-preset `<g>` (§1.5) is an atomic exception | -| `data-pptx-layer="slide"` | direct full-canvas solid `<rect>` only | Writes a one-page override as Slide `p:bg` | -| `data-pptx-placeholder="..."` | direct slot `<g id>` | Declares a reusable Layout slot whose visible content remains Slide-local | -| `data-pptx-bounds="x y width height"` | slot `<g>` | Supplies the positive reusable design-zone frame in SVG user units with at most two decimals per value | -| `data-pptx-idx="1"` | slot `<g>` | Retains an imported source Layout placeholder index; optional for reconstructed layouts | +| `data-pptx-layout-name="Title and Content"` | root `<svg>` | Layout picker name; defaults from the layout key | +| `data-pptx-show-master-shapes="false"` | root `<svg>` | Optional; exact lowercase `true` / `false`; the assigned Layout's `showMasterSp`, repeated identically by every SVG sharing the key; omission means `true` | +| `data-pptx-show-inherited-shapes="false"` | root `<svg>` | Optional; exact lowercase `true` / `false`; this Slide's `showMasterSp` — `false` hides inherited shapes without removing backgrounds, placeholders, parts, or parents; omission means `true` | +| `data-pptx-layer="master"` / `"layout"` | direct semantic atom | Moves one repeated static object/background into the Master or the selected Layout; ordinary `<g>` is forbidden, one validated compact authored-preset `<g>` (§1.5) is the atomic exception | +| `data-pptx-layer="slide"` | direct full-canvas solid `<rect>` only | One-page background override written as Slide `p:bg` | +| `data-pptx-placeholder="..."` | direct slot `<g id>` | Reusable Layout slot whose visible content stays Slide-local | +| `data-pptx-bounds="x y width height"` | slot `<g>` | Mandatory positive reusable design-zone frame in SVG user units, at most two decimals per value | +| `data-pptx-idx="1"` | slot `<g>` | Retains an imported source placeholder index; optional for reconstructed layouts | | `data-pptx-carrier="true"` | one compatible direct child of a normal slot | Binds that visible child as the real Slide placeholder carrier | | `data-pptx-binding="proxy"` | composite `object` slot `<g>` only | Keeps the visible group ordinary and creates one hidden transparent binding proxy | | `data-pptx-editable="false"` | master/layout element or slide background | Declares intentional editing outside ordinary slide content | -**Hard rule — explicit only**: On a structured `template_reuse_scope: mirror|layout` route, every SVG requires the four root Master/Layout identity attributes. Optional inherited-shape visibility uses only exact lowercase `true` / `false`; other spellings fail, and omission means `true`. Every Master/Layout atom and slot requires a unique stable `id` and is a direct root child. Layouts with zero slots are valid. `data-pptx-layout-kind`, `distilled`, and `utility` are legacy metadata and fail the structured contract. Flat `template_reuse_scope: style`, free-design, and brand-only pages omit the structural markers and visibility attributes; ordinary groups still use the shared `data-pptx-bounds` module contract. - -**Identity is not layer membership**: An SVG `id` identifies one element and -must be unique inside that SVG document. Any number of direct atoms may repeat -the same `data-pptx-layer="master"` or `data-pptx-layer="layout"` value; the -layer attribute, never the `id`, determines ownership. Separate standalone SVG -pages may repeat the same stable fixed-atom `id` when they declare the same -Master/Layout contract. Unmarked visual content is Slide-local, except that the -optional direct solid Slide-background marker below makes one-page background -ownership explicit. - -**Layer order**: Author the SVG in PowerPoint paint order: Master background, -Layout background, optional Slide background, remaining Master atoms, remaining Layout atoms, -then slot groups and Slide-local content groups. Backgrounds are a special inheritance -plane beneath every shape; this order keeps standalone SVG preview and -PowerPoint rendering aligned. The exporter rejects interleaved layers. - -**Solid background ownership**: Structured export deliberately narrows scoped -background ownership to a direct full-canvas solid `<rect>` and disables the -generic conversion-level promotion described in §4.2. Mark the solid rect -`data-pptx-layer="master"` for the deck-wide default, -`data-pptx-layer="layout"` for a page-type override, or -`data-pptx-layer="slide"` for a one-slide override. An unmarked direct -full-canvas solid rect in the background plane is also treated as Slide scope. -A Layout background overrides the Master background; a Slide background -overrides both. Use the Master for a globally stable color and the Layout for -cover/section/content variants under the same design language. Gradient and -preset-pattern rects remain ordinary shapes on declared Master/Layout layers -or as Slide-local content; images remain pictures. Textures, transformed rects, -and visible-stroke rects also remain ordinary objects. - | Placeholder value | Direct carrier inside slot `<g>` | PowerPoint placeholder | |---|---|---| | `title`, `subtitle`, `body` | one `<text data-pptx-carrier="true">` | `title`, `subTitle`, `body` | | `date`, `footer`, `slide-number` | one `<text data-pptx-carrier="true">` | `dt`, `ftr`, `sldNum` | -| `picture` | one `<image>` or supported imported crop `<svg>`, marked as carrier | `pic` | -| `chart`, `table` | one matching `data-pptx-replace-with` marker group, marked as carrier | `chart`, `tbl` | -| `object` | one text, image, basic SVG shape, or validated compact authored-preset `<g>` marked as carrier; alternatively the slot group declares `binding="proxy"` | `obj` | -| `media` | one `<image>` or supported imported crop `<svg>`, marked as carrier | `media` | +| `picture`, `media` | one `<image>` or supported imported crop `<svg>`, marked as carrier | `pic`, `media` | +| `chart`, `table` | one matching `data-pptx-replace-with` marker group, marked as carrier; requires `--native-charts-and-tables` | `chart`, `tbl` | +| `object` | one text, image, basic SVG shape, or validated compact authored-preset `<g>` marked as carrier; or the slot declares `binding="proxy"` | `obj` | -A template-owned chart/table carrier may declare -`data-pptx-native-authority="json"`. Its inline metadata, marker identity, -bounds, and slot binding remain structural facts; its non-metadata SVG preview -children are derived and may be regenerated without changing that contract. +**Hard rule — explicit only**: on a structured route every SVG carries the four root identity attributes; every Master/Layout atom and slot is a direct root child with a unique stable `id`; `data-pptx-layout-kind`, `distilled`, and `utility` are legacy and fail. Flat pages omit the structural markers and visibility attributes; ordinary groups still use the shared `data-pptx-bounds` contract. The `id` identifies an element; `data-pptx-layer`, never the `id`, decides ownership, and separate pages may repeat the same fixed-atom `id` under the same Master/Layout contract. Unmarked content is Slide-local. -**Text slot carrier**: A multiline text placeholder must remain one native text -frame. Default export and `--reflow-text` do; `--no-merge` cannot supply several -line shapes as one PowerPoint placeholder prototype/binding. Leave strict-line -text Slide-local when separate frames are required. +**Layer order**: author in PowerPoint paint order — Master background, Layout background, optional Slide background, remaining Master atoms, remaining Layout atoms, then slot groups and Slide-local content. Backgrounds are the inheritance plane beneath every shape; keeping this order aligns SVG preview with PowerPoint rendering. -For a materialized mirror, an imported text carrier may additionally keep the -source shape's positive `data-pptx-frame="x y width height"`. That frame owns -the Slide carrier `a:xfrm`; the converter reconstructs text-body insets from the -visible SVG anchor/baseline instead of shrinking the shape to glyph bounds. -`data-pptx-bounds` remains the reusable Layout default and may -legitimately differ. Do not add `data-pptx-frame` to an authored -`standard` / `fidelity` carrier merely to duplicate its Layout bounds. +**Solid background ownership**: only a direct full-canvas solid `<rect>` can own a scoped background. Mark it `layer="master"` for the deck-wide default, `layer="layout"` for a page-type variant under the same design language, `layer="slide"` for a one-slide override; Layout overrides Master, Slide overrides both. Gradient/pattern rects, textures, transformed rects, and visible-stroke rects remain ordinary shapes on declared layers or Slide-local; images remain pictures. -**Blank text carrier**: Leave a marked text carrier empty or whitespace-only -when the placeholder must remain visually blank. Export materializes one -invisible U+200B run so the carrier still becomes a native PowerPoint text -shape. Do not insert a dummy dash, shrink text below the DrawingML 1pt minimum, -or hide a visible glyph with opacity/background paint; those workarounds either -leak content or produce a PPTX that PowerPoint repairs. +**Slot bounds**: derive `data-pptx-bounds` from the intended design zone, column, panel inset, safe area, or picture frame — never from text length, glyph width, line count, or a tight content box. Repeat the same slot ids/types/effective indices/default bounds/binding modes on every slide using that Layout; Slide content and local carrier geometry may differ from the default frame. A template-owned chart/table carrier may declare `data-pptx-native-authority="json"`; its metadata, marker identity, bounds, and slot binding are structural facts while its preview children are derived. -`title` is normally type-matched without an index in reconstructed layouts; if -an imported source title explicitly has one, preserve that exact index. Every -indexed placeholder on one layout uses a unique OOXML UInt32 index. Structured export writes the semantic type on both the Layout and Slide carrier (except `obj`, whose OOXML default is already `obj`) so PowerPoint and `python-pptx` retain the same identity. A composite object slot instead keeps its visible group ordinary and uses a hidden transparent proxy. -Date, footer, and slide-number placeholders enable their matching Layout `p:hf` -flags; a date placeholder also gets a `datetimeFigureOut` field in the reusable -Layout definition. The current Slide keeps its authored date content. - -Because an omitted `p:ph@idx` has the effective value `0`, an omitted-index -title reserves `0`; no other placeholder on that Layout may use the same -effective index. - -**Slot prototype**: The prototype source declared by the unique Layout definition supplies that Layout's placeholder formatting. `data-pptx-bounds` supplies the reusable default frame and is mandatory on every slot. Derive it from -the intended design zone, column, panel inset, safe area, or picture frame — -never from text length, glyph width, line count, or a tight content bounding -box. Repeat the same slot ids/types/effective indices/default bounds/binding modes on every slide using that Layout. The Layout owns the reusable `p:ph`; normal visible carriers keep a matching Slide binding so approved rendering stays identical. A composite `object` proxy adds one hidden transparent binding shape to suppress empty inherited placeholder paint. Bounds define the Layout default only; actual Slide content and local carrier geometry may differ. - -**Final-package read-back gate**: After writing a temporary structured PPTX and before publishing it, export reopens the package and -verifies that each published Slide targets exactly one Layout, one Layout key always resolves to the -same part, different keys do not collapse onto one part, and every declared Layout—including one unused by all published Slides—is -registered through its Master and the Presentation. Physical Slide/Layout/ -Master part rosters, their content-type overrides, and their Presentation/ -Master registrations must be exact. It also verifies the Layout picker name, -Master picker identity, placeholder type and effective index, matching `p:hf` flags, explicit design-zone frame, direct prompt size, and level-one default size. -Every owned `p:bg` is checked as an exact zero-or-one payload against the pre- -promotion result; this includes preserving the base Master background when no -authored Master background replaces it. During the same export, every finished -Slide, Layout, and Master must reproduce its exact top-level shape-name roster -and order after packaging. The gate verifies that each carrier-bound slot owns the expected Slide binding, each composite visible carrier remains ordinary, and every composite binding proxy is hidden. A zero-slot Layout must read back with no placeholder. Later slides may keep different Slide-local geometry; only the reusable -Layout frame is checked against the explicit/prototype contract. Any mismatch -fails export without replacing the requested output. - -**Static structure consistency**: Repeat the same master element ids on every -slide and the same layout element ids on every slide sharing a layout. Their -generated OOXML must be identical within the affected master/layout group. -Static structure may carry shapes, text, or images; non-image/external -relationships are rejected. Every static object is atomic. An ordinary -`<g data-pptx-layer="master|layout">` is forbidden; the validated compact -authored-preset group from §1.5 is the sole group exception because it compiles -to one native object. A full-canvas first rect may be marked as a Master or -Layout background. - -**Native object slot carriers**: `chart` / `table` slots require -`--native-charts-and-tables`; fallback groups contain several shapes and cannot map to one -PowerPoint placeholder. `object` is the generic PowerPoint content slot and -uses either one carrier object—including one validated compact authored-preset -group—or the explicit composite proxy downgrade. `media` currently binds -an authored image/crop to a native `media` placeholder; it does not synthesize -video or audio media from a decorative SVG group. +**Text carriers**: a multiline placeholder stays one native text frame, so leave strict-line text Slide-local when separate frames are required. Leave a carrier empty or whitespace-only when the placeholder must be visually blank — export materializes an invisible run; never insert a dummy dash, sub-1pt text, or an opacity-hidden glyph. A materialized mirror carrier may keep the source `data-pptx-frame`; do not add it to an authored `standard` / `fidelity` carrier merely to duplicate its bounds. `object` is the generic content slot; `media` binds an authored image/crop and does not synthesize video or audio from a decorative group. ## 3. Legacy Template Input Boundary -Existing structured/template projects or source-analysis packages that carry `analysis/native_structure.json` / `sources/source.pptx`, `pptx_structure.mode: baseline|template|preserve`, `layout_strategy`, `data-pptx-layout-kind`, `distilled` / `utility`, direct atomic placeholders, or an incomplete root Master identity are not generation/export inputs and are never upgraded in place. Create a separate current workspace through [`create-template`](../workflows/create-template.md). A project explicitly declaring `pptx_structure.mode: flat` is the current free-design/brand-only route and needs no conversion merely because it has no Master/Layout metadata. +Projects or analysis packages carrying `analysis/native_structure.json` / `sources/source.pptx`, `pptx_structure.mode: baseline|template|preserve`, `layout_strategy`, `data-pptx-layout-kind`, `distilled` / `utility`, direct atomic placeholders, or an incomplete root Master identity are not generation/export inputs and are never upgraded in place; create a separate current workspace through [`create-template`](../workflows/create-template.md). A project explicitly declaring `mode: flat` is the current free-design/brand-only route and needs no conversion. | Available source | Allowed create-template behavior | |---|---| | Original PPTX Type A | `standard` / `fidelity` author new topology; `mirror` authors compact SVG from parsed evidence while preserving supported Master/Layout/placeholder facts that still exist in the package | | Legacy or unstructured SVG Type B | `standard` / `fidelity` use pages as visual/contextual reference and author a complete new contract; old metadata is not output topology | -| Complete current SVG Type B | `mirror` may author a compact equivalent while preserving the explicit current contract in a new workspace; authored modes may replace it | +| Complete current SVG Type B | `mirror` may author a compact equivalent preserving the explicit current contract in a new workspace; authored modes may replace it | -Without an original PPTX or complete current Type B contract, do not claim mirror or source-topology recovery. After template creation, Generate PPTX Step 6 (or Quick §3) authors new structured `svg_output/` pages; the exporter only compiles those declarations and never derives, repairs, or migrates structure. +Without an original PPTX or complete current Type B contract, do not claim mirror or source-topology recovery. After template creation, Generate Step 6 (or Quick §3) authors new structured `svg_output/` pages; the exporter only compiles those declarations. --- diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/preset-shape-vocabulary.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/preset-shape-vocabulary.md index 43d69d71..b195bc76 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/preset-shape-vocabulary.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/preset-shape-vocabulary.md @@ -1,8 +1,8 @@ # Native Preset Shape Vocabulary This is Executor's complete authoring-side map of the 187 registered DrawingML -preset names. Read it once before choosing a newly authored page or template -contour. The Office categories and family descriptions expose what exists and +preset names. Read it once, completely, with the executor core before the first page +(Generate) or at authored-mode entry (Create Template). The Office categories and family descriptions expose what exists and what each contour objectively depicts; the current page's meaning, visual system, and composition determine whether and how to use it. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/semantic-svg.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/semantic-svg.md index 79229ac7..0e8f494e 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/semantic-svg.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/semantic-svg.md @@ -1,102 +1,57 @@ # Minimal Semantic SVG Markers -PPT Master uses rendering-neutral compiler hints only where ordinary SVG cannot express PowerPoint Master, Layout, placeholder, native-object, or package behavior. +Rendering-neutral compiler hints, used only where ordinary SVG cannot express PowerPoint Master, Layout, placeholder, native-object, or package behavior. The completed SVG remains the full visible page: removing the metadata must not change browser rendering, and metadata never copies visible text, geometry, style, or asset values. ## 1. Boundary | Marker | Placement | Purpose | |---|---|---| -| `data-pptx-page-role` | Root `<svg>` on flat pages only | Classify a free-design/brand-only page as `cover`, `toc`, `section`, `content`, or `ending`. | -| `data-pptx-master` / `data-pptx-master-name` | Root `<svg>` | Bind the page to one named PowerPoint Slide Master. | -| `data-pptx-layout` / `data-pptx-layout-name` | Root `<svg>` | Bind the page to one named Layout under that Master. | -| `data-pptx-layer="master"` | Direct atomic child of root | Promote one fixed visual object to the named Master. | -| `data-pptx-layer="layout"` | Direct atomic child of root | Promote one fixed visual object to the named Layout. | -| `data-pptx-placeholder` | Direct child `<g id>` of root | Declare one reusable Layout slot whose visible content remains Slide-local. | -| `data-pptx-role` | Structural page-frame element | Supply package, page-number, or animation behavior not already expressed by specialized metadata. | +| `data-pptx-page-role` | Root `<svg>` on flat pages only | Classify a free-design/brand-only page as `cover`, `toc`, `section`, `content`, or `ending` | +| `data-pptx-master` / `-master-name`, `data-pptx-layout` / `-layout-name` | Root `<svg>` on structured pages | Bind the page to one named Master and one Layout under it | +| `data-pptx-layer="master\|layout"` | Direct atomic child of root | Promote one fixed visual object to the Master or Layout | +| `data-pptx-placeholder` | Direct child `<g id>` of root | Declare one reusable Layout slot whose visible content stays Slide-local | +| `data-pptx-role` | Structural page-frame element | Package, page-number, or animation behavior no specialized metadata already expresses | -The completed SVG remains the full visible page. Removing the metadata must not change browser rendering. Do not copy visible text, geometry, style, or asset values into metadata. +**Hard rule — route boundary**: free-design, brand-only, and `template_reuse_scope: style` pages use `pptx_structure.mode: flat`, declare one root `data-pptx-page-role`, and omit every Master/Layout/layer/placeholder marker. Only Default `template_reuse_scope: mirror|layout` pages or Quick pages authoring an installed Layout/Deck owner's structure declare Master and Layout before drawing and omit `data-pptx-page-role`; the exporter compiles that contract and never selects, clusters, distills, or infers it. -**Hard rule — route boundary**: Free-design, brand-only, and `template_reuse_scope: style` pages use `pptx_structure.mode: flat`, declare one canonical root `data-pptx-page-role`, and omit every Master/Layout/layer/placeholder marker in this document. Only Default `template_reuse_scope: mirror|layout` pages or Quick pages authoring an installed Layout/Deck owner's structure declare their final Master and Layout before drawing begins and omit `data-pptx-page-role`; the structured exporter compiles that contract and never selects, clusters, distills, or visually infers it. - -**Hard rule — specialized metadata wins**: Use Master/Layout/placeholder metadata for native structure, `data-pptx-replace-with` for optional PowerPoint-native Chart/Table replacement, and the imported/authored shape metadata defined in [`shared-standards-core.md`](./shared-standards-core.md) §§1.4–1.5. Do not duplicate those facts with `data-pptx-role`. +**Hard rule — specialized metadata wins**: Master/Layout/placeholder metadata for native structure, `data-pptx-replace-with` for native Chart/Table/Formula replacement, and the shape metadata of [`shared-standards-core.md`](./shared-standards-core.md) §§1.4–1.5 are never duplicated with `data-pptx-role`. --- ## 2. Master and Layout Atoms -On structured `template_reuse_scope: mirror|layout` routes, Master and fixed Layout visuals are atomic root children: +Structured routes only — attribute table, layer order, and consistency rules in [`pptx-structure-interface.md`](./pptx-structure-interface.md) §2. Canonical form: ```xml -<svg xmlns="http://www.w3.org/2000/svg" - viewBox="0 0 1280 720" - data-pptx-master="master-default" - data-pptx-master-name="Default Master" - data-pptx-layout="content-two-column" - data-pptx-layout-name="Two Column"> - <rect id="master-bg" data-pptx-layer="master" - x="0" y="0" width="1280" height="720" fill="#F8FAFC"/> - <path id="layout-rule" data-pptx-layer="layout" - d="M72 132H1208" stroke="#CBD5E1"/> +<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1280 720" + data-pptx-master="master-default" data-pptx-master-name="Default Master" + data-pptx-layout="content-two-column" data-pptx-layout-name="Two Column"> + <rect id="master-bg" data-pptx-layer="master" x="0" y="0" width="1280" height="720" fill="#F8FAFC"/> + <path id="layout-rule" data-pptx-layer="layout" d="M72 132H1208" stroke="#CBD5E1"/> </svg> ``` -| Requirement | Rule | -|---|---| -| Placement | Every Master/Layout atom is a direct child of the root SVG and has a stable unique `id`. | -| Grouping | A `<g>` may not carry `data-pptx-layer="master|layout"`. The sole exception is one validated compact authored-preset `<g>` ([`shared-standards-core.md`](./shared-standards-core.md) §1.5), which compiles to one native object. Imported PowerPoint groups flatten recursively into atomic children with their transform/style/opacity/z-order semantics. | -| Atomicity | One marked child must compile to one DrawingML object. A nested crop `<svg>` is allowed only when it is the supported single-picture carrier, not an arbitrary container. | -| Consistency | Pages sharing one Master key repeat the identical ordered Master atom contract. Pages sharing one `(master, layout)` pair repeat the identical ordered Layout atom contract. | -| Ownership | Concrete titles, body text, metrics, charts, tables, images, and page-specific decoration stay Slide-local or inside a declared slot. | - -> Note: Flattening a source PPTX group preserves supported appearance and native-layer ownership, but intentionally does not preserve the source group-editing hierarchy. +Every atom is a direct root child with a stable unique `id` that compiles to one DrawingML object; a `<g>` may not carry the layer attribute except the one validated compact authored-preset group. Concrete titles, body text, metrics, charts, tables, images, and page-specific decoration stay Slide-local or inside a declared slot. --- ## 3. Layout Slots -### 3.1 Carrier-bound slot - -Use one direct root group as the authoring boundary and one compatible direct child as the visible PowerPoint placeholder carrier: +Structured routes only — placeholder values, carrier compatibility, and bounds derivation in [`pptx-structure-interface.md`](./pptx-structure-interface.md) §2. Canonical forms: ```xml -<g id="title-slot" - data-pptx-placeholder="title" - data-pptx-bounds="72 48 1136 72"> - <text id="title-carrier" - data-pptx-carrier="true" - x="72" y="100">Actual title</text> +<g id="title-slot" data-pptx-placeholder="title" data-pptx-bounds="72 48 1136 72"> + <text id="title-carrier" data-pptx-carrier="true" x="72" y="100">Actual title</text> </g> -``` -| Requirement | Rule | -|---|---| -| Placement | The slot `<g id>` is a direct root child. Structural metadata may not be nested below it. | -| Bounds | `data-pptx-bounds="x y width height"` is mandatory, finite, and positive. It describes the reusable design zone, not the current glyph/content tight bounds. | -| Carrier | The group contains exactly one compatible direct drawable child marked `data-pptx-carrier="true"`. Export unwraps that child into the real Slide placeholder binding. | -| Identity | `data-pptx-idx` is optional; effective indices must be unique within one Layout. Preserve a source index when reconstructing an existing PPTX. | -| Fixed decoration | Reusable decoration does not belong in the slot. Author it as a root Layout atom. Page-specific labels/captions use another slot or remain Slide-local. | - -Canonical placeholder values are `title`, `subtitle`, `body`, `picture`, `chart`, `table`, `object`, `media`, `date`, `footer`, and `slide-number`. Carrier compatibility is defined in [`pptx-structure-interface.md`](./pptx-structure-interface.md) §2. - -### 3.2 Explicit composite proxy - -When one reusable region is a composite object that cannot bind to one real PowerPoint placeholder, declare the downgrade explicitly: - -```xml -<g id="hero-composite-slot" - data-pptx-placeholder="object" - data-pptx-binding="proxy" +<g id="hero-composite-slot" data-pptx-placeholder="object" data-pptx-binding="proxy" data-pptx-bounds="544 160 664 472"> <rect x="544" y="160" width="664" height="472" fill="#E2E8F0"/> <text x="576" y="214">Visible composite content</text> </g> ``` -The visible group stays Slide-local. Export creates one hidden transparent matching placeholder proxy. Proxy binding is valid only for `object`; it is an explicit fallback, not the default slot form. - -### 3.3 Zero-slot Layout - -A Layout may contain no slot groups. Cover, poster, full-visual, or other fixed-composition pages still declare their Master/Layout root identity and any fixed atoms; do not manufacture a full-page `object` placeholder merely to make the Layout non-empty. +A carrier-bound slot holds exactly one compatible direct child marked `data-pptx-carrier="true"`; reusable decoration is a root Layout atom, not slot content. The proxy form is the explicit `object`-only downgrade for a composite region: the visible group stays Slide-local and export adds one hidden transparent placeholder. A Layout may have zero slots. --- @@ -106,27 +61,15 @@ Use `data-pptx-role` only when no specialized marker owns the behavior: | Value | Compiler behavior | |---|---| -| `background` | Treat an otherwise unmarked background as static page framing for animation. | -| `decoration` | Exclude decorative framing from automatic entrance animation. | -| `header`, `footer`, `logo`, `watermark`, `chrome` | Identify Slide-local static framing without claiming Master/Layout ownership. | -| `page-number` | Identify a Slide-local number when no `slide-number` placeholder exists. | +| `background` | Treat an otherwise unmarked background as static page framing for animation | +| `decoration` | Exclude decorative framing from automatic entrance animation | +| `header`, `footer`, `logo`, `watermark`, `chrome` | Slide-local static framing without Master/Layout ownership | +| `page-number` | Slide-local number when no `slide-number` placeholder exists | -On flat pages, a direct root background image or full-canvas scrim/decoration -rectangle may carry the matching role and remain a primitive. Give the marked -element a stable unique `id`; do not add a `<g>` solely to avoid an -ungrouped-element advisory. - -Do not add structural roles to ordinary titles, body copy, cards, KPIs, diagrams, charts, icons, or images. +On flat pages a direct root background image or full-canvas scrim/decoration rectangle may carry the role and remain a primitive with a stable unique `id`; do not add a `<g>` solely to avoid an ungrouped-element advisory. Never add structural roles to ordinary titles, body copy, cards, KPIs, diagrams, charts, icons, or images. --- ## 5. Validation and Migration -For structured `template_reuse_scope: mirror|layout` projects, validation rejects: - -- a missing root Master/Layout identity or a page-to-lock mismatch; -- an ordinary Master/Layout `<g>` (the compact authored-preset atom is the sole exception), nested structure marker, missing/stale id, or inconsistent shared atom contract; -- a slot without positive bounds, a carrier-bound slot without exactly one compatible carrier, or a proxy binding on a non-`object` slot; -- incomplete page mappings, cross-Master Layout-key reuse, or conflicting same-key Layout contracts. - -Legacy structured/template SVGs using unmapped `baseline`, `preserve`, `layout_strategy: distill`, `data-pptx-layout-kind`, `distilled`, `utility`, direct atomic placeholders, or an incomplete Master identity are not a second supported structured contract. Create a new workspace through [`create-template`](../workflows/create-template.md) before generation or export. An explicit `mode: flat` free-design/brand-only project is current and intentionally has no Master identity. Original PPTX Type A may preserve native identities that still exist in the package; legacy SVG-only Type B may guide `standard` / `fidelity` visually but does not authorize topology recovery. Export never derives, repairs, or migrates structure. +Structured validation rejects a missing or lock-mismatched root identity, an ordinary Master/Layout `<g>`, nested structure markers, missing/stale ids, inconsistent shared atom contracts, slots without positive bounds or exactly one compatible carrier, proxy binding on a non-`object` slot, incomplete page mappings, cross-Master key reuse, and conflicting same-key contracts. Legacy metadata and the input boundary are in [`pptx-structure-interface.md`](./pptx-structure-interface.md) §3; export never derives, repairs, or migrates structure. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/shared-standards-core.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/shared-standards-core.md index 862e9c36..acdf4bbd 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/shared-standards-core.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/shared-standards-core.md @@ -1,36 +1,16 @@ # Shared SVG Core Standards -Mandatory reference for every route that authors or regenerates slide visuals through SVG. It owns XML validity, the closed generated-authoring surface, basic converter compatibility, page closure, semantic grouping, shared visual-quality defaults, and fidelity vocabulary. +Mandatory reference for every route that authors or regenerates slide visuals through SVG. It owns XML validity, the closed generated-authoring surface, page closure, semantic grouping, shared visual-quality defaults, and fidelity vocabulary. The complete closed grammar that the checker and exporter enforce — mapping tables, accepted-but-warned spellings, rejection boundaries, import-side metadata — lives in [`svg-contract.md`](../scripts/docs/svg-contract.md); this file keeps the form the model writes. **Conditional module routing**: | Trigger | Load | |---|---| -| Default or Quick Generate; otherwise noncanonical/alpha paint, advanced line or text treatment, gradient/filter/effect, transform, freeform/radial geometry, or constructed style | [`svg-effects.md`](./svg-effects.md) | +| Default or Quick Generate at the executor-base routing trigger (the first visual job beyond the everyday block); other routes when noncanonical/alpha paint, advanced line or text treatment, gradient/filter/effect, transform, freeform/radial geometry, or constructed style is used | [`svg-effects.md`](./svg-effects.md) | | A page will use a preset pattern fill or evaluate native chart/table replacement | [`native-data-interface.md`](./native-data-interface.md) before deciding eligibility or emitting metadata | | Default structured lock, or Quick installed Layout/Deck structured authoring | [`pptx-structure-interface.md`](./pptx-structure-interface.md) | -**Default — shared aesthetic baseline (may be overridden by explicit user, installed template / brand, or locked / Quick-resolved visual-style requirements)**: Required / Forbidden technical contracts remain absolute. When a higher authority is silent, build clear hierarchy through typography and leading, alignment, negative space, purposeful imagery / icons, shapes, and repetition. Deliberate tightness, imbalance, off-axis placement, or container-heavy structure remains valid when that authority calls for it. - -| Concern | Shared default | -|---|---| -| Text-block rhythm | Use §4.2 leading. Make the baseline step into a new paragraph visibly larger than the intra-paragraph line step; keep the extra gap between list items smaller than paragraph separation but large enough to scan each item. Repeated peer blocks share one rhythm unless their hierarchy differs. | -| Typography roles | Use the fewest semantic text roles that preserve hierarchy, and make their differences legible at slide-thumbnail scale. Consolidate near-neighbor sizes that serve the same role; otherwise distinguish roles through a deliberate combination of size, weight, color, position, and surrounding space. | -| Viewing-distance legibility | Resolve delivery context and viewing distance before fixing density and type scale. Preserve necessary text at a readable scale by applying only actions the active route's content and page invariants permit: restructure, shorten, split, or reflow. If none is permitted, surface the unresolved fit instead of silently miniaturizing it. Do not turn this into one universal font-size floor: captions and metadata may be smaller when their role and context remain legible. | -| Contrast and semantic encoding | Within the active profile's fidelity boundary, keep meaning-bearing text distinguishable from its actual background. For newly authored distinctions, combine luminance, weight, scale, shape, position, or explicit labeling; color may reinforce meaning but never carry a required distinction alone. When fidelity requires preserving source-only color encoding, reproduce it rather than inventing a cue. Reserve lower-contrast treatment for genuinely secondary metadata that remains legible. | -| Natural wrapping | Break at semantic phrase or punctuation boundaries where possible. Reflow the text frame or adjust neighboring geometry before using any permitted local size reduction. Let the final line run naturally shorter; avoid mechanically equal lines or a stranded single-character / single-word line when an earlier natural break preserves meaning. | -| Content field | Establish the usable body frame before placing modules. Divide it into one or a small set of macro-regions from information weight and reading order: use unequal weight when the information differs, while true peers may share equal weight. Give each region its own local axes / micro-grid while retaining only the cross-region anchors the composition needs. On a dense page, let the planned content system organize that frame; create breathing room through gutters, module spacing, and intentional voids between semantic clusters. Unorganized residual space that leaves content stranded in one part of the frame is leftover blank, not negative space. | -| Alignment and proximity | Establish shared axes from the current composition. Align related titles, copy, labels, images, and diagram nodes to those edges, centers, or baselines; group related elements more tightly than unrelated groups so spacing carries hierarchy. Break an axis only when the offset performs hierarchy, direction, or tension. | -| Visual weight | Judge weight from area, darkness, saturation, density, stroke, image detail, and elevation together. Distribute it to support the focal path; symmetry is optional, and deliberate imbalance may create direction. | -| Boundary strength | Boundaries range from spacing / alignment, rule / bracket, and tint field through outline, filled panel, and true floating layer; choose the strength from the relationship. Peer relationships use comparable strength while focus, hierarchy, or material difference may use a different one. | -| Containers | A card or panel expresses grouping, hierarchy, boundary, capacity, or a distinct material plane; peer containers share treatment unless a semantic difference justifies contrast. An unplanned repeated web-card grid is a carrier / topology problem, not a reason to suppress meaningful borders, shapes, or containers. | -| Titles and page chrome | Treat the semantic page title as part of the current composition rather than an automatic fixed header band; its position, scale, and relationship may change with page role while preserving the active route's content invariants. Add or retain running headers, footers, and page numbers only when they carry navigation, identity, attribution, or another explicit page job. Fidelity profiles preserve required source chrome. | - -**Reference — effects vocabulary**: Default and Quick Generate load [`svg-effects.md`](./svg-effects.md); its §6.1 Visual Job Router lists the visual jobs an effect can serve. Whether any compatible technique is added is the author's call. - -**Reference — where expression lives**: §4.2 owns editable text form, including -per-run inline emphasis and leading; §4.3 owns grouping. §1.4's imported-PowerPoint -metadata applies only to import, mirror, and round-trip routes. +Design defaults that apply when no higher authority speaks are collected in §6. **Fidelity labels**: @@ -48,34 +28,10 @@ metadata applies only to import, mirror, and round-trip routes. - **Reference — not a constraint** passages expose capabilities and recipes; they do not require every page or visual style to use them. - The locked `visual_style` controls whether and how strongly a compatible effect is used. It never expands the technical boundary. -**Hard rule — generated authoring is fail-closed**: `svg_output/` and reusable -template SVGs may use only properties and conditional interfaces explicitly -listed in this file or a triggered module in the routing table above. `svg_quality_checker.py` rejects unknown inline visual -properties and conditional contracts that have no reliable compatibility -mapping; documented fallback forms remain valid and receive warnings. - -**Default — recommended authoring and supported input stay separate (may -preserve supported input)**: generated SVG uses one predictable default -spelling, while converter-supported equivalent spellings remain valid input. -The checker may recommend normalization, but such warnings do not require -modification or block export. Only invalid, unsafe, or unreliably convertible -input is an error; do not remove converter support to enforce a narrower -generation preference. - -**Hard rule — one-way fidelity vocabulary**: the labels above describe the -`svg_output/` → generated PPTX path. They do not promise reconstruction of the -original SVG syntax, `<defs>` graph, `<use>` structure, path commands, or -`<tspan>` layout after PPTX-to-SVG import, nor pixel identity across PowerPoint, -LibreOffice, Keynote, and WPS. - -**Hard rule — capability boundary**: a recipe never expands converter support. -Use only the target elements and syntax documented by each conditional -contract. Unsupported element tags fail preflight; browser-rendered attributes -outside these contracts must not be assumed to have a DrawingML mapping. +**Hard rule — generated authoring is fail-closed**: `svg_output/` and reusable template SVGs may use only properties and conditional interfaces explicitly listed in this file or a triggered module in the routing table above. `svg_quality_checker.py` and exporter preflight share one validator: unknown inline visual properties and unmapped conditional contracts are errors; documented compatible spellings remain valid input and receive recommendation warnings that never require modification or block export. A recipe never expands converter support, and the fidelity labels describe only the `svg_output/` → PPTX path — not reconstruction after PPTX import, nor pixel identity across PowerPoint, LibreOffice, Keynote, and WPS. --- - ## 1. Required Foundation, Forbidden Features, and Conditional Interfaces ### 1.0 Text characters: must be well-formed XML @@ -89,7 +45,7 @@ SVG is strict XML. Two rules for all text and attribute values: One offending character invalidates the file and aborts export. -**Structural blacklist** (in addition to the character rules above): +**Structural blacklist** (exhaustive for globally forbidden syntax; not a positive allowlist): | Banned Feature | Description | |----------------|-------------| @@ -104,167 +60,31 @@ One offending character invalidates the file and aborts export. | `<script>` / event attributes | Scripts and interactivity | | `<iframe>` | Embedded frames | -The blacklist above is exhaustive for globally forbidden structural syntax. -It is not a positive allowlist for every browser-rendered property. Features -that require a restricted form are valid only under the conditional contracts -below; unlisted visual properties are unsupported. +**Hard rule — inline visual-property allowlist**: inline `style` may carry only paint/line (`fill`, `stroke`, `stroke-width`, `stroke-dasharray`, `stroke-linecap`, `stroke-linejoin`, `fill-opacity`, `stroke-opacity`, `vector-effect`), text (`font-family`, `font-size`, `font-weight`, `font-style`, `text-anchor`, `letter-spacing`, `text-decoration`), alpha and definition paint (`opacity`, `stop-color`, `stop-opacity`, `flood-color`, `flood-opacity`), the §2.1 literal geometry properties, and preview-only `shape-rendering`. `filter`, `clip-path`, `marker-start` / `marker-end`, and `baseline-shift="super|sub"` on `<tspan>` are direct attributes, never inline style. -**Hard rule — inline visual-property allowlist**: +**Default — ordinary generated paint**: new solid paint uses uppercase six-digit `#RRGGBB`; `fill` / `stroke` may instead use lowercase `none` or an exact local `url(#id)`. Alpha channels, dashes, two-stop gradients, and the shadow/glow filters of `executor-base.md`'s everyday block need no further file; load [`svg-effects.md`](./svg-effects.md) (executor-base routing trigger) before any other alternative color spelling, cap/join choice, gradient stroke or text fill, filter form, transform beyond rotate, or constructed paint/effect. Ordinary text uses a non-empty `font-family`, a finite positive unitless-px `font-size`, `font-weight` `normal` / `bold` / an integer hundred, `font-style` `normal` / `italic`, and `text-anchor` `start` / `middle` / `end` on `<svg>`, `<g>`, or `<text>` (never `<tspan>`); tracking, underline/strike, outline, gradient, and filter text treatments follow `svg-effects.md` §6.7. -| Property family | Allowed inline `style` properties | -|---|---| -| Paint and line | `fill`, `stroke`, `stroke-width`, `stroke-dasharray`, `stroke-linecap`, `stroke-linejoin`, `fill-opacity`, `stroke-opacity`, `vector-effect` | -| Text | `font-family`, `font-size`, `font-weight`, `font-style`, `text-anchor`, `letter-spacing`, `text-decoration` | -| Alpha and definition paint | `opacity`, `stop-color`, `stop-opacity`, `flood-color`, `flood-opacity` | -| Literal geometry | The element-specific properties in §2.1 | -| Preview-only | `shape-rendering`; it does not change native geometry | +**Hard rule — compact inherited authoring**: put common typography presentation attributes on `<svg>`, with a direct `font-family` whenever text is visible; root paint/effects are forbidden. Put shared typography or paint on the nearest meaningful `<g>` and keep true child overrides explicit. The source stays valid, browser-visible, semantic, locally editable SVG; never use classes/stylesheets, aliases/private keys, encoded payloads, precision loss, or unrelated indirection. `--canonical-authoring` reports drift from the compact form as an advisory warning. -**Default — ordinary generated paint**: the table allows inline placement of -those property names. New solid paint uses uppercase six-digit `#RRGGBB`; -`fill` / `stroke` may instead use lowercase `none` or an exact local -`url(#id)`. Load [`svg-effects.md`](./svg-effects.md) before authoring any -alternative compatible color spelling, alpha/opacity channel, dash/cap/join, -gradient, filter, or constructed paint/effect. Existing compatible alternatives -remain valid input and receive recommendation warnings rather than errors. - -Conditional properties with a required XML form stay out of inline style: -write `filter="url(#id)"`, `clip-path="url(#id)"`, and -`marker-start` / `marker-end` as direct attributes. Ordinary-text superscript -and subscript likewise use only direct `baseline-shift="super|sub"` on -`<tspan>`. `!important`, unknown CSS properties, blend modes, isolation, and -backdrop filters fail quality check. - -The table registers property names, not arbitrary CSS values. Ordinary generated -text uses a non-empty `font-family`, a finite positive unitless-px `font-size`, -`font-weight` of `normal` / `bold` / an integer hundred from `100` through -`900`, `font-style` of `normal` / `italic`, and `text-anchor` of `start` / -`middle` / `end`. Inheritable text declarations belong only on `<svg>`, `<g>`, -`<text>`, or `<tspan>`; `text-anchor` is invalid on `<tspan>`. Load -[`svg-effects.md`](./svg-effects.md) §6.7 before authoring tracking, -underline/strike, text outline/alpha, gradient text, or text filter effects. -Unknown or unmapped declarations fail Checker preflight and native export. - -**Hard rule — compact inherited authoring**: Author canonical compact SVG on -first publish. Put common typography presentation attributes on `<svg>`, with a -direct `font-family` whenever text is visible; root paint/effects are forbidden. -Put shared typography or paint on the nearest meaningful `<g>` and keep true -child overrides explicit. Inheritance is part of native export, not a lossy -post-process. - -The source stays valid, browser-visible, semantic, locally editable SVG; -meaning and deterministic export outrank bytes. Never use classes/stylesheets, -aliases/private keys, encoded payloads, precision loss, or unrelated -indirection. `--canonical-authoring` reports drift from the compact form as an advisory -warning; `compact_svg_styles.py --inplace` applies the same normalization on -request to authored project pages, never to structured template rosters. - -> **`marker-start` / `marker-end` is conditional** — see §1.1. -> -> **`clipPath` on `<image>` is conditional** — see §1.2. -> -> **Static same-document `<use>` is conditional** — see §1.3. -> -> **Imported native-shape metadata is conditional** — see §1.4. -> -> **Authored native preset fragments are conditional** — see §1.5. -> -> **Inline CSS geometry, simple gradients, filters, and approximate group -> opacity are conditional** — see §2 and [`svg-effects.md`](./svg-effects.md). -> -> **PPT preset patterns and native chart/table/template metadata are -> conditional** — see [`native-data-interface.md`](./native-data-interface.md) and [`pptx-structure-interface.md`](./pptx-structure-interface.md). - -DrawingML has no arbitrary per-pixel alpha-compositing path. A registered -single-image text picture/texture fill follows [`svg-effects.md`](./svg-effects.md) -§6.3; arbitrary text-knockout composites, multi-layer image text, and arbitrary -alpha composites remain bake-required before SVG export. +> **Conditional interfaces**: `marker-start` / `marker-end` — §1.1. `clipPath` on `<image>` — §1.2. Static same-document `<use>` — §1.3. Imported native-shape metadata — §1.4. Authored native preset fragments — §1.5. Inline geometry, simple gradients, filters, and approximate group opacity — §2 and [`svg-effects.md`](./svg-effects.md). PPT preset patterns and native chart/table/template metadata — [`native-data-interface.md`](./native-data-interface.md) and [`pptx-structure-interface.md`](./pptx-structure-interface.md). Arbitrary per-pixel compositing (text knockouts, multi-layer image text, alpha composites) is bake-required; the one registered exception is the single-image text picture fill in `svg-effects.md` §6.3. --- ### 1.1 Line-end Markers (Conditional Contract) -`marker-start` and `marker-end` are supported on `<line>` and `<path>` only -when the referenced marker fits this native-arrow contract: - -| Concern | Required form | -|---|---| -| Reference | Exact local `url(#id)` to a `<marker>` in `<defs>` | -| Orientation | `orient="auto"` or `orient="auto-start-reverse"`; the latter reverses `marker-start` while behaving like `auto` at `marker-end` | -| Shape | One direct shape representing a DrawingML `triangle`, `stealth`, `arrow`, `diamond`, or `oval` line end: a 3-vertex `<polygon>` / closed path (triangle), a simple concave 4-vertex `<polygon>` / closed path (stealth), an open 3-vertex path (arrow), a simple convex 4-vertex `<polygon>` / closed path (diamond), or one `<circle>` / `<ellipse>` (oval) | -| Path grammar | Use one explicit `M`/`L` command per vertex. Triangle, stealth, and diamond paths end in `Z`; arrow paths remain open after the third vertex. Do not use `H`, `V`, curves, or an implicit multi-point `L` command inside a marker path | -| Color parity | Triangle, stealth, diamond, and oval use a fill matching the parent line stroke. The open arrow uses `fill="none"` and a stroke matching the parent line stroke. DrawingML line ends inherit the line color | - -The converter maps these five shapes to their corresponding DrawingML line-end -types. Prefer `<polygon>` for the closed triangle, stealth, and diamond forms; -the open arrow form requires `<path>`. Four-vertex shapes must be simple and -non-degenerate: convex geometry maps to diamond and concave geometry maps to -stealth. Checker and exporter preflight consume this same contract; other -marker shapes have no native mapping and block export instead of being silently -dropped. - -PPTX import compatibility, tolerant recovery, strict-mode rejection, and -diagnostic behavior are indexed in -[`conversion.md`](../scripts/docs/conversion.md#import-compatibility-and-recovery-boundary). +`marker-start` / `marker-end` on `<line>` and `<path>` reference one local `<marker>` in `<defs>` with `orient="auto"` (or `auto-start-reverse`) whose single child is one of the five DrawingML line ends: a 3-vertex closed polygon (triangle), a simple concave 4-vertex closed polygon (stealth), an open 3-vertex path (arrow), a simple convex 4-vertex closed polygon (diamond), or one `<circle>` / `<ellipse>` (oval). Closed shapes take a fill matching the parent stroke; the open arrow takes `fill="none"` and a matching stroke. Any other marker shape blocks export. Grammar detail and import behavior: [`svg-contract.md`](../scripts/docs/svg-contract.md) §1.1. --- ### 1.2 Image Clipping (Conditional Contract) -`clip-path` maps natively only on SVG `<image>` (including an exact crop -wrapper's inner image) under this contract. Legacy imported crops may retain -an outer-wrapper clip as compatible input: - -| Concern | Required form | -|---|---| -| SVG-namespace `<clipPath>` defined inside `<defs>` | Converter looks up one exact local id; missing, duplicate, foreign-namespace, or malformed references fail | -| Contains exactly one direct SVG-namespace supported shape child | Multiple shapes are not composited | -| Shape is one of: `<circle>`, `<ellipse>`, `<rect>` (optional rx/ry), `<path>`, `<polygon>` | These map to DrawingML geometry (preset or custom) | -| No `clip-rule` or `fill-rule`, whether direct or in inline `style` | DrawingML picture geometry has no equivalent winding-rule control | -| Used only on `<image>` or a compatible legacy imported crop wrapper | Shapes, groups, text, and generalized nested SVG targets are **forbidden** | - -| SVG clip shape | DrawingML output | -|---|---| -| `<circle>` / `<ellipse>` | Full-frame `<a:prstGeom prst="ellipse"/>`; the child must exactly cover the image frame. A `userSpaceOnUse` circle requires a square physical frame; a normalized `objectBoundingBox` circle may fill any frame | -| `<rect>` / `<rect rx="..."/>` | A plain full-frame rect is a compatible no-op; rounded form maps to full-frame `<a:prstGeom prst="roundRect"/>` with one physical radius adjustment. The rect must exactly cover the image frame and cannot express non-uniform physical corner radii | -| `<path>` / `<polygon>` | `<a:custGeom>` with coordinates mapped into the image frame | - -`clip-path` on shapes, groups, or text is forbidden; author the target geometry -directly instead. Use a path/polygon clip when the intended contour does not -cover the full picture frame. A contour that depends on even-odd or another -explicit winding rule is outside this mapping and must be rebuilt as one -unambiguous visible contour or pre-rendered. +`clip-path` maps natively only on `<image>`: one local `<clipPath>` in `<defs>` containing exactly one `<circle>`, `<ellipse>`, `<rect>` (optional `rx`/`ry`), `<path>`, or `<polygon>`, with no `clip-rule` / `fill-rule`. Circle, ellipse, and rect clips must exactly cover the image frame and become preset picture geometry; a path or polygon becomes custom geometry inside the frame, so use it whenever the contour does not cover the full frame. `clip-path` on shapes, groups, or text is forbidden — author the target geometry directly. Mapping table: [`svg-contract.md`](../scripts/docs/svg-contract.md) §1.2. --- ### 1.3 Static Same-Document `<use>` (Conditional Contract) -**Expansion contract**: Static local reuse is compile-time authoring shorthand. `finalize_svg.py` and -native export replace each qualifying instance with cloned primitive content; -PPTX-to-SVG import emits the resulting primitives and does **not** reconstruct -the original `<use>` / `<symbol>` structure. - -| Concern | Required form | -|---|---| -| Reference syntax | Author new SVG with the SVG 2 form `href="#id"`. Legacy `xlink:href="#id"` remains read-compatible and Live Preview normalizes it to `href`; if both attributes exist, their values MUST match. | -| Referenced target | One of `<symbol>`, `<g>`, `<use>`, `<rect>`, `<circle>`, `<ellipse>`, `<line>`, `<path>`, `<polygon>`, `<polyline>`, `<text>`, or `<image>`. Nested local `<use>` is recursively expanded. | -| Instance position | Generated `<use x>` / `<use y>` use finite unitless values; an explicit `px` suffix is read-compatible. Omitted values default to `0`. | -| Symbol viewport | A referenced `<symbol>` MUST have a finite four-number `viewBox` with positive width/height. Its `<use>` MUST have positive finite unitless `width` and `height`; an explicit `px` suffix is read-compatible. | -| Aspect ratio | Default/aligned `meet` values and plain `preserveAspectRatio="none"` are supported. `slice`, `refX`, and `refY` are forbidden. | -| Viewport boundary | Symbol artwork MUST stay inside its `viewBox`; expansion does not reproduce symbol overflow clipping. | -| Internal references | Author exact `href="#id"` and `url(#id)` fragments. The expander also reads legacy `xlink:href="#id"` and rewrites all instance-local cloned IDs. | -| Structural metadata | Neither the `<use>` instance nor its referenced subtree may carry `data-pptx-layer*`, chart/table replacement metadata (`data-pptx-replace-with`, `data-pptx-replacement-*`, `data-pptx-import-source`, or `data-pptx-fallback-*`), or `data-pptx-placeholder*`. Author those objects directly instead of reusing them. | -| Safety limits | A reachable reference chain may contain at most 64 instances, and one SVG may expand at most 10,000 local `<use>` instances. | - -**Forbidden — unsafe local references**: - -- External/file/data URLs, missing targets, conflicting `href` / `xlink:href`, - unsupported target elements, and circular reference chains -- Duplicate IDs on the referenced target, the `<use>` instance, or anywhere in - the reused subtree -- Quoted/whitespace CSS fragment variants such as `url('#id')`; use exact - `url(#id)` when an internal paint/filter/clip reference must be rewritten - -**Contract example**: +Author `href="#id"` to a `<symbol>` (finite positive `viewBox`, artwork inside it, instance `width` / `height` positive unitless) or to a primitive, `<g>`, `<text>`, or `<image>`. This pipeline departs from browser SVG in two ways: finalization and native export clone the referenced primitives into each instance (PowerPoint keeps no symbol graph, and PPTX import never reconstructs `<use>`), and the reused subtree may carry no layer, placeholder, or chart/table replacement metadata. Limits and forbidden forms: [`svg-contract.md`](../scripts/docs/svg-contract.md) §1.3. ```xml <svg xmlns="http://www.w3.org/2000/svg"> @@ -286,156 +106,13 @@ the original `<use>` / `<symbol>` structure. ### 1.4 Imported Native PowerPoint Shapes (Conditional Contract) -`pptx_to_svg.py` emits rendering-neutral metadata when a visible SVG object -originates from `p:sp`, `p:cxnSp`, or `p:grpSp`. This contract is for lossless -import SVGs and unchanged imported objects that remain Slide-local or inside a -slot during mirror materialization. Ordinary authored SVG does not need these -attributes, and no separate source-payload opt-in marker exists. - -| Metadata | Placement | Required behavior | -|---|---|---| -| `data-pptx-object` | Logical `<g>` and native carrier | `shape`, `connector`, `group`, or `picture`; never infer the object kind from path appearance. | -| `data-pptx-shape-id` + `data-pptx-shape-scope` | Logical `<g>` and carrier | Preserve the source part-scoped identity. Export remaps duplicate Master/Layout/Slide ids into page-unique ids before rebinding connector references. | -| `data-pptx-frame="x y width height"` | Logical `<g>` and carrier | Own native `a:xfrm` position and size. Lossless import SVGs and tool-side native records use sufficient precision for exact EMU recovery; the model-facing authoring IR may use the compact page-coordinate spelling defined below. Path bounds, stroke, markers, shadows, and text glyph bounds never replace this frame. | -| `data-pptx-prst` | Preset carrier and logical `<g>` | One of the locked 187 DrawingML `ST_ShapeType` values. | -| `data-pptx-av-*` | Preset carrier and logical `<g>` | Preserve the complete validated DrawingML adjustment formula, including non-`val` formulas. | -| `data-pptx-part="geometry"` | One hidden carrier path | The single native export authority for frame, base fill/line/effect, preset/custom geometry, and object identity. | -| `data-pptx-part="geometry-preview"` / `geometry-detail` | Visible preview group/paths | Render the preset's independent path fill/stroke layers. A hash-locked preview group may mirror the carrier's one filter so a multi-path preset renders one aggregate imported effect; these elements are never emitted as duplicate PowerPoint shapes. | -| `data-pptx-preview-sha256` | Logical preset `<g>` and carrier | Detect edits to visible preset paths or paint. A stale preview fails quality check/export instead of silently reusing old native metadata. | -| `data-pptx-geometry-kind="custom"` + `data-pptx-custgeom` or `data-pptx-custgeom-ref` | Custom-geometry carrier | Preserve the validated original `a:custGeom` subtree. If the visible path hash is unchanged, export writes formulas, handles, connection sites, text rectangle, and path list exactly; edited paths compile from current SVG geometry. | -| `data-pptx-start/end-shape-id/site` | Connector logical `<g>` and carrier | Restore `a:stCxn` / `a:endCxn` after scoped shape-id allocation. A connector may retain one zero frame axis; it must not be expanded from visible stroke or marker bounds. | -| `data-pptx-shape-style` or `data-pptx-shape-style-ref` | Native carrier | Preserve a relationship-free `p:style` independently of text, including shapes with no visible text. | -| `data-pptx-effect-status="unsupported"` + `data-pptx-effect-reason` | Imported `p:sp` / `p:cxnSp` logical object and native carrier; imported `p:pic` carrier and logical object; imported `p:grpSp` logical group; imported table `p:graphicFrame` logical group | Record why an encountered source object or text-run `effectLst` / `effectDag` cannot enter the registered target-specific effect mapping without changing semantics. Checker and export stop with the recorded reason; these attributes are diagnostics, not a preserved effect payload or authoring syntax. | -| `metadata[data-pptx-part="txbody"]` with inline Base64 or `data-pptx-ref` | Logical shape `<g>` | Preserve unchanged `p:txBody`, including an empty text body. Content, whitespace, positioning, visible typography, or incompatible child-topology edits invalidate the payload. A source payload with run-level effects then blocks checker/export instead of losing those effects; an effect-free payload uses the normal SVG text fallback. | - -**Hard rule — compact native metadata transport**: Type A mirror -materialization moves `p:txBody`, relationship-free `p:style`, and -`a:custGeom` payloads into the content-addressed -`templates/native_payloads.json.gz` store. It also deduplicates repeated native -restoration fields—object identity, frame, preset/custom-geometry guards, -preview/text hashes, connector endpoints, payload references, and adjustment -formulas—into short `data-pptx-native-ref` records in the same store. Checker, -template-structure validation, and export validate and hydrate both layers in -memory. Keep Master/Layout, placeholder, layer, editable-object, diagnostic, -and editable chart/table metadata inline; authoritative Chart/Table JSON stays -inside its SVG marker, never in the payload store. Legacy inline Base64 and v1 -payload-only stores remain readable. - -One effect reason remains its existing plain token. If one imported object has -multiple independent unsupported reasons, both marker copies store the same -deduplicated, lexicographically sorted compact JSON string array in -`data-pptx-effect-reason`; adding a later reason must not overwrite an earlier -one. This array is still diagnostic metadata, not an authoring surface. - -**Import/authoring representation split**: - -| Representation | Contract | -|---|---| -| Lossless import SVG | Immutable native payload and preview evidence in the temporary analysis workspace; never editable template source. | -| Authoring IR bundle | Editable SVG plus model-readable `authoring_summary.json` and tool-only `authoring_manifest.json`. Keep visible intent and document-local `data-pptx-source-ref`, but omit opaque/duplicate carriers. Before hashing, compact safe imported frame/transform coordinates to two decimals. Summary indexes current files; manifest owns source paths/hashes and stays outside model context. | -| `standard` / `fidelity` output | Use §1.5 compact presets; never transplant opaque payload or source topology. | -| `mirror` output | Template_Designer reviews/authors the compact parsed IR; materialization validates refs/graph and publishes that tree without restoring visible lossless subtrees. Recover only supported non-visible semantics; expand fixed Master/Layout wrappers without changing ownership or intended presentation. | - -**Default — model-facing page-coordinate precision (the canonical checker reports over-precision as an advisory warning)**: - -| Surface | Precision contract | -|---|---| -| Imported `data-pptx-frame` in authoring IR | At most two decimals; the compact frame owns visible geometry. | -| `data-pptx-bounds` in generated and final template SVG | At most two decimals. | -| `translate(...)`, `rotate(... cx cy)`, and `matrix(... e f)` | Translation/center values use at most two decimals; keep angle and matrix `a b c d` unchanged. | -| Protected values | Never compact path/points geometry, crop/nested-`viewBox` ratios, gradient offsets, opacity, scale, canonical preset frames, or lossless/tool-side frames. | - -**Hard rule — authoring source refs**: `data-pptx-source-ref` is create-template -IR-only and unique per document. Tools resolve it through that document's -`authoring_manifest.json`; models never read the manifest. Extract/re-inline -preserves the ref and vector inventory mapping. Final templates and -`svg_output/` contain no source refs. - -**Hard rule — decoration extraction**: move text-free imported vectors to -`icons/imported/` and leave an inventoried `<use data-icon="imported/...">`. -The editor expands it; unchanged assets restore source objects and edited ones -become page-local vector units. - -**Hard rule — imported source proxy fallback**: only unsupported, text-free, -schema-free, unmarked ornament may use an atomic -`<image data-pptx-source-proxy="native-restore">` preview under -`images/source-object-previews/`. Meaning-bearing content stays readable inline -or reports a conversion gap. Unchanged proxies restore; removing a Slide-local -proxy deletes it, while inherited proxies remain. Proxy edits fail export. -Extraction/proxies are import-time only, never free-authored `svg_output/`. - -**Hard rule — structural-layer boundary**: An unchanged imported logical object -may keep currently supported metadata while it remains Slide-local or inside a -slot. An imported logical `<g>` cannot be assigned to Master/Layout because -those layers require direct semantic atoms. Mechanically expand a fixed-layer -source group into direct atoms, rebuilding a preset when supported and -otherwise retaining the visible SVG fallback. A newly authored compact preset -`<g>` from §1.5 is the sole group exception: validation proves that it compiles -to exactly one native shape/connector. Do not use this normalization to change -ownership or appearance. - -**Hard rule — selective payload**: Keep the lossless import SVG as immutable -evidence; do not copy every metadata block into a template. Mirror publishes the -compact authored subtree and recovers only converter-supported non-visible -metadata, never ordinary visible source XML. Unsupported/edited objects use the -SVG fallback. `data-pptx-replace-with` remains reserved for optional native -Chart/Table replacement. - -**Registry and rendering rules**: - -- The hash-locked shared registry must equal the independent 187-value shape - catalog. Missing, duplicate, unknown, or corrupt definitions fail closed. -- Preset preview paths come from the shared DrawingML formula evaluator; do not - add per-shape Python geometry handlers. -- Preset size is controlled only by `data-pptx-frame` / `a:xfrm`. Adjustment - formulas control the contour inside that frame and are not rescaled when the - frame changes. -- A group transform may move, scale, rotate, or flip the complete logical - shape without invalidating its preview fingerprint. Editing a generated - `geometry-detail` path directly is unsupported unless the carrier metadata - and preview fingerprint are regenerated together. -- Unknown or malformed SVG transform operations fail closed. DrawingML cannot - represent arbitrary shear, so a non-orthogonal transform must stop native - export instead of being silently approximated as rotation and scale. -- Opaque XML payloads containing any `r:*` relationship attribute are never - copied into a new slide part. Relationship-bearing text content and - shape-level `a:blipFill` use the existing rebuilt visual fallback and are - not covered by atomic `p:sp + p:txBody` rehydration. -- Unknown future presets and explicit `unsupported` geometry status never - downgrade silently to `rect`; native export stops with the recorded reason. - -**Fidelity boundary**: native preset/custom geometry, logical frame, scoped -identity, connector topology, and relationship-free unchanged horizontal -text-body semantics on ordinary shape fills are `Native-stable`. The SVG -preview paint for gradient/pattern -`darken`/`lighten` layers is `Native-normalized`; original group child -coordinates, shape-level image-fill reconstruction, and vertical-text -reconstruction are also normalized rather than byte-identical OOXML. +`pptx_to_svg.py` emits rendering-neutral metadata (`data-pptx-object`, `data-pptx-shape-id`, `data-pptx-frame`, `data-pptx-prst`, `data-pptx-av-*`, `data-pptx-part`, payload and effect diagnostics) for objects that originate from `p:sp`, `p:cxnSp`, or `p:grpSp`. It applies only to lossless import SVGs and unchanged imported objects on import, mirror, and round-trip routes; ordinary authored SVG never writes these attributes, and export never downgrades an unknown preset or unsupported effect silently. The complete metadata, representation split, precision, proxy, and registry contract: [`svg-contract.md`](../scripts/docs/svg-contract.md) §1.4. --- ### 1.5 Authored Native PowerPoint Presets (Conditional Contract) -New SVG pages and project-owned canonical reusable templates may opt one -complete geometric object into a native DrawingML preset through the -deterministic fragment helper. Selection behavior lives in -[`native-shape-authoring.md`](./native-shape-authoring.md); this section owns -the machine contract. This compact canonical form describes the intended -preset, frame, adjustments, paint, and an optional shape effect once, keeps only -registry-generated visible SVG paths, and embeds no source OOXML or serialized -preview fingerprint. - -| Metadata / structure | Required behavior | -|---|---| -| `data-pptx-authoring="preset"` | Appears once on the logical `<g>`; distinguishes strict project authoring from legacy/imported metadata. | -| `data-pptx-object` | `shape` or `connector`; connector-family presets must use `connector`, and `connector` must use a connector-family preset. Authored connectors require `fill="none"` plus a visible stroke and export as unconnected `p:cxnSp`. | -| `data-pptx-prst`, `data-pptx-frame`, `data-pptx-av-*` | Generated together from the locked registry and written once on the logical group. The frame is the helper's exact four-part, space-separated ordinary-decimal spelling and remains authoritative even when visible path bounds differ; commas, scientific notation, leading `+`, and redundant decimal spellings are rejected. | -| Local `fill` / `stroke` plus supported paint attributes | Base paint is written once on the group; a visible stroke also carries an explicit width. Canonical page/template authoring keeps channel paint local. Compatible ancestor paint/opacity may compose under the general SVG rules and receives a recommendation warning. | -| Optional direct `filter="url(#id)"` | Shape presets only: the helper writes one exact local reference to a direct [`svg-effects.md`](./svg-effects.md) §6.4 filter definition. It compiles once on the complete native shape; connector presets, inline style, ordinary group filters, and child-path filters remain unsupported. | -| Ordered direct `<path>` children | Browser-visible registry layers only. Each child writes just its required path-level fill/stroke override; labels and decorations stay outside the atomic group. | -| No carrier / wrapper / fingerprint | `data-pptx-part`, hidden geometry carriers, preview wrappers, and `data-pptx-preview-sha256` belong to expanded import/compatibility transport, not canonical project authoring. | - -Generate one fragment at a time: +New SVG pages and project-owned canonical templates may opt one complete geometric object into a native DrawingML preset through the deterministic fragment helper. Selection lives in [`native-shape-authoring.md`](./native-shape-authoring.md); the helper prints one compact atomic `<g data-pptx-authoring="preset">` carrying preset, frame, adjustments, and base paint once, plus the registry-generated visible paths — no carrier, wrapper, or fingerprint. ```bash python3 ${SKILL_DIR}/scripts/preset_shape_svg.py render rightArrow \ @@ -446,76 +123,9 @@ python3 ${SKILL_DIR}/scripts/preset_shape_svg.py render rightArrow \ --adjust "adj1=val 50000" ``` -When one native effect is justified, append `--filter-id softShadow`; that id -must already name one direct page-level §6.4 filter definition. +Append `--filter-id softShadow` only when that id already names one direct page-level [`svg-effects.md`](./svg-effects.md) §6.4 filter definition. -**Hard rule — helper-only metadata**: never add or edit authored preset -metadata or registry paths by hand. The compact helper output is atomic. -Regenerate it when preset, frame, adjustment, fill, stroke, stroke width, or the -filter reference changes. Replace the whole fragment with ordinary SVG when -free contour editing is required. - -Template ownership metadata is orthogonal to preset geometry. After inserting -the complete helper output, `create-template` may add only the registered -`data-pptx-layer`, `data-pptx-editable`, `data-pptx-carrier`, or -`data-pptx-role` attribute needed by the surrounding structured contract. It -must not change preset/frame/adjustment/paint metadata, the filter reference, or -any direct path. - -**Reusable-template boundary**: a project-owned canonical template may retain -one complete helper-generated atomic fragment when the stock preset is an exact -semantic match and both its paint and optional effect stay inside the authoring -boundary below. The fragment is an executable exemplar and one semantic atom, -not a freely editable -template primitive. It may be Slide-local, the one carrier of an `object` slot, -or a direct Master/Layout fixed atom. An adaptation may reuse it unchanged only -when preset, frame, adjustments, paint, and the optional filter reference are -unchanged; otherwise regenerate the whole fragment with the helper. -Imported, mirror, and third-party templates are never upgraded by contour -inference. - -**Hard rule — visible page closure**: the helper prints a complete visible -fragment to stdout; export never invents its preview. The main Agent inserts -that output into the hand-authored page or canonical reusable template. The -helper cannot write a project, select layout, or generate a page. - -**Authoring paint/effect boundary**: v1 accepts `none` or six-digit solid HEX -fill and stroke, optional fill/stroke opacity, stroke width, line cap, line join, -and one shape-only local filter id under [`svg-effects.md`](./svg-effects.md) -§6.4. -Normal generated pages use `spec_lock.md` for stable semantic color anchors and -choose page-local paint from the retained Design Spec, style, and composition context. -The lockless [`quick-generate`](../workflows/profiles/quick-generate.md) profile -keeps every chosen paint value explicit in the SVG. -`create-template` authored templates take their values from the confirmed brief -and template `design_spec.md`. -Use ordinary SVG for gradients, patterns, or other treatments outside this -narrow contract. Registry-derived multi-path darken/lighten colors and -other contextual derivatives need no separate lock row unless they become a -recurring named role. Mirror preserves source paint under §1.4 instead. - -**Validation**: quality check and export both rerender authored fragments from -`preset + frame + adjustments + group paint` and compare every visible path and -path-level paint override directly. They separately validate the optional effect -reference through §6.4. Registry-path edits, geometry metadata that leaves those -paths stale, unknown adjustments, invalid or unresolved filter references, -out-of-range frames/transforms, -zero-scale transforms, and shear/skew fail closed. Export expands the validated -compact group only in memory and reuses the lossless native-shape conversion -path. Older authored carrier/preview fragments remain compatible as ordinary -Slide-local input and -receive a non-blocking migration warning; they do not gain the new compact -group's structured-atom exception. `pptx_to_svg` expanded output remains the -lossless round-trip form and is not warned as authored input. - -**Fidelity boundary**: an unchanged authored fragment is `Native-stable` as -one `p:sp` or `p:cxnSp`. Text remains outside the atomic fragment and may export -as a grouped editable text box. Authoring v1 creates only unconnected -`p:cxnSp`; it does not accept hand-written endpoint/site metadata. An -`actionButton*` preset maps visual geometry only. Preset appearance never -invents connector attachment, action behavior, navigation targets, or -hyperlinks. Link and navigation behavior is authored explicitly instead — see -[`native-hyperlinks.md`](./native-hyperlinks.md). +**Hard rule — helper-only metadata**: never add or edit authored preset metadata or registry paths by hand; regenerate the whole fragment when preset, frame, adjustment, fill, stroke, stroke width, or the filter reference changes, and replace it with ordinary SVG when free contour editing is required. The helper accepts `none` or six-digit solid HEX paint, optional channel opacity, stroke width, cap, join, and one shape-only filter; gradients, patterns, and other treatments stay ordinary SVG. Text stays outside the atomic fragment. Checker and exporter rerender every fragment from its metadata and fail closed on any drift; machine contract, template-ownership rules, and fidelity boundary: [`svg-contract.md`](../scripts/docs/svg-contract.md) §1.5. --- @@ -523,72 +133,11 @@ hyperlinks. Link and navigation behavior is authored explicitly instead — see ### 2.1 Literal Geometry Lengths and Inline Geometry -**Hard rule — direct geometry length grammar**: New generated SVG writes the -following XML geometry values and `stroke-width` as finite unitless ordinary -decimals in the page `viewBox` coordinate space, for example `x="120"` and -`stroke-width="2"`. The explicit `px` suffix is read-compatible and receives a -recommendation warning. No other unit is registered for this surface. - -| Element / surface | Direct length attributes | -|---|---| -| `<svg>`, `<rect>`, `<image>`, `<use>` | `x`, `y`, `width`, `height`; `<rect>` also `rx`, `ry` | -| `<circle>` | `cx`, `cy`, `r` | -| `<ellipse>` | `cx`, `cy`, `rx`, `ry` | -| `<line>` | `x1`, `y1`, `x2`, `y2` | -| `<text>` / positional `<tspan>` | `x`, `y`; `<tspan>` also `dx`, `dy` | -| Any supported painted element | `stroke-width` | - -`width`, `height`, `r`, `rx`, `ry`, and `stroke-width` must be non-negative; -the stricter positive `<use>` symbol-viewport rule remains in §1.3. `pt`, -`pc` / `pica`, `in`, `cm`, `mm`, `q`, `em`, `rem`, percentages, unknown units, -non-finite values, expressions, scientific notation, leading plus signs, and -trailing decimal points are invalid here even when generic SVG/CSS defines -them. A missing attribute may use its documented SVG/project default; an -explicitly supplied invalid value never falls back to that default. - -The following geometry properties may appear in the same element's -`style="..."`. The pipeline materializes them as -XML geometry attributes before SVG post-processing and native PPTX conversion. -An inline geometry declaration overrides an existing same-name XML attribute. - -| Element | Recognized properties | -|---|---| -| `<rect>` | `x`, `y`, `width`, `height`, `rx`, `ry` | -| `<circle>` | `cx`, `cy`, `r` | -| `<ellipse>` | `cx`, `cy`, `rx`, `ry` | -| `<image>` | `x`, `y`, `width`, `height` | -| `<svg>` | `x`, `y`, `width`, `height` | -| `<use>` | `x`, `y`, `width`, `height` | - -**Hard rule — inline geometry grammar**: every non-zero value is one finite -`px` literal, such as `120px` or `-8.5px`; exact zero may be unitless. `width`, -`height`, `rx`, `ry`, and `r` must be non-negative. Percentages, `auto`, -`calc()`, `var()`, `!important`, `inherit`, and every other unit are forbidden. -Do not put geometry on an unsupported element: line endpoints, text positions, -path data, and polygon/polyline points remain XML attributes. - -**Forbidden — CSS geometry cascade**: `<style>`, `class`, selector rules, -external stylesheets, and imported styles remain forbidden. This contract is -only for literal declarations in an element's own `style` attribute; PPT Master -does not compute CSS cascade or custom properties. Root canvas authority remains -the `viewBox`, regardless of root `<svg>` compatibility width/height values. -The shared coordinate and geometry implementation is -[`utils.py`](../scripts/svg_to_pptx/drawingml/utils.py). +**Hard rule — direct geometry length grammar**: write `x`, `y`, `width`, `height`, `rx`, `ry`, `cx`, `cy`, `r`, `x1`…`y2`, `dx`, `dy`, and `stroke-width` as finite unitless ordinary decimals in the page `viewBox` space (`x="120"`, `stroke-width="2"`); sizes and radii are non-negative. `px` is read-compatible and warns; every other unit, percentage, expression, or exotic numeric spelling is an error, and an invalid explicit value never falls back to a default. The same geometry properties may instead appear in the element's own `style` as `px` literals (`style="x:120px"`); zero may be unitless, and the pipeline materializes them as XML attributes. Line endpoints, text positions, path data, and points remain XML attributes. Complete grammar: [`svg-contract.md`](../scripts/docs/svg-contract.md) §2.1. ### 2.2 Group Opacity Compatibility -**Default — descendant alpha (may preserve compatible group opacity)**: New -`svg_output/` and reusable templates put alpha on the affected descendant -paint, text run, picture, or supported effect. DrawingML has no isolated -group-alpha model, so overlapping descendants can look different when one -group value is distributed across them. - -The converter nevertheless accepts `<g opacity="...">` and inline group -`opacity` by multiplying group alpha into descendants. That path is -`Approximate`; nested group/child alpha multiplies, and `--native-charts-and-tables` -rejects transparent native table/chart markers. The quality checker reports a -non-blocking fidelity warning so existing or intentionally authored input can -continue without modification. +**Default — descendant alpha (may preserve compatible group opacity)**: put alpha on the affected descendant paint, text run, picture, or supported effect. `<g opacity>` remains accepted (`Approximate`, multiplied into descendants, fidelity warning only) because DrawingML has no isolated group-alpha model. --- @@ -609,38 +158,15 @@ Use the already locked canvas id and exact viewBox. [`canvas-formats.md`](canvas | PPTX translation | The exporter may map represented SVG content to DrawingML/native objects and deduplicate represented elements into Master/Layout/Slide parts. It MUST NOT invent visible slide content absent from the SVG. | | Excluded package behavior | Speaker notes, animations, transitions, narration audio, PPTX relationships, and direct native-PPTX workflows remain separately owned. They are not part of the SVG page-design contract. | -**Hard rule — page-design closure**: A final page SVG is complete but does not -own the whole PPTX package. Its ordinary content and SVG-first Chart/Table -markers are authoritative. For `data-pptx-native-authority="json"`, inline JSON -is authoritative and the visible subtree is a derived, possibly approximate -preview; authority never moves to a sidecar. +**Hard rule — page-design closure**: A final page SVG is complete but does not own the whole PPTX package. Its ordinary content and SVG-first Chart/Table markers are authoritative. For `data-pptx-native-authority="json"`, inline JSON is authoritative and the visible subtree is a derived, possibly approximate preview; authority never moves to a sidecar. ### 4.1 Semantic SVG Marker Contract Semantic markers are minimal compiler hints. Flat pages declare one root `data-pptx-page-role` and omit Master/Layout/layer/placeholder markers. Structured pages carry their final root identity, layer atoms, slots, and native-object metadata from authoring start and omit `data-pptx-page-role`. Use `data-pptx-role` with a stable `id` only when no specialized marker expresses page-frame behavior. Keep ordinary visible content in SVG attributes/text; [`semantic-svg.md`](semantic-svg.md) owns the vocabulary. -- **Canvas authority**: New authoring writes `viewBox="0 0 W H"` with positive - integer pixels from the lock, or from the first SVG when the explicit - `quick-generate` profile is active. Numerically equivalent spellings and positive - fractional imported dimensions remain compatible; export quantizes once at - `1 SVG px = 9,525 EMU`. Invalid/non-finite values, non-zero origin, - non-positive size, or unsupported PowerPoint dimensions are errors. All pages - and Layout prototypes in one normal build share the numeric canvas and match - `spec_lock.md canvas.viewBox`; quick-generate pages match the first SVG; - standalone templates match `design_spec.md canvas_viewbox`. Optional root - `width`/`height` do not override `viewBox`. - Root `<svg>` transform is forbidden; nested crop and `<symbol viewBox>` keep - their own contracts. -- **Font portability**: resolve an explicit user/template delivery target first; - otherwise default to Windows Microsoft PowerPoint with locale following the - deck's primary language. Exported Latin/EA faces must be installed or approved - on that target. The authoring host's fonts affect SVG preview and measurement - only and MUST NOT select PPTX faces; a local counterpart may appear only as a - preview tail that preserves the same export resolution. `@font-face` remains - forbidden; the typography contract lives in [`strategist.md §g`](strategist.md). -- **Icon placeholders**: `<use data-icon="library/name">` is a pipeline-specific - form, distinct from local SVG reuse. Follow the contract in - [`../templates/icons/README.md`](../templates/icons/README.md). +- **Canvas authority**: new authoring writes `viewBox="0 0 W H"` with positive integer pixels from the lock, or from the first SVG under `quick-generate`; all pages and Layout prototypes in one build share it, optional root `width`/`height` never override it, and a root `<svg>` transform is forbidden. Export quantizes once at `1 SVG px = 9,525 EMU`. +- **Font portability**: resolve an explicit user/template delivery target first; otherwise default to Windows Microsoft PowerPoint with locale following the deck's primary language. Exported Latin/EA faces must be installed or approved on that target. The authoring host's fonts affect SVG preview and measurement only and MUST NOT select PPTX faces; a local counterpart may appear only as a preview tail that preserves the same export resolution. `@font-face` remains forbidden; the typography contract lives in [`strategist.md §g`](strategist.md). +- **Icon placeholders**: `<use data-icon="library/name">` is a pipeline-specific form, distinct from local SVG reuse. Follow the contract in [`../templates/icons/README.md`](../templates/icons/README.md). - **Local reuse**: ordinary same-document `<use>` follows §1.3. ### 4.2 Editability, Package Promotion, and Text Leading @@ -651,27 +177,19 @@ These forms are needed only when the stated PPT behavior matters: |---|---| | One editable PPT text frame with mixed formatting or multiline prose | Use one `<text>` per logical paragraph and non-positional `<tspan>` children for inline runs. Per-run `fill` / `font-weight` / `font-size` is retained: export walks nested runs and emits one DrawingML run per styled segment, so an emphasised phrase stays inside the same editable frame, and a positioned line-break `<tspan>` may itself contain inline runs. Keep the first line as direct text; later lines use direct positioned `<tspan>` children that repeat parent `x` with positive relative `dy`; an all-`<tspan>` form may start at `dy="0"`. Default retains these breaks without PowerPoint wrapping; `--reflow-text` may join eligible lines. A font-size change, list marker, or larger accepted gap starts another paragraph. Sibling `<text>` elements are forbidden as one paragraph's line breaks; they remain valid for independent frames. | | Stable object grouping or object-level animation anchor | Wrap the intended object in `<g id="...">`. Content grouping is **mandatory** per §4.3 — a top-level `<g id>` is also the animation anchor; it is not an optional convenience. | -| Native PowerPoint background promotion | Outside structured mode, the first eligible visual layer may be a direct full-canvas `<rect>` or one inside a simple single-child group. Its fill must have a registered native mapping (solid, linear/radial gradient, or preset pattern), and it must have no transform, filter, clip, rounding, or visible stroke. Export writes the fill as Slide `p:bg`; image elements remain pictures. Structured routes use the narrower explicit solid-background ownership contract in [`pptx-structure-interface.md`](./pptx-structure-interface.md). | -| Free-design / brand-only PowerPoint structure | Use `pptx_structure.mode: flat`. Keep represented objects Slide-local; export emits one clean Master plus Blank Layout, removes stock content placeholders/Layout inventory, and retains the standard date/footer/slide-number hooks. Do not author Master/Layout identities, layers, or slots. Without a Layout/Deck owner, Quick uses the same ownership with converter-default theme scaffolding. | -| Reusable template-based PowerPoint Layout | Default maps complete page prototypes through `page_layouts` and declared Master/Layout definitions through `page_pptx_layouts`; strict preserves the contract and adaptive uses a declared current/new Layout under its Master. Quick has no lock: read the complete roster and author the selected Master/Layout/slot contract in every output SVG; its all-or-none gate infers structured packaging. Never infer ownership from repeated Slide-local geometry. | +| Native PowerPoint background promotion | Outside structured mode, make the first visual layer a direct full-canvas `<rect>` (or one inside a simple single-child group) with a solid, linear/radial gradient, or preset-pattern fill and no transform, filter, clip, rounding, or visible stroke; export writes it as Slide `p:bg`. Structured routes follow [`pptx-structure-interface.md`](./pptx-structure-interface.md). | +| Free-design / brand-only PowerPoint structure | Use `pptx_structure.mode: flat`: keep objects Slide-local and author no Master/Layout identities, layers, or slots; export emits one clean Master plus Blank Layout. | +| Reusable template-based PowerPoint Layout | Default maps page prototypes through `page_layouts` and Master/Layout definitions through `page_pptx_layouts`; Quick authors the selected Master/Layout/slot contract in every output SVG and its all-or-none gate infers structured packaging. Never infer ownership from repeated Slide-local geometry. | **Default — leading by role and density (may be overridden for user, template, typeface, legibility, or locked visual-style fit)**: For direct positioned `<tspan>` rows, start multiline titles around `1.2–1.3 × font-size`, dense / small body around `1.4–1.5 ×`, ordinary body around `1.5–1.6 ×`, and large / sparse / breathing body around `1.6–2.0 ×`. These are starting ranges, not checker quotas; display headlines may be tighter when the selected style calls for it. Author the spacing as positive relative `dy`, not CSS/SVG `line-height`, which has no registered DrawingML mapping. -**Hard rule — supported shape conversion**: Every PPT editability claim in this specification refers to the project converter reading `svg_output/` and emitting native DrawingML. `svg_final/` is a self-contained visual preview that may be inserted into PowerPoint as an SVG picture. PowerPoint's manual Convert-to-Shape operation is unsupported; do not narrow the authoring contract to its undocumented SVG subset. +**Hard rule — supported shape conversion**: every editability claim here refers to the project converter reading `svg_output/`. `svg_final/` is a self-contained visual preview that may be inserted into PowerPoint as an SVG picture; PowerPoint's manual Convert-to-Shape operation is unsupported and never narrows the authoring contract. ### 4.3 Element Grouping (Mandatory) -**Hard rule — root groups protect body-text layout**: Every visible direct root `<g>` except a compact helper-authored preset atom declares positive root-coordinate `data-pptx-bounds="x y width height"`. That text-free atom stays top-level when standalone, uses `data-pptx-frame`, and never carries bounds. Frame/native coordinates do not replace bounds on any other group; placeholder bounds also supply the slot frame. On flat pages, maximize ordinary zones within canvas/sibling space without overlap; Checker fails overlap exceeding `1px` on both axes. Structured slots, structural-role groups, and off-canvas Morph staging groups are exempt; structured Slide-local groups are not. Checker compares each subcanvas with the root `viewBox`, and estimable descendant text—including both §4.2 multiline forms—with the subcanvas using the shared per-run width estimate, inline-formula height envelope, and DrawingML wrapping headroom. It separately compares estimable visible text with the root `viewBox` before that headroom. Nested groups and all shapes, images, paths, `<use>` instances, effects, and object frames are not module-boundary inputs. Per side, Checker ignores overflow through `1px`; module-boundary overflow warns through `5%` and fails above `5%`, while any larger root-`viewBox` text overflow fails. Bounds do not clip or reflow; unestimable visible text receives an advisory warning. The only page-boundary exception is a wholly off-canvas direct-root Morph endpoint marked `data-pptx-morph-staging="true"`; its own module bounds still apply, retained Morph uses an explicit pair, and the marker never excuses partial page overflow. +**Hard rule — root groups protect body-text layout**: every visible direct root `<g>` except a compact helper-authored preset atom declares positive root-coordinate `data-pptx-bounds="x y width height"` sized as the intended module zone. On flat pages, maximize ordinary zones within canvas/sibling space without overlap; the checker fails root-group overlap beyond `1px`, warns on module text overflow through `5%` and fails above it, and fails any larger root-`viewBox` text overflow. Bounds do not clip or reflow. Structured slots, structural-role groups, and a wholly off-canvas Morph endpoint marked `data-pptx-morph-staging="true"` are the only exemptions; thresholds and estimator detail: [`svg-contract.md`](../scripts/docs/svg-contract.md) §4. -Wrap each logical Slide-local body unit in one descriptive top-level `<g id>`; group count follows the page's semantic units, and each group becomes one stable animation target when animation is enabled. Generic deck-wide animation gives that target one step; an explicit animation sidecar may assign it several ordered effects. Nested implementation groups may remain anonymous and need no bounds; any nested bounds are ignored. Flat pages use ordinary groups; structured slots already qualify, while titles, direct atomic Master/Layout elements, and canvas-level static framing—including background images and full-canvas scrim/decoration rectangles—may remain root primitives. On flat pages, give such static framing a stable `id` plus `data-pptx-role="background"` / `"decoration"`; never add a `<g>` solely to silence an ungrouped-element advisory. - -**Reference — not a constraint**: A top-level semantic group may contain -descriptive nested `<g>` edit groups when its internal elements form useful -subunits, such as icon + title, value + label, or repeated information rows. -Nested groups carry no `data-pptx-bounds` and create no automatic animation -step; an unnecessary one-child wrapper may flatten. Choose whether and how -deeply to nest from the page's actual editing semantics—there is no default -nesting pattern, level, or quota. +Wrap each logical Slide-local body unit in one descriptive top-level `<g id>`; group count follows the page's semantic units, and each group becomes one stable animation target when animation is enabled. Nested implementation groups may remain anonymous, need no bounds, and create no animation step; use them only when internal subunits (icon + title, value + label, repeated rows) are useful to edit — there is no default nesting pattern, depth, or quota. Titles, direct atomic Master/Layout elements, and canvas-level static framing — background images and full-canvas scrim/decoration rectangles — may remain root primitives; on flat pages give such framing a stable `id` plus `data-pptx-role="background"` / `"decoration"` and never add a `<g>` solely to silence an ungrouped-element advisory. **Structural atoms and slots are excluded automatically.** `data-pptx-layer` and `data-pptx-placeholder` semantics are read first; otherwise explicit `data-pptx-role` values (`background`, `decoration`, `header`, `footer`, `chrome`, `watermark`, `page-number`, `logo`) mark Slide-local static framing (§4.1, [`semantic-svg.md`](semantic-svg.md)). A normal slot group has exactly one direct compatible carrier; several drawing atoms require the explicit composite `object` proxy fallback. Native chart/table carrier groups retain their specialized [`native-data-interface.md`](./native-data-interface.md) contract. @@ -687,20 +205,14 @@ nesting pattern, level, or quota. | Page footer | Page number + branding | | Decorative cluster | Related decorative shapes (rings, dots, orbs) | -An authored native preset fragment (§1.5) is already an atomic `<g id>` and -counts as one content group. Keep it top-level without `data-pptx-bounds` when -it stands alone. When it needs a label or decoration, place the preset and those -siblings inside a separate bounded parent content group; never put them inside -the preset group itself. +An authored native preset fragment (§1.5) is already an atomic `<g id>` and counts as one content group. Keep it top-level without `data-pptx-bounds` when it stands alone; when it needs a label or decoration, place the preset and those siblings inside a separate bounded parent content group, never inside the preset group itself. **Forbidden**: - One giant `<g>` around the whole slide (collapses to a single animation step). -- Many ungrouped Slide-local `<rect>` / `<text>` / `<path>` atoms — they have no stable sidecar target and selection/editing degrades. Primitive fallback applies only when the root contains no top-level `<g>` at all; it is capped at 8 visible primitives. +- Many ungrouped Slide-local `<rect>` / `<text>` / `<path>` atoms — they have no stable sidecar target and selection/editing degrades. - One top-level group per icon / text line / mark (too many animation steps). -- Anonymous top-level groups — every top-level semantic group needs a descriptive `id`. - -**Naming — required.** A descriptive, page-unique `id` on every top-level content `<g>` (`card-1`, `step-discover`, `header`, `footer`) is mandatory; it is the stable SVG-side animation and trace anchor. An anonymous top-level group still converts, but `animations.json` cannot reference it; an anonymous one-child implementation wrapper may also flatten. Primitive fallback is unrelated and applies only to roots with no top-level groups. +- Anonymous top-level groups — every top-level semantic group needs a descriptive, page-unique `id` (`card-1`, `step-discover`, `header`, `footer`); it is the stable SVG-side animation and trace anchor. ```xml <g id="card-benefits-1" data-pptx-bounds="60 115 565 260"> @@ -719,18 +231,28 @@ the preset group itself. ## 5. Workflow Authority -The normal serial post-processing and export workflow belongs to -[`generate-pptx.md`](../workflows/generate-pptx.md) Step 7. The explicit -direct-generation exception belongs to -[`quick-generate.md`](../workflows/profiles/quick-generate.md). This file defines SVG -authoring boundaries and intentionally does not mirror commands, flags, or -output behavior. +Serial post-processing and export belong to [`generate-pptx.md`](../workflows/generate-pptx.md) Step 7 and, for the direct-generation exception, [`quick-generate.md`](../workflows/profiles/quick-generate.md). This file defines SVG authoring boundaries only; project structure, commands, quality-gate order, and export products are intentionally outside it. --- +## 6. Shared Aesthetic Baseline -## 8. Scope Boundary +**Default — shared aesthetic baseline (may be overridden by explicit user, installed template / brand, or locked / Quick-resolved visual-style requirements)**: Required / Forbidden technical contracts remain absolute. When a higher authority is silent, build clear hierarchy through typography and leading, alignment, negative space, purposeful imagery / icons, shapes, and repetition. Deliberate tightness, imbalance, off-axis placement, or container-heavy structure remains valid when that authority calls for it. -Generate project structure, commands, quality-gate order, and export products -are owned by [`generate-pptx.md`](../workflows/generate-pptx.md) and its -selected profile. They are intentionally outside this SVG authoring policy. +| Concern | Shared default | +|---|---| +| Text-block rhythm | Use §4.2 leading. Make the baseline step into a new paragraph visibly larger than the intra-paragraph line step; keep the extra gap between list items smaller than paragraph separation but large enough to scan each item. Repeated peer blocks share one rhythm unless their hierarchy differs. | +| Typography roles | Use the fewest semantic text roles that preserve hierarchy, and make their differences legible at slide-thumbnail scale. Consolidate near-neighbor sizes that serve the same role; otherwise distinguish roles through a deliberate combination of size, weight, color, position, and surrounding space. | +| Viewing-distance legibility | Resolve delivery context and viewing distance before fixing density and type scale. Preserve necessary text at a readable scale by applying only actions the active route's content and page invariants permit: restructure, shorten, split, or reflow. If none is permitted, surface the unresolved fit instead of silently miniaturizing it. Do not turn this into one universal font-size floor: captions and metadata may be smaller when their role and context remain legible. | +| Contrast and semantic encoding | Within the active profile's fidelity boundary, keep meaning-bearing text distinguishable from its actual background. For newly authored distinctions, combine luminance, weight, scale, shape, position, or explicit labeling; color may reinforce meaning but never carry a required distinction alone. When fidelity requires preserving source-only color encoding, reproduce it rather than inventing a cue. Reserve lower-contrast treatment for genuinely secondary metadata that remains legible. | +| Natural wrapping | Break at semantic phrase or punctuation boundaries where possible. Reflow the text frame or adjust neighboring geometry before using any permitted local size reduction. Let the final line run naturally shorter; avoid mechanically equal lines or a stranded single-character / single-word line when an earlier natural break preserves meaning. | +| Content field | Establish the usable body frame before placing modules. Divide it into one or a small set of macro-regions from information weight and reading order: use unequal weight when the information differs, while true peers may share equal weight. Give each region its own local axes / micro-grid while retaining only the cross-region anchors the composition needs. On a dense page, let the planned content system organize that frame; create breathing room through gutters, module spacing, and intentional voids between semantic clusters. Unorganized residual space that leaves content stranded in one part of the frame is leftover blank, not negative space. | +| Alignment and proximity | Establish shared axes from the current composition. Align related titles, copy, labels, images, and diagram nodes to those edges, centers, or baselines; group related elements more tightly than unrelated groups so spacing carries hierarchy. Break an axis only when the offset performs hierarchy, direction, or tension. | +| Visual weight | Judge weight from area, darkness, saturation, density, stroke, image detail, and elevation together. Distribute it to support the focal path; symmetry is optional, and deliberate imbalance may create direction. | +| Boundary strength | Boundaries range from spacing / alignment, rule / bracket, and tint field through outline, filled panel, and true floating layer; choose the strength from the relationship. Peer relationships use comparable strength while focus, hierarchy, or material difference may use a different one. | +| Containers | A card or panel expresses grouping, hierarchy, boundary, capacity, or a distinct material plane; peer containers share treatment unless a semantic difference justifies contrast. An unplanned repeated web-card grid is a carrier / topology problem, not a reason to suppress meaningful borders, shapes, or containers. | +| Titles and page chrome | Treat the semantic page title as part of the current composition rather than an automatic fixed header band; its position, scale, and relationship may change with page role while preserving the active route's content invariants. Add or retain running headers, footers, and page numbers only when they carry navigation, identity, attribution, or another explicit page job. Fidelity profiles preserve required source chrome. | + +**Reference — effects vocabulary**: the executor core carries the everyday effects; [`svg-effects.md`](./svg-effects.md) loads on its routing trigger, and its §6.1 Visual Job Router lists the visual jobs an effect can serve. Whether any compatible technique is added is the author's call. + +**Reference — where expression lives**: §4.2 owns editable text form, including per-run inline emphasis and leading; §4.3 owns grouping. §1.4's imported-PowerPoint metadata applies only to import, mirror, and round-trip routes. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/shared-standards.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/shared-standards.md index 5afc8be6..165ba9e6 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/shared-standards.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/shared-standards.md @@ -5,7 +5,7 @@ Compatibility router for the split SVG specifications. Runtime routes load the c | Scope | Authority | Trigger | |---|---|---| | XML/SVG foundation, shared visual-quality defaults, page closure, grouping | [`shared-standards-core.md`](./shared-standards-core.md) | Always for SVG authoring | -| Advanced effects and geometry | [`svg-effects.md`](./svg-effects.md) | Always for Default / Quick Generate; otherwise when the corresponding effect or geometry is used | +| Advanced effects and geometry | [`svg-effects.md`](./svg-effects.md) | Default / Quick Generate on the executor-base routing trigger (first visual job beyond the everyday block); otherwise when the corresponding effect or geometry is used | | Preset patterns and native chart/table metadata | [`native-data-interface.md`](./native-data-interface.md) | Corresponding native-data interface is used | | Master/Layout/placeholder structure | [`pptx-structure-interface.md`](./pptx-structure-interface.md) | Default structured lock, or Quick installed Layout/Deck structured authoring | diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/strategist-image.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/strategist-image.md index bcc523db..249cb433 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/strategist-image.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/strategist-image.md @@ -2,81 +2,44 @@ # Strategist Image Planning -Always-on Stage-2 rendering-candidate extension plus confirmed image elaboration and `design_spec.md §VIII` resource planning. +Always-on Stage-2 rendering-candidate extension plus, after confirmation, image elaboration and `design_spec.md §VIII` resource planning. -**Trigger**: Load before every fresh Stage-2 direction set. Apply §2 first from the rendering index, freeze each direction's exact bases, and only then read the deduplicated selected detail files before completing its behavior. [`strategist.md`](./strategist.md) independently owns source recommendation. A confirmed non-`none` source activates the applicable resource-planning sections; confirmed `none` stops before resources. Rendering candidates are authored once before confirmation and never backfilled from a later source toggle. +**Trigger**: load before every fresh Stage-2 direction set. Author the three rendering candidates first (§2) from the rendering index; [`strategist.md`](./strategist.md) independently owns the source recommendation. A confirmed non-`none` source activates the resource sections; confirmed `none` stops before them. Candidates are authored once before confirmation and never backfilled from a later source toggle. + +**Contract — what this module writes**: one `image_strategy` per direction (§2); §VIII rows only for planned images, each with filename, dimensions/ratio, layout suggestion, crop policy, purpose/type, `Acquire Via` (`ai`, `web`, `user`, `placeholder`, `slice`), status under [`svg-image-embedding.md`](./svg-image-embedding.md), reference, and conditional AI fields; after final confirmation, each placed row projected into `spec_lock.md images` as `<path> | source=<Acquire Via> | crop=<adaptive|no-crop>` (unplaced source/sheet rows omitted; `Layout pattern` stays in §VIII as preferred expression). An unavailable planned or required asset stays `Pending` or `Needs-Manual`, never deleted or reclassified. --- ## 1. Proposed and Confirmed Image Plan -Before Stage 2, construct rendering candidates independently of the proposed source set. After confirmation, use this module within [`strategist.md`](./strategist.md)'s one-pass page carrier planning: run its eligibility and fit decisions inside that pass, then plan and route only the resulting image, lettering, and illustrated-icon jobs; map the confirmed source set through §h and honor explicit `image_notes` roles. This module never reopens the complete carrier mix as a separate pass, materializes a file, or adds a source. The confirmed non-`none` set is the acquisition boundary. Explicit must-use sources, assets, or page roles remain required. Asset inventory and judgment determine unconfirmed count, subject, placement, and composition without substituting an unconfirmed source. +Run this module inside [`strategist.md`](./strategist.md)'s one-pass resource-need planning — image eligibility and fit decided in that pass, then only the resulting image, lettering, and illustrated-icon jobs planned and routed; the confirmed source set mapped through §h is the acquisition boundary; explicit `image_notes` roles, must-use sources, assets, and page roles remain required; unconfirmed count, subject, placement, and composition come from inventory and judgment without adding a source. The module never reopens resource need as a separate pass or materializes a file. -For illustration, confirmed `none` stops and explicit user intent wins. Otherwise the locked visual style's `Illus.` propensity (`core` / `supportive` / `sparse`) tunes centrality and recurrence after the per-page composition scan; it never restricts eligible page types, element scale, or carrier combinations. When illustration is active, prefer one coherent family that can serve the actual page jobs, including recurring title/corner chrome, dominant anchors, supporting figures, and accents. A compact icon cue does not discharge a scene, subject, or visual-weight job that a photo or illustration family would serve. +**Illustration**: confirmed `none` stops and explicit user intent wins; otherwise the locked style's `Illus.` propensity (`core` / `supportive` / `sparse`) tunes centrality and recurrence after the per-page scan without restricting page types, element scale, or carrier combinations. Prefer one coherent family that serves the actual jobs — recurring title/corner chrome, dominant anchors, supporting figures, accents; a compact icon cue does not discharge a scene, subject, or visual-weight job a photo or family would serve. -**Context-first understanding for provided assets**: Do not visually scan `images/`. First infer identity, role, and crop / focus needs from source position and surrounding prose, captions / alt / titles, filename, user notes / confirmed `image_notes`, existing resource records, and CSV geometry. Inspect only one specific image when a remaining ambiguity would change selection, factual identity, page role, crop safety, or focal placement. Never inspect for inspiration, bulk-open the folder, or infer external facts / provenance from pixels. Record the result in §VIII. Leave an optional unresolved asset unused; route an unresolved must-use asset through failure recovery. +**Context-first understanding of provided assets**: never scan `images/` for inspiration or bulk-open it. Infer identity, role, and crop/focus needs from source position, surrounding prose, captions/alt/titles, filename, user notes and `image_notes`, existing records, and CSV geometry; inspect one specific image only when a remaining ambiguity would change selection, identity, page role, crop safety, or focal placement, never inferring external facts or provenance from pixels. Record the result in §VIII; leave an optional unresolved asset unused and route a must-use one through failure recovery. -**Default — use Illustration Sheets when a compatible group benefits from a shared generation context**: illustration elements, illustrated-icon cues, and lettering may all use this path. [`image-generator.md`](./image-generator.md) §4.3 owns grouping and split decisions. +**Default — Illustration Sheets for a compatible group (may split for geometry, detail, or quality)**: illustration elements, illustrated-icon cues, and lettering share one generation context under [`image-generator.md`](./image-generator.md) §4.3. Plan one unplaced `ai` Illustration Sheet row plus one placed `slice` row per used element (only slice rows enter the lock; one element may serve several pages), stating each element's communication job, placement/reuse relationship, relative weight, energy, family, and shape without prescribing an effect stack. Glyph-native expression is the default; a lettering-plus-illustration lockup only on explicit request or when the confirmed direction requires it. Lettering sheets use `text_policy: embedded` — the asset may carry the complete display title while any searchable, selectable, or outline-visible title stays a separate native frame. §§4.3 and 5.3 own the controlled-default/high-expression boundary, grid, key field, slicing, and execution; Stage 2 chooses the AI path under §7, never re-picked here. -For each sheet, plan one unplaced `ai` Illustration Sheet row plus one placed `slice` row per used element; only slice rows enter `spec_lock.md images`, and one element row may serve several §IX pages. State each element's communication job, placement/reuse relationship, relative visual weight, energy, family, and shape without prescribing an effect stack. Use glyph-native expression by default; record a lettering-plus-illustration lockup only when the user explicitly requests it or the confirmed direction requires it. Lettering sheets use `text_policy: embedded`; the asset may carry the complete display title, while any required searchable, selectable, or outline-visible title remains an ordinary separate native text frame. [`image-generator.md`](./image-generator.md) §§4.3 and 5.3 own the controlled-default/high-expression boundary, artistic authorship, grid, key field, slicing, and execution details. Final Stage 2 chooses the AI execution path under `image-generator.md` §7; do not pre-empt or re-pick it here. +**Illustrated icons (confirmed AI)**: a compact semantic cue may become a project-specific illustrated cue through the same sheet-to-slice contract — `Type: Illustrated icon`, `Crop Policy: no-crop`, an appropriate layout recommendation, parent as an unplaced `Type: Illustration Sheet`; no confirmation field, slices never in `icons/`, coexistence with base SVG/emoji icons when the system stays coherent. -**Illustrated icons (confirmed AI permission)**: a compact semantic cue may be -produced as a project-specific illustrated cue through the same sheet-to-slice -contract. Each placed cue uses -`Type: Illustrated icon`, `Crop Policy: no-crop`, and an appropriate layout -recommendation; the parent remains an unplaced `Type: Illustration Sheet`. -There is no confirmation field. Illustrated cues may coexist -with base SVG/emoji icons when the overall visual system remains coherent, and -their slices stay out of `icons/`. +**Reference — decorative-lettering candidates**: under confirmed `ai` (a Permission, not coverage), any stable wording is a candidate when an artistic treatment could communicate better than native type; wording that fails either test stays native. Page role, character/word/line count, kind of noun, and locked style never pre-filter — a long title, phrase, or multi-line lockup is as eligible as a short mark, and a full exact string stays one mark, never trimmed, rewritten, or split for generation. Zero selected marks is valid. Materialize each selected mark as an ordinary `ai` row or through §4.3 sheet/element rows, grouped by letterform character and treatment; the asset may carry the complete title as display layer while a native title/subtitle stays in its own frame wherever a searchable, selectable, or outline-visible heading is needed; chrome and body stay native. Confirmed `none`, an explicit no-AI or editable-only instruction, or an Offline Manual path does not activate this rule; a user-required lettering asset follows the ordinary contract. -**Reference — decorative-lettering candidates**: under confirmed `ai`, any -stable wording is a lettering candidate when an artistic treatment could -communicate better than native type; confirmed `ai` is a Permission, not -coverage, and wording that fails either test stays native editable text. Page role, character count, word count, line count, kind of noun, -and locked style never pre-filter candidates; a complete long title, multi-word -phrase, and multi-line lockup are as eligible as a short mark. Preserve each -full exact character sequence as one intended mark when its hierarchy belongs -to the art; never trim, rewrite, or split it merely to ease generation. Zero selected marks remains valid. Materialize each -selected mark as an ordinary `ai` row or group compatible marks through the -§4.3 sheet/element rows rather than leaving it as a planning suggestion. Let -letterform character, treatment, and practical generation needs guide grouping. -An asset may carry the complete long or multi-line -title as its display layer. Keep an ordinary native title/subtitle in a -separate text frame wherever the page needs a searchable, -selectable, or outline-visible heading. Chrome and body remain native text. A -confirmed `none`, explicit no-AI instruction, -editable-only hook, or Offline Manual path does not activate this proactive -rule; an explicit user-required lettering asset still follows the ordinary -resource contract. - -**Image treatment path** (per selected image): `none` (unchanged), `native` (SVG crop/clip, transform, opacity, frame/depth, overlap), or `prepared derivative` (separate pixel blur/tone or cutout/registered layers); `none` is valid. - -When a subject crosses a native title, panel, frame, or shape, the prepared path is mandatory: plan a clean full-canvas base plus minimum registered RGBA layers; set full-canvas members `no-crop`; name their shared source/registration in `Reference`; suggest `#A2-03`. A shared plate requires padded-bbox-disjoint objects and independent final crops. Use `user` only when every final asset is supplied, otherwise `ai`; [`image-generator.md`](./image-generator.md) §4.4 owns preparation. An independent floating cutout may use `#A2-01`. +**Image treatment path** per selected image: `none` (unchanged), `native` (SVG crop/clip, transform, opacity, frame/depth, overlap), or `prepared derivative` (pixel blur/tone, or cutout/registered layers); `none` is valid. A subject crossing a native title, panel, frame, or shape mandates the prepared path: a clean full-canvas base plus the minimum registered RGBA layers, full-canvas members `no-crop`, the shared source/registration named in `Reference`, `#A2-03` suggested; a shared plate needs padded-bbox-disjoint objects and independent final crops; `user` only when every final asset is supplied, otherwise `ai` under [`image-generator.md`](./image-generator.md) §4.4. A free-floating cutout may use `#A2-01`. ## 2. AI Image Strategy — always propose three; lock only for confirmed `ai` -Before any rendering detail, use the already-loaded [`image-renderings/_index.md`](./image-renderings/_index.md) as the sole rendering-basis catalog authority. First author exactly three complete, project-fit solution intents; use the index to freeze each intent's exact rendering bases, then read once only the deduplicated referenced sibling files. Project one complete `image_strategy` into each direction regardless of `recommend.image_usage`. Every candidate carries `name`, `rendering: custom`, `visual`, `mood`, and non-empty `behavior`, each written once in the confirmed UI language. Mood includes a recognizable real-world analogy. All three must credibly serve their owning whole solution; rendering treatments and bases may coincide when other components express the direction difference. Do not force artificial safe / shifted / bold extremes. Image colors always inherit that direction's deck HEX roles; never add an image palette or alter deck colors to rescue a rendering. +Project one complete `image_strategy` into each direction authored under [`strategist.md`](./strategist.md) §d, regardless of `recommend.image_usage`, with the loaded [`image-renderings/_index.md`](./image-renderings/_index.md) as the sole basis authority: freeze each direction's exact bases, then read once only the deduplicated referenced sibling files. Each candidate carries `name`, `rendering: custom`, `visual`, `mood` (with a recognizable real-world analogy), and non-empty `behavior`, written once in the confirmed UI language; it may use catalog material in any way or none, names every basis it actually uses (each owning a distinct line, texture, depth, material, or mood contribution), and inherits the direction's deck HEX roles — never a second palette. Treatments may coincide when other components carry the difference; no forced safe / shifted / bold extremes. Only a confirmed custom locks `image_rendering_behavior` plus `image_rendering_references` when catalog material is used; unselected candidates stay recommendation-only, and legacy `image_palette` or a fourth `custom_candidates.image_strategy` is never written. The UI hides the candidates until AI is selected and reveals the same three without a backend rerun; Image_Generator later reads only the selected preset or exact references. -Every direction is a `custom` rendering, unconstrained by how it relates to the catalog. It may use catalog material in any way or none, including carrying one complete preset treatment unchanged. Name every actual id in the visible behavior and read only those files after selection; when several are named, each owns a distinct line, texture, depth, material, or mood contribution. Reference count has no fixed cap, and a second basis is never required. With no catalog basis, name none and read none. Under a template it obeys inherited identity and application. Only a confirmed custom locks its edited behavior as `image_rendering_behavior`; when catalog material is actually used, also project the exact ids as `image_rendering_references`, otherwise omit that field. Unselected candidates remain recommendation-only. Do not write a separate fourth `custom_candidates.image_strategy`; ignore legacy `image_palette`. - -The UI hides these candidates while AI is not selected. If the user adds AI, it reveals the already-authored three without another backend recommendation; source selection never creates or rewrites rendering candidates. After confirmation, Image_Generator reads only the selected preset or exact custom references and must not blend unselected candidate identities. - -For specialized or regulated paper-figure subjects, preserve the prompt depth required by [`image-generator.md`](./image-generator.md) §4.2 rather than shortening to a generic brief. Scan the outline for genuine image-led pages, list the proposed hero pages in Stage-2 `image_notes` so the user can retain, edit, or remove them in the same confirmation, then mark only the confirmed pages' AI rows `page_role: hero_page`; local is the default. `text_policy: embedded` is reserved for stable figure-internal identifiers or lettering deliberately fused into the artwork; page titles, editable data values/labels, and prose remain SVG. Resolve confirmed provided assets through the context-first boundary above before writing §VIII. +For specialized or regulated paper-figure subjects keep the prompt depth of [`image-generator.md`](./image-generator.md) §4.2. Scan the outline for genuine image-led pages, list proposed hero pages in Stage-2 `image_notes` for the user to retain, edit, or remove, then mark only confirmed pages' AI rows `page_role: hero_page` (local is the default). `text_policy: embedded` is reserved for stable figure-internal identifiers or lettering fused into the artwork; titles, editable data, and prose stay SVG. Resolve provided assets through the context-first boundary before writing §VIII. ## 3. Image Resource List -Add §VIII rows only for planned images. Fill filename, dimensions/ratio, layout suggestion, crop, purpose/type, acquisition, status, reference, and conditional AI fields. `Acquire Via` is `ai`, `web`, `user`, `placeholder`, or `slice`; status follows [`svg-image-embedding.md`](./svg-image-embedding.md). Keep any unavailable planned/required asset `Pending` or `Needs-Manual`; never delete or reclassify it to appear complete. After final confirmation, project each placed row into `spec_lock.md images` as `<path> | source=<Acquire Via> | crop=<adaptive|no-crop>` and omit unplaced source/sheet rows. Preserve exact confirmed `source`/`crop`; `Layout pattern` stays in §VIII as preferred expression rather than locked geometry. +**Prepared derivatives**: keep the canonical row and add a deterministic child with a distinct `.png`, `Reference: Derived from <bare filename>; treatment=<operation>;`, inheriting acquisition (§4.4 follows `user` / `ai` above); lock placed children; [`image-base.md`](./image-base.md) §1–2 owns preparation. -**Prepared derivatives**: Keep canonical; `Reference`: `Derived from <bare filename>; treatment=<operation>;`. Deterministic child: distinct `.png`, inherits acquisition; §4.4 follows `user`/`ai` above. Lock placed children; [`image-base.md`](./image-base.md) §2–3 owns preparation. +**References describe visual intent**: AI rows carry subject + intent + composition without repeating rendering or HEX; web rows carry the exact subject, view/mood, focal/quiet region, crop safety, and positive quality cues, from which Image_Searcher derives a separate short provider query (complete entity names or disambiguation may use more words). When page use depends on stable composition, put subject/quiet zones, boundary or direction, intended overlap/seam, and approximate share in `Reference` or the §IX block, not only in `Layout pattern`. -References describe visual intent: AI uses subject + intent + composition without repeating rendering or HEX; web records exact subject, view/mood, focal/quiet region, and crop safety with positive quality cues; Image_Searcher later derives a separate short, specific provider query without rewriting this locked intent, while complete entity names or necessary disambiguation may use more words. When page use depends on stable image composition, put its subject/quiet zones, boundary or direction, intended overlap/seam, and approximate share only when needed in `Reference` or the matching §IX block—not only in `Layout pattern`. +**Prepared-user fast path**: for initial imported or user-supplied assets confirmed as `provided`, copy the exact basename, derive `Dimensions` / `Ratio` from the row's EXIF-corrected `Width` / `Height` / `AspectRatio` in the latest `analysis/image_analysis.csv` (`SourceDisplayRatio` is source context, not the crop ratio), drop source-side directories, set `Acquire Via: user` and `Status: Existing`, and decide the rest normally; existing §VIII, lock, or provenance records override this inference, and assets declared `ai`, `web`, `slice`, or manual keep that provenance wherever they sit. -**Prepared-user fast path**: For initial imported or user-supplied assets confirmed as `provided`, copy the exact `Filename` basename and derive `Dimensions` / `Ratio` from that row's EXIF-corrected `Width` / `Height` / native `AspectRatio` in the latest `analysis/image_analysis.csv`; `SourceDisplayRatio` is source-context metadata, not the bitmap crop ratio. Drop source-side directories, set `Acquire Via: user` and `Status: Existing`, and decide the remaining §VIII fields normally. Existing §VIII / lock / provenance-manifest records override this inference. Assets declared as `ai`, `web`, `slice`, or manual fulfillment retain that provenance and advance through their own status lifecycle after entering `images/`; location never reclassifies them as `user / Existing`. +**Layout pattern** (one non-empty value per placed row, required by the checker): preferred expression in ordinary words, not locked geometry (an id from [`image-layout-patterns.md`](./image-layout-patterns.md) only when already known; Executor loads that catalog); Executor adjusts it freely as a Reference while keeping resource identity, must-use status, crop/content, and explicit constraints (layout-only changes need no upstream rewrite). A useful entry names the job the image does for the content or the page's shapes — the catalog is recall, an uncatalogued technique answers a job equally, plain split and full bleed stay valid, and a `no-crop` or supporting row keeps one concise suggestion. Choose narrative intent before dimensions, then derive `Dimensions` / `Ratio` from the intended region of the confirmed canvas (placement geometry itself is Executor's [`image-layout-spec.md`](./image-layout-spec.md)); a cutout, blurred crop, or desaturated copy requires that prepared asset. -**Layout pattern** (the checker requires one non-empty value per placed row): it is preferred expression, not locked geometry; optional hierarchical ids from the already-read [`image-layout-patterns.md`](./image-layout-patterns.md) must be exact. They are prompt lookup handles for Executor, not exporter effect codes. Executor may adopt, adapt, or decline the suggestion while preserving resource identity/source, must-use status, crop/content, and explicit user/template constraints; layout-only changes need no upstream rewrite. - -**Reference — job-bearing pattern text**: a useful entry names the job the image does for the content or the page's shapes, not only a skeleton id, position, size, crop, or scrim. The already-read [`image-layout-patterns.md`](./image-layout-patterns.md) is recall for that composition, never a menu — an unlisted combination or a technique it never names answers a job just as well, and the job is never restated to reach a listed entry. Plain split and full bleed stay valid when the named job is best served plainly. A `no-crop` or supporting row keeps one concise suggestion instead. - -Choose narrative intent before dimensions, then apply the already-read [`image-layout-spec.md`](./image-layout-spec.md) to the actual page region. Techniques needing a cutout, blurred crop, or desaturated copy require that prepared asset. Write `Crop Policy: no-crop` whenever cropping could remove required pixels, labels, evidence, identity, or edge content; screenshots, charts, certificates/contracts, dense diagrams, logos, and product markings are common triggers rather than an exhaustive list. Otherwise write `Crop Policy: adaptive`: Executor may use complete display or a focal-safe crop, and the value never commands cropping. - -Judge `text_policy` per AI row using [`image-generator.md`](./image-generator.md) §5.3; paper figures, academic schematics, panel comparisons, data-axis graphics, and stable decorative lettering are positive triggers for reconsidering an all-`none` plan. Step 5 dispatches pending `ai` / `slice` rows to Image_Generator and pending `web` rows to Image_Searcher. +**Crop policy**: `no-crop` whenever cropping could remove required pixels, labels, evidence, identity, or edge content (screenshots, charts, certificates, dense diagrams, logos, product markings are common triggers); otherwise `adaptive` — Executor may use complete display or a focal-safe crop, and the value never commands cropping. Judge `text_policy` per AI row under [`image-generator.md`](./image-generator.md) §5.3; paper figures, schematics, panel comparisons, data-axis graphics, and stable lettering are triggers to reconsider an all-`none` plan. Step 5 dispatches pending `ai` / `slice` rows to Image_Generator and `web` rows to Image_Searcher. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/strategist-template.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/strategist-template.md index ac83226a..31223750 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/strategist-template.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/strategist-template.md @@ -4,104 +4,76 @@ Conditional extension for applying an installed Brand/Style/Layout/Deck workspace to Stage 2 recommendations and the execution lock. -**Trigger**: Load only after Stage 1 confirms a library or explicit workspace selection and the post-confirmation apply stage either installs it into `<project_path>/templates/` or confirms that the target project is consuming it in place. Bare template names, style words, and free-design projects do not trigger this module. +**Trigger**: Load only after Stage 1 confirms a library or explicit workspace selection and the post-confirmation apply stage installs it into `<project_path>/templates/` or confirms in-place consumption. Bare template names, style words, and free-design projects do not trigger this module. --- ## 1. AI-Authored Template Application Plan -**Template vs preset**: A style mention and a Style workspace are different inputs. Bare names and style words remain interpretive input and never resolve to a local path; only a selected and installed workspace activates the rules below. Every installed `<project_path>/templates/design_spec.<kind>.<id>.md` is a template-design source; read all of them. The presence of a `design_spec.style.*.md` file is what marks an active Direction / method segment. Whether a source root was labelled `library` or `explicit` is installation provenance only and never affects Stage-2 precedence. +**Inputs**: every installed `<project_path>/templates/design_spec.<kind>.<id>.md` is a template-design source; read all of them. A `design_spec.style.*.md` file marks an active Direction / method segment. Bare names and style words stay interpretive input and never resolve to a local path. Library/explicit provenance never affects precedence. A legacy or incomplete Layout/Deck is not a Step 3 input — rebuild it through [`create-template`](../workflows/create-template.md), preferably from the original PPTX; never mutate the input. -**Source-analysis template boundary**: A legacy or incomplete Layout/Deck is not a Generate Step 3 input. Rebuild it through [`create-template`](../workflows/create-template.md), preferably from the original PPTX when native topology matters. Brand and Style are intentionally roster-free. Never mutate the input. +**Hard rule — no Stage-1 influence**: Do not load this module, the template spec, prototypes, assets, or template canvas while authoring Stage 1, and never revise a confirmed Stage 1 to match the workspace. -**No template-mode confirmation**: Never ask the user to choose internal exporter reuse/adherence values. Natural-language instructions win. Otherwise decide from current content and installed state. Common readings are: reference-led may redesign after full-roster study; augment-only freezes non-slot objects, permits slot edits, and only adds; replacement-only changes information carriers while preserving the rest. They are examples, not fixed modes; use reference-led when no stronger fit exists. +**Outputs**: -**Hard rule — no Stage-1 influence**: Do not load this module, the installed template spec, prototypes, assets, or template canvas while authoring Stage 1. Stage 1 is already confirmed when this module begins; never revise it to match the workspace. - -Immediately before authoring the Stage-2 solution, load each relevant template -resource once per path + SHA and inspect: - -- every installed `design_spec.<kind>.<id>.md`; inspect the actual Page Roster and every complete Slide prototype from Layout when present, otherwise from Deck; a mirror scope note about omitted source identities is evidence, not a page-candidate list; -- the Identity, Structure, Reusable Application Context, and Direction / method segment owners, resolved here from the installed set under [`apply-template-workspace`](../workflows/stages/apply-template-workspace.md) §5; -- the confirmed current communication contract, source obligations, planned page count, and content shape of every planned page; -- the user's natural-language instructions, including any page names/numbers or elements they explicitly require. - -Then author one plan that decides all of the following without presenting an option menu: - -- for Layout/Deck, whether the full prototype set, a relevant subset, or only the design language is useful; -- for Layout/Deck, which prototype each generated page starts from, which template pages are skipped, and which prototypes are repeated or reordered; -- whether content is inserted directly, reorganized inside existing structure, or rebuilt under the resolved Direction / method segment; -- for Style, which communication method, visual language, composition rhythm, and information-expression defaults are adopted or adapted without inventing page prototypes; -- which visible elements must remain literal because the user said so, and which may change to serve the current content. - -If a prototype detail becomes uncertain, re-read its installed SVG; do not -substitute memory, a semantic label, or the source PPTX. - -For Layout/Deck, template size is evidence, not policy. A short template may use every prototype when the content genuinely fits; a 20–30 page source may contribute only a few suitable pages, or several pages may be reorganized into a new sequence. Never infer that all pages must be kept or that visible sample content is protected merely because it exists in the template. Style and Brand have no prototype set. - -**Hard rule — Slide prototypes drive authoring**: Every template SVG is a -complete Slide prototype with resolved Master + Layout + Slide context. Use -these files for `page_layouts`; standalone Master/Layout definition SVGs are -invalid. An unselected authored Slide prototype may still supply a -`pptx_layouts` definition, while mirror exposes only actual source Slides. - -Record the resulting exporter plan internally: - -| Internal value | When the authored plan requires it | +| Output | Form | |---|---| -| `template_reuse_scope: mirror` | The workspace has `replication_mode: mirror`, the plan calls for literal page reuse, and each page changes only allowed visible text values while preserving visual and text-node topology. | -| `template_reuse_scope: layout` | The plan reuses the template Master/Layout system and prototypes while allowing current-project content and appearance decisions. | -| `template_reuse_scope: style` | A Style-only workspace is active, or the plan uses only communication/design direction, color, typography, decoration language, composition, or rhythm and intentionally creates flat free-design pages. | -| `template_adherence: strict` | Every structured page fits an existing prototype contract without changing its Layout identity or slot topology. Mandatory for `template_reuse_scope: mirror`. | -| `template_adherence: adaptive` | Structured reuse remains useful, but at least one page needs a new explicit Layout under the selected Master. | +| `recommendations.stage2.json` top-level `template_application.value` | One concise natural-language paragraph; omitted without a template | +| `design_spec.md §I` | `- **Template Application**: <prose>` persisted from the confirmed `result.json` value (or exact chat answer); blank returns the decision to Strategist | +| `spec_lock.md pptx_structure` | Only the derived internal values below (§3); never in `design_spec.md`, stage files, the Confirm UI, or `result.json` | -Write only the derived values to `spec_lock.md pptx_structure`; omit `template_adherence` for `style`. Do not put these internal values in `design_spec.md`, recommendation stage files, the Confirm UI, or `result.json`. +| Internal value | When the plan requires it | +|---|---| +| `template_reuse_scope: mirror` | Workspace has `replication_mode: mirror`, the plan reuses pages literally, and each page changes only allowed visible text values while preserving visual and text-node topology | +| `template_reuse_scope: layout` | The Master/Layout system and prototypes are reused while current-project content and appearance decisions remain open | +| `template_reuse_scope: style` | A Style-only workspace is active, or only communication/design direction, color, typography, decoration, composition, or rhythm is reused and pages are flat free-design | +| `template_adherence: strict` | Every structured page fits an existing prototype contract without changing Layout identity or slot topology; mandatory for `mirror` | +| `template_adherence: adaptive` | Structured reuse stays useful but at least one page needs a new explicit Layout under the selected Master | -**Mandatory — natural-language Stage-2 plan**: Write one concise paragraph. For Layout/Deck, state prototype use/order, what stays literal, and what may change; name exact SVG basenames for prototype-specific exceptions, never roles such as “cover”. For Brand/Style, state identity or Direction / method constraints and free composition unless structure comes from another workspace. Write top-level `template_application.value` in `recommendations.stage2.json`; omit it without a template. After Stage 2, re-read the confirmed `result.json` value (or exact chat answer); blank returns the decision to Strategist. Persist `- **Template Application**: <prose>` in `design_spec.md §I`, derive internal mappings, and never copy it to `spec_lock.md` or add fixed options. +**Procedure** — immediately before authoring the Stage-2 solution, load each relevant resource once per path + SHA: every installed spec with its Page Roster and every complete Slide prototype (Layout first, otherwise Deck; a mirror scope note about omitted source identities is evidence, not a page-candidate list); the Identity, Structure, Reusable Application Context, and Direction / method owners resolved under [`apply-template-workspace`](../workflows/stages/apply-template-workspace.md) §5; the confirmed communication contract, source obligations, planned page count, and content shape of every page; the user's natural-language instructions including required page names/numbers or elements. Then author one plan, without an option menu, that decides: for Layout/Deck, whether the full prototype set, a subset, or only the design language is useful, which prototype each page starts from, which pages are skipped, repeated, or reordered; whether content is inserted directly, reorganized inside existing structure, or rebuilt under the resolved Direction / method; for Style, which communication method, visual language, composition rhythm, and expression defaults are adopted without inventing prototypes; which visible elements stay literal because the user said so. Re-read an installed SVG when a prototype detail is uncertain — never memory, a semantic label, or the source PPTX. -**Two-stage boundary**: An installed template changes the content of final Stage 2, never the confirmation sequence. Run Stage 1 → final Stage 2 in order in both Confirm UI and chat fallback; do not skip a stage or treat template inspection as user confirmation. On browser timeout, return to the same stage in chat. +**Judgment**: Template size is evidence, not policy — a short template may use every prototype when content fits; a 20–30 page source may contribute a few pages or be reorganized into a new sequence. Never infer that all pages must be kept or that sample content is protected merely because it exists. Natural-language instructions win; otherwise decide from content and installed state. Common readings — reference-led redesigns after full-roster study; augment-only freezes non-slot objects, permits slot edits, and only adds; replacement-only changes information carriers and preserves the rest — are examples, not modes; use reference-led when nothing fits better. Never ask the user to choose internal reuse/adherence values. + +**Hard rule — Slide prototypes drive authoring**: every template SVG is a complete Slide prototype with resolved Master + Layout + Slide context; use these files for `page_layouts`. Standalone Master/Layout definition SVGs are invalid. An unselected authored prototype may still supply a `pptx_layouts` definition; mirror exposes only actual source Slides. + +**Plan wording**: for Layout/Deck, state prototype use/order, what stays literal, and what may change, naming exact SVG basenames for prototype-specific exceptions rather than roles such as "cover". For Brand/Style, state identity or Direction / method constraints and free composition unless structure comes from another workspace. + +**Two-stage boundary**: an installed template changes the content of final Stage 2, never the confirmation sequence. Run Stage 1 → Stage 2 in order in both Confirm UI and chat fallback; template inspection is not user confirmation. On browser timeout, return to the same stage in chat. --- ## 2. Scenario Fit and Inherited Design -**Mandatory — decide from the §1 inspection**: For an installed `kind: deck`, compare the retained Template Overview with the confirmed audience, intent, outcome, delivery context, artifact afterlife, and source obligations. Deck application is reusable context for this comparison, never the current project's application contract and never an override. Compare the retained Page Roster and complete SVG roster with required narrative roles, content shapes, slots, and capacity. Reopen a resource only when its path + SHA changed. The template describes what exists; it never overrides the current project or own required/optional/repeatable or fixed/replaceable/example-only policy. For `kind: layout`, compare only structural roles, slots, and capacity. For an active Style segment, compare its communication method with the current contract and its composition requirements with any selected Layout/Deck structure. Surface a material incompatibility; never silently weaken one segment to make it fit. +**Mandatory — decide from the §1 inspection**: for `kind: deck`, compare the retained Template Overview with the confirmed audience, intent, outcome, delivery context, afterlife, and source obligations, and its Page Roster and SVG roster with required narrative roles, content shapes, slots, and capacity; Deck application is reusable context, never the current contract or an override. For `kind: layout`, compare only structural roles, slots, and capacity. For an active Style segment, compare its communication method with the current contract and its composition requirements with any selected Layout/Deck structure. Surface a material incompatibility; never silently weaken one segment to make it fit. Reopen a resource only when its path + SHA changed. | Internal scope | Appropriate when | |---|---| -| `mirror` | The artifact repeats a known form; literal appearance and text topology are requirements; new content fits existing roles and slots. | -| `layout` | The structural system and brand continue, but the communication outcome requires reflow, new emphasis, or an adaptive Layout. | -| `style` | Only communication/design direction is reused, a Style-only workspace is active, or the outcome requires a different sequence, density, or composition system. | +| `mirror` | The artifact repeats a known form; literal appearance and text topology are requirements; new content fits existing roles and slots | +| `layout` | The structural system and brand continue, but the outcome requires reflow, new emphasis, or an adaptive Layout | +| `style` | Only direction is reused, a Style-only workspace is active, or the outcome requires a different sequence, density, or composition system | -When the communication contract conflicts with the workspace, choose and state the best-fit application plan in the complete Stage-2 solution. Surface the mismatch only when it materially limits the result; do not respond with a mode questionnaire. Template capability constrains what is legal; scenario fit decides what is useful. +When the communication contract conflicts with the workspace, state the best-fit plan in the Stage-2 solution and surface the mismatch only when it materially limits the result; no mode questionnaire. Template capability constrains what is legal; scenario fit decides what is useful. (`content_divergence` controls source reorganization; `template_reuse_scope` records the reused layer; `template_adherence` records whether a structured plan keeps or extends Layout identities.) -> Internal note: `content_divergence` controls source reorganization; the AI-derived `template_reuse_scope` records the reused layer; `template_adherence` records whether a structured plan keeps or extends existing Layout identities. +**Precedence**: explicit current user instructions and final confirmation win. The installed set contributes at most one of each kind; all four may coexist. Brand overrides Deck identity. Layout overrides Deck structure; Deck keeps application context and identity not overridden by Brand; without Layout, Deck owns structure. Style owns Direction / method only: its visual values are candidate defaults that yield to resolved Brand/Deck identity, and its preferred Mode / Visual Style seed the single final locks. Style takes this segment ahead of ordinary Stage-2 defaults; active prototypes and Deck Signature facts remain compatibility constraints. -**Template design precedence**: Explicit current user instructions and final confirmation win. The installed set contributes at most one of each kind; all four may coexist. Brand overrides Deck identity. Layout overrides Deck structure; Deck retains application context and identity not overridden by Brand. Without Layout, Deck owns structure. Style owns Direction / method only: its visual values remain candidate defaults and yield to resolved Brand/Deck identity, while its preferred Mode / Visual Style seed the single final locks instead of creating parallel authority. Style takes this segment ahead of ordinary Stage-2 defaults; active prototypes and Deck Signature facts remain compatibility constraints. Library/explicit provenance never changes this order. - -**Default — template-led recommendation (may override when explicit user or confirmed-contract requirements demand another result)**: Make all three directions obey the same resolved template context. Repeat fixed Brand/Deck palette roles and complete fonts with `typography.fixed: true`; keep resolved icon/image constraints and vary only open roles or dimensions. Mark the viable direction that most fully expresses the template-owned or template-informed structure, visual language, and application rules as `design_directions.selected`. Never weaken template use or split its segments across cards to manufacture alternatives. Style Review Focus never activates [`visual-review`](../workflows/stages/visual-review.md); only an explicit user request does. +**Default — template-led recommendation (may override for explicit user or confirmed-contract requirements)**: all three directions obey the same resolved template context. Repeat fixed Brand/Deck palette roles and complete fonts with `typography.fixed: true`; keep resolved icon/image constraints and vary only open roles or dimensions. Mark as `design_directions.selected` the viable direction that most fully expresses the template-owned structure, visual language, and application rules. Never weaken template use or split its segments across cards to manufacture alternatives. Style Review Focus never activates [`visual-review`](../workflows/stages/visual-review.md); only an explicit user request does. --- ## 3. Structured Lock Planning -For Style-only or Style + Brand, write `pptx_structure.mode: flat` plus `template_reuse_scope: style`; omit `template_adherence` and every structured mapping section. When a Style is installed alongside Layout or Deck, it changes only Direction / method and does not force flat/structured routing. Derive reuse scope from the selected Layout/Deck application plan; a literal `mirror` plan is compatible only when the Style segment requires no visual or topology change. +| Plan | Lock rows | +|---|---| +| Style-only or Style + Brand | `pptx_structure.mode: flat`, `template_reuse_scope: style`; omit `template_adherence` and every structured mapping section | +| `mirror` / `layout` | `pptx_structure.mode: structured`, `template_adherence: strict\|adaptive` (mirror always `strict`); no legacy `baseline`, `template`, `preserve`, `layout_strategy`, or Layout-kind rows | -For `mirror` / `layout`, write `pptx_structure.mode: structured` plus `template_adherence: strict|adaptive`; mirror always writes `strict`. Do not write legacy `baseline`, `template`, `preserve`, `layout_strategy`, or Layout-kind rows. +A Style installed alongside Layout/Deck changes only Direction / method and never forces flat/structured routing; a literal `mirror` plan is compatible only when the Style segment requires no visual or topology change. -- **Master roster**: Write one `pptx_masters` row per Master as `<master_key>: <picker name>` and copy the workspace's prototype roster. Keys use 1–64 ASCII letters, digits, dots, underscores, or hyphens, start with a letter/digit, and contain no spaces; human-readable spaces belong only in the picker name. Master visuals are root-level atomic elements and may never be `<g>`. -- **Reusable Layout roster**: Write every unique Layout once as `<layout_key>: <master_key> | <PowerPoint layout name> | <prototype source>`. Each installed `template:<basename>` source is a complete Slide prototype, including one not selected for the current generated deck. A new adaptive Layout uses its first generated `P<NN>` as source. Reuse a key only when fixed atoms and slot ids/types/indices/bounds/binding modes are identical. Name authored keys after composition, never page topic. A Layout may intentionally have zero slots; do not manufacture an empty `utility` kind or full-page fake slot. -- **Page assignment**: Write exactly one `page_pptx_layouts` row per page. Each key must exist in `pptx_layouts`. Check that distinct compositions do not collapse into role-only keys and that one skeleton does not split into topic-specific keys. -- **Slot planning**: Each reusable slot is a direct root `<g id>` with `data-pptx-placeholder`, positive design-zone bounds, and exactly one compatible direct carrier. Bounds come from the intended safe area, column, panel inset, or media frame—not sample text ink. A genuinely composite region may use only the explicit `object` + `proxy` downgrade. -- **Adaptive refinement**: Initial definitions are complete. If construction shows that reusable framing or slot topology/bounds must change, return to Strategist to add a definition sourced from that page and update its assignment before execution resumes. Executor never mutates or extends the contract; export only compiles declared structure and never discovers or clusters Layouts. -- **Input prototypes**: Add one `page_layouts` row per page using a complete Slide prototype. Strict preserves that SVG's contract; adaptive keeps its Master and may declare a new output Layout. Mirror preserves ordinary authored visuals and text-node topology; a direct JSON-first Chart/Table may regenerate only its derived preview children while retaining marker, metadata, bounds, and structure. +- **Master roster**: one `pptx_masters` row per Master as `<master_key>: <picker name>`, copied from the workspace roster. Keys are 1–64 ASCII letters/digits/dots/underscores/hyphens starting with a letter or digit; spaces belong only in the picker name. Master visuals are root-level atoms, never `<g>`. +- **Reusable Layout roster**: every unique Layout once as `<layout_key>: <master_key> | <PowerPoint layout name> | <prototype source>`. Each installed `template:<basename>` is a complete Slide prototype, including ones not selected for this deck; a new adaptive Layout uses its first generated `P<NN>`. Reuse a key only when fixed atoms and slot ids/types/indices/bounds/binding modes are identical. Name authored keys after composition, never page topic. Zero-slot Layouts are valid; do not manufacture an empty `utility` kind or a full-page fake slot. +- **Page assignment**: exactly one `page_pptx_layouts` row per page; each key must exist in `pptx_layouts`. Check that distinct compositions do not collapse into role-only keys and that one skeleton does not split into topic-specific keys. +- **Slot planning**: each reusable slot is a direct root `<g id>` with `data-pptx-placeholder`, positive design-zone bounds from the safe area, column, panel inset, or media frame — not sample text ink — and exactly one compatible direct carrier. A genuinely composite region uses only the explicit `object` + `proxy` downgrade. +- **Adaptive refinement**: initial definitions are complete. If construction shows that reusable framing or slot topology/bounds must change, return to Strategist to add a definition sourced from that page and update its assignment before execution resumes. Executor never mutates the contract; export only compiles declared structure. +- **Input prototypes**: one `page_layouts` row per page using a complete Slide prototype. Strict preserves that SVG's contract; adaptive keeps its Master and may declare a new output Layout. Mirror preserves authored visuals and text-node topology; a JSON-first Chart/Table may regenerate only its derived preview children. -**Visualization compatibility**: Use `page_layouts` with optional Chart/Table -`page_visualizations` only when the prototype shell can carry the actual §IX -information model. The reference changes neither Layout identity, slot -topology, nor final visualization type. Qualitative relationships stay in §IX -and are composed Slide-locally; they never supply Master/Layout/placeholder -ownership. Without an exact prototype match, adaptive mode starts from the -closest neutral prototype and declares an output Layout; strict mode selects an -existing compatible Layout or revises the outline. Never omit `page_layouts` -on a structured route or write legacy `page_charts` in a new lock. +**Visualization compatibility**: use `page_layouts` with optional Chart/Table `page_visualizations` only when the prototype shell can carry the actual §IX information model; the reference changes neither Layout identity, slot topology, nor visualization type. Qualitative relationships stay in §IX and are composed Slide-locally. Without an exact match, adaptive starts from the closest neutral prototype and declares an output Layout; strict selects an existing compatible Layout or revises the outline. Never omit `page_layouts` on a structured route or write legacy `page_charts`. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/strategist.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/strategist.md index 52dd41a0..1a44e5d2 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/strategist.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/strategist.md @@ -2,7 +2,7 @@ ## Core Mission -As a top-tier AI presentation strategist, receive source documents, perform content analysis and design planning, and output the **Design Specification & Content Outline** (hereafter `design_spec`). +Receive source documents, analyze content, plan the design, and output the **Design Specification & Content Outline** (`design_spec`) plus its execution lock. ## Pipeline Context @@ -10,73 +10,58 @@ As a top-tier AI presentation strategist, receive source documents, perform cont |--------------|---------|-----------| | Project creation + template-candidate preparation complete | **Strategist**: Stage 1 communication/template confirmation → installation handoff → Stage 2 solution + Design Spec | Image_Generator or Executor | ---- - -## Canvas Format Quick Reference - -> See [`canvas-formats.md`](canvas-formats.md) for the full format table (presentations / social / marketing) and the format-selection decision tree. +Canvas formats and their typography scale start: [`canvas-formats.md`](canvas-formats.md). --- ## 1. Strategist Confirmation Stage -🚧 **GATE — whole-document authoring**: Generate Step 4 reads `${SKILL_DIR}/templates/design_spec_reference.md`, authors the complete Design Spec once, passes Gate 1, then reads `${SKILL_DIR}/templates/spec_lock_reference.md` and authors the complete lock once. Do not scaffold or patch placeholders. Run `project_manager.py validate`; machine schemas, not remembered headings, own grammar validation. +🚧 **GATE — whole-document authoring**: Generate Step 4 reads `${SKILL_DIR}/templates/design_spec_reference.md`, authors the complete Design Spec once, passes Gate 1, then reads `${SKILL_DIR}/templates/spec_lock_reference.md` and authors the complete lock once; no scaffolds, no placeholder patching; `project_manager.py validate` owns grammar. -⛔ **BLOCKING**: After the read, present professional recommendations for the confirmation fields below and wait for explicit user confirmation. - -**Two-stage confirmation (the default Confirm UI flow; chat mirrors it).** -Generate Step 3 prepares candidates only. Stage 1 confirms the communication -contract and template/free-design choice together, while keeping the -communication recommendation independent of every template candidate. After -that single confirmation, selected workspaces are installed before the complete -solution + production gate: +⛔ **BLOCKING**: present professional recommendations for the fields below and wait for explicit user confirmation. Generate Step 3 prepares candidates only; Stage 1 confirms the communication contract and the template/free-design choice together (the recommendation independent of every candidate); the selected workspaces are installed before Stage 2. | Stage | Items | Role | |---|---|---| -| **1 — communication contract + template choice** | `primary_language` · `c` audience · open-ended communication intent · audience outcome · core message / delivery context (primary + optional secondary) / artifact afterlife · `content_divergence` (all prose fields may be blank) · `a` canvas · explicit `free_design` or `templates` choice and selected roots | confirmed together; candidate workspaces do not influence the communication recommendation | -| **2 — final solution + production** (authored once from the user's *actual* Stage 1) | reading mode (`delivery_purpose`, PPT only) · `d` mode + visual style · `b` page count · `e` color · `f` icon · `g` typography · `h` image source + generated-image rendering · conditional natural-language template application · conditional AI-image acquisition path · generation mode · refine-spec toggle · `design_spec_depth` · proactive speaker notes / custom animations / narration audio | derived as one coherent plan from the confirmed contract; internal template exporter modes remain hidden | +| **1 — communication contract + template choice** | `primary_language` · `c` audience · open-ended communication intent · audience outcome · core message / delivery context (primary + optional secondary) / artifact afterlife · `content_divergence` (all prose may be blank) · `a` canvas · explicit `free_design` or `templates` choice and selected roots | confirmed together; candidates never influence the communication recommendation | +| **2 — final solution + production** (authored once from the user's *actual* Stage 1) | reading mode (`delivery_purpose`, PPT only) · `d` mode + visual style · `b` page count · `e` color · `f` icon · `g` typography · `h` image source + generated-image rendering · conditional template application · conditional AI-image acquisition path · generation mode · refine-spec toggle · `design_spec_depth` · proactive speaker notes / custom animations / narration audio | one coherent plan from the confirmed contract; exporter reuse/adherence stays internal | -Do not force communication intent into one catalog label; Stage 1 records composite intent in prose. Editable prose fields are recommendation drafts, not required inputs: confirmation preserves current text and blanks; never repopulate a cleared field. Stage 2 confirms narrative spine, reading density, page budget, visual system, image direction, production mechanics, and how any installed template should be used. It never chooses or installs a template. Inspect only project-local template spec/prototypes, present one editable application plan, and keep exporter reuse/adherence internal. First author exactly three complete, project-fit solution directions from the confirmed contract and source; only then project each direction into mode, visual style, color, type, icons, and generated-image rendering for lower-level adjustment. Every direction projects a project-specific `custom` mode, `custom` visual style, and `custom` generated-image rendering; the fixed catalogs remain conservative lower-level single-select alternatives. Each direction is one complete design authored top-down within the confirmed contract, never assembled bottom-up from catalog picks; three exist so a single recommendation cannot lock the user in, and the fixed catalogs stay the manual lower layer. Its custom projections are unrestricted by catalog relationship and may carry one preset unchanged. The three directions are plainly different designs at the whole-deck level before any field is written; that difference lives in the solutions, not in one designated field. Whichever components a direction's own design requires carry it — mode, visual style, rendering, color, type, or icons — any of them may, and none is required to differ. A different name, note, or reference count alone is not a difference, and projections identical on every component are not three solutions. Do not force safe / shifted / bold archetypes or artificial extremes. After all three bundles are complete, choose the strongest overall fit when no template is installed; with installed template state, choose the viable direction that most strongly expresses its resolved context under [`strategist-template.md`](./strategist-template.md). Write its actual zero-based index as `design_directions.selected` (`0`, `1`, or `2`); array order never determines preference. Every direction carries a complete generated-image rendering candidate even when AI imagery is not recommended; `recommend.image_usage` independently decides whether AI is proposed. Generated images inherit deck colors—there is no second image palette. Proactive defaults are speaker notes `true`, custom animations `false`, and narration audio `false`; a prior explicit user instruction overrides the matching recommendation, and effective narration audio requires effective speaker notes. Recommend `design_spec_depth: brief` — the same author draws the pages, so full page copy in the spec is duplicated work; recommend `complete` only when `split` mode, `refine_spec: true`, or a preservation profile forces it, or the user asked for a hand-off document others will read. Author each stage once; same-stage edits update only visible browser state through documented deterministic dependencies, without another AI/backend recommendation. Launch/derive/wait mechanics live in [`generate-pptx.md`](../workflows/generate-pptx.md) Step 4; item specs keep `a`–`h`. +Stage 1 records composite intent in prose, never one catalog label; editable prose fields are drafts — confirmation keeps the current text and blanks, and a cleared field is never repopulated. Stage 2 confirms narrative spine, reading density, page budget, visual system, image direction, production mechanics, and how an installed template is used (inspecting only project-local specs and prototypes); it never chooses or installs a template. Author the three whole-deck directions under §d, then set `design_directions.selected` to the strongest fit (with an installed template, the viable direction that best expresses its resolved context under [`strategist-template.md`](./strategist-template.md)) as the actual zero-based index (`0`, `1`, or `2`); array order never determines preference. Every direction carries a rendering candidate whether or not AI is proposed; generated images inherit deck colors. Proactive defaults are notes `true`, custom animations `false`, narration `false`; an earlier explicit instruction overrides the matching recommendation, and narration requires notes. Recommend `design_spec_depth: brief` (the same author draws the pages) and `complete` only for `split`, `refine_spec: true`, a preservation profile, or a requested hand-off document. Author each stage once; launch/wait mechanics are in [`generate-pptx.md`](../workflows/generate-pptx.md) Step 4. -**Default — continuity-aware whole solution (may override when a scene reset communicates better)**: Within active-profile invariants and before recommending page count or production mechanics, judge whether adjacent explanation beats can remain within one recognizable mental map while a visible state changes. Where that choice lowers cognitive switching and motion has a named communication job, let it shape the solution's narrative spine, page rhythm, visual approach, and enabled notes/narration segmentation, and recommend the existing `proactive_custom_animations: true`. This is one positive signal, not the only reason to enable animation; absent it, retain the existing default or other valid evidence. Topic or wording repetition alone is insufficient. A `Motion suggestion` remains optional advice and never changes the effective outcome. +**Default — continuity-aware whole solution (may override when a scene reset communicates better)**: before recommending page count or production mechanics, judge whether adjacent beats can stay within one recognizable mental map while a visible state changes; where that lowers cognitive switching and motion has a named job, let it shape the spine, rhythm, visual approach, and notes/narration segmentation, and recommend `proactive_custom_animations: true`; plan such neighbors as visible states of one scene — recognizable anchors kept, the delta legible, each enabled notes/narration segment aligned with its state, every state page still carrying content and an `Audience move`; reset when the map changes or continuity adds nothing. One positive signal, not the only one; topic or wording repetition alone is insufficient, and a `Motion suggestion` never changes the effective outcome. -**Hard rule — Stage-1 source boundary**: Build the communication recommendation only from the current user request, source facts, conversation constraints, and project-initialization state. Author it before loading index summaries for a chat listing, and do not read any candidate spec, prototype, asset, or template-owned canvas. The same Stage-1 surface may display template controls, but their values are confirmation state, not recommendation evidence. Do not load or apply [`strategist-template.md`](./strategist-template.md) until Stage 1 is confirmed and the selected workspace has been installed for Stage 2. +**Hard rule — Stage-1 source boundary**: build the communication recommendation only from the current request, source facts, conversation constraints, and project-initialization state — before loading index summaries for a chat listing and without reading any candidate spec, prototype, asset, or template canvas; template controls on the same surface are confirmation state, not evidence. Load [`strategist-template.md`](./strategist-template.md) only after Stage 1 is confirmed and the selection installed. -> **Execution discipline**: Step 3 is non-interactive candidate preparation. Stage 1 is the first BLOCKING checkpoint and closes communication plus template/free-design choice in one confirmation. Its receipt is intermediate and MUST NOT end the task or produce a final chat reply. In the same active run, install/fuse any selection, complete its handoff, author fresh Stage 2, and enter the final confirmation wait. After final confirmation, proceed without another pause unless spec refinement is enabled. +> **Execution discipline**: Stage 1 is the first BLOCKING checkpoint; its receipt is intermediate and never ends the task. In the same run, install/fuse the selection, complete the handoff, author fresh Stage 2, and enter the final wait; after final confirmation proceed without another pause unless refinement is enabled — the only opt-in exception is [`refine-spec`](../workflows/stages/refine-spec.md), offered with the split-mode note and never entered unprompted. > -> **One opt-in exception**: present the refinement line with the split-mode note ([`generate-pptx.md`](../workflows/generate-pptx.md) Step 4). Only explicit opt-in runs [`refine-spec`](../workflows/stages/refine-spec.md): write the Design Spec once, pass Gate 1, then stop before the lock for unrestricted chat revision. Never enter it unprompted. +> **Presentation surface**: apply the sticky per-run surface decision in [`confirm-surface.md`](./confirm-surface.md) and author the Stage-1/Stage-2 payloads in its shapes; the chat/delegated branch keeps equivalent state without fabricating receipts. Stage 1 writes canonical BCP-47 `primary_language`; Stage 2 carries exactly three immutable `design_directions`; the final result stores only current component values, never a direction id. Server lifecycle: [`confirm_ui.md`](../scripts/docs/confirm_ui.md). -> **Default presentation surface — Confirm UI.** Before the first actual confirmation phase, apply [`confirm_ui.md`](../scripts/docs/confirm_ui.md)'s sticky per-run surface decision; its explicit chat branch skips every UI command, and a chat selection after UI launch follows its in-run switch procedure. Chat-question tools alone do not select a branch. In the UI branch, `template_options.json` and `recommendations.stage1.json` open one Stage-1 page; its single submission writes the pure Strategist `result.json` plus the sidecar `template_selection.json`. After installation/free-design closure, `template_handoff.json` gates `.stage2.json`. The chat/delegated branch keeps equivalent state without fabricating those receipts. Replace only the active unconfirmed stage and print the URL plus combined Stage-1 summary/fallback without treating that handoff as confirmation. Stage 1 writes canonical BCP-47 `primary_language` apart from UI `lang`; Strategist projects it through Design Spec §I to lock communication. Stage 2 carries exactly three immutable `design_directions`, each with a unique stable id, `custom` mode, `custom` visual style, six-role HEX palette, primary-language heading/body typography plus an English companion only for non-English decks, icons, and `custom` generated-image rendering. Its `selected` index marks the Strategist's post-comparison preference and initializes the whole bundle. An inactive direction card applies its bundle; lower controls may then diverge through the three projected custom candidates or the fixed single-select catalogs, and the adjusted active card exposes an explicit restore action. The final result stores only the current component values, never the direction id as execution authority. Step 4 retains final confirmation from the selected channel for Design Spec authoring. `confirm_ui.md` owns selection-surface and staged-confirmation lifecycle. - -**Confirmed-value semantics**: confirmation preserves both the value and the owning field's semantic type. Apply the type to the affected property, not automatically to the whole object: +**Confirmed-value semantics** — confirmation preserves the value and the owning field's semantic type, applied to that property, not the whole object: | Type | Consumption | |---|---| | Literal requirement | Preserve the exact contracted value, pixels, wording, or topology. | | Semantic requirement | Preserve facts, relationships, intent, prohibitions, and completeness; expression may change. | | Identity anchor | Keep recurring identity stable without creating an exhaustive allowlist. | -| Reference | Consider the suggested direction or role; adopt, adapt, or decline it while preserving semantic and binding requirements. | -| Permission / default | An allowed candidate/source boundary or preference; Strategist may leave it unused, with no quota. | +| Reference | A starting sketch: Executor adjusts or replaces it freely for the page's purpose, with no upstream repair or stated reason. It carries no binding semantics; label it `(binding)` only when the user, a template, or a resource contract requires that property. | +| Permission / default | An allowed candidate/source boundary or preference; may stay unused, with no quota. | -**Authority chain — materials → Strategist preparation → realization.** User inputs set materials/acquisition bounds. Strategist owns sufficiency, gap-filling, and selection: roster/content, semantic relationships, prepared resources/paths, structured-template routing references, fonts, palette anchors, the icon library/stroke plus curated project pool, and crop bans; it owns optional Chart/Table construction-reference recommendations without locking their realization. It may recommend macro composition, visual focus, and cross-page continuity as Reference, but selects no element geometry or local authoring method. Topic research and import of its two-artifact research pair may precede confirmation; facts URLs are not auto-expanded. Only after normal image search fails may one adopted webpage become a reviewable Markdown + companion-image source package, with accepted files promoted individually. Independent AI/web/slice acquisition follows final confirmation plus completed §VIII/lock; icons are synced/validated during authoring without page assignment. Before Executor, each resource has a path and terminal/`Needs-Manual` state. Locally callable native construction is an Executor capability—not a resource or planning output. Executor owns its discovery and selection plus final geometry, composition, hierarchy, spacing, treatment, and per-page choice among prepared icons; it never searches, generates, syncs, invents, or substitutes resources. Missing material/reselection returns upstream. Specificity defines freedom; a Reference may be adopted, adapted, or declined without changing a binding selection. +Explicit *must*, *only*, *exactly*, *verbatim*, *do not*, or `no-crop` wording strengthens only the named property; accepting a recommendation keeps the field's default type. -Explicit *must*, *only*, *exactly*, *verbatim*, *do not*, or `no-crop` wording may strengthen only the named property into the appropriate Literal or Semantic requirement. Accepting an AI recommendation keeps the field's default type; it does not promote a Reference or Permission into a Literal requirement. +**Authority chain — materials → Strategist preparation → realization**: user inputs bound materials and acquisition. Strategist owns sufficiency, gap-filling, and selection — roster and content, `Relationships`, prepared resources and paths, structured-template routing, fonts, palette anchors, icon library/stroke and curated pool, crop bans, and optional Chart/Table references — and sketches macro composition, focus, and continuity as Reference (binding only when labeled `(binding)`), never a carrier mix, element geometry, or authoring method. Topic research and its two-artifact pair may precede confirmation (facts URLs never auto-expanded; one adopted webpage may become a reviewable source package only after normal image search fails). AI/web/slice acquisition follows final confirmation plus §VIII/lock; icons are synced during authoring without page assignment; before Executor every resource has a path and a terminal or `Needs-Manual` state. Native construction is an Executor capability, not a resource; missing material returns upstream, never invented or substituted. -> ⛔ **GATE — final confirmation is consumed once into the Design Spec.** Use the complete final object already read by Generate Step 4 (`stage: final`, `status: confirmed`); on a chat path, use the final visible confirmation summary as the equivalent retained state. Do not reopen `result.json` during normal Design Spec or lock authoring. Consume every explicitly present field according to the semantics above and its field owner. Do not omit or substitute a value, and do not silently strengthen or weaken its type. Decide only details left unconfirmed; preserve an explicitly cleared prose field as empty. If a confirmed requirement cannot be honored, keep it visible and follow [`failure-recovery.md`](../workflows/governance/failure-recovery.md) instead of silently changing it. +⛔ **GATE — final confirmation is consumed once into the Design Spec**: use the complete final object already read by Generate Step 4 (`stage: final`, `status: confirmed`) or the chat path's final visible summary; never reopen `result.json` during Design Spec or lock authoring. Consume every present field by its semantic type and owner without omission, substitution, or silent strengthening/weakening; decide only what was left unconfirmed; keep a cleared prose field empty; an unhonorable requirement stays visible and follows [`failure-recovery.md`](../workflows/governance/failure-recovery.md). ### a. Canvas Format Confirmation -Recommend format from the current scenario and project initialization (see [`canvas-formats.md`](canvas-formats.md)). A template canvas is not Stage-1 evidence; Stage 2 later checks whether selected structure can serve the confirmed current-project canvas. +Recommend from the scenario and project initialization ([`canvas-formats.md`](canvas-formats.md)). A template canvas is not Stage-1 evidence; Stage 2 later checks whether selected structure serves the confirmed canvas. ### b. Page Count Confirmation -**Default — open `page_count` as a narrow range (may override when an exact count is supplied or locked)**: At confirmation, the recommendation should be a range rather than a single value, narrow enough for the user to judge at a glance without becoming a material decision burden. - -**Stage-2 planning input.** Confirm UI may hold an approximation/range; *exactly*, *1:1*, or preservation fixes it. After Stage 1, choose one exact count from source volume, audience outcome, delivery context/afterlife, and reading mode, then author the complete §IX roster. After Gate 1 and any enabled refine-spec approval, that roster's ids, count, and order—not the earlier UI wording—are invariant. Executor cannot add, drop, merge, split, or reorder pages; changes first repair or reconfirm the Design Spec. +**Default — open `page_count` as a narrow range (may override when an exact count is supplied or locked)**: narrow enough to judge at a glance. After Stage 1 choose one exact count from source volume, audience outcome, delivery context/afterlife, and reading mode, then author the complete §IX roster; *exactly*, *1:1*, or preservation fixes it. After Gate 1 and any refine approval, the roster's ids, count, and order are invariant — Executor never adds, drops, merges, splits, or reorders without Design Spec repair or reconfirmation. ### c. Communication Contract Confirmation -Seed the following as open-prose recommendations when the source and user request support an assessment. The user may retain, edit, or clear every editable field; the UI does not reduce the contract to a survey and does not require a non-empty answer: +Seed these as open-prose recommendations when the source and request support them; the user may retain, edit, or clear every field, and none requires a non-empty answer: | Field | Question it answers | |---|---| @@ -84,28 +69,20 @@ Seed the following as open-prose recommendations when the source and user reques | `communication_intent` | What must the presentation accomplish? It may combine several purposes and state priority or sequence. | | `audience_outcome` | What observable change means the communication succeeded — what will the audience know, understand, believe, decide, or do? | | `core_message` | Which claim(s), decision ask(s), or action(s) must land even if little else is remembered? | -| `delivery_context` | What is primary—presenter-led, reader-led, hybrid, or recorded/self-running? For hybrid, which mode leads; what secondary use, occasion, and time constraint remain? | -| `artifact_afterlife` | What must the file support afterward — review, approval, audit, archive, hand-off, reuse, or no planned afterlife? | +| `delivery_context` | What is primary — presenter-led, reader-led, hybrid (which leads), or recorded/self-running (no live presenter; narration, timing, transitions, playback)? What secondary use, occasion, and time constraint remain? One open field, never an enum. | +| `artifact_afterlife` | What must the file support afterward — review, approval, audit, archive, hand-off, reuse, or nothing? | -**Delivery-context distinction**: Keep one open-prose field. Recommend a primary context and optional secondary use: presenter-led has a live presenter; reader-led must stand alone; hybrid names which one leads and what secondary use remains; recorded/self-running has no live presenter and relies on narration, timing, transitions, and playback. The user may clear it; do not replace it with an enum or add another field. +**Communication intent is open-ended**: *inform / explain / persuade / decide / align / teach / report and account / mobilize / record and hand off* are prompts, never a checkbox list or a `primary_job`; several purposes keep their relationship in prose ("report progress and expose risk first; then obtain a decision"). The contract is not the narrative mode: intent says what change is needed, `mode` is one Stage-2 way to organize the argument. -**Communication intent is open-ended.** Use *inform / explain / persuade / decide / align / teach / report and account / mobilize / record and hand off* only as prompts that help the user articulate an answer. Never render them as a checkbox list, radio group, or required single `primary_job`. When several purposes coexist, preserve their relationship in the prose (for example, “report progress and expose risk first; then obtain a decision on the next investment”). Do not silently collapse a composite answer into one label. +**Hard rule — confirmed current value wins**: submit every Stage-1 prose field exactly as it stands at confirmation; blank means no explicit constraint (downstream judgment from source and request) and is never restored to the recommendation. A profile-declared `locked: true` field is the only read-only exception. -**Hard rule — confirmed current value wins.** Submit every Stage-1 prose field exactly as it appears when the user confirms. Blank means no explicit user constraint and may trigger downstream judgment from the source and request; keep the stored value blank and never restore the initial recommendation. A profile-declared `locked: true` field remains read-only and is the only exception. +**Reading mode** (PPT only, Stage 2): `text` (read-close) / `balanced` (business, default) / `presentation`, kept under the compatibility key `delivery_purpose` but reasoned about as information carriage — how meaning divides among page, visuals, presenter, and enabled notes — driving page grammar, granularity, density, and the §b recommendation; the §g body baseline is a consequence, not the definition. -The contract is not the narrative mode. `communication_intent` says what change is needed; `mode` is one Stage-2 strategy for organizing the argument. Several intents may share one dominant mode, and one intent may support several possible modes. +**Material divergence** (`content_divergence`): a free-text Stage-1 field the user fills in their own words — how closely the deck follows the source versus how freely it reshapes it — never a set of options and never recommended from source analysis; blank is a balanced default. Read it as a spectrum from *stay close* (track structure and wording, tune for clarity) through *balanced* (re-architect into a narrative under the locked mode, keeping all substance) to *free* (regroup, reframe, expand, connect, invent structure and transitions). **Hard rule — facts stay sourced however free the user asks**: divergence develops what is in the source and never licenses outside facts, figures, or claims — that is `topic-research`'s job; `mode` and divergence are orthogonal. Apply it only while authoring §IX and record it in `design_spec.md §I`, never in the lock; Beautify seeds and locks verbatim preservation, Edit Native PPTX does not surface it. -**Reading mode** (PPT only) is a closed Stage-2 information-carriage axis: `text` (read-close) / `balanced` (business, default) / `presentation`. Keep the existing `recommend.delivery_purpose` / `result.json.delivery_purpose` key for compatibility, but label and reason about it as reading mode—never as communication purpose. It decides how meaning is divided among the page, visuals, presenter, and, when enabled, notes, driving page grammar, granularity, density / rhythm, and the §b page-count recommendation. The §g body baseline is a downstream typography default, not the label or definition shown in the reading-mode control. +**Fact provenance contract**: when `sources/*.facts.json` exists, read it before outlining and cite its stable `fact_id` values as `Fact IDs: F001, ...` on every §IX page that uses an external quantitative or factual claim; invented demo KPIs, ratios, targets, and roadmap numbers carry `Data class: scenario` and never a `fact_id`. One page may hold both classes as long as each number's class is unambiguous. -**Material divergence** — a **free-text** source-treatment intent in the Stage-1 delivery section: in their own words, how closely the deck should follow the source vs how freely it may reshape it. This is the user's own call — a free prose field (`content_divergence`), **not** a fixed set of options and **not** something you recommend from analyzing the source. Surface the question plainly (in the confirm UI it appears after the delivery-context fields); leave it for the user to fill. Blank = a balanced default. - -Read the user's prose as a point on a spectrum and apply judgment — from *stay close* (track the source's structure and wording, tune only for clarity, no substantive add / drop) through the default *balanced* (re-architect and distill into a narrative under the locked `mode`, keeping all substance) to *free* (regroup, reframe, expand terse points, draw out connections latent in the source, invent section structure and transitions). - -**Hard rule — facts stay sourced however free the user asks.** Divergence is freedom to *develop* what is in the source (reorganize / reframe / expand / connect), never licence to invent. Even the freest request must not introduce facts, figures, or claims from outside the source material — that is the `topic-research` job, not divergence. `mode` and divergence are orthogonal (e.g. a pyramid that hews to the source's own points vs. a pyramid built from freely synthesized themes). - -**Fact provenance contract**: When `sources/*.facts.json` exists, read it before outlining and reference its stable `fact_id` values in every §IX page that uses an external quantitative or factual claim. Add `Fact IDs: F001, ...` to that page. Invented demo KPIs, internal ratios, targets, and roadmap numbers must instead carry `Data class: scenario`; never assign them an external `fact_id`. The same page may use both classes, but each number's class must remain unambiguous so Executor can place citations in notes/footnotes and visibly label scenario data. - -When authoring §IX, translate every purpose named in `communication_intent` into an outline obligation. The rows below are a reasoning checklist, not a classifier; apply every relevant row and preserve the user's stated priority / sequence: +When authoring §IX, translate every purpose named in the intent into an outline obligation (a reasoning checklist, not a classifier; preserve the user's priority and sequence): | Intent named in the prose | Outline must enable | |---|---| @@ -119,59 +96,48 @@ When authoring §IX, translate every purpose named in `communication_intent` int | Mobilize | Urgency + agency + concrete action + immediate next step | | Record and hand off | Context + decisions + status + owners + unresolved items + durable provenance | -**Material-divergence consumption — outline-authoring only.** Apply the user's stated divergence intent when authoring the `§IX` outline. Record the prose (or "balanced default") in `design_spec.md §I` (Content Strategy). Do **NOT** write it to `spec_lock.md`—it is baked into `§IX` at authoring time and the Executor never reads it. It carries no page-count coupling. Beautify seeds verbatim preservation and surfaces the field as locked/read-only; the server restores the locked value on every staged submit. Edit Native PPTX does not surface the field; it is outside this confirmation flow. - ### d. Style Objective Confirmation -**Stage 2 only.** Do not recommend or confirm any item in this section until the Stage-1 communication contract is confirmed. These are tools selected to serve the scenario, not substitutes for defining it. +**Stage 2 only** — tools that serve the confirmed scenario, never substitutes for defining it. Two independent layers, each locking one preset or `custom`; output `d. Mode: <mode> + Visual style: <visual_style>`. -Two independent layers, each locks one preset or `custom`. Output: `d. Mode: <mode> + Visual style: <visual_style>`. - -> **Top-down custom direction construction.** Author three complete solution intents from the confirmed project contract and source before selecting any catalog basis; do not assemble three apparent solutions from independent mode/style/rendering picks. The fixed planning-capability batch may already be in context, but only the three mode/style/rendering indexes act as basis selectors. Use their summaries to freeze the exact reference ids for each direction, then read once only the deduplicated union of those referenced detail files and author the final behaviors. Every direction MUST serialize `mode: custom`, `visual_style: custom`, and `image_strategy.rendering: custom`, each with visible, non-empty behavior prose. `custom` is not constrained by a catalog relationship: it may use catalog material in any way or none, including carrying one exact preset unchanged. References record only actual sources; one may carry the complete preset behavior, while several must each own a distinct executable contribution. Omit every basis whose contribution the behavior cannot state, and never add a decorative second basis. The three whole-deck directions MUST be plainly different designs before any field is written; complete each one's detail, then project that detail onto the fields. No component is the designated proof: whichever ones a direction's design requires carry the difference, any of them may, and mode, style, rendering, catalog bases, color, type, and icons are each free to coincide. A different name, note, or reference count alone is not a difference, and projections identical on every component are not three solutions. Where authoritative truth fixes some components, the remaining open ones carry it; when nothing is open, keep the projections identical and state that boundary instead of inventing a false difference. These three projections are the project-specific choices above the conservative fixed catalogs, not a fourth Custom proposal. Never glob a catalog, read an unselected sibling, or write bespoke prose as an enum value. +**Hard rule — top-down direction construction**: author three complete, project-fit solution intents from the confirmed contract and source before touching any catalog basis; the three mode/style/rendering indexes are the only basis selectors. Freeze each direction's exact reference ids from the index summaries, read once only the deduplicated union of those detail files, then write the behaviors. Every direction serializes `mode: custom`, `visual_style: custom`, and `image_strategy.rendering: custom`, each with visible non-empty behavior prose; a custom may use catalog material in any way or none — one preset carried unchanged is valid — and references record only actual sources, each owning a distinct executable contribution (never a decorative second basis). The three directions are plainly different designs *before* any field is written: whichever components a design requires carry the difference, and mode, style, rendering, bases, color, type, and icons are each free to coincide — a different name, note, or reference count alone is no difference, and identical projections are not three solutions. Where authoritative truth fixes components, the open ones carry the difference; where nothing is open, keep the projections identical and state that boundary. Never force safe / shifted / bold archetypes, glob a catalog, read an unselected sibling, or write bespoke prose as an enum value. #### Layer 1 — Communication mode -🚧 **GATE**: use the already-loaded [`modes/_index.md`](./modes/_index.md) as the sole mode-basis catalog authority. After the three direction intents exist and their mode reference ids are frozen, read only those exact sibling files once; a novel mode reads none. +🚧 **GATE**: [`modes/_index.md`](./modes/_index.md) is the sole mode-basis authority; read only the frozen sibling files once; a novel mode reads none. -The deck's **narrative + persuasion skeleton** — how the argument is organized and advanced. Lock one preset from `pyramid` / `narrative` / `instructional` / `showcase` / `briefing`, or `custom` with behavior. +The narrative + persuasion skeleton: one preset from `pyramid` / `narrative` / `instructional` / `showcase` / `briefing`, or `custom` with behavior — one value per deck, never several simultaneous modes. -**Source**: -- User supplied their own outline / structure → preserve its facts and intended relationships, then apply the confirmed `content_divergence`. Treat an ordinary source outline as a Reference: regroup, reorder, or retitle when the communication contract benefits. Treat it as authoritative only when the user presents it as the final page plan or explicitly asks to preserve page order, titles, or wording; record that promoted boundary in `design_spec.md`. Still lock a mode for register, voice, and any permitted reshaping. `briefing` imposes the least if no particular "讲法" is intended. -- Beautify / re-layout profile ([`beautify-pptx.md`](../workflows/profiles/beautify-pptx.md)) → the extracted source content is authoritative and **verbatim**, one step stricter than the user-outline case above. Each source slide becomes exactly one `§IX` page in source order; transcribe every content block word-for-word — never reshape / re-primary / condense / merge / split / reword. All three custom mode behaviors preserve that 1:1 boundary and may share `briefing` as their sole basis; do not manufacture narrative variation. Color (e) and typography (g) are whatever the user confirmed in the beautify plan — the source identity (theme or observed) by default, or a content / brand-aware alternative the beautify plan offered and the user picked — locked as truth. Charts / tables / images are regenerated from their extracted data in the inherited style: record only selected catalog references in §VII, keep unmatched chart/table plans in their §IX page blocks, and route pictures to §VIII. Data values stay frozen and the rendering is the deck's own; visuals are never carried over verbatim. Layout, hierarchy, rhythm, and visual rendering are what gets redesigned. -- Each direction crystallizes one editable cadence / posture in `mode_behavior`. It is unconstrained by its relationship to the catalog and may use catalog material in any way or none, including carrying one preset unchanged. A catalog-based direction retains only the exact ids it actually uses; a direction using no catalog material invents no basis. One deck locks one `custom` value, never several simultaneous modes. -- No user structure or cadence → derive each whole solution from the confirmed `communication_intent`, `audience_outcome`, source texture, and delivery context, then project its custom mode. Directions may share catalog bases or the same mode behavior when their complete solutions remain plainly different; never force mode variation merely to separate the bundles. +- **User outline or structure** → preserve its facts and relationships, then apply `content_divergence`; an ordinary outline is a Reference (regroup, reorder, retitle when the contract benefits) and becomes authoritative only when presented as the final page plan or with an explicit ask to keep order, titles, or wording — record that promotion in `design_spec.md`. Still lock a mode for register and voice; `briefing` imposes the least. +- **Beautify** ([`beautify-pptx.md`](../workflows/profiles/beautify-pptx.md)) → extracted content is authoritative and verbatim: one source slide = one §IX page in order, every block transcribed word-for-word, never reshaped, condensed, merged, split, or reworded; all three mode behaviors keep that boundary and may share `briefing`. Color (e) and typography (g) are whatever the beautify plan confirmed (source identity by default) locked as truth; charts, tables, and images are regenerated from extracted data in the inherited style with values frozen (catalog references in §VII, unmatched plans in §IX, pictures in §VIII). Layout, hierarchy, rhythm, and rendering are what gets redesigned. +- **No user structure** → derive each solution from `communication_intent`, `audience_outcome`, source texture, and delivery context, then project its custom mode; directions may share bases or behavior when the whole solutions differ. -Record the confirmed mode and rationale in `design_spec.md` first, including every exact catalog basis when a selected custom uses any. Then project `- mode:` to `spec_lock.md`; for `custom`, also project `- mode_behavior:` and, only when catalog material is actually used, `- mode_references: <id>[, <id> ...]`. Executor reads only those exact references; an unreferenced novel custom follows the behavior directly. +Record the mode and rationale in `design_spec.md` (with every catalog basis a custom uses), then project `- mode:` — and for custom `- mode_behavior:` plus `- mode_references:` only when catalog material is used — to `spec_lock.md`; Executor reads only those references. #### Layer 2 — Visual style -🚧 **GATE**: use the already-loaded [`visual-styles/_index.md`](./visual-styles/_index.md) as the sole style-basis catalog authority. After the three direction intents exist and their style reference ids are frozen, read only those exact sibling files once; a novel style reads none. +🚧 **GATE**: [`visual-styles/_index.md`](./visual-styles/_index.md) is the sole style-basis authority; read only the frozen sibling files once; a novel style reads none. -The deck's **visual aesthetic** — shape language, decoration density, whitespace rhythm, typographic character, texture. Anchors downstream fields e (Color), f (Icon), g (Typography), h (Image). Lock one preset from the catalog, or `custom`. +The visual aesthetic — shape language, decoration density, whitespace rhythm, typographic character, texture — anchoring e, f, g, and h. It carries no color (it governs how the HEX locked at `e` is *used*), and when the deck has AI images the style's paired rendering keeps layout and illustration in one aesthetic. -**Source**: -- User named a style (chat / template / beautify) → it is truth: retain it as the required basis or inherited anchor in every custom behavior. Derive each direction's application through the style dimensions left open. When the user or template forbids all visual variation, the three style behaviors may be identical and the remaining open components carry the direction difference; state that boundary in the direction note instead of fabricating difference. -- No user description → author three project-fit whole solutions first, then project one complete custom aesthetic for each. Write each behavior as the carriers and techniques the direction uses — containers, icons, swatches, shadows, gradients, image treatments, native shapes — never as a list of what it avoids; a prohibition appears only when the user or the material requires it, because a locked prohibition removes that tool from every page. A custom aesthetic is not constrained by its relationship to the catalog; it may use catalog material in any way or none, including carrying one fitting style unchanged. Directions may share catalog bases, and their `visual_style_behavior` values differ whenever the three designs genuinely differ in aesthetic rather than to satisfy a variation quota. Do not force different bases, a safe-to-bold ladder, or one deliberately extreme option merely to manufacture variety. Give each direction a name and note, written once in the confirmed UI language (plain keys, no locale suffixes), as a compact user-facing style summary. The note may reuse localized display labels from Confirm UI's `visual_styles` catalog (for example, `瑞士极简`, `柔和圆角`, or `编辑出版`) when they concisely describe the result, but these labels are optional vocabulary, not a selection constraint or required mapping. Use concise natural language wherever the catalog wording does not fit, and never force the nearest label. Keep the summary to one or two short sentences without exposing catalog ids or reference mechanics. The Confirm UI exposes these three project-specific styles above all 18 fixed manual alternatives. +- **User named a style** (chat, template, beautify) → it is truth: the required basis or inherited anchor in every behavior; derive each direction through the open dimensions, and when all variation is forbidden let the other components carry the difference and say so in the note. +- **No description** → project one complete custom aesthetic per solution, written as the carriers and techniques it *uses* — containers, icons, swatches, shadows, gradients, image treatments, native shapes — never as a list of avoidances (a locked prohibition removes that tool from every page; write one only when the user or material requires it). Behaviors differ when the designs genuinely differ, never to meet a quota; no forced bases, safe-to-bold ladder, or deliberate extreme. Give each direction a `name` and one- or two-sentence `note` in the confirmed UI language (plain keys); Confirm UI's localized labels such as `瑞士极简`, `柔和圆角`, `编辑出版` are optional vocabulary, never a required mapping, and the note exposes no catalog ids. -**Forbidden — a non-catalog name as `visual_style`**: every direction recommendation uses literal `custom` for `visual_style`; bespoke prose belongs only in `visual_style_behavior`, while optional `visual_style_references` contain only first-column catalog ids. A name from the `_index` "Paired rendering" column (`flat`, `vector-illustration`, `digital-dashboard`, `3d-isometric`, `corporate-photo`, …) is an image-rendering id, not a style reference. Generic words such as flat / modern / clean / simple / minimal are also insufficient behavior: use the index to choose an exact basis when applicable, then state the executable shape language, composition, density, whitespace, typography, and texture carried into this direction. Those rules may match one preset exactly; do not invent a difference merely to justify `custom`. +**Forbidden — a non-catalog name as `visual_style`**: the field is literal `custom`; prose lives in `visual_style_behavior` and `visual_style_references` holds only first-column catalog ids (a "Paired rendering" id such as `flat` or `digital-dashboard` is a rendering, not a style). Generic words — flat / modern / clean / simple / minimal — are not behavior: state the executable shape language, composition, density, whitespace, typography, and texture, which may match one preset exactly. -**Carries no color.** A visual style governs how the deck's HEX (locked at `e`) is *used* — never which colors, same discipline as [`image-renderings`](./image-renderings/_index.md). When the deck has AI images, prefer the style's paired rendering so layout and illustration share one aesthetic. +Record the style and rationale in `design_spec.md`, then project `- visual_style:` — and for custom `- visual_style_behavior:` plus `- visual_style_references:` only when catalog material is used — to `spec_lock.md`. -Record the confirmed visual style and rationale in `design_spec.md` first, including every exact catalog basis when a selected custom uses any. Then project `- visual_style:` to `spec_lock.md`; for `custom`, also project `- visual_style_behavior:` and, only when catalog material is actually used, `- visual_style_references: <id>[, <id> ...]`. Executor reads only those exact references; an unreferenced novel custom follows the behavior directly. +**Conditional template workspace**: when the Stage-1 choice is installed under `<project_path>/templates/`, read [`strategist-template.md`](./strategist-template.md) before completing Stage 2 — installed spec and prototypes only, never the library root. It owns the editable application plan, confirmed-value consumption, prototype selection, reuse/adherence derivation, inherited precedence, and structured-lock planning; it decides how to use the template, never which one. -**Conditional template workspace**: When the Stage-1 template choice has been installed into `<project_path>/templates/`, read [`strategist-template.md`](./strategist-template.md) before completing Stage 2. Read the installed project-local spec and prototypes only; never reopen the library/external source root. The module owns the editable natural-language application plan, confirmed-value consumption, AI-authored prototype selection, internal reuse/adherence derivation, inherited design precedence, and structured-lock planning. This plan decides how to use the installed template, never which template to select. Bare names, style words, and free-design projects do not trigger it. - -**Downstream effect**: e / f / g / h realize the locked mode + visual style. Example: `showcase` + `dark-tech` → e applies one luminous accent on a dark field; g pairs a clean sans with mono; f minimal glow icons; h the `digital-dashboard` rendering. +**Downstream effect**: e / f / g / h realize mode + style — e.g. `showcase` + `dark-tech` → one luminous accent on a dark field, a clean sans paired with mono, minimal glow icons, the `digital-dashboard` rendering. ### e. Color Scheme Recommendation -**Hard rule**: User-specified colors are truth. Lock supplied HEX, brand colors, or natural-language directives; templates follow inherited-design precedence. Even direct locks fill all six roles (`background`, `secondary_bg`, `primary`, `accent`, `secondary_accent`, `body_text`) in each of the three directions: repeat fixed roles and vary only open ones. Never emit an empty palette. Preserve confirmed/brand semantic roles. When writing §III, derive the standard `secondary_text` and `divider` neutrals and project them to `spec_lock.md colors`; §V fixes the five deck-wide spacing anchors. +**Hard rule**: user-specified colors are truth — lock supplied HEX, brand colors, or natural-language directives (templates follow inherited-design precedence). Every direction fills all six roles (`background`, `secondary_bg`, `primary`, `accent`, `secondary_accent`, `body_text`), repeating fixed roles and varying only open ones; never an empty palette. In §III derive the standard `secondary_text` and `divider` neutrals and project them to `spec_lock.md colors`; §V fixes the five deck-wide spacing anchors. -**Reference — not a constraint**: WCAG AA body-text contrast is 4.5:1. +**Reference — not a constraint**: no universal palette — user / brand → active template → project-specific proposal from content and style; 60-30-10 is the starting proportion, body contrast at least 4.5:1 (WCAG AA), hue count follows encoding, style, and natural assets; how color is *used* on a page (fields, gradients, accent placement, mood) is Executor's craft. `scripts/config.py` industry anchors (finance/business navy `#003366`, technology bright blue `#1565C0`, healthcare teal `#00796B`, government red `#C41E3A`) and polarity ramps (positive `#2E7D32 → #4CAF50 → #81C784`, warning `#F57C00 → #FFA726 → #FFD54F`, negative `#C62828 → #EF5350 → #E57373`) are recall aids, never default locks; brand identities come from a Brand/Deck workspace, never a memorized list. Strategist owns reusable positive / warning / negative roles; Executor derives tints, shades, alpha, gradients, and effects. -**Reference — not a constraint**: Without user/template colors, propose project-specific directions from content and style. `scripts/config.py` industry colors and dominant/support/accent hierarchy are recall aids, never default locks, ratios, or color-count quotas. - -**Lock recurring semantic anchors, not every possible paint.** Add the neutral roles already known to recur across the deck—such as `surface`, `grid`, `scrim`, `overlay`, or `block-shade`—when the visual style and page plan establish a stable meaning for them. Do not try to predict every page-local tint, gradient stop, shadow/glow color, transparency composite, or one-off illustration tone. Those values are chosen from page context during execution; promote one into `spec_lock.colors` only when it becomes a reusable named role. +**Lock recurring semantic anchors, not every paint**: add neutral roles the style and page plan give a stable meaning — `surface`, `grid`, `scrim`, `overlay`, `block-shade` — and leave page-local tints, gradient stops, shadow/glow colors, and one-off tones to execution, promoting one only when it becomes a reusable named role. | Style trait | Extra neutral tiers to lock | |---|---| @@ -181,7 +147,7 @@ Record the confirmed visual style and rationale in `design_spec.md` first, inclu ### f. Icon Usage Confirmation -The base icon style is one single-select identity, not a material whitelist: +One single-select base identity, not a material whitelist: | Option | Approach | Suitable Scenarios | |--------|----------|-------------------| @@ -190,74 +156,27 @@ The base icon style is one single-select identity, not a material whitelist: | **C** | Custom project icons | Supplied, template-carried, or imported assets | | **D** | No base icons | No shared generic base-icon identity is selected | -AI-generated illustrated icons are not a base-style option, add-on, Confirm UI -field, or result key. Like decorative lettering, they are a downstream image -carrier that §h and [`strategist-image.md`](./strategist-image.md) may choose -proactively when AI imagery is appropriate. Their transparent slices stay -under `images/`; never put them under `icons/`, add them to `icons.inventory`, -or reference them through `<use data-icon>`. +AI illustrated icons are not a base option, add-on, field, or key — like decorative lettering they are a downstream image carrier §h and [`strategist-image.md`](./strategist-image.md) may choose, with slices under `images/` (never `icons/`, `icons.inventory`, or `<use data-icon>`); they may coexist with base icons. Real brand marks are identity assets: any company, product, service, or social identity in the content may use its exact supplied or `simple-icons` mark under every base choice, with no extra option. Library inventory, prefixes, and placeholder syntax: [`../templates/icons/README.md`](../templates/icons/README.md). -Base SVG/emoji icons and illustrated-icon slices may be combined. Real brand -marks remain identity assets rather than another stylistic library. +**Mandatory — bundled SVG resources**: -The built-in icon library contains multiple stylistic libraries plus a brand-logo library: +1. At confirmation decide only the generic library and stroke. One primary stylistic library per pool (`icon_sync.py` rejects mixed batches): `chunk-filled` (fill, straight-line geometry, heavy, architectural), `tabler-filled` (fill, bezier curves, smooth, approachable), `tabler-outline` (stroke, airy, best for screen), `phosphor-duotone` (main shape + 20 % backplate, layered). A missing generic icon is replaced within the same library. `simple-icons` is never a Confirm UI choice: it holds brand marks only and may accompany any selection including `none`. This governs catalog selection, not the prepared pool — user, template, imported, custom, and previously prepared files under `<project_path>/icons/` stay valid whatever their namespace. +2. For a stroke library (currently `tabler-outline`) lock one deck-wide `stroke_width` from `{1.5, 2, 3}` (default `2`). +3. After approval, when writing §VI / the lock, materialize the curated pool before Executor starts (Executor cannot sync; which icons a page uses is realization, never a preassignment). Put known basenames in the final batch; search an uncertain one only inside the chosen library (or `simple-icons` for a brand) by the drawable object, never the abstract concept ([README § Searching for Icons](../templates/icons/README.md)); copy and validate in one batch — `python3 skills/ppt-master/scripts/icon_sync.py <project_path> <lib/name> [<lib/name> …]` — keeping each successful case-sensitive `lib/name` (bundled basenames are lowercase); record each synced path with broad scenarios in §VI and the same pool, primary library, and any `stroke_width` in `spec_lock.md icons` (`simple-icons/*` ids join the inventory without becoming a second library; other prepared icons stay usable). -See [`../templates/icons/README.md`](../templates/icons/README.md) for the current library inventory, counts, prefixes, and SVG placeholder details. - -Brand preparation applies under every base choice: a real company, product, -service, or social identity that appears in the content may use its exact -supplied or `simple-icons` mark. This requires no extra user-facing option. - -> **Mandatory rules for bundled SVG resources**: -> -> **At the Strategist confirmation stage — decide the generic base library and stroke only; resolve generic and content-driven brand filenames after approval.** -> -> 1. **One primary stylistic library per pool** (`icon_sync.py` rejects a batch that mixes them) — the four bundled choices: -> - **`chunk-filled`** — fill, straight-line geometry (M/L/H/V/Z only); sharp right angles; heavy, solid, architectural -> - **`tabler-filled`** — fill, bezier curves and arcs (C/A); smooth, rounded, organic; medium weight, approachable -> - **`tabler-outline`** — stroke (line art); airy, refined, lightweight; best for screen-only (thin strokes may be hard to read in print) -> - **`phosphor-duotone`** — duotone; main shape + 20% opacity backplate; medium weight, layered, contemporary -> - A generic icon missing from the chosen library is replaced **within that same library**. -> - **`simple-icons` is never a Confirm UI choice**: it is a brand-logo resource for real company / product / service marks (customer logos, tech-stack icons, social handles). It may accompany any base selection, including `none`, and holds no generic icons. -> - This restriction governs Strategist selection from the bundled catalog, not the prepared project asset pool. User-provided, template-carried, imported, custom, and previously prepared files under `<project_path>/icons/` remain valid material regardless of namespace or visual style. -> 2. **Stroke weight lock (stroke-style libraries only)** — for stroke-based libraries (currently `tabler-outline`), pick one deck-wide value from `{1.5, 2, 3}` (default `2`). -> -> **After the Strategist confirmation stage is approved — when writing `design_spec.md` §VI / `spec_lock.md`**, materialize a curated project icon pool: -> -> 3. A confirmed bundled library is materialized as a synced project pool before Executor starts; Executor cannot sync. Which prepared icons a page uses is realization, never a preassignment. -> 4. Put known basenames in the final batch. For an uncertain one, search the chosen style library — or `simple-icons` for a real brand mark — with `rg --files "skills/ppt-master/templates/icons/<library>" -g '*<drawable-object>*.svg'`. Abstract concept words return nothing; translate the semantic into a drawable object first, per [`../templates/icons/README.md`](../templates/icons/README.md). Do not enumerate broad keyword families. -> 5. **Copy and validate in one batch** — run `python3 skills/ppt-master/scripts/icon_sync.py <project_path> <lib/name> [<lib/name> …]`. This both validates and materializes `<project>/icons/<lib>/`; skip per-file prechecks. -> 6. Keep each successful, case-sensitive `lib/name`: bundled basenames are lowercase (`tabler-outline/award`, never `tabler-outline/Award`); custom icons retain exact case. -> 7. Record each synced bundled path with broad suitable scenarios in `design_spec.md` §VI; record the same curated pool, its primary stylistic library, and any stroke-library `stroke_width` in `spec_lock.md icons`. Keep actually needed `simple-icons/*` ids in the same inventory without treating them as a second stylistic library or user-facing selection. `inventory` indexes the synced pool; other prepared project-local icons remain usable. -> -> 🚧 **GATE — missing icon = re-pick now**: on non-zero exit, search a missing generic concept only in the chosen stylistic library, or a missing real brand mark in `simple-icons`; re-pick and rerun the final batch until clean. Never carry a missing icon forward or switch among the four stylistic libraries to fill the gap. -> -> **Default — targeted lookup only**: do not load or rebuild a full index; search only unresolved concepts. +🚧 **GATE — missing icon = re-pick now**: on non-zero exit, search the missing concept only in the chosen library (or `simple-icons` for a brand), re-pick, and rerun the final batch until clean; never carry a missing icon forward or switch libraries to fill it. Search only unresolved concepts; never load or rebuild a full index. ### g. Typography Plan Confirmation (Font + Size) -🚧 **GATE**: Apply the chosen custom behavior and only the detail files already loaded from its exact `visual_style_references`. The title carries the character; the body may remain neutral. +🚧 **GATE**: apply the chosen custom behavior and only the already-loaded `visual_style_references` files. The title carries the character; the body may stay neutral. -**Family selection**: +**Family selection**: user/template typography is authoritative — repeat fixed stacks with `typography.fixed: true` in every direction (reasonable repetition is non-blocking; no extra font round). Each direction carries `heading` / `body` `primary`, `css`, and a positive `body_size`, plus `english` only for a non-English deck. Delivery target: an explicit user/template target first, otherwise Windows Microsoft PowerPoint (owner: [`shared-standards-core.md`](./shared-standards-core.md) §4.1) — the authoring host's installed fonts never select a face; name concrete faces installed or approved on that target (the Confirm UI catalog is manual choice, not a whitelist); at most four families; a brand/web face leads only after user-confirmed installation, otherwise export a safe face and keep it as a Design Spec reference (fonts are not embedded; CSS tails are preview aids, not PowerPoint fallbacks). Avoid near-equivalent splits (YaHei↔PingFang, SimSun↔Songti, Arial↔Helvetica↔Segoe UI, Times↔Times New Roman). Fonts in one deck form contrast (different family, weight, or proportion) or concord (one family throughout); across the direction set include both a concord and a contrast pairing unless the user or template fixes the stack, and never default to title = body without a reason. -- User/template typography is authoritative. Repeat fixed stacks with `typography.fixed: true` in every direction; never vary them for diversity. Keep the three directions distinguishable as full bundles; reasonable font repetition is non-blocking, with no extra font round. -- Every Stage-2 direction carries `heading` / `body` `primary`, `css`, and positive `body_size`; add `english` only when the deck's main language is not English. -- Resolve the delivery target under [`shared-standards-core.md`](./shared-standards-core.md) §4.1, then use concrete, target-installed/approved PowerPoint faces. The Confirm UI font catalog supplies additional manual dropdown choices, not a recommendation whitelist. -- Keep stacks to four families or fewer. A brand/web face may lead only after user-confirmed target installation/approved install; PPT Master does not embed fonts. Otherwise export a safe face and keep the unavailable face as Design Spec reference. -- Avoid near-equivalent role splits such as YaHei↔PingFang, SimSun↔Songti, Arial↔Helvetica↔Segoe UI, or Times New Roman↔Times. Counterparts may aid SVG/browser preview; CSS tails are not deterministic PowerPoint fallbacks. -- Choose by locked style and vary the axis: serif×sans, Kai/FangSong×hei, hei×song, double-serif, display×neutral, same-family weight, or sans+mono. These are recall seeds, not presets. +**Reference — PPT-safe faces (recall, not a whitelist; name one concrete face per script, never a comma stack)**: CJK sans `Microsoft YaHei` / `SimHei`, CJK serif `SimSun` / `FangSong` / `KaiTi` (their macOS counterparts `PingFang SC` / `Heiti SC` / `Songti SC` are preview aliases, never the named face), Latin sans `Arial` / `Calibri` / `Segoe UI` / `Verdana` / `Trebuchet MS`, Latin serif `Times New Roman` / `Georgia` / `Cambria` / `Palatino` / `Garamond`, mono `Consolas` / `Courier New`, display `Impact` / `Arial Black`. Let the locked style's character pick the axis and lead the title — `Microsoft YaHei` / `Arial` are the neutral members, never the automatic lead; a neutral sans title where the style asks for character is the failure to avoid. Non-pre-installed directions — retro/pixel Press Start 2P / VT323, rounded Nunito / Quicksand / OPPO Sans (safe substitute `Trebuchet MS` / `Verdana`), modern web Inter / HarmonyOS Sans / Source Han, calligraphic 隶书 / 华文行楷 / 华文新魏 (safe substitute `KaiTi` / `FangSong`, titles only), brand faces — need target installation or stay Design Spec references. -**Strategist-owned role extension after confirmation**: Confirm UI keeps the heading/body choice unchanged. While authoring the complete §IX roster and §IV typography plan, scan the actual content for recurring roles that materially need a different family for character or legibility—such as `annotation`, `footer`, `footnote`, `data`, `emphasis`, `quote`, or `code`. Add a lowercase snake_case role and exact stack only when it recurs; inherited roles and one-off garnish stay omitted. The extension must remain coherent with the confirmed heading/body system and locked visual style, and it does not reopen confirmation. Only when an additional family role is added, record one compact `Role rationale` in §IV naming the added role(s) and why; otherwise omit the line. +**Role extension after confirmation**: while authoring §IX and §IV, add a lowercase snake_case role with an exact stack only for a recurring role that materially needs a different family (`annotation`, `footer`, `footnote`, `data`, `emphasis`, `quote`, `code`), coherent with the confirmed heading/body system and locked style; one-off garnish stays omitted, confirmation is not reopened, and one compact `Role rationale` line in §IV names any added role. -**Size anchors — px only**: Every authoring layer carries bare px numbers. PowerPoint's displayed pt is an export result (`px × 0.75`), never an input or confirmation value. - -**Mandatory — canvas-owned body start**: Read -[`canvas-formats.md`](canvas-formats.md) § "Typography Scale Start" before -authoring size candidates. It owns the initial body anchor and sanity band for -PPT reading modes plus registered/custom non-PPT canvases; do not reproduce or -rederive them here. The confirmed role-anchor values always win: take Confirm UI -`body_size` / `sizes` verbatim as anchors; a manually edited anchor remains -pinned, and changing canvas does not secretly rescale it. +**Size anchors — px only**: every layer carries bare px; PowerPoint pt (`px × 0.75`) is an export result. **Mandatory**: take the initial body anchor and sanity band from [`canvas-formats.md`](canvas-formats.md) § Typography Scale Start (never rederived here), and take Confirm UI `body_size` / `sizes` verbatim — a manually edited anchor stays pinned and a canvas change never rescales it. | Recurring role | Ratio to body | |---|---:| @@ -270,352 +189,157 @@ pinned, and changing canvas does not secretly rescale it. | Annotation | 0.7–0.85× | | Footnote / page number | 0.5–0.65× | -Scan §IX before locking. Declare every recurring role, including `lead`, `footnote`, and chart annotations when used; a lead is always at least body size. Give each role one deck-wide anchor and snap derived anchors to clean even px (for body 24, a sound set is title 42, subtitle 32, lead 30, annotation 18, footnote 16). Executor may vary one occurrence within that role's anchor ±2px while preserving hierarchy and readability. A short non-structural Hero/Display size planned for at most two occurrences may remain undeclared; the third planned occurrence makes it recurring and requires an explicit named slot. Structural text never uses this sparse exception. +Scan §IX before locking and declare every recurring role (`lead` at least body size; `footnote`; chart annotations when used), one deck-wide anchor each, snapped to clean even px (body 24 → title 42, subtitle 32, lead 30, annotation 18, footnote 16). Executor may vary one occurrence within ±2 px; a short non-structural Hero/Display size may stay undeclared for at most two planned occurrences, and the third requires a named slot — structural text never uses that exception. -#### Mathematical Content Planning +#### Mathematical and hyperlink content -Preserve every source-backed equation and its mathematical meaning. In each -applicable §IX page block, record the exact expression under `Mathematical -content` in the canonical form: a LaTeX body without `$...$`, `$$...$$`, -`\(...\)`, or `\[...\]` source delimiters. This field may cover any mathematics that needs exact -preservation; do not classify it as inline or structural or choose its -implementation. Never invent an equation for decoration or create a formula -policy, manifest, PNG, §VIII row, or `spec_lock.md images` entry. Executor owns -the text-versus-native-formula decision and its authoring; if the documented -Microsoft 365 input profile cannot preserve the planned content, return here for a -content-level correction. +Record every source-backed equation under `Mathematical content` in the applicable §IX block as a LaTeX body without `$…$`, `$$…$$`, `\(…\)`, or `\[…\]` delimiters — never classified as inline or block, never invented for decoration, and never a policy, manifest, PNG, §VIII row, or lock entry; Executor owns the text-versus-native decision and returns here only for a content-level correction, including when the documented Microsoft 365 input profile cannot preserve the planned content. Record every explicit or source-backed link as the linked text/object plus its exact absolute URI or 1-based same-deck slide target — never guessed, never carrier-selected, never a manifest or lock entry; Executor authors it under [`native-hyperlinks.md`](./native-hyperlinks.md). -#### Hyperlink Content Planning +### Resource Need and Reference Planning (non-blocking; no user confirmation) -Preserve every explicit or source-backed link intent. In the applicable §IX -page block, record the linked text/object and its exact absolute URI or final -1-based same-deck slide target. Never guess an external destination, select the -inline/whole-object carrier, or create a link manifest or lock entry. Executor -owns SVG authoring under [`native-hyperlinks.md`](./native-hyperlinks.md). +**Default — resource need from the roster (may stay implicit when a page's need is obvious)**: while composing the roster, decide which pages need a prepared image, lettering, or illustrated-icon resource — the jobs only a prepared file can serve — and derive §VIII rows from that need. The page's carrier mix itself (background, text, native geometry, imagery, icons, visualizations and their weights) is Executor's page decision and is never planned. Use existing fields: the icon basis and pool in §VI; an image, lettering, or illustrated-icon resource in §VIII only when the page assigns it a plausible job. Macro composition stays Reference; resource identities and explicit requirements keep their authority. -### Page Carrier and Capability Planning (Non-blocking — Strategist recommends, no user confirmation needed) - -**Default — carrier planning in §IX (may stay implicit when a page's mix is obvious)**: During the same §IX roster -composition, decide each page's semantic carrier mix—background -field, editable text and optional lettering, native-geometry/relationship jobs, -photos/scenes/illustrations/icons, and applicable visualizations—before -deriving §VIII resource rows. Decide the primary, structural, and supporting -jobs together. Use existing §VI/§VIII/§IX fields: keep the -ordinary icon basis and prepared-pool plan in §VI, and add an image, lettering, -or illustrated-icon resource to §VIII only when the page mix assigns it a -plausible job. This creates no new field or candidate inventory. Macro composition recommendations -remain Reference; planned resource identities/jobs and explicit user/template -requirements retain their existing authority. - -**Hard rule — native construction stays downstream**: record the page's -semantic relationships, prepared resource roles, and any useful macro -composition or visual-system recommendation. Do not inventory or bind a preset, -primitive, Connector, Boolean/freeform operation, coordinates, or other local -authoring method as the construction plan. A technique may appear only as -optional inspiration inside a macro Reference; Executor independently -discovers and selects construction from the actual page content and visual -system. +**Hard rule — native construction stays downstream**: record each page's `Relationships`, resource roles, and any useful macro composition or visual-system Reference; never inventory or bind a preset, primitive, Connector, Boolean/freeform operation, coordinates, or authoring method. A technique may appear only as optional inspiration inside a macro Reference. | Capability | Opportunity signal | Design Spec handoff | |---|---|---| -| Image composition | Image-as-canvas, editorial crop, collage, cutout, or meaningful focus / comparison / evidence units carry the page better than an adjacent rectangle | Propose a permitted source; when selected, apply the already-loaded [`strategist-image.md`](./strategist-image.md) resource contract and image-layout references, record a concise §VIII `Layout pattern` suggestion, and describe page-level image/overlay relationships in §IX `Layout` / `Images` | -| Composable illustration family | One or more pages benefit from coherent reusable title/corner ornaments, dominant anchors, supporting figures, compact illustrated-icon cues, or accents that can mix with text, shapes, photos, or lettering | Apply [`strategist-image.md`](./strategist-image.md): plan transparent elements by compatible family, record fixed reuse or adaptive variation in §VIII `Reference`, and describe each used page's carrier relationships in §IX `Layout` / `Images` | -| Native paint / overlay | Gradient, translucency, scrim, vignette, or wash supports focus, hierarchy, depth, legibility, or image integration | Record purpose/layering in §IX `Layout`, plus `Images` when imagery participates; no new field or type/stops/opacity/coordinates—Executor chooses realization | -| AI decorative lettering asset | Any stable display string in the deck — including a complete long or multi-line title, cover hook, chapter word, place or product name, dish or exhibit name, year, hero number, pull quote, or motif word — reads better with a material, dimensional, hand-rendered, or otherwise illustrative treatment than as ordinary text | Apply [`strategist-image.md`](./strategist-image.md): preserve every complete exact string, group compatible marks when useful, and keep chrome/body as native text. The lettering asset may carry the complete long or multi-line title as its display layer; keep an ordinary native title/subtitle in a separate text frame wherever the page needs a searchable, selectable, or outline-visible heading. Never shorten copy to make it look more like a wordmark | -| Page transition | A section/state change, spatial continuity, recorded/self-running flow, or the same semantic object changing position, scale, crop, or state across adjacent pages benefits from motion | Add an optional §IX `Motion suggestion` describing the communication job and any continuing object's initial state → action → end state; leave effect, ids, pairing names, and timing to Executor | -| Object animation | Progressive reveal, emphasis, movement, removal, or deliberate stillness clarifies sequence, causality, comparison, hierarchy, narration order, full-view → detail, atmosphere → evidence, or hotspot/annotation order | Add an optional §IX `Motion suggestion` naming each relevant semantic unit's lifecycle duty and initial state → communication action → end state, plus any meaningful order/relationship; leave group ids, effects, options, and timing to Executor | +| Image composition | Image-as-canvas, editorial crop, collage, cutout, or meaningful focus / comparison / evidence units carry the page better than an adjacent rectangle | Propose a permitted source; when selected, apply [`strategist-image.md`](./strategist-image.md), record a concise §VIII `Layout pattern` in ordinary words, and state how several images relate in §IX `Images` | +| Composable illustration family | Pages benefit from coherent reusable title/corner ornaments, dominant anchors, supporting figures, compact illustrated-icon cues, or accents mixing with text, shapes, photos, or lettering | Plan transparent elements by compatible family under `strategist-image.md`, record fixed reuse or adaptive variation in §VIII `Reference`, and describe each page's carrier relationships in §IX | +| AI decorative lettering asset | Any stable display string — a complete long or multi-line title, cover hook, chapter word, place or product name, dish or exhibit name, year, hero number, pull quote, motif word — reads better with a material, dimensional, hand-rendered, or illustrative treatment than as ordinary text | Under `strategist-image.md`: preserve every exact string, group compatible marks, keep chrome/body native; the asset may carry the complete title as its display layer while a native title/subtitle stays in a separate frame wherever a searchable, selectable, or outline-visible heading is needed; never shorten copy toward a wordmark | +| Motion | A section/state change or continuity across adjacent pages, or a reveal / emphasis / movement order within a page, clarifies sequence, causality, comparison, or hierarchy | Optional §IX `Motion suggestion`: the communication job, the units involved, and their meaningful order or initial → end state; effects, ids, options, and timing stay with Executor, and a suggestion never activates the custom stage | -**Reference — not a constraint: motion lifecycle vocabulary.** +**Mandatory — information model, not source object type**: qualitative `order` / `link` / `parent` / `membership` / `contrast` / `overlap` is written on the page's §IX `Relationships` line (its units and their source-stated relationship, or `none`; no catalog key, grammar atom, coordinate, shape, or named model — Executor decides at runtime whether geometry carries it); values, dates, or durations that determine geometry are a Chart; row header × column header facts are a Table, each compared against the complete loaded vocabulary. -| Duty | Semantic lifecycle | -|---|---| -| `enter` | absent → introduce → present | -| `emphasize` | present → redirect attention → present/altered | -| `move` | state/position A → progress → state/position B | -| `exit` | present → retire → absent | -| `static` | present → hold as reference → present | - -Use only relevant duties—no category quota. For every unit mentioned in a -`Motion suggestion`, state its duty, lifecycle, and meaningful order; never -name an effect, target id, option, or timing. Write useful advice regardless of -the effective outcome. Suggestions remain non-binding and never activate the -custom stage; only an explicit motion requirement or an enabled outcome may -require visible lifecycle-state preparation. - -Classify by information model, never source PowerPoint object type: - -| Model | Planning action | -|---|---| -| Qualitative `order`, `link`, `parent`, `membership`, `contrast`, or `overlap` | Preserve units, relationship, and reading path as free §IX prose; no catalog key | -| Values/dates/durations determine geometry | Chart; compare the complete loaded chart expression vocabulary | -| Row header × column header addresses each fact | Table; compare the complete loaded Table expression vocabulary | - -**Mandatory — relationship handoff**: keep every qualitative relationship in §IX free prose; never serialize grammar atoms, coordinates, or named models. Executor makes the per-page Structure decision at runtime. - -**Reference — Chart/Table vocabularies**: the already-loaded Chart and Table -expression vocabularies list what can be selected for a page's information -model; their descriptions do not rank candidates or replace judgment from the -actual information. Custom objects and qualitative composition stay outside -them. Retain `no-template-match` when no registered reference fits. - -**Selection**: - -1. Choose at most one flexible Chart/Table `family/key` per page; keep children and qualitative relationships in §IX. -2. If none fits, keep `no-template-match` and plan the fallback only in §IX; never serialize no-match. -3. Validate every selected canonical reference before the lock: +**Reference — Chart/Table vocabularies**: the loaded vocabularies list what can be selected; they rank nothing, and custom objects and qualitative composition stay outside them. Choose at most one flexible `family/key` per page (children and qualitative relationships stay in §IX), keep `no-template-match` in §IX when none fits (never serialized), and validate every selected reference before the lock, correcting a failed selection by re-reading the complete vocabulary/registry: ```bash python3 skills/ppt-master/scripts/visualization_recall.py validate \ <family>/<key> [<family>/<key> ...] ``` -Correct failed selections by re-reading the complete vocabulary/registry; -`no-template-match` never enters `page_visualizations`. - -**Section VII selection list**: write `Page | Family | Template | Usage` for each `chart|table` reference; Usage is semantic purpose. Omit empty/no-match detail. Qualitative composition stays in §IX; only Layout/Deck owns reusable PowerPoint structure. - -**Native-ready boundary**: Give every independent data chart and pure text-grid table in §IX `Visualization` a unique page-local semantic `kebab-case` key, then write one `Native-ready` map: `<key>=yes|no; ...`. Decide `yes` by default; use `no` only when [`native-data-interface.md`](./native-data-interface.md) §2 cannot express that object. Qualitative shape compositions and incidental microvisuals stay unlisted. - -```markdown -| Page | Family | Template | Usage | -| --- | --- | --- | --- | -| P03 | chart | line_chart | Compare the source metrics over time | -``` +Write §VII as `Page | Family | Template | Usage` for each `chart|table` reference (Usage = semantic purpose; omit no-match), e.g. `| P03 | chart | line_chart | Compare the source metrics over time |`. **Native-ready boundary**: give every independent data chart and pure text-grid table in §IX `Visualization` a unique page-local `kebab-case` key and write one `Native-ready` map `<key>=yes|no; ...` — `yes` by default, `no` only when [`native-data-interface.md`](./native-data-interface.md) §2 cannot express the object; qualitative compositions and incidental microvisuals stay unlisted. ### h. Image Source Recommendation | Source id | Approach | Use when | |---|---|---| -| `none` | No images | No image source owns a meaningful communication job for the planned deck | +| `none` | No images | No source owns a meaningful communication job | | `provided` | User-provided assets | Existing images carry factual, brand, product, or narrative authority | -| `ai` | AI-generated | Invented or deliberately stylized scenes, illustrations, backgrounds, metaphors, decorative lettering, or another generated visual treatment is needed | -| `web` | Web-sourced | Named or evidence-bearing real-world subjects that must appear as themselves, plus generic photographic mood, background, or scene jobs that benefit from sourced visual grounding | +| `ai` | AI-generated | Invented or deliberately stylized scenes, illustrations, backgrounds, metaphors, decorative lettering, or another generated treatment | +| `web` | Web-sourced | Named or evidence-bearing real-world subjects that must appear as themselves, plus generic photographic mood, background, or scene jobs | | `placeholder` | Deferred | The image is required but will be supplied later | -**Current inventory**: If `images/` is non-empty, run `python3 scripts/analyze_images.py <project_path>/images` and read `analysis/image_analysis.csv` before recommending a source. Re-run after that folder changes. +If `images/` is non-empty, run `python3 scripts/analyze_images.py <project_path>/images` and read `analysis/image_analysis.csv` before recommending (rerun after changes). -**Hard rule**: Credentials do not decide image need. Missing `IMAGE_BACKEND`, host generation, or keyed stock-provider credentials never justifies `none` or deletion of a planned web-compatible role. Web search retains zero-config providers; an explicit generation-only requirement follows the normal Offline Manual boundary. +**Hard rule — credentials never decide image need**: a missing `IMAGE_BACKEND`, host generation, or stock credential never justifies `none` or the deletion of a planned web role; do not inspect configuration or probe a provider — Generate Step 5 is the first capability check. When `ai` is included, preserve an explicit user path instruction, otherwise recommend `auto`. -**Mandatory — no AI capability preflight**: When `recommend.image_usage` includes `ai`, preserve an explicit user path instruction; otherwise recommend `auto`. Do not inspect backend configuration, check host-tool availability, or probe a provider during planning. Generate Step 5 execution is the first capability check. +**Default — visual grounding before `none` (may override when the full-roster review finds no image job)**: honor an explicit no-image requirement; otherwise, when the audience must recognize, experience, compare, or choose an externally verifiable subject, place, product, or setting, propose `provided` / `web`, and propose `ai` where invented or stylized expression materially improves a visual job. Mixed sources serve different roles; a rendering candidate resolves how imagery looks, never whether a real subject appears as itself. -**Default — visual grounding before `none` (may override when the full-roster carrier review finds no useful image job)**: Honor an explicit no-image requirement. First decide whether the audience must recognize, experience, compare, or choose an externally verifiable subject, place, product, or setting. When yes, propose `provided` / `web`; propose `ai` when invented or deliberately stylized expression materially improves a planned visual job. Mixed sources may serve different page roles. The three Stage-2 style directions never settle source: a rendering candidate resolves how imagery looks, never whether a real subject must appear as itself. +**Proactive illustrated icons and lettering**: before each Stage-2 `recommend.image_usage`, run [`strategist-image.md`](./strategist-image.md)'s illustrated-icon and decorative-lettering candidate scan over the complete roster; a selected mark may be the sole AI job and may support an `ai` recommendation in `image_notes.value`; zero is valid without explanation, and explicit no-AI or editable-only requirements win. -**Default — consider proactive illustrated icons without creating another -confirmation field**: Before each Stage-2 `recommend.image_usage`, consider -whether compact semantic jobs would communicate better through a coherent -illustrated cue family. This may support an `ai` recommendation, but it is not -an automatic source trigger or coverage quota. Resource grouping remains a -fit-driven decision under [`strategist-image.md`](./strategist-image.md). +**Recommendation output**: `recommend.image_usage` is one source id or an array (`none` exclusive). `image_notes.value` carries each source's intended jobs, authoritative assets, preferred/avoided imagery, placeholder tolerance, and — when `ai` is proposed — how generated visuals contribute, including any anticipated illustration, illustrated-icon, or lettering role: an open strategy, not an enum, allowlist, page assignment, count, or manifest. On confirmation map `ai→ai`, `web→web`, `provided→user`, `placeholder→placeholder` into §VIII `Acquire Via`. -**Mandatory — scan proactive decorative-lettering capability without making -candidates an automatic source trigger**: Before each Stage-2 -`recommend.image_usage`, scan the complete planned roster for exact stable -display strings whose artistic treatment could plausibly communicate better -than native type. Page role, character count, word count, line count, kind of -noun, and proposed style never pre-filter candidates: a complete long or -multi-line title is as eligible as a short mark. Never invent, rewrite, -shorten, or split copy to make generation easier. Passing both discovery -questions exposes one possible AI visual job, not a selected resource or a -mechanical reason to add `ai`. During page-carrier planning, compare those -candidates with native type and the complete deck mix; select only the marks -whose treatment wins that fit. Zero selected marks remains valid and needs no -skip explanation or coverage quota. A selected mark may be the sole intended -AI job and may support an AI recommendation stated in `image_notes.value`; -when either discovery answer is no, native editable text remains valid. The -absence of another AI-image job never forces lettering. Explicit no-AI or -editable-only requirements win. Execution follows -[`image-generator.md`](./image-generator.md) §7. - -**Recommendation output**: Write `recommend.image_usage` as one source id or an array for mixed sources. Put the intended communication jobs of each proposed source, authoritative assets, preferred/avoided imagery, and placeholder tolerance in `image_notes.value`. When `ai` is proposed, explain in editable natural language how generated visuals are expected to contribute and mention any materially anticipated illustration, illustrated-icon, or lettering role. Keep the note an open strategy—not an enum, carrier allowlist, page-by-page assignment, count, or resource manifest; name exact pages/assets only when already authoritative or required. `none` is exclusive. - -**Confirmed value wins**: Accept the confirmed legacy string or multi-select array. Map `ai→ai`, `web→web`, `provided→user`, and `placeholder→placeholder` into §VIII `Acquire Via`. Every direction already carries a rendering candidate whether or not AI is proposed; generated images inherit the deck colors and never introduce a second image-palette choice. - -**Always-on decision module; conditional resource extension**: - -1. Before authoring Stage-2 directions, load the workflow's complete fixed - planning-capability batch. It includes this module, the image-layout - authorities, all compact decision maps, the icon-library contract, the - complete Chart and Table expression vocabularies. After the - three whole-direction intents exist and their mode/style/rendering reference - ids are frozen, read only - those exact detail siblings once and author one complete custom rendering - inside each direction before deciding whether `recommend.image_usage` - includes AI. -2. Independently derive `recommend.image_usage` from source needs. Confirmed - non-`none` sources activate the module's resource-planning sections. - Confirmed `none` writes no image rows, but does not erase the three - recommendation-only rendering candidates or the already-loaded composition - vocabulary. - -The module owns AI rendering alternatives, acquisition paths, resource rows, prompt depth, page roles, and placement intent. +**Always-on decision module; conditional resource extension**: the fixed planning batch (this module, the decision indexes, the icon contract, the Chart/Table vocabularies) is loaded before the directions; after the three intents are frozen, [`strategist-image.md`](./strategist-image.md) authors one complete custom rendering per direction before AI is decided. `recommend.image_usage` is derived independently from source needs; a confirmed non-`none` set activates its resource-planning sections, and confirmed `none` writes no rows while keeping the rendering candidates and composition vocabulary. ### Speaker Notes Requirements -Resolve the effective Speaker Notes outcome from the latest explicit user -instruction, then final Stage 2 `proactive_speaker_notes`, then workflow default -`true`. Effective Narration Audio `enabled` requires Speaker Notes `enabled` -without changing the raw proactive preference; when that dependency changes the -notes outcome, its provenance names enabled Narration Audio. +Resolve the effective outcome as latest explicit instruction → final Stage 2 `proactive_speaker_notes` → default `true`; enabled Narration Audio requires enabled notes and names that dependency in provenance. | Effective outcome | Design Spec §X | |---|---| | `enabled` | Record filename policy, content/source handling, total duration, notes style, and presentation purpose | | `disabled` | Keep §X and write `Generation: disabled`; do not invent note requirements | -When enabled, match SVG names where possible (`01_cover.svg` → -`notes/01_cover.md`); `notes/slide01.md` remains compatible. Split files contain -no `#` heading lines; `notes/total.md` uses `#` headings. - -**Prepared final narration**: when the user explicitly marks a script as -final/literal and intends it for notes or generated audio, preserve its wording -and order. Segment it by semantic scene while resolving §IX, record its source -and verbatim policy in §X `Content`, and let Generate write the frozen -`notes/total.md` only after the final roster and lock pass their gates. Do not -copy the full script into on-slide `Content` or rewrite it as visible body text. +Note files match SVG names (`01_cover.svg` → `notes/01_cover.md`; `notes/slide01.md` stays compatible); split files carry no `#` headings while `notes/total.md` does. A user-marked final/literal script keeps its wording and order: segment it by scene while resolving §IX, record source and verbatim policy in §X `Content`, and let Generate freeze `notes/total.md` after the roster and lock pass — never copy it into on-slide `Content`. --- ## 2. Mode & Visual-Style Catalogs (Reference for Confirmation Item d) -Confirmation `d` locks two independent catalog items: - -- **Mode** — narrative skeleton: [`modes/_index.md`](./modes/_index.md) → `pyramid` / `narrative` / `instructional` / `showcase` / `briefing`. -- **Visual style** — aesthetic: [`visual-styles/_index.md`](./visual-styles/_index.md) → presets + `custom`. - -Strategist first loads the fixed planning-capability batch. For -mode/style/rendering basis selection it uses only the three corresponding -indexes, freezes the bases for the three whole directions, then reads only the -deduplicated referenced detail files before authoring their custom behaviors. -Executor reads one locked preset file or the exact references of a selected -custom; neither role globs a detail catalog (see -[`generate-pptx`](../workflows/generate-pptx.md) Step 6). +Mode: [`modes/_index.md`](./modes/_index.md) → `pyramid` / `narrative` / `instructional` / `showcase` / `briefing`. Visual style: [`visual-styles/_index.md`](./visual-styles/_index.md) → presets + `custom`. The three indexes are the only basis selectors; freeze each direction's bases from them and read only the deduplicated detail files; Executor later reads one locked preset file or a custom's exact references ([`generate-pptx`](../workflows/generate-pptx.md) Step 6). --- ## 3. Color Selection Reference -Do not start from a universal palette. Precedence is user / brand → active template → project-specific proposal; `scripts/config.py` industry anchors are optional recall. Color count and distribution follow encoding, style, and natural assets. - -Lock the stable role set the deck needs, including recurring neutrals such as `surface`, `grid`, `scrim`, `overlay`, or `block-shade`. These are identity anchors, not an exhaustive paint list. Executor may derive tints, shades, alpha, gradients, and effects, preserve necessary natural asset colors, and add sparse page-local accents for differentiation or ornament. Such accents must not form a competing/recurring palette; Strategist owns reusable positive / warning / negative roles. +Owned by §e: precedence, proportion, anchor tiers, and polarity ramps live there. --- -## 4. Layout Pattern Library +## 4. Layout Reference and Motif -**Reference — not a constraint**: use these patterns as macro recommendation vocabulary. Proportion follows information weight, not preset ratios. Recommend or combine the smallest direction that expresses the relationship; Executor may adopt, adapt, or decline it after reading the actual page content and visual system. Repeating symmetric card grids without a page job is a failure mode. +**Reference — a starting sketch, never a constraint**: a §IX `Layout` line names the macro relationship the page's content suggests (one focal claim, equal comparison, dominant evidence + takeaway, parallel sequence, core + surrounding forces, wide visual + explanation) in ordinary words; Executor owns the structure and geometry that realize it (its layout-structure vocabulary lives in [`executor-base.md`](./executor-base.md) Page Expression Core) and adjusts or replaces the line freely after reading the page. Never write element-level sizes or coordinates into §IX. -| Content relationship | Useful starting structure | -|---|---| -| One focal claim | centered single column, negative space, or full-bleed + floating text | -| Equal comparison | symmetric split or a true matrix | -| Dominant evidence + takeaway | asymmetric split with one dominant field | -| Parallel sequence | three-column, process line, or Z-pattern | -| Core + surrounding forces | center-radiating or hub-spoke | -| Wide visual + explanation | top-bottom split | - -**Reference — not a constraint**: after the complete §IX roster and planned -visual resources are known, recommend a cross-page motif or coherent element -family when it can carry identity or meaning—such as title/corner ornaments, a -directional contour, opening, line lattice, or oversized numeral. Record its -continuity job and possible reuse mode in §III `Theme`; mention it only in §IX -`Layout` blocks that benefit. Executor may adopt, adapt, or decline it and owns -its geometry and construction. Create no motif field or lock row, and impose no -decoration quota. +Once the roster and planned resources are known, recommend a cross-page motif or element family when it can carry identity or meaning — title/corner ornaments, a directional contour, an opening, a line lattice, an oversized numeral — recording its continuity job and reuse mode in §III `Theme` and mentioning it only in the §IX `Layout` blocks that benefit; Executor owns its geometry and may decline it; no motif field, lock row, or quota. --- ## 5. Template Flexibility Principle -**Reference — not a constraint**: free-design patterns are starting points, not quotas. Recommend a macro direction from the confirmed reading mode, page rhythm, and content; Executor owns exact composition and spacing within locked typography anchors. When a template workspace is active, do not reinterpret its reuse contract here; load [`strategist-template.md`](./strategist-template.md). +Free-design patterns are starting points, not quotas: recommend a macro direction from reading mode, page rhythm, and content, and leave exact composition and spacing to Executor within the locked typography anchors. An active template workspace is governed only by [`strategist-template.md`](./strategist-template.md). ## 6. Workflow & Deliverables ### 6.1 Content Planning Strategy -Content-outline strategy and, when enabled, speaker-notes strategy follow the deck's locked **mode** — see [`modes/_index.md`](./modes/_index.md), then the locked preset file or every listed custom reference plus its behavior. The guidance below applies within any mode: +Outline and, when enabled, notes strategy follow the locked mode ([`modes/_index.md`](./modes/_index.md), then the preset file or the custom's references plus behavior). Within any mode: -**Reading mode controls information carriage, not communication intent.** `result.json delivery_purpose` is retained as the compatibility key for `text` (read-close) / `balanced` (business, default) / `presentation`, confirmed with the complete deck solution in Stage 2. It decides how meaning is divided among the page, visuals, presenter, and enabled notes. The body baseline (§g) is one consequence, not the definition: +**Reading mode controls information carriage, not communication intent** — `delivery_purpose` is the compatibility key; the body baseline is a consequence: | Reading mode | Primary carrier | §IX page grammar | Granularity / rhythm | Speaker notes | |---|---|---|---|---| | `text` · read-close | page / document | complete assertions, short prose paragraphs, captions, tables, and necessary detail; bullets only for genuinely parallel or ordered items | fewer, fuller pages; leans `dense` | supplemental context, not a substitute for missing page logic | | `balanced` · business (default) | page + presenter | one primary claim with concise explanation, structured evidence, or a necessary list | moderate granularity; mixed rhythm | interpretation and transitions | -| `presentation` | presenter + visuals | one claim per page, keywords / short phrases, a large visual or hero number; no paragraph dumps or prose compressed into bullet fragments | more, sparser pages; leans `anchor` / `breathing` | carries explanation, transitions, and supporting detail | +| `presentation` | presenter + visuals | one claim per page, keywords / short phrases, a large visual or hero number; no paragraph dumps or prose compressed into fragments | more, sparser pages; leans `anchor` / `breathing` | carries explanation, transitions, and supporting detail | -When Speaker Notes is disabled, the final column is unavailable: keep every -required meaning in the visible page and confirmed presenter channel. +With notes disabled the last column is unavailable: every required meaning stays on the page or the confirmed presenter channel. Derive the initial mode from `audience`, `delivery_context`, and `artifact_afterlife`: asynchronous review, reference, approval, audit, and leave-behind lean `text`; presenter-led projection, large rooms, launches, and classrooms lean `presentation`; hybrid review / roadshow leans `balanced`, and `balanced` when live projection and durable afterlife both matter. A confirmed `presentation` supports afterlife through notes, appendix pages, captions, and visible sources rather than crowding slides. A `presentation` deck and a `text` deck from the same source and contract must differ in page grammar, count, text volume, visual burden, density, rhythm, and notes — not only in font size; page count stays the user's call. Record it as **Reading Mode** in `design_spec.md §I` (lock key `consumption_mode`); `page_rhythm` leans are a bias, not a quota; preservation paths honor it only in styling and notes. -**Recommendation signals**: derive the initial reading mode from the confirmed `audience`, `delivery_context`, and `artifact_afterlife`. Asynchronous review, reference, approval, audit, and leave-behind use lean `text`; presenter-led projection, large-room delivery, launch, or classroom explanation lean `presentation`; hybrid review / roadshow use leans `balanced`. When live projection and durable afterlife both matter, recommend `balanced` unless the contract clearly prioritizes one. If the user confirms `presentation`, support afterlife through enabled notes, appendix pages, captions, and visible sources instead of crowding every slide. - -**Default — visible-state sequence (may override when a new composition is clearer)**: Before freezing the §IX roster and enabled notes/narration boundaries, compare adjacent semantic beats within the active profile's roster/content invariants. When recurring roles, relationships, and spatial orientation form one mental map and the next beat has a meaningful state or focus change, plan neighboring pages as visible states of that scene: preserve recognizable anchors, make the semantic delta legible, and align each enabled notes/narration segment with its supporting visible state. This is a content-and-rhythm strategy, not a page quota. Reset the composition when the mental map changes or continuity adds no clarity. Within the confirmed page count, every state page must carry content and an `Audience move`; the effective motion outcome changes realization, not roster authority. - -**Per-block expression**: let the semantic relationship choose the form. Causal explanation, argument, interpretation, and narrative continuity use prose. Truly parallel, ordered, or enumerable items may use bullets / numbers. Never create bullets merely because copy is long or a template exposes a list slot. In `presentation`, distill one assertion and move its explanation into enabled notes rather than turning every sentence into a fragment; when notes are disabled, keep the necessary explanation in the visible page or confirmed presenter channel. Source texture remains a secondary cue: an article / transcript / talk leans prose, while a data sheet or inventory may lean structured labels. At `complete` depth write complete, usable phrasing into §IX; at `brief` depth write each page as a short block list — one bullet per block in the phrasing that fits it — and leave the full page copy to page authoring. Neither is a skeleton: every claim, fact, relationship, and qualifier the page must carry is present. Written wording is preferred wording unless literal preservation applies; Executor owns faithful expression adaptation under [`executor-base.md`](./executor-base.md) §2.1's content-vs-expression contract. - -This is what makes the axis meaningful: a `presentation` deck and a `text` deck built from the **same source and communication contract** must differ in page grammar, page count recommendation, per-page text volume, visual burden, layout density, rhythm, and enabled notes—not only in font size. Page count stays the user's call; reading mode informs the recommendation when the user has not fixed one. Record it as **Reading Mode** in `design_spec.md §I` (compatibility key `delivery_purpose`, lock key `consumption_mode`). Separately, `communication_intent` / `audience_outcome` determine what the outline must accomplish, while `delivery_context` and `artifact_afterlife` help select the reading mode and still remain independent constraints after selection. The `page_rhythm` leans are a bias, not a quota. Preservation paths keep source wording and structure verbatim: honor reading mode only in styling and enabled notes, never by rephrasing or re-paginating. - -> Note: §IX is the page brief at the confirmed depth; Executor retains it with the lock until context invalidation, then reloads both once. +**Per-block expression**: the semantic relationship chooses the form — prose for cause, argument, interpretation, and narrative continuity; bullets or numbers only for genuinely parallel, ordered, or enumerable items, never because copy is long or a template exposes a list slot. In `presentation`, distill one assertion and move explanation into enabled notes (or keep it on the page when notes are off). Source texture is a secondary cue. At `complete` depth write usable phrasing into §IX; at `brief` depth one bullet per block in the phrasing that fits, leaving page copy to authoring — neither is a skeleton: every claim, fact, relationship, and qualifier is present, and written wording is preferred wording unless literal preservation applies (Executor adapts under [`executor-base.md`](./executor-base.md) §2.1). §IX is the page brief at the confirmed depth; Executor retains it with the lock until context invalidation. ### 6.2 Planning Artifact Content -Generate Step 4 owns this sequence. `design_spec.md` is the complete human-readable decision; `spec_lock.md` is its context-selected execution subset/routing contract. Consume `result.json` once into the initial Design Spec and never reopen it for the lock. Refinement edits that same Design Spec; affected user revisions become the latest authority. Never treat the planning files as parallel interpretations. +Generate Step 4 owns the sequence: `design_spec.md` is the complete human-readable decision, `spec_lock.md` its context-selected execution subset; `result.json` is consumed once and never reopened; refinement edits the same Design Spec, and the files are never parallel interpretations. A later explicit notes/animation/narration instruction updates only the affected §I outcome and provenance (animation provenance is final Stage 2 `false`, explicit objects-off, or explicit all-motion-off — only the last includes transitions), after Generate's notes/audio dependency gate, without reopening Confirm UI or touching the lock. -After final confirmation, a newer explicit notes/animation/narration instruction -updates only affected §I outcomes/provenance and resumes their owner; never -reopen Confirm UI or add them to `spec_lock.md`. Before editing, apply -Generate's notes/audio dependency gate. Record animation provenance as -final Stage 2 `false`, explicit objects-off, or explicit all-motion-off; only the last -includes transitions. - -1. With Generate Step 4's retained complete final-confirmation state, read `${SKILL_DIR}/templates/design_spec_reference.md`. -2. Compose the whole Design Spec in active context before touching the target path. Create `design_spec.md` once from the schema marker through §X; do not copy a scaffold into the project or patch placeholder fields. Record production mechanics in §I, including one effective outcome plus provenance for Speaker Notes, Custom Animations, and Narration Audio. Resolve them from latest explicit user instruction → matching final Stage 2 proactive value → workflow default `enabled` / `disabled` / `disabled`; Narration Audio enabled requires Speaker Notes enabled without rewriting the raw proactive evidence, and a dependency-driven notes outcome records that provenance. In §IX, create the complete ordered roster; each entry carries title, core message, **Audience move**, content at the confirmed depth (complete preferred wording or a short block list), optional layout, exact mathematical content when applicable, capability recommendations, visualization/image references, sourced `Fact IDs`, and `Data class: scenario` for invented demo data. After Gate 1 plus conditional refine approval, roster ids/count/order and semantic content are authoritative (continuous runs may repair the roster within the confirmed range per [`executor-base.md`](./executor-base.md) §2.1); non-literal wording, block texture, layout, cover/closing composition, capability recommendations, and image/visualization patterns remain References unless promoted, so Executor may adopt, adapt, or decline them without upstream repair while preserving their semantic jobs and all binding constraints. -3. Compare `design_spec.md` against the final confirmation field by field. Repair every omission or deviation before entering an enabled refine-spec review or authoring `spec_lock.md`. -4. If enabled, run [`refine-spec`](../workflows/stages/refine-spec.md) after Gate 1; edit only that Design Spec and create no lock before explicit approval. -5. Read `${SKILL_DIR}/templates/spec_lock_reference.md`; create the lock once or resynchronize stale derived state from the approved Design Spec and context. Retain identity/refinements and stable roles/routing; omit unnamed page-local values, do not reopen evidence, and make no new recommendation. - -**Final confirmation → Design Spec consumption map**: +1. With the retained final confirmation, read `${SKILL_DIR}/templates/design_spec_reference.md`. +2. Compose the whole Design Spec in context and create `design_spec.md` once from the schema marker through §X. §I records production mechanics — one effective outcome plus provenance each for Speaker Notes, Custom Animations, and Narration Audio (latest explicit instruction → final Stage-2 proactive value → default enabled / disabled / disabled; narration enabled requires notes). §IX is the complete ordered roster: title, core message, **Audience move**, **Relationships** (the page's semantic units and their source-stated relationship, or `none`, at every depth), content at the confirmed depth, optional layout Reference, exact mathematics, capability recommendations, visualization/image references, sourced `Fact IDs`, and `Data class: scenario` for invented data. After Gate 1 and any refine approval, roster ids/count/order and semantic content are authoritative (a continuous run may repair within the confirmed range per `executor-base.md` §2.1); non-literal wording, texture, layout, cover/closing composition, capability recommendations, and image/visualization patterns stay References — starting sketches Executor adjusts freely — unless labeled `(binding)`. +3. Compare `design_spec.md` with the final confirmation field by field and repair every omission before refinement or the lock. +4. When enabled, run [`refine-spec`](../workflows/stages/refine-spec.md) on that file; no lock before explicit approval. +5. Read `${SKILL_DIR}/templates/spec_lock_reference.md` and create or resynchronize the lock once from the approved Design Spec and context — identity, refinements, stable roles and routing; no page-local values, no reopened evidence, no new recommendation. | Confirmed state | Required Design Spec realization | |---|---| -| Communication contract and `content_divergence` | §I records the confirmed contract; §IX realizes every stated purpose, outcome, priority, and source-treatment constraint | -| Canvas, reading mode, and page count | §I records the confirmed input and exact resolved count; §IX contains that many ordered pages. Executor produces exactly one output slide per entry, in order | -| Mode, visual style, palette, and generated-image rendering | §I and §III record the selected direction as identity anchors; named core roles stay stable while page-local expression remains contextual | -| Typography, including Strategist-derived recurring family overrides and every visible role size | §IV records Character/upgrade References, resolved heading/body stacks, recurring support-role stacks justified by §IX, and exact `body`, `title`, `subtitle`, and `annotation` anchors; never discard a declared role override or re-derive a confirmed anchor | -| Icons | §VI records the confirmed base library/no-icon/custom path and any content-driven `simple-icons` brand marks; illustrated-icon families are planned as AI image resources in §VIII and require no separate confirmation choice | -| Confirmed image-source set, `image_notes`, and AI strategy | §VIII uses only permitted sources and includes every explicitly required source, asset, or page role; a permitted but unused source needs no row | -| Natural-language template application | §I records it and the relevant layout/prototype choices realize it without silently dropping a requested use or exclusion | -| AI-image acquisition path, generation mode, refine-spec toggle | §I records them as production mechanics; their owning Generate stage consumes the Design Spec | -| Proactive speaker notes, custom animations, and narration audio | §I records the three resolved effective outcomes with provenance, while §X records enabled note requirements or `Generation: disabled`; they remain outside `spec_lock.md`. §IX Motion suggestions remain optional advice regardless of the animation outcome | -| Explicit final/literal narration script | §IX segments the argument by semantic scene and gives each segment a supporting visible state; §X records the source plus verbatim policy, and Generate freezes the actual segments in `notes/total.md` after Gate 2 | +| Communication contract and `content_divergence` | §I records the contract; §IX realizes every stated purpose, outcome, priority, and source-treatment constraint | +| Canvas, reading mode, and page count | §I records the confirmed input and exact resolved count; §IX contains that many ordered pages, one slide each | +| Mode, visual style, palette, and generated-image rendering | §I and §III record the selected direction as identity anchors; core roles stay stable, page-local expression contextual | +| Typography, including derived family overrides and every visible role size | §IV records Character/upgrade References, resolved heading/body stacks, recurring support-role stacks justified by §IX, and exact `body`, `title`, `subtitle`, `annotation` anchors; never drop a declared override or re-derive an anchor | +| Icons | §VI records the confirmed base library / no-icon / custom path and content-driven `simple-icons` marks; illustrated-icon families are §VIII AI resources | +| Confirmed image-source set, `image_notes`, AI strategy | §VIII uses only permitted sources and includes every explicitly required source, asset, or page role; an unused permitted source needs no row | +| Natural-language template application | §I records it; layout/prototype choices realize it without dropping a requested use or exclusion | +| AI-image path, generation mode, refine-spec toggle | §I records them as production mechanics for their owning stage | +| Proactive notes, animations, narration | §I records the three effective outcomes with provenance; §X records note requirements or `Generation: disabled`; none enters the lock; §IX Motion suggestions stay advice | +| Explicit final/literal narration script | §IX segments by scene with a supporting visible state each; §X records source and verbatim policy; Generate freezes `notes/total.md` after Gate 2 | -⛔ **GATE 1 — active-decision fidelity.** Do not create `spec_lock.md` until the initial Design Spec passes the comparison above and any enabled refinement is explicitly approved. Before Gate 2, every requested revision must be present and every unaffected decision intact. Missing/substituted values, unapplied revisions, or silently changed semantic types block despite schema validity; bounded Reference adaptation and unused Permission remain valid. +⛔ **GATE 1 — active-decision fidelity**: no lock until the Design Spec passes that comparison and any refinement is approved; missing or substituted values, unapplied revisions, or silently changed semantic types block despite schema validity, while bounded Reference adaptation and unused Permission remain valid. -⛔ **GATE 2 — lock context fidelity.** After Gate 1 closes, author machine-relevant anchors/routing into `spec_lock.md`. The lock may normalize syntax and add justified recurring roles, but must not change identity, discard a refinement, introduce a direction, or become a field copy/allowlist. On contradiction, return to Gate 1 using retained confirmation by default or the approved revised Design Spec after refinement; fresh recovery reads persisted final evidence once only when active state is absent. +⛔ **GATE 2 — lock context fidelity**: the lock may normalize syntax and add justified recurring roles but never changes identity, discards a refinement, introduces a direction, or becomes a field copy or allowlist; on contradiction return to Gate 1 (fresh recovery reads persisted final evidence once only when active state is absent). -**Execution lock content**: `spec_lock.md` compactly carries communication, stable color/type anchors, icons, images, page rhythm, Chart/Table references, and route-specific PowerPoint structure; qualitative relationships stay only in §IX. Name every recurring typography role; a planned short non-structural Hero/Display size may stay omitted only while the same value appears at most twice, and its third occurrence requires a named role. Never re-derive a confirmed anchor. New locks keep `font_family` as the body/default compatibility stack and also write explicit `title_family` + `body_family`; every additional recurring Design Spec role projects to `<role>_family`. Collapsing distinct Design Spec stacks into `font_family`, or dropping an extra role, fails Gate 2. Keep core fonts/palette roles stable; page authoring varies treatment and may add sparse local garnish. Project every placed §VIII image's source, layout suggestion, and crop policy; omit unplaced sheets and planning provenance. Free-design, brand-only, and `template_reuse_scope: style` use `pptx_structure.mode: flat`; the template module owns structured mappings. Executor context policy lives in [executor-base.md](executor-base.md) §2.1. Repair from Gate 2's active decision authority, then re-author affected lock rows. +**Execution lock content**: `spec_lock.md` carries communication, stable color/type anchors, icons, images, page rhythm, Chart/Table references, and route-specific structure; qualitative relationships stay in §IX. Grammar — section set, typography projection (`title_family` + `body_family` + every `<role>_family` and size anchor), `page_visualizations`, flat/structured `pptx_structure` — is [`spec_lock_reference.md`](../templates/spec_lock_reference.md) §2–4; never re-derive a confirmed anchor, collapse distinct stacks into `font_family`, or drop a recurring role. Derived paint and sparse local garnish may stay in one SVG; new base colors, structural fonts, resources, or recurring identity patterns require upstream repair, and Executor never reverse-projects a local choice as planning fact. **Hard rule — a lock prohibition is the user's**: `forbidden` takes the technical baseline plus prohibitions the user stated in their own words, each quoted verbatim and tagged `(user)` ([`spec_lock_reference.md`](../templates/spec_lock_reference.md) §2); a confirmed direction's behavior stays identity prose and is never projected into a prohibition. -**Contextual extension**: derived paint or sparse local font/color garnish may stay in one SVG while non-structural and non-recurring. New base/semantic colors, structural/recurring fonts, resources, or recurring cross-page identity patterns require upstream repair; a page-local §VIII preferred image pattern follows [`executor-image.md`](./executor-image.md) and may change during realization. Executor never reverse-projects a local choice as planning fact. Promote recurring garnish upstream before reuse, read back and validate the affected planning fragments, and never add values to silence a comparison. - - - **Communication trace is mandatory**: Keep the full confirmed communication contract in `design_spec.md §I`, then project only `audience`, `objective`, `core_message`, and canonical `consumption_mode` into `spec_lock.md communication`. Write `objective` as one concise execution sentence that preserves both the confirmed `communication_intent` and the success condition in `audience_outcome`; do not copy `delivery_context`, `artifact_afterlife`, dates, provenance, or conflict-resolution commentary into the lock. Before finalizing §IX, check that every named purpose has at least one outline obligation and **every Slide block**, including cover / divider / closing pages, has an `Audience move` that advances the global outcome. A page that advances no purpose or outcome should be merged, rewritten, or cut. `project_manager.py validate` and `svg_quality_checker.py` enforce the compact lock fields and per-page move presence, not their subjective quality. - - **Custom behavior is concise and executable**: For confirmed `custom` mode or visual style, project one resolved `mode_behavior` / `visual_style_behavior` sentence or short paragraph. When the direction actually uses catalog entries, also project the exact, comma-separated `mode_references` / `visual_style_references`; omit the field when it uses none and never fabricate a nearby reference. Preserve the confirmed direction, reference locked role names such as `colors.primary` when needed, and omit selection history, contradictions, precedence explanations, or other Design Spec provenance. Executor reads these fields from the retained lock and loads every referenced catalog entry once per valid context. - - **page_rhythm is mandatory**: Based on the page list in §IX Content Outline, assign each page one of `anchor` / `dense` / `breathing`. This is what breaks the uniform "every page is a card grid" feel. New locks may not omit the section; consumer omission behavior is owned by [`executor-base.md`](executor-base.md) §2.1. - - **Fact IDs and scenario labels are mandatory when applicable**: Read any `sources/*.facts.json`. For each §IX page, list the stable IDs actually used; never cite an ID whose claim is absent from the page. Mark invented KPIs/targets/internal ratios as `Data class: scenario` and state which values are scenario data. Executor carries external sources into notes/footnotes and renders a visible scenario label for scenario figures. - - **Mandatory — whole-roster rhythm check**: During the same §IX composition, compare neighbors and section arcs to judge whether chapter entries visibly reset, extended same-density runs are intentional, extended same-carrier or same-topology runs form an intentional semantic sub-arc, repeated dominant geometry carries a continuity job, any qualifying §6.1 visible-state sequence preserves a recognizable mental map while making its next semantic change legible, each section follows a mode-fitting progression—including framework → explanation/evidence → judgment/action when it serves the objective—and the final arc resolves the communication objective before a genuine ending lowers information load. Same section, equal weight or density, one style, and prior-page precedent do not establish a semantic sub-arc. Repair the existing roster, `Layout` recommendations, and `page_rhythm` choices in place. This is judgment, not quota; preserve intentional continuity, legitimately all-`dense` material, and 1:1/literal order. Do not invent filler pages to manufacture rhythm; a `breathing` page marks a meaningful pause—chapter transition, standalone emphasis, or SCQA bridge—and must stand alone. Create no field, lock row, artifact, or second review/execution pass. - - **Cover impact is mandatory**: In `design_spec.md §IX`, give `P01` one concrete hook from the source's strongest claim, metaphor, number, moment, or conflict plus a recommended composition. **Reference — not a constraint**: composition starting points include full-bleed image with floating title, typographic poster, hero object, data hook, editorial scene, and high-contrast abstract geometry; a fresh composition the subject suggests is equally valid — these are starting points rather than the allowed set. A distilled display phrase taken from the deck's own subject may carry the cover as the dominant mark while the complete title stays as a native subtitle. The hook binds; Executor may adopt, adapt, or decline the composition while preserving the hook and explicit constraints. With no suitable image, recommend a native-SVG hook instead of a generic title treatment. Beautify preservation paths are exempt. - - **Cover rhythm lock**: `P01` remains `anchor`. Default away from generic content-page templates; a card grid, agenda, or equal-weight columns remains valid when content, user direction, or the template makes it the clearest cover. - - **Closing impact (only when the deck closes)**: For a genuine conclusion / CTA / final takeaway, name the binding takeaway plus a recommended composition; Executor may adopt, adapt, or decline the latter while preserving the takeaway and explicit constraints. Do not default to an information-empty "Thank you", contact-only slide, or cover reprise; an explicit contact/event CTA may serve the purpose. **Do NOT invent a closing page to satisfy this**. Preservation paths are exempt. - - **pptx_structure is mandatory**: Free-design, brand-only, and `template_reuse_scope: style` routes write `mode: flat`; a style-reference route may also record `template_reuse_scope: style` but omits every structure mapping and `template_adherence`. `template_reuse_scope: mirror|layout` writes `mode: structured` plus `template_adherence: strict|adaptive`. Do not write legacy `baseline`, `template`, `preserve`, `layout_strategy`, or Layout-kind rows into a new project. - - **Flat-route boundary**: With `mode: flat`, omit `pptx_masters`, `pptx_layouts`, `page_pptx_layouts`, and `page_layouts`. Do not plan native Master/Layout families or reusable placeholder slots. Every generated SVG object remains Slide-local: omit root Master/Layout identity, `data-pptx-layer`, and `data-pptx-placeholder*` metadata. Export materializes one clean project-owned Master plus one Blank Layout from the current color/typography lock, removes stock content placeholders/Layout inventory, and retains only the standard date/footer/slide-number capability hooks. - - **Structured template route**: When [`strategist-template.md`](./strategist-template.md) is active and reuse is `mirror|layout`, follow its complete Master/Layout/slot/prototype mapping rules. - - **page_visualizations**: project at most one §VII `P<NN>: <chart|table>/<key>` per page. Usage/children/qualitative relationships stay in the Design Spec; omit empty/no-match. It locks no geometry/native output. New locks never write legacy `page_charts`. +- **Communication trace is mandatory**: keep the full contract in §I and project only `audience`, `objective` (one execution sentence preserving intent and the `audience_outcome` success condition), `core_message`, and `consumption_mode` into `spec_lock.md communication`. Before finalizing §IX, every named purpose has an outline obligation and every Slide block — cover, divider, closing included — has an `Audience move`; a page that advances nothing is merged, rewritten, or cut. Tools enforce presence, not quality. +- **Custom behavior is concise and executable**: one resolved `mode_behavior` / `visual_style_behavior` sentence or short paragraph plus exact `*_references` only when catalog entries are used; no selection history. +- **page_rhythm is mandatory**: one of `anchor` / `dense` / `breathing` per §IX page — what breaks the uniform card-grid feel; consumer omission behavior is `executor-base.md` §2.1's. +- **Fact IDs and scenario labels**: list the stable IDs actually used per page, never one whose claim is absent; mark invented KPIs, targets, and ratios `Data class: scenario` and say which values they are. +- **Mandatory — whole-roster rhythm check**: while composing §IX, compare neighbors and section arcs — chapter entries visibly reset; same-density, same-resource, or same-relationship runs are intentional sub-arcs; a repeated motif carries a continuity job; any visible-state sequence keeps a recognizable map while its next change is legible; each section follows a mode-fitting progression (including framework → explanation/evidence → judgment/action when it serves); the final arc resolves the objective before a genuine ending lowers load. Same section, equal density, one style, and precedent establish no sub-arc. Repair roster, `Layout`, and `page_rhythm` in place; preserve intentional continuity, legitimately all-`dense` material, and 1:1 order; add no filler — a `breathing` page marks a real pause and must stand alone. No field, lock row, artifact, or second pass. +- **Cover impact is mandatory**: give `P01` one concrete hook from the source's strongest claim, metaphor, number, moment, or conflict plus one optional composition Reference in ordinary words (a distilled display phrase may carry the cover while the complete title stays a native subtitle; with no suitable image, a native-SVG hook). The hook binds; the composition is a Reference. `P01` stays `anchor`, defaulting away from generic content-page templates unless content, user, or template makes a card grid, agenda, or equal-weight columns the clearest cover. Beautify preservation is exempt. +- **Closing impact (only when the deck closes)**: for a genuine conclusion, CTA, or final takeaway, name the binding takeaway plus a recommended composition; never an information-empty "Thank you", contact-only slide, or cover reprise (an explicit contact/event CTA may serve), and never an invented closing page. Preservation is exempt. +- **pptx_structure and page_visualizations**: free-design, brand-only, and `template_reuse_scope: style` write `mode: flat` and omit every structured mapping section; `mirror|layout` writes `mode: structured` with `template_adherence` and the four mapping sections under [`strategist-template.md`](./strategist-template.md). Project at most one §VII `P<NN>: <chart|table>/<key>` per page; grammar in [`spec_lock_reference.md`](../templates/spec_lock_reference.md) §3–4. --- ## 7. Project Boundary -The Generate route owns project initialization and supplies `<project_path>`. Strategist writes only the two complete planning artifacts at that root plus the explicitly triggered resource manifests; it does not choose or create another project path. - ---- +Generate owns project initialization and supplies `<project_path>`; Strategist writes only the two planning artifacts at that root plus explicitly triggered resource manifests. ## 8. Handoff -After validation, return to the Generate Step 4 checkpoint. The route—not this role—owns whether Step 5 runs and how execution resumes or auto-proceeds. +After validation, return to the Generate Step 4 checkpoint; the route owns whether Step 5 runs and how execution proceeds. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/svg-effects.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/svg-effects.md index 4e56de99..a54b8c9e 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/svg-effects.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/svg-effects.md @@ -2,14 +2,14 @@ # SVG Effects and Geometry Specification -Authority for advanced paint, effects, transforms, freeform/radial geometry, and constructed visual styles. Default and Quick Generate load it before SVG authoring; other SVG-authoring routes follow their workflow trigger. +Authority for advanced paint, effects, transforms, freeform/radial geometry, and constructed visual styles. Default and Quick Generate load it on the executor-base routing trigger — the first page whose visual job reaches beyond the everyday block — and keep it for the rest of the run; other SVG-authoring routes follow their workflow trigger. It keeps the form the model writes and the design decisions behind each technique; the complete grammar the checker and exporter enforce for §6.2–§6.10 is in [`svg-contract.md`](../scripts/docs/svg-contract.md) Part II under the same section numbers; §6.1 and §6.11–§6.13 are design guidance with no separate contract. **Cross-reference map**: unqualified §1, §2, and §4 references point to [`shared-standards-core.md`](./shared-standards-core.md); §6 references are local to this file. ## 6. Advanced SVG Effects and Authoring Techniques -**Mandatory**: Default and Quick Generate read this file completely before SVG -authoring and keep its compatible techniques in active construction vocabulary. +**Mandatory**: once triggered, read this file completely before that page's +first SVG line and keep its compatible techniques in active construction vocabulary. Before finalizing each page, run the §6.1 selection procedure, with the Visual Job Router as recall for the jobs it diagnoses. Use §6.13 when diagnosed jobs benefit from one coordinated page recipe. @@ -53,13 +53,11 @@ simplify any competing scaffold without a separate communication job. #### Visual Job Router **Reference — not a quota**: recall candidates for a diagnosed problem from -this table. A -page may use no listed technique, one technique, or several techniques with -different jobs. The table recalls constructions rather than bounding them: one -it never names is equally valid when it satisfies every applicable technical -contract — the shared core's closed authoring surface, this file, the route's -other required construction references, and any triggered module. Those -contracts are the boundary; membership in this table is not. +this table. A page may use no listed technique, one technique, or several +techniques with different jobs. The table recalls constructions rather than +bounding them: one it never names is equally valid when it satisfies every +applicable technical contract. Those contracts are the boundary; membership in +this table is not. | Diagnosed visual problem | Candidate technique | Authority / stop | |---|---|---| @@ -89,7 +87,7 @@ modifier or prepared-asset treatments, resolve its implementation here. | `M3 · 01/02/05` · frame, print frame, contour/cut edge | Registered native stroke/path; §6.6 | | `M3 · 03; M1 · 09` · rotation, misregistration, Riso offset | Transform + explicit duplicate layers; §6.8 / §6.11 | | `M1 · 03` + effect-only forms · paper cut, facets/folds, ribbon, staging | Ordered paths/facets + consistent paint/light; §6.11 / [`native-shape-authoring.md`](./native-shape-authoring.md) §7 | -| `M1 · 01/02/04–08` · crop, opening, subtraction, reveal | Direct clip or materialized Boolean; no `<mask>`; [`shared-standards-core.md`](./shared-standards-core.md) §1.2 / [`native-shape-authoring.md`](./native-shape-authoring.md) §6 | +| `M1 · 01/02/04–08` · crop, opening, subtraction, reveal | Direct clip or materialized Boolean; no `<mask>`; §1.2 / [`native-shape-authoring.md`](./native-shape-authoring.md) §6 | | Effect-only · faux glass | Visible field + translucent panel + highlight; no blur or frosted-crop substitution; §6.5 | | `A1 · 02–04; A3 · 02/03` · blur, duotone, blend, frost, desaturation | Prepared local bitmap/composite/derivative; registered frost is a blurred derivative; §6.12 | @@ -97,122 +95,41 @@ modifier or prepared-asset treatments, resolve its implementation here. generated pages choose paint from the Default locked or Quick-resolved identity anchors, visual style, content semantics, and current composition. A contextual tint, gradient stop, shadow/glow paint, or one-off display color need not -already be a persistent identity role; -promote it only when it becomes a recurring named role. Fidelity labels are defined -in [`shared-standards-core.md`](./shared-standards-core.md). Review an `Approximate` result in native PPTX -when the effect carries material meaning. +already be a persistent identity role; promote it only when it becomes a +recurring named role. Review an `Approximate` result in native PPTX when the +effect carries material meaning. --- ### 6.2 Color, Alpha, and Opacity -Compatible paint grammar includes recognized named colors, `rgb()` / `rgba()`, -`hsl()` / `hsla()`, and `#RGB` / `#RGBA` / `#RRGGBB` / `#RRGGBBAA`. The -converter also tolerates legacy bare 3/4/6/8-digit hexadecimal tokens. The -shared converter implementation for §§6.2–6.8 is -[`utils.py`](../scripts/svg_to_pptx/drawingml/utils.py). +Write solid paint as uppercase `#RRGGBB`, `none`, or an exact local `url(#id)`. +Put alpha on the channel that owns it — `fill-opacity`, `stroke-opacity`, +`stop-opacity`, or `flood-opacity` as a unitless `0..1` — and use element +`opacity` only for an `<image>` or one non-group atomic object that fades all +of its channels together. Do not use element `opacity` as an alias for +`rgba()` on a fill-only object, and prefer descendant alpha over group opacity +(§2.2). Alpha multiplies down the tree: color alpha × ancestor group opacity × +element opacity × channel opacity. Named colors, short/alpha HEX, `rgb()` / +`hsl()`, and percentages remain compatible input that the checker only +recommends normalizing. -**Default — canonical generated paint tokens (may preserve compatible -alternatives)**: New `svg_output/` and reusable template SVGs write solid paint -as uppercase six-digit `#RRGGBB`. `fill` / `stroke` may instead use lowercase -`none` or the exact local reference form `url(#id)`. Named colors, lowercase or -short/alpha HEX, functional colors, and bare legacy HEX remain supported input. -The quality checker prints an optional canonical rewrite as a recommendation -warning; it does not require modification or block export. -Explicit empty, malformed, or unrecognized paint values are errors in both -Checker and exporter preflight; neither converts unknown intent into -`noFill` or default black. Omitted properties still follow their own element -contract, such as SVG's default fill or §6.3's required gradient-stop color. - -| Intent | Canonical authoring | Native result / fidelity | -|---|---|---| -| Solid fill or text paint | `fill="#RRGGBB"` | Solid DrawingML paint; `Native-stable` | -| Fill/text alpha | Opaque `fill` + `fill-opacity="0..1"` | Fill/run alpha; `Native-stable` | -| Stroke alpha | Opaque `stroke` + `stroke-opacity="0..1"` | Line/outline alpha; `Native-stable` | -| Gradient-stop alpha | Opaque `stop-color` + `stop-opacity="0..1"` | Per-stop alpha; `Native-stable` | -| Shadow/glow alpha | Opaque `flood-color` + `flood-opacity="0..1"` | Glow is `Native-stable`; outer shadow is visually calibrated `Approximate` within §6.4 | -| Picture fade | `<image opacity="0..1">` | Picture `<a:alphaModFix>`; `Native-stable` | -| One atomic whole-object fade | Non-group element `opacity="0..1"` | Alpha compiled into its supported paint/effect channels; `Native-normalized` | -| Pattern alpha | Opaque pattern child paint + child fill/stroke opacity | Conditional; [`native-data-interface.md`](./native-data-interface.md) | -| CSS color alpha | Alpha-bearing named/functional/HEX paint | `Native-normalized`; recommendation warning only | -| Group fade | `<g opacity>` compatibility | `Approximate`; fidelity warning; §2.2 | - -```text -effective fill alpha -= color alpha × ancestor group opacity × element opacity × fill-opacity -``` - -**Default — opaque color authority (may preserve compatible alpha colors)**: -New generated SVG puts alpha on the semantic channel that owns it. Existing or -intentional alpha-bearing color tokens remain convertible; they normalize into -the matching DrawingML color/alpha channels. - -**Default — channel-specific alpha (may override for one atomic whole-object -fade)**: use `fill-opacity`, `stroke-opacity`, `stop-opacity`, or -`flood-opacity` when only that channel fades. Use element `opacity` only when -an image or one non-group atomic object intentionally fades all of its -supported paint/effect channels together. Do not use element `opacity` as an -alias for `rgba()` on a fill-only object. - -**Default — alpha grammar (may preserve compatible alternatives)**: write -`opacity`, `fill-opacity`, `stroke-opacity`, `stop-opacity`, and -`flood-opacity` as finite unitless numbers from `0` to `1`. The converter also -accepts finite numeric values that SVG/CSS clamps into that interval; -`stop-opacity` and `flood-opacity` additionally accept finite percentages. The -checker reports those supported non-default spellings as recommendation warnings. -Malformed or non-finite values are errors in both Checker and exporter -preflight; neither substitutes an opaque default for unknown intent. -`fill="transparent"` / `stroke="transparent"` become no fill/line; use a color -plus alpha when a painted transparent layer must remain represented. Prefer -descendant alpha over group opacity when isolated compositing matters (§2.2). - -PPTX import is a user-input boundary, not generated authoring. Tolerant mode -retains recognized color semantics, omits only unsupported paint properties, -and records the decision in `conversion-report.json`; `--strict` keeps the -closed parser checks. See -[`conversion.md`](../scripts/docs/conversion.md#import-compatibility-and-recovery-boundary). --- ### 6.3 Gradients and Paint Effects -| Concern | Contract | -|---|---| -| Definition | Direct `<linearGradient>` / `<radialGradient>` child of `<defs>` with unique `id` | -| Reference | Exact local `url(#id)` | -| Stops | ≥2 direct `<stop>` children; explicit color; finite non-decreasing offset in `0..1` or `0%..100%` (ties form hard edges); optional alpha | -| Coordinates | `objectBoundingBox` only. Generated values: `0..1`; omitted linear axis = `(0,0) → (1,0)`. Only import-normalized linear projections may reach `-0.105..1.105`; radial values stay in `0..1`, and their effective focus must lie inside the circle centered at `(0.5,0.5)` with radius `0.5` | -| Forbidden | External/quoted refs, `href` inheritance, `gradientTransform`, `spreadMethod`, CSS gradients | - -| Target | Contract and fidelity | -|---|---| -| `<rect>`, `<circle>`, `<ellipse>`, `<path>`, `<polygon>` fill/stroke | Linear `Native-normalized`; radial `Approximate` | -| `<line>` / `<polyline>` | Gradient stroke only; linear `Native-normalized`, radial `Approximate` | -| `<text>` / non-positional `<tspan>` | Gradient fill only; no gradient text outline | -| `<image>` | No gradient paint; use §6.5 overlays | - -Linear export preserves stops/alpha and reduces direction to an angle; -coincident endpoints are invalid. Radial export preserves the effective focus -(`fx/fy`, otherwise `cx/cy`) as a point-focused circle; its outer center and -radius normalize to `0.5`, so distinct outer `cx/cy` and `r` are dropped. A -focus outside that canonical circle is invalid because SVG renderers clamp it -to the circumference while DrawingML retains the rectangle coordinates; -reverse import centers such a source focus and records a diagnostic. -Gradient strokes stay editable; -reverse import may keep the first stop only. Stop alpha multiplies element opacity. -PPTX import normalizes gradients and reports degradation; -`--strict` keeps the closed parser contract. See -[`conversion.md`](../scripts/docs/conversion.md#import-compatibility-and-recovery-boundary). -Checker/exporter preflight share this validation. -Gradient-stop colors are contextual paint values. Keep them coherent with the -deck anchors and page intent; they are not required to duplicate existing -Default `spec_lock.colors` literals or Quick-resolved anchors. - -**Hard rule — non-degenerate gradient geometry**: an `objectBoundingBox` -gradient stroke requires non-zero intrinsic width and height. SVG stroke width -does not expand that object bounding box, so a perfectly horizontal or vertical -gradient ribbon disappears even when its stroke is thick. Author such a ribbon -as a closed shape with gradient `fill`, or use a path whose intrinsic geometry -has both dimensions. Checker and exporter reject the degenerate stroke form. +A gradient is a direct `<linearGradient>` / `<radialGradient>` in `<defs>` with +≥2 explicit-color stops at non-decreasing `0..1` offsets, referenced by exact +`url(#id)`, in `objectBoundingBox` units — no `gradientTransform`, +`spreadMethod`, or CSS gradients. Linear exports as an angle +(`Native-normalized`); radial keeps only its focus point and normalizes the +outer circle to the object (`Approximate`), so place the hotspot with `fx/fy` +inside the object and expect the rim to differ. Text takes gradient fill only; +images take no gradient paint (use §6.5 overlays). A gradient *stroke* needs a +path with both width and height — a perfectly horizontal or vertical gradient +ribbon disappears, so author it as a closed gradient-filled band. Stop colors +are contextual paint: keep them coherent with the deck anchors and page +intent without duplicating a lock row. ```xml <defs> @@ -225,23 +142,12 @@ has both dimensions. Checker and exporter reject the degenerate stroke form. stroke="url(#flow)" stroke-width="12"/> ``` -**Native text picture/texture fill**: - -| Concern | Contract | -|---|---| -| Target | Direct `fill="url(#id)"` on `<text>` or a non-positional `<tspan>`; the text remains editable | -| Definition | Direct `<pattern>` child of `<defs>` with unique `id` and exact `data-pptx-text-image-fill="stretch"` or `"tile"` | -| Image | Exactly one direct SVG-namespace `<image>` child; project-local or data-URI source; explicit positive `width` / `height` | -| Native result | `stretch` → run-level `a:blipFill/a:stretch`; `tile` → run-level `a:blipFill/a:tile` | -| Alpha | Text `fill-opacity` multiplies the native picture-fill alpha | -| Forbidden | Preset-pattern attributes; `patternTransform`; additional pattern children; image style/alpha/clip/filter/mask/transform; use outside text; unannotated custom image patterns; multi-image/layer knockout composites | - -Use this registered pattern when the design calls for a photograph, material, -or texture inside editable glyphs. The pattern is an authoring carrier for a -PowerPoint run picture fill, not a general SVG pattern promise. PowerPoint owns -the final run bounding box: `stretch` is `Native-normalized`, while `tile` may -normalize tile scale or phase and needs visual review. Forward SVG→PPTX export -is native; PPTX→SVG does not reconstruct run-level picture fills yet. +**Native text picture/texture fill**: when the design calls for a photograph, +material, or texture inside editable glyphs, fill the `<text>` (or a +non-positional `<tspan>`) with a registered single-image `<pattern>` marked +`data-pptx-text-image-fill="stretch"` or `"tile"`. It exports as a PowerPoint +run picture fill (`stretch` `Native-normalized`; `tile` needs visual review), +not as a general SVG pattern; the text stays editable. ```xml <defs> @@ -265,48 +171,16 @@ Preset patterns are a separate PPT interface in [`native-data-interface.md`](./n ### 6.4 Shadows, Glow, and Elevation -Filters are native-effect metadata, not a general pixel-filter surface. - -| Concern | Contract | -|---|---| -| Definition/reference | Direct `<defs><filter id="...">` child with unique id; direct `filter="url(#id)"` attribute, never inline style | -| Public targets | `<rect>`, `<circle>`, `<image>`, `<path>`, `<text>`; one validated compact authored shape-preset `<g>` from [`native-shape-authoring.md`](./native-shape-authoring.md) §4; an exact outer `<g filter>` whose sole visual child is one clipped `<image>` | -| Required primitive | `feDropShadow` or `feGaussianBlur` | -| Generated glow form | Zero-offset `feDropShadow` with flood paint, or the complete blur + flood + composite + merge graph below; never bare blur | -| Required parameters | Explicit `stdDeviation` on either effect primitive; explicit `dx`, `dy`, and `flood-opacity` on `feDropShadow`; explicit `flood-opacity` on `feFlood`; explicit `slope` on linear `feFuncA` | -| Accepted helpers | `feOffset`, `feFlood`, `feComposite`, `feMerge`, `feMergeNode`, `feComponentTransfer`, linear `feFuncA` | -| Alpha transfer | Linear `feFuncA` maps multiplicative `slope` only; `intercept` is unsupported | -| Blur sampling | `feGaussianBlur edgeMode` is unsupported; native effects do not expose the SVG edge-sampling modes | -| Primitive coordinates | Omit `primitiveUnits` or use `userSpaceOnUse`; `objectBoundingBox` coordinates are unsupported | -| Numeric values | Finite unitless values; non-negative `stdDeviation`; finite `dx` / `dy`; `feFuncA slope` within `0..1`; mapped glow `rad = stdDeviation × 9525`, shadow `blurRad = stdDeviation × 2 × 9525`, and shadow `dist = hypot(dx,dy) × 9525` must round into DrawingML `0..27273042316900` | -| Classification | Meaningful non-zero offset → one outer shadow; zero/no offset → one glow | -| Fidelity | `Approximate`; one filter becomes one DrawingML effect | - -Flood opacity, linear `feFuncA slope`, and element opacity multiply. The -converter-only historical path may also multiply flood-color alpha and -ancestor group opacity. -Native export does not preserve filter-region, `in/in2/result`, merge order, or -composite topology. Other primitives, multiple independent effects, filters on -`<tspan>` / ordinary `<g>` / unsupported targets are forbidden; apply the -effect to supported objects or use explicit layers. -Special `<g filter>` targets are limited to the helper-authored compact shape -preset above, the exact single clipped-image form in §6.5, the hash-locked -`data-pptx-part="geometry-preview"` transport in §1.4—a direct child of an -imported preset object referencing the hidden geometry carrier's filter—and the -exact imported picture-crop carrier in §6.5, which keeps the effect outside its -viewport. The compact preset applies its filter once to the logical shape; its -direct registry paths remain unfiltered. None of these cases authorizes ordinary -group filters or creates a second PowerPoint object. -PPTX import maps one classifiable shape/connector/picture outer shadow or glow -to this contract. Unsupported effects and outer-shadow variants whose scale, -skew, alignment, or rotation semantics cannot be retained become import -diagnostics instead of a silently simplified authoring surface. See -[`conversion.md`](../scripts/docs/conversion.md#import-compatibility-and-recovery-boundary) -for tolerant, strict, and release-handling behavior. -The quality checker and exporter preflight enforce the same definition, -reference, primitive, target, and numeric-value contract. Missing required -geometry and malformed values are never replaced by effect defaults during -native export. +A filter is native-effect metadata, not a pixel-filter surface: one direct +`<defs><filter>` referenced as a direct `filter="url(#id)"` on a `<rect>`, +`<circle>`, `<image>`, `<path>`, `<text>`, or a helper-authored preset group, +built from `feDropShadow` or the blur + flood + composite + merge graph below +with explicit `stdDeviation`, `dx`/`dy`, and `flood-opacity`. A meaningful +offset becomes one outer shadow; zero offset — even `feDropShadow` with +`dx="0" dy="0"` — becomes one glow. Both are `Approximate`: one filter, one +DrawingML effect. Filters on `<tspan>` or ordinary `<g>` and every other +primitive are forbidden; use an existing accent color for glow, since black +reads as diffuse shadow. ```xml <defs> @@ -330,10 +204,6 @@ native export. </defs> ``` -Even `feDropShadow` with `dx="0" dy="0"` becomes glow. Use an existing accent -color; black reads as diffuse shadow. Bare `feGaussianBlur` remains compatible -input but is never generated: preview blurs the object while export emits glow. - | Elevation | Use | `dy` | `stdDeviation` | Alpha | |---|---|---:|---:|---:| | Floor | Backgrounds, dividers, equal peers, body containers, decorative lines/icons, single-layer pages | — | — | — | @@ -350,82 +220,38 @@ paper-layer treatment flips every affected layer together, so one plane keeps one light direction. **Reference — not a constraint**: use no more elevation categories than the -hierarchy needs; a page may reuse one category across several related objects. -Same-family colored shadow is reserved for a focal accent. -On dark backgrounds a light hairline or restrained glow separates surfaces; glow on body copy reduces legibility. -For older/strict renderers, replace a filter with two or three offset -translucent shapes behind the object: -alpha `0.03–0.05`, increasing offset/radius, and optional same-family tint near -`0.04` (`Native-stable`). +hierarchy needs; a page may reuse one category across several related objects, +but two or three shadowed objects usually read cleanest — check that a fourth +earns its weight. Pick one weight tool per container — shadow, border, +gradient fill, or strong tint — never stacked; peer-grid cards, dividers, +body containers, and background panels stay on the floor. +Same-family colored shadow is reserved for a focal accent. On dark backgrounds +a light hairline or restrained glow separates surfaces; glow on body copy +reduces legibility. For older/strict renderers, replace a filter with two or +three offset translucent shapes behind the object: alpha `0.03–0.05`, +increasing offset/radius, and optional same-family tint near `0.04` +(`Native-stable`). --- ### 6.5 Image Treatments, Overlays, and Glass-like Surfaces -#### Image Carrier and Crop Contracts - | Need | Authoring contract | Fidelity | |---|---|---| -| Cover/crop | Readable raster dimensions + aligned `slice` | Native `srcRect`; `Native-stable`; otherwise native crop cannot be guaranteed | +| Cover/crop | Readable raster dimensions + aligned `slice` | Native `srcRect`; `Native-stable` | | Contain/fit | Aligned `meet` | Fitted picture frame; `Native-normalized` | | Stretch | `preserveAspectRatio="none"` | Native stretched frame | | Uniform fade | `<image opacity="...">` | Native picture alpha | | Shaped picture | §1.2 image-only `clip-path` | Preset/custom picture geometry | -**Hard rule — closed image aspect-ratio grammar**: on `<image>`, omit -`preserveAspectRatio` for the default `xMidYMid meet`, use `none` alone for -stretch, or use one of the nine case-sensitive alignments (`xMinYMin`, -`xMidYMin`, `xMaxYMin`, `xMinYMid`, `xMidYMid`, `xMaxYMid`, `xMinYMax`, -`xMidYMax`, `xMaxYMax`) followed by explicit `meet` or `slice`. Generated SVG -always includes the mode on an aligned value. An alignment without a mode and -values needing whitespace normalization are compatible input and receive a -Checker recommendation. Empty values, `defer`, unknown/wrong-case alignments or -modes, `none` with a mode, and extra tokens are errors; the converter never -guesses a fallback. - -**Hard rule — fit/clip interaction**: a non-trivial clip disables `meet` -frame-fit. Match the image box to the source ratio or use `slice`. Put one §6.4 -filter directly on an unclipped `<image>`. For a clipped picture, keep -`clip-path` on the `<image>` and put the filter on an exact outer `<g>` whose -sole visual child is that image. Never combine `filter` and `clip-path` on the -same `<image>`: SVG would clip the preview effect while PowerPoint would not. -The carrier may keep object-local id, role, transform, and -`data-pptx-carrier`. It may own `data-pptx-layer="master|layout"` only when -the carrier itself is the direct fixed atom. It must not own -`data-pptx-placeholder`, `data-pptx-binding`, or chart/table replacement -metadata; keep slot ownership on the outer placeholder boundary. - -**Hard rule — picture frames and sources are explicit and decodable**: every -SVG `<image>` has explicit positive `width`/`height` and exactly one non-empty -`href` or compatible `xlink:href`. A data URI must use a supported `image/*` -MIME type, valid strict base64 when marked -`base64`, a non-empty payload, and bytes that decode as the declared format. -An external asset must resolve, use a supported extension, be non-empty, and -decode as that extension. The registered formats are PNG, JPEG, GIF, WebP, -BMP, TIFF, SVG, EMF, and WMF. Explicit template substitution tokens may remain -unresolved only during template checking; export requires the resolved image. -Missing, ambiguous, corrupt, mislabeled, or unsupported sources are errors and -must never be dropped or packaged as invalid zero-byte media. - -**Hard rule — nested SVG is picture-crop transport, not a general viewport**: -every non-root `<svg>` is the exact wrapper accepted by the shared crop parser: - -| Part | Required form | -|---|---| -| Outer | Registered `x`, `y`, positive `width`/`height`; four ordinary-decimal unit coordinates in `viewBox`; `preserveAspectRatio="none"`; `overflow="hidden"` | -| Child | Exactly one direct empty `<image>` with one non-empty `href`/`xlink:href`, `x="0" y="0" width="1" height="1" preserveAspectRatio="none"` | -| Context | Only root SVG / ordinary visual `<g>` ancestors; outer may add `id`, supported `transform`, registered layer/carrier metadata, and `data-pptx-frame`, `data-pptx-object`, `data-pptx-shape-id`, `data-pptx-shape-name`, `data-pptx-shape-scope`; an exact imported picture carrier may hold its one §6.4 filter outside this viewport | -| Shape crop | Exact outer `data-pptx-crop="1"`; authored wrappers put the registered, locally resolving image-only clip on the inner image, using `userSpaceOnUse` geometry matching the visible `viewBox`; legacy imported outer clips remain compatible | - -The inner image may add only registered `opacity` and that clip. Quantize the -`viewBox` without clamping: every signed crop fits -`-2147483648..2147483647`, with `l + r < 100000` and `t + b < 100000`. -Retain negative/outside-source crops exactly; write redundant `0 0 1 1` as a -plain `<image>`. Extra, indirect, or character content; unknown attributes; -malformed or unrepresentable crops; and general nested viewports fail. Checker -and converter share this parser. - -#### Image Overlay and Material Techniques +Every `<image>` has explicit positive `width`/`height`, one decodable +project-local or data-URI `href`, and — when not the default `xMidYMid meet` — +an aligned `preserveAspectRatio` with explicit `meet` or `slice`, or `none` +alone. A clip disables `meet` frame-fit, so match the box to the source ratio +or use `slice`; put a §6.4 filter directly on an unclipped image, and for a +clipped one on an exact outer `<g>` whose sole visual child is that image — +never both on the same `<image>`. A nested `<svg>` is only the exact +single-image crop wrapper the crop parser accepts, not a general viewport. | Overlay | Construction | Typical stops / alpha | |---|---|---| @@ -445,39 +271,15 @@ fidelity. ### 6.6 Lines, Connectors, Borders, and Markers -| Surface | Contract / native result | -|---|---| -| Solid stroke/width/alpha | `Native-stable` editable line | -| `4,4`; `6,3`; `2,2`; `8,4`; `8,4,2,4` (comma or space separators) | `dash`; `dash`; `sysDot`; `lgDash`; `lgDashDot` (`Native-normalized`) | -| Canonical custom dash | Exactly two positive finite unitless ordinary decimals (`dash gap`); export scales/quantizes against stroke width; `Native-normalized` | -| Compatible custom dash | Three or more positive finite unitless values are accepted but reduce to the first pair with a Checker recommendation; compatible numeric spellings also warn | -| `stroke-linecap` | `butt`, `round`, `square`; `Native-stable` | -| `stroke-linejoin` | `miter`, `round`, `bevel`; `Native-stable` | -| `vector-effect` | Exactly `none` or `non-scaling-stroke`; export resolves the choice into native line width (`Native-normalized`) | -| `stroke-dashoffset` | No general line mapping; allowed only as a direct finite unitless ordinary-decimal attribute on a §6.10 thick-circle shorthand (`px` suffix is compatible input and warns) | -| Gradient stroke | §6.3; re-import may flatten to first stop | -| `marker-start` / `marker-end` | §1.1 native line end; type `Native-normalized`, size `Approximate` (`sm/med/lg`) | - -PPTX import treats unsupported line properties as source diagnostics: tolerant -mode retains the object and omits only the unsupported outline; `--strict` -retains the closed rejection behavior. See -[`conversion.md`](../scripts/docs/conversion.md#import-compatibility-and-recovery-boundary). - -The dash grammar is closed: exact lowercase `none`, or at least two finite -unitless numbers separated by whitespace or one comma. Generated SVG uses -ordinary decimal spellings. A leading plus sign, exponent, trailing decimal -point, surrounding whitespace, or longer custom list is compatible input and -produces a non-blocking normalization recommendation. Unknown units, one-value -arrays, empty or repeated comma fields, non-finite values, and negative or zero -entries are errors. The only zero exception is a gap declared directly on the -§6.10 thick-circle element. - -Generated cap, join, and `vector-effect` values use the exact lowercase tokens -in the table. Surrounding whitespace is compatible input and produces a -recommendation; every other token is an error. +A solid stroke with width and alpha is an editable native line. Dashes map to +the five presets (`4,4` / `6,3` dash, `2,2` sysDot, `8,4` lgDash, `8,4,2,4` +lgDashDot) or to one custom `dash gap` pair; caps are `butt` / `round` / +`square`, joins `miter` / `round` / `bevel`, `vector-effect` `none` or +`non-scaling-stroke`. Markers follow §1.1 (type native, size approximate); a +gradient stroke follows §6.3. **Default — relationship-fit dash rhythm (may override when style calls for -another rhythm)**: After §6.1 selects dash, preserve direction markers and +another rhythm)**: after §6.1 selects dash, preserve direction markers and branch-owned placeholder patterns. | Already-dashed/dotted job (illustrative) | Dash | @@ -487,39 +289,17 @@ branch-owned placeholder patterns. | Optional/future timeline/flow connector | `8,4` | | Technical/dimension line | `8,4,2,4` | +**Default — contour-fit joins (may override when the resolved style calls for +another character)**: smooth polyline/organic form → `round`; technical +diagram → `bevel`; crisp rectangle/arrow → `miter`. + ```xml -<!-- General boundary versus quiet non-image placeholder --> <rect x="60" y="60" width="400" height="240" rx="12" fill="none" stroke="#999999" stroke-width="2" stroke-dasharray="4,4"/> -<line x1="100" y1="360" x2="1180" y2="360" - stroke="#CCCCCC" stroke-width="1" stroke-dasharray="2,2"/> - -<!-- Optional/future timeline connector versus technical dimension line --> <line x1="100" y1="420" x2="500" y2="420" stroke="#1A73E8" stroke-width="2" stroke-dasharray="8,4"/> -<line x1="620" y1="420" x2="1020" y2="420" - stroke="#555555" stroke-width="2" stroke-dasharray="8,4,2,4"/> -``` - -**Default — contour-fit joins (may override when the resolved style calls for -another character)**: - -| Contour/job (illustrative) | Join | -|---|---| -| Smooth polyline/organic form | `round` | -| Technical diagram | `bevel` | -| Crisp rectangle/arrow | `miter` | - -```xml -<!-- Smooth series: round avoids a miter spike at the turn. --> <polyline points="100,200 200,100 300,200" fill="none" stroke="#1A73E8" stroke-width="3" stroke-linejoin="round"/> - -<!-- Technical corner versus crisp rectangle --> -<polyline points="400,200 500,100 600,200" fill="none" - stroke="#555555" stroke-width="3" stroke-linejoin="bevel"/> -<rect x="740" y="120" width="180" height="160" fill="none" - stroke="#333333" stroke-width="3" stroke-linejoin="miter"/> ``` Match marker paint to the parent stroke using the shape-specific channel from @@ -537,105 +317,23 @@ fixed-density preset pattern: ### 6.7 Advanced Text Treatments -**Hard rule — closed text property grammar**: generated text uses only the -values in the `Canonical authoring` column. Registered compatible input remains -convertible and receives a non-blocking normalization recommendation. Every -other value is invalid; the converter must not replace it with a default. - -| Property | Canonical authoring | Compatible input | DrawingML mapping / rejection boundary | -|---|---|---|---| -| `font-weight` | `normal`, `bold`, or an exact integer hundred from `100` through `900` | `medium` → `500`; `semibold` → `600` | `normal` and `100..500` map to regular; `bold` and `600..900` map to `b="1"`; therefore numeric weights are `Native-normalized` | -| `font-style` | `normal` or `italic` | None | `italic` maps to `i="1"`; oblique, angle, relative, and CSS-wide values are invalid | -| `text-anchor` | `start`, `middle`, or `end` on `<svg>`, `<g>`, or `<text>` | None | Maps to left/center/right paragraph alignment plus normalized frame position; it is invalid on `<tspan>` because run-level anchoring has no mapping | -| `text-decoration` | `none`, `underline`, `line-through`, or `underline line-through` | `line-through underline` → canonical order | Maps to the single underline and strike run properties; unknown, repeated, or substring-like tokens are invalid | -| `baseline-shift` | Exact direct `super` or `sub` on `<tspan>` | None | Maps to editable ordinary-text `a:rPr@baseline` at `30000` or `-25000`; it does not resize the run, is invalid as inline style or on any other element, and cannot combine with an inline formula marker | -| `letter-spacing` | Finite unitless ordinary decimal SVG px | The same ordinary decimal with `px`, `pt`, or `em`; normalize to unitless px | Maps to `a:rPr@spc`; the final value must fit DrawingML `-400000..400000`, and negative tracking must leave every generated DrawingML run with a positive estimated advance and its text frame with a positive extent; keywords, percentages, exponents, leading plus signs, trailing decimal points, non-finite values, and other units are invalid | - -The registered inheritable text properties follow SVG inheritance, including -declarations on the root `<svg>`: inline `style` overrides the same element's -direct attribute, which overrides its ancestor. `baseline-shift` is the narrow -exception: declare it directly on the owning `<tspan>`; nested inline content -inherits that run shift, while surrounding text keeps its own baseline. -Relative font sizes and `em` tracking resolve against the same effective -inherited size in Checker and converter. Every declaration is validated even -when a later declaration overrides it, so hidden garbage cannot bypass -preflight. - -The DrawingML character-spacing range is necessary but not sufficient for -negative tracking. After run assembly, each output run must retain a positive -estimated advance using the quantized `sz` and `spc` values that will actually -be written; a wider sibling run or paragraph line cannot hide a run whose -aggregate advance would reverse or collapse, which can reorder or drop -characters across PowerPoint-compatible renderers. The generated text frame -must also retain a positive horizontal and vertical extent. Checker rejects -directly measurable single-line violations, and the converter revalidates -every generated run and text frame before writing OOXML. It must not clamp, -take the absolute value of, or otherwise hide a non-positive advance or extent. -Adjacent authored runs with identical final DrawingML run properties form one -output run before sizing and validation; splitting text across equivalent -`<tspan>` nodes is not a tracking escape hatch. Tracking and width estimates -count the registered project text clusters rather than raw Unicode code points: -combining marks, variation selectors, emoji modifiers and ZWJ sequences, -paired regional indicators, and same-script virama conjuncts do not receive -internal spacing. -An unchanged imported native text body reuses the geometry carrier's positive -shape frame and attaches the preserved `txBody` payload instead of regenerating -runs or a text frame from the SVG estimate. - -**Hard rule — element-specific text surface**: - -- Inheritable text declarations belong only on `<svg>`, `<g>`, `<text>`, or - `<tspan>`; placing them on geometry, image, definition, or reuse elements is - an error rather than ignored decoration. -- `<text>` accepts `x`, `y`, registered paint/alpha/run properties, the text - properties above, `font-family`, `font-size`, direct `filter`, direct - `transform`, `xml:space`, `id`, and project `data-*` metadata. -- `<tspan>` accepts `x`, `y`, `dx`, `dy`, registered paint/alpha/run - properties, `font-family`, `font-size`, `font-weight`, `font-style`, - `letter-spacing`, `text-decoration`, direct `baseline-shift`, `xml:space`, - `id`, and project `data-*` metadata. It does not accept `text-anchor`, - `filter`, or `transform`. -- `word-spacing`, `dominant-baseline`, `alignment-baseline`, - font shorthand/variant/stretch/feature/variation/synthesis controls, - `font-kerning`/`kerning`, `font-size-adjust`, `line-height`, text alignment, - indent/shadow/rendering controls, white-space/word-break/hyphenation - controls, `writing-mode`, `vertical-align`, `direction`, `unicode-bidi`, and - `text-transform` have no registered native mapping and are errors as direct - attributes or inline style. -- Any other unregistered `font-*` or `text-*` property is also an error; the - closed grammar must not grow through an ignored CSS spelling. - -**Hard rule — project text whitespace**: - -- `xml:space` is the project's closed authoring control for significant text - whitespace. It is valid only as an exact direct attribute on `<text>` or - `<tspan>`, accepts only the case-sensitive values `default` and `preserve`, - inherits through the text tree, and may be reset on a child `<tspan>`. -- The project maps this control to the visible Chromium/SVG2 behavior used by - Live Preview; it does not claim the legacy SVG 1.1 newline-deletion model. - XML line endings and tabs become U+0020 SPACE. In `default` mode, contiguous - U+0020 characters collapse across inline run boundaries and leading or - trailing default-mode spaces in the resulting text chunk are removed. In - `preserve` mode, every resulting U+0020 character remains significant. -- Only XML whitespace is normalized. NBSP, ideographic space, and other - Unicode spacing characters remain literal text and must not be rewritten by - a generic Unicode-whitespace regular expression. -- Source line breaks do not create PowerPoint paragraphs. Use the registered - positioned-`tspan`/paragraph structure for visual lines, and preserve DOM - text/tail order plus original style inheritance when normalizing that - structure. - -These allowlists are additive to the global structural blacklist and the -paint, font-size, opacity, filter, and transform value contracts owned by their -respective sections; they do not weaken those contracts. +Generated text uses only the canonical values: `font-weight` `normal` / `bold` +/ an integer hundred, `font-style` `normal` / `italic`, `text-anchor` on +`<text>` or above, `text-decoration` `underline` / `line-through` / both, +direct `baseline-shift="super|sub"` on `<tspan>`, and unitless-px +`letter-spacing` and `font-size`. Inheritable text declarations belong only on +`<svg>`, `<g>`, `<text>`, or `<tspan>`; `xml:space` (`default` or `preserve`) on +`<text>` / `<tspan>` is the one whitespace control — it inherits through the +text tree and may be reset on a child `<tspan>`, so one frame can mix +collapsed and preserved runs. Every other `font-*` / `text-*` +property has no native mapping and is an error. | Treatment | SVG surface | Result / boundary | |---|---|---| | Underline / strike / both | `text-decoration="underline"`, `line-through`, or both | `Native-stable`; both emits both run properties | | Mixed runs | Non-positional `<tspan>` | One `Native-normalized` editable frame; §4.2 | -| Superscript / subscript | Direct `baseline-shift="super|sub"` on `<tspan>` | Editable ordinary-text run at PowerPoint's native baseline offset; set `font-size` on the same run when a smaller glyph is intended | -| Font size | Generated default is a finite unitless SVG px value; compatible `px`, `pt`, `pc`/`pica`, `in`, `cm`, `mm`, `q`, `em`, and `rem` values receive a recommendation warning only | Converted to SVG px, then editable DrawingML point size; unsupported units/percentages error | -| Tracking | §6.7 closed `letter-spacing` grammar | `Native-normalized`; compatible units normalize to SVG px before DrawingML conversion | +| Superscript / subscript | Direct `baseline-shift="super|sub"` on `<tspan>` | Editable run at PowerPoint's native baseline offset; set `font-size` on the same run when a smaller glyph is intended | +| Tracking | Unitless-px `letter-spacing` | `Native-normalized`; negative tracking must leave every run a positive advance | | Transparency | `opacity` / `fill-opacity` on text/run | `Native-normalized` run alpha, not isolated compositing | | Gradient fill | §6.3 gradient on text/run | Editable fill; geometry normalizes | | Outline | Solid `stroke`, `stroke-width`, `stroke-opacity` | `Native-normalized` editable run outline; re-import does not reconstruct it | @@ -658,116 +356,61 @@ conventionally read as polarity. </text> ``` -**Underline**: conventionally marks links, key terms, or local emphasis. +**Underline** conventionally marks links, key terms, or local emphasis — +decorate the linked run, not the whole sentence. **Strikethrough** marks +removed/former values; it is ordinary notation, not a style-exclusive effect. ```xml -<!-- Key term --> -<text x="100" y="200" font-size="20" fill="#333333" - text-decoration="underline">Important Term</text> - -<!-- Link: decorate the linked run, not the whole sentence. --> <text x="100" y="240" font-size="18" fill="#333333">Read <a href="https://example.com"><tspan text-decoration="underline">the guide</tspan></a>.</text> -``` - -**Hard rule — generated decorative lettering ownership**: Approved AI -decorative lettering is a prepared `<image>` asset under the image contracts, -not an advanced native-text treatment. Keep ordinary editable titles and -subtitles as normal `<text>`; this contract does not add WordArt, text warp, or -text-on-path authoring. - -```xml <text x="100" y="200" font-size="20" xml:space="preserve">Current <tspan fill="#999999" text-decoration="line-through">old</tspan> value</text> <text x="100" y="240" font-size="20">CO<tspan baseline-shift="sub" font-size="14">2</tspan></text> ``` -Strikethrough conventionally marks removed/former values; it is ordinary notation, not a -style-exclusive effect. Imported double underline/strike normalizes to single. -Bullet detection allows optional leading whitespace, requires non-empty content, -and leaves non-leading decorative glyphs as ordinary text. -CJK tracking defaults near/below 2% of font size and above 5% triggers review. Text outline is solid only. `textPath`, masks, blend -modes, generated effects, and text-image knockouts are outside editable text. +**Hard rule — generated decorative lettering ownership**: approved AI +decorative lettering is a prepared `<image>` asset under the image contracts, +not an advanced native-text treatment. Keep ordinary editable titles and +subtitles as normal `<text>`; this contract does not add WordArt, text warp, or +text-on-path authoring. + +CJK tracking defaults near/below 2% of font size and above 5% triggers review. +Text outline is solid only. `textPath`, masks, blend modes, generated effects, +and text-image knockouts are outside editable text. --- ### 6.8 Transforms, Layering, and Static Reuse -| Surface | Contract / fidelity | -|---|---| -| `rotate(angle[, cx, cy])` | Geometry/image/text/ordinary group; `Native-normalized` | -| `translate(x y)` | Geometry/image/group; pure translation also safe on text; `Native-normalized` | -| Positive scale / negative mirror | Geometry/image or a group/use whose expanded visual subtree is geometry/image only; explicit pivot; `Native-normalized` | -| `matrix(a b c d e f)` | Geometry/image or the same geometry/image-only group/use; transformed axes finite, non-zero, orthogonal; excludes rounded rectangles and subtrees containing them; `Native-normalized` | -| Source order | Back-to-front PPT z-order; `Native-stable` | -| `<g opacity>` | Compatible approximate mapping; generated SVG prefers descendant alpha, §2.2 | -| Local `<use>` | §1.3 compile-time reuse; `Native-normalized` | - -**Hard rule — closed transform grammar**: Use only lowercase `translate`, -`scale`, `rotate`, and `matrix` with exact finite unitless argument counts: -`translate` 1/2, `scale` 1/2, `rotate` 1/3, and `matrix` 6. Separate arguments -and operations with whitespace or one comma. Leading/trailing/repeated commas, -adjacent operations without a separator, units, unknown functions, and -incomplete input fail quality check and export. Generated numeric tokens use -ordinary decimals; a supported leading `+`, exponent, or trailing decimal point -remains compatible input and receives a non-blocking normalization warning. -Model-facing translation values, rotation centers, and matrix `e/f` use at -most two decimals under §1.4; angles, scale arguments, and matrix `a/b/c/d` -retain the precision required by the transform. - -Set text size/position directly. A text transform is either a translate-only -list or one rotate operation; do not scale, matrix-transform, or mix operations -on text. A group containing text follows the same translate-only/single-rotate -limit. `skewX`, `skewY`, zero/non-orthogonal axes, and shear matrices are -forbidden. Native chart/table markers allow translate/scale only. The §6.10 -thick-circle shortcut does not inherit general transform support. Positive -rotation is clockwise and pivoted rotation normalizes the native frame. Every -cumulative matrix, including transforms split across ancestors, must remain -finite, non-zero, and orthogonal; importer/live-editor matrices do not expand -the hand-authored contract. -Mirror around vertical pivot `cx` with -`translate(cx 0) scale(-1 1) translate(-cx 0)`; use the analogous Y sequence -for a horizontal pivot. During mirror materialization, imported PowerPoint -groups with an axis flip keep their geometry reflection, while each descendant -SVG text node receives the matching counter-reflection so browser previews keep -glyphs upright. The tool-side native record retains the source group flip. +Use only lowercase `translate`, `scale`, `rotate`, and `matrix` with finite +unitless arguments; `rotate` is clockwise and may take a pivot. Geometry, +images, and geometry-only groups accept any of them (`Native-normalized`) as +long as the cumulative matrix stays finite, non-zero, and orthogonal — no +`skewX` / `skewY` or shear, and `matrix` excludes rounded rectangles. Text, and +any group containing text, takes only a translate-only list or one rotate; set +text size/position directly. Native chart/table markers allow translate/scale +only. Mirror around a vertical pivot `cx` with +`translate(cx 0) scale(-1 1) translate(-cx 0)`, and never mirror text, logos, +or directional evidence. Layer back-to-front: background/image → scrim/shadow → main geometry → labels / -icons → top annotation. Finalization and native export independently expand -`<use>` into cloned editable primitives; PowerPoint does not retain a symbol / -instance graph. +icons → top annotation; source order is PPT z-order. Local `<use>` (§1.3) is +compile-time reuse — finalization and native export expand it into cloned +editable primitives, and PowerPoint retains no symbol/instance graph. Group +opacity remains an approximate compatibility mapping; generated SVG prefers +descendant alpha (§2.2). --- ### 6.9 Freeform Shapes and Curves -| Input | Native normalization | Fidelity | -|---|---|---| -| `M/L/H/V`, absolute or relative | Absolute `M/L` | `Native-normalized` | -| `C` | Cubic Bézier | `Native-normalized` | -| `S/Q/T` | Explicit cubic controls | `Native-normalized` | -| `A` | Cubic segments of at most 90° | `Approximate` | -| `Z`; polygon/polyline | Closed/open freeform | `Native-normalized` | - -**Hard rule — complete freeform grammar**: Generated `path@d` and -`polygon` / `polyline@points` use finite unitless ordinary decimals and only -the commands registered above. Native export consumes the complete attribute; -it never extracts recognizable fragments while ignoring other characters. -Finite scientific notation, a leading plus sign, and a trailing decimal point -remain read-compatible and receive recommendation warnings; generated SVG does -not write them. Unknown commands or characters, misplaced/repeated commas, -non-finite numbers, missing attributes, incomplete command groups, and odd -point counts are invalid. A path starts with `M` / `m`; `A` radii are -non-negative and both arc flags are exactly `0` or `1`. Each registered path -command accepts its uppercase absolute and lowercase relative form. Legal -separator-free arc flag sequences remain valid and are parsed as individual -flag tokens. A polygon has at least three coordinate pairs and a polyline at -least two. - -**Validation**: Checker and native export consume the same parser in -[`paths.py`](../scripts/svg_to_pptx/drawingml/paths.py); native-object fallback -bounds reuse its normalized commands rather than a second path grammar. +Every SVG path command, `<polygon>`, and `<polyline>` is accepted; export +normalizes to absolute `M/L` and cubic Béziers, and arcs become ≤90° cubic +segments (`Approximate`). Write `d` and `points` as finite unitless ordinary +decimals; geometry needs non-zero bounds; do not depend on +`fill-rule="evenodd"` — build explicit visible geometry, bake an essential +knockout, or on a fixed background use a background-colored overlay. **Reference — not a constraint**: use the fewest curve segments and control points that preserve the intended silhouette. Set endpoints and tangent @@ -781,29 +424,19 @@ preserve deliberate tangent continuity. fill="none" stroke="#0F766E" stroke-width="4" stroke-linecap="round"/> ``` -Command identity, relative coordinates, shorthand, arc parameters, and original -handles are not retained. Geometry needs non-zero bounds. Before authoring a -freeform, apply [`native-shape-authoring.md`](./native-shape-authoring.md): +Before authoring a freeform, apply [`native-shape-authoring.md`](./native-shape-authoring.md): prefer editable primitives and exact Office presets, independently composed when possible; materialize a Boolean only when one contour requires it. Use a -closed cubic path only for an organic silhouette those -cannot express, polygon/closed path for unmatched ribbons/facets, and an open -path only for a required data curve, custom route, or locked or Quick-resolved -hand-drawn / organic style. Straight relationships use `<line>`; exact stock bends/curves +closed cubic path only for an organic silhouette those cannot express, +polygon/closed path for unmatched ribbons/facets, and an open path only for a +required data curve, custom route, or locked or Quick-resolved hand-drawn / +organic style. Straight relationships use `<line>`; exact stock bends/curves use an authored native Connector preset. Multi-`M` paths remain available for -exact linework, and a [`shared-standards-core.md`](./shared-standards-core.md) -§1.2 path clip for unmatched organic pictures. Filled silhouettes end with -`Z`; open paths use `fill="none"`. Do not depend on -`fill-rule="evenodd"`; build explicit visible geometry or bake an essential -knockout. -For a fixed background, a background-colored overlay is also valid. - -| Rounded rect input | Result | -|---|---| -| One positive radius, or `0 < rx == ry <= min(width,height)/2` | `Native-stable` adjustable `roundRect` without distorting transforms; the same short-side limit applies to one-radius input | -| `0 < abs(rx-ry) < 0.5px` after scaling | One normalized native radius; `Approximate` | -| `abs(rx-ry) >= 0.5px`, either positive | Cubic custom geometry; no radius handle; `Approximate` | -| Equal radius above half the short side | Native short-side clamp may differ from SVG; `Approximate` | +exact linework, and a §1.2 path clip for unmatched organic pictures. Filled +silhouettes end with `Z`; open paths use `fill="none"`. A rounded `<rect>` +stays a native adjustable `roundRect` only while `rx == ry` and the radius is at +most half the short side; unequal radii become custom geometry without a +handle. --- @@ -820,10 +453,8 @@ For clockwise pie/donut sectors, default to `-90°` only when the chart starts a 12 o'clock. A full-circle percentage sector spans `percentage × 360°`; large-arc is `1` above `180°`; outer sweep is `1`, inner return is `0`. Split both outer and inner boundaries of a full ring into at least two arcs each. -Calculated endpoints survive subject to EMU rounding; `A` curves remain cubic -approximations. Verify all spans plus gaps against the planned sweep. -Explicit arc sectors are editable `Approximate` freeforms. Thin circles using a -§6.6 preset/two-number dash stay `Native-normalized` ellipse lines. +Verify all spans plus gaps against the planned sweep. Explicit arc sectors are +editable `Approximate` freeforms. ```xml <!-- 75% donut: center 400,400; outer 180; inner 100; -90° → 180°. --> @@ -834,26 +465,22 @@ Explicit arc sectors are editable `Approximate` freeforms. Thin circles using a **Gauge**: require `max > min`, `p = clamp((value-min)/(max-min),0,1)`, and `0 < planned clockwise sweep <= 360°`; value sweep is `p × planned sweep`. `valueEndAngle = startAngle + valueSweep`; large-arc is `1` iff -`abs(valueSweep) > 180°`. -Omit the value sector at `p=0`. At `p=1` with `360°`, split both boundaries into -at least two arcs. Track/value share center, radii, start, and sweep flags. +`abs(valueSweep) > 180°`. Omit the value sector at `p=0`. At `p=1` with +`360°`, split both boundaries into at least two arcs. Track/value share center, +radii, start, and sweep flags. -**Sunburst — `Approximate`**: one explicit annular sector per node; each depth owns one radius -band and child angular intervals partition the parent. Do not use one `evenodd` -compound ring. +**Sunburst — `Approximate`**: one explicit annular sector per node; each depth +owns one radius band and child angular intervals partition the parent. Do not +use one `evenodd` compound ring. -**Thick-circle shorthand — `Approximate`, non-position-sensitive only**: +A thin circle with a §6.6 preset or two-number dash stays a `Native-normalized` +ellipse line; the shorthand below is for thick ring segments only. -- One circle per segment; `fill="none"`; the circle may use one `rotate` for its - start angle, and ancestor transforms must be translate-only. -- Exactly two non-preset finite unitless ordinary-decimal values (`dash gap`); - `stroke-dashoffset` is a direct finite unitless ordinary-decimal attribute. -- `0 < stroke-width < 2r`, `stroke-width/r >= 0.15`, - `0 < dash < 2πr`, `gap >= 0`, and `dash + gap >= 2πr - 1` SVG unit. The - one-unit tolerance exists only for integer-rounded circumference values. -- Native construction uses only the first dash and re-imports as a freeform. - Its native start is 90° counterclockwise from the SVG preview; use explicit - arcs whenever start angle, cap, or radial precision matters. +**Thick-circle shorthand — `Approximate`, non-position-sensitive only**: one +`fill="none"` circle per segment with a two-value `dash gap` covering the +circumference and a direct `stroke-dashoffset`; native construction keeps only +the first dash and starts 90° counterclockwise from the SVG preview, so use +explicit arcs whenever start angle, cap, or radial precision matters. ```xml <circle cx="400" cy="400" r="140" fill="none" stroke="#2563EB" @@ -952,10 +579,6 @@ halftone and route dense full-slide texture to §6.12. glow; it does not blur the object or backdrop. Use a low-alpha raster for dense grain and explicit circles/paths only for sparse editable marks. -Unsupported source effects remain visible where possible and retain their -import diagnostics. Resolve those diagnostics before release export; see -[`conversion.md`](../scripts/docs/conversion.md#import-compatibility-and-recovery-boundary). - --- ### 6.13 Page-Level Composition Recipes @@ -974,6 +597,6 @@ back-to-front and omit every layer without a distinct job. | Evidence / metric | Context field → local contrast → native leaders/labels/metric → optional focus/elevation | Claims stay native | | Comparison | Matched planes → optional shared wash/divider → matched labels → one difference marker | Keep crop, elevation, and paint symmetric unless asymmetry is the claim | | Closing / CTA | Receded field → echoed contour/gradient → native action → optional raised accent | Keep the native action legible | -| Cross-page motif | Reuse contour, gradient direction, line language, texture, or light logic; vary scale, crop, or position by page job | Preserve recognition without copying the page or adding novelty effects | +| Cross-page motif | Reuse contour, gradient direction, line language, texture, or light logic; vary scale, crop, position by page job | Preserve recognition without copying the page or adding novelty effects | --- diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/svg-image-embedding.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/svg-image-embedding.md index 818292ec..de600479 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/svg-image-embedding.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/svg-image-embedding.md @@ -2,21 +2,13 @@ # SVG Image Embedding Guide -Technical spec and workflow for adding images to SVG files. +Status names, resource lifecycle, and the embedding workflow for images in SVG pages. [`svg-effects.md`](./svg-effects.md) §6.5 owns the native carrier, crop transport, and filter/clip contracts; Base64 embedding, preview serving, and image-optimization flags are tool behavior in [`svg-pipeline.md`](../scripts/docs/svg-pipeline.md). --- ## Image Resource List Format -Each image carries an `Acquire Via` field plus a status annotation. This file -owns status names, resource lifecycle, and embedding workflow; -[`svg-effects.md`](./svg-effects.md) §6.5 owns native carrier, crop transport, -and filter/clip contracts. - -| Mode | Resource authority and preparation timing | -|---|---| -| Default Generate | `design_spec.md §VIII` plus its lock projection; when user-provided images are selected, run `analyze_images.py` after Strategist confirmation and complete the list before Executor | -| Quick Generate | Current main agent's active-context resource decisions; materialize explicit user paths first, resolve unspecified acquisition decisions automatically, and finish user/ai/web/slice preparation before SVG authoring without confirmation or a persisted roster | +Each image carries an `Acquire Via` field plus a status. Default Generate's authority is `design_spec.md §VIII` plus its lock projection (run `analyze_images.py` after confirmation when user images are selected and complete the list before Executor); Quick's is the main agent's active-context decisions (explicit user paths first, unspecified acquisition resolved automatically, all preparation finished before SVG authoring without confirmation or a persisted roster). ```markdown | Filename | Dimensions | Purpose | Type | Layout pattern | Crop Policy | Acquire Via | Status | Reference | @@ -28,177 +20,34 @@ and filter/clip contracts. | Status | Meaning | Executor Handling | |--------|---------|-------------------| -| **Pending** | Acquisition or declared derivation is needed; not yet attempted | Step 5 consumes this; must not remain afterward | -| **Failed** | The latest automatic acquisition attempt failed; this is retryable and non-terminal | Step 5 reruns the owning manifest or explicitly resolves the row to `Needs-Manual`; Executor must never treat `Failed` as usable content | -| **Needs-Selection** | Web search produced one bounded thumbnail-only candidate page; no original or provenance exists yet | Step 5 reviews/promotes one candidate, advances to `next_candidate_page`, or after pool exhaustion materially changes the query and returns the row to `Pending`; Executor must never consume this intermediate state | -| **Generated** | AI/slice output exists | Reference from `../images/`; manifest records govern attribution. An `Illustration Sheet` stays in §VIII only as an unplaced slice source | -| **Sourced** | Web-sourced file exists at expected path | Reference from `../images/`; check `image_sources.json` for `license_tier` — if `attribution-required`, render an inline credit element on the slide (see [`executor-web-image.md`](./executor-web-image.md) §1 and [`image-searcher.md`](./image-searcher.md) §7 for the attribution contract) | -| **Needs-Manual** | The owning source path requires manual fulfillment; for `slice`, the parent sheet is unavailable | Default Generate may use a dashed placeholder until its readiness gate. Quick Generate blocks every required row still in this status, even if an unverified candidate file exists; validate a supplied replacement and reconcile it to `Existing`, `Generated`, or `Sourced` first. Quick automated AI exhaustion never creates this status: [`image-generator.md`](./image-generator.md) §7 removes the affected AI/dependent-slice jobs through its declared no-AI replan. For a retained manual `slice`, supply the parent sheet and rerun `slice_images.py`; do not hand-place individual element files. | -| **Existing** | User already has image (`Acquire Via: user`) | Place in `images/`, reference with `<image>` | -| **Placeholder** | Intentionally not prepared yet (`Acquire Via: placeholder`) | Dashed border placeholder; replace later | +| **Pending** | Acquisition or declared derivation needed, not yet attempted | Step 5 consumes it; must not remain afterward | +| **Failed** | Latest automatic attempt failed; retryable, non-terminal | Step 5 reruns the owning manifest or resolves the row to `Needs-Manual`; never usable content | +| **Needs-Selection** | Web search produced one bounded thumbnail page; no original or provenance yet | Step 5 promotes one candidate, advances to `next_candidate_page`, or after exhaustion changes the query and returns the row to `Pending`; never consumed | +| **Generated** | AI/slice output exists | Reference from `../images/`; manifest records govern attribution; an `Illustration Sheet` stays in §VIII only as an unplaced slice source | +| **Sourced** | Web-sourced file exists at the expected path | Reference from `../images/`; with `license_tier: attribution-required` in `image_sources.json`, render an inline credit ([`executor-web-image.md`](./executor-web-image.md) §1, [`image-searcher.md`](./image-searcher.md) §7) | +| **Needs-Manual** | The owning path requires manual fulfillment; for `slice`, the parent sheet is unavailable | Default may use a dashed placeholder until its readiness gate; Quick blocks every required row in this status even with an unverified candidate file — validate and reconcile a supplied replacement to `Existing`, `Generated`, or `Sourced` first. Quick automated AI exhaustion never creates it ([`image-generator.md`](./image-generator.md) §7's no-AI replan). A retained manual `slice` needs the parent sheet and a `slice_images.py` rerun, never hand-placed element files | +| **Existing** | User-supplied (`Acquire Via: user`) | Place in `images/`, reference with `<image>` | +| **Placeholder** | Intentionally not prepared (`Acquire Via: placeholder`) | Dashed placeholder; replace later | --- ## Workflow -``` -1. Resolve image needs: - - Default Generate → Strategist-owned resource list + lock projection - - Quick Generate → current main agent resolves the required resource in active context; explicit user paths/URLs/choices win, unspecified choices use automatic resolution, no interaction or persisted roster -2. Prepare project-local resources before SVG authoring: - - user → materialize the explicit source under project/images/ → Existing - - Pending prepared derivative → follow [`image-base.md`](./image-base.md) §3 before ordinary `Acquire Via` dispatch - - Pending / Failed + ai → Image_Generator executes the selected path → Generated, Default recovery decision, or Quick no-AI replan - - Pending / Failed + web + vision → Image_Searcher saves at most 8 ranked previews → Needs-Selection → promote one original or fetch the next page → Sourced / Needs-Manual - - Pending / Failed + web without vision → Image_Searcher accepts only a strict metadata-ranked best-only candidate and records that method → Sourced or Needs-Manual - - Pending + slice → after parent AI sheet is Generated, slice_images.py cuts element files → Generated -3. SVG authoring consumes only prepared resources (Executor in Default Generate; current main agent in Quick Generate) - ├── Existing / Generated → <image href="../images/xxx.png" .../> - ├── Sourced + license_tier=no-attribution → <image href=...> only - ├── Sourced + license_tier=attribution-required → <image href=...> + small <text> credit element on the slide - ├── Sourced + license_tier=manual → <image href=...> only (user-supplied --from-url; rights/credit are user responsibility) - └── Placeholder / Needs-Manual → Dashed border + description text until a supplied file is validated and status is reconciled -4. Preview: python3 -m http.server -d <project_path> 8000 → /svg_output/<filename>.svg -5. Export: - - Default Generate → follow [`generate-pptx.md`](../workflows/generate-pptx.md) Step 7 - - Quick Generate → after every required resource has a validated expected file/provenance and usable status, run the profile's final checker, then its `--quick-generate` export -``` +1. Resolve image needs — Default: Strategist resource list + lock projection; Quick: the main agent in active context. +2. Prepare project-local resources before SVG authoring: `user` → materialize under `images/` → `Existing`; a Pending prepared derivative → [`image-base.md`](./image-base.md) §1 before ordinary dispatch; `ai` → Image_Generator → `Generated`, a Default recovery decision, or the Quick no-AI replan; `web` with vision → Image_Searcher saves at most 8 ranked previews → `Needs-Selection` → promote or next page → `Sourced` / `Needs-Manual`; `web` without vision → strict metadata-ranked best-only candidate with the method recorded → `Sourced` / `Needs-Manual`; `slice` → after the parent sheet is `Generated`, `slice_images.py` → `Generated`. +3. Authoring consumes only prepared resources: `Existing` / `Generated` → `<image href="../images/xxx.png" …/>`; `Sourced` → `<image>` plus a credit `<text>` only for `attribution-required` (`no-attribution` and `manual` place the image alone); `Placeholder` / `Needs-Manual` → dashed border plus description text until a supplied file is validated and reconciled. +4. Export — Default: [`generate-pptx.md`](../workflows/generate-pptx.md) Step 7; Quick: after every required resource has a validated file/provenance and usable status, its final checker then `--quick-generate` export. -> Keep external references in `svg_output/` during generation. Default Generate uses `finalize_svg.py` to embed images into the mandatory `svg_final/` visual preview. Quick Generate omits that preview artifact. Both native PPTX exports independently read image references from `svg_output/`. - -**Hard rule — export boundary**: `svg_final/` is a self-contained SVG preview for embeddable raster/SVG assets and may be manually inserted into PowerPoint as an SVG picture. EMF/WMF assets retain the documented external-reference exception for lossless native passthrough. The only supported generated-PPTX route is `svg_output/` through the project SVG-to-DrawingML converter. PowerPoint's manual Convert-to-Shape operation is unsupported. +Keep external references in `svg_output/` during generation; Default's `finalize_svg.py` embeds images into the `svg_final/` preview, Quick omits it, and both native exports read `svg_output/` directly. **Hard rule — export boundary**: `svg_final/` is a self-contained preview that may be inserted into PowerPoint as an SVG picture (EMF/WMF keep the external-reference exception for lossless passthrough); the only supported generated-PPTX route is `svg_output/` through the project converter; PowerPoint's manual Convert-to-Shape is unsupported. --- -## External Reference vs Base64 Embedding - -| Method | Pros | Cons | Suitable For | -|--------|------|------|-------------| -| **External reference** | Small file size, fast iteration, easy to replace | Preview requires HTTP server from project root | `svg_output/` development phase | -| **Base64 embedding** | Self-contained file, stable direct preview / SVG-picture insertion | Large file size | `svg_final/` preview phase | - ---- - -## Method 1: External Reference (Recommended for Generation Phase) - -### Syntax +## Canonical `<image>` form ```xml -<image href="../images/image.png" x="0" y="0" width="1280" height="720" - preserveAspectRatio="xMidYMid slice"/> +<image href="../images/image.png" x="0" y="0" width="1280" height="720" preserveAspectRatio="xMidYMid slice"/> ``` -### Key Attributes +`href` is the relative project path; `x`, `y`, `width`, `height` the display frame; `preserveAspectRatio` `xMidYMid slice` (center crop, like CSS `cover`), `xMidYMid meet` (complete display, like `contain`), or `none` (stretch — never for a `no-crop` source). A Base64 `data:` href is the `svg_final/` preview form produced by finalization, not an authoring form. `clipPath` on `<image>` is conditionally allowed under [`shared-standards-core.md`](./shared-standards-core.md) §1.2; when it does not fit, bake rounded corners into an alpha PNG before embedding. -| Attribute | Description | Example | -|-----------|-------------|---------| -| `href` | Image path (relative or absolute) | `"../images/cover.png"` | -| `x`, `y` | Image top-left corner position | `x="0" y="0"` | -| `width`, `height` | Image display dimensions | `width="1280" height="720"` | -| `preserveAspectRatio` | Scaling mode | `"xMidYMid slice"` | - -### preserveAspectRatio Common Values - -| Value | Effect | -|-------|--------| -| `xMidYMid slice` | Center crop (similar to CSS `cover`) | -| `xMidYMid meet` | Complete display (similar to CSS `contain`) | -| `none` | Stretch to fill, no aspect ratio preservation | - -### Preview Method - -Browser security blocks external images on directly opened SVGs. Serve via HTTP from the project root: - -```bash -python3 -m http.server -d <project_path> 8000 -# Visit http://localhost:8000/svg_output/your_file.svg -``` - ---- - -## Method 2: Base64 Embedding (Recommended for Preview Phase) - -### Syntax - -```xml -<image href="data:image/png;base64,iVBORw0KGgo..." x="0" y="0" width="1280" height="720"/> -``` - -### MIME Types - -| MIME Type | File Format | -|-----------|-------------| -| `image/png` | PNG | -| `image/jpeg` | JPG/JPEG | -| `image/gif` | GIF | -| `image/webp` | WebP | -| `image/svg+xml` | SVG | - ---- - -## Conversion Process - -Default Generate follows [`generate-pptx.md`](../workflows/generate-pptx.md) -Step 7; it owns the serial post-processing and export commands. Quick Generate -follows [`quick-generate.md`](../workflows/profiles/quick-generate.md) after its -required-resource gate. The native PPTX converter reads `svg_output/` and maps -its project-local image references directly to DrawingML in both modes. - -### Standalone: align_embed_images.py (advanced) - -For processing specific SVGs without the full pipeline: - -```bash -python3 scripts/svg_finalize/align_embed_images.py <svg_file> -python3 scripts/svg_finalize/align_embed_images.py --dry-run <svg_file> -``` - -Use `finalize_svg.py --only align-images` for project-level batches. The old -`crop-images`, `fix-aspect`, and `embed-images` step names are compatibility -aliases only when invoked through `finalize_svg.py --only`. - ---- - -## Best Practices - -### Native PPTX Image Export - -**Default — preserve unmodified image bytes**: `svg_to_pptx.py` uses `--image-sizing cap`. It keeps original bytes when an image needs neither resizing nor EXIF geometry normalization, and re-encodes only images that require one of those transformations. Use the explicit compact command only when a compact export is requested. - -| Need | Command | -|---|---| -| Normal native export | `python3 scripts/svg_to_pptx.py <project_path>` | -| Explicit compact export | `python3 scripts/svg_to_pptx.py <project_path> --image-sizing display --image-scale 2 --image-quality 85` | -| Force original bytes | `python3 scripts/svg_to_pptx.py <project_path> --no-image-optimize` | - -### File Organization - -``` -project/ -├── images/ # Image assets -├── sources/ # Source files and their accompanying images -│ └── article_files/ -├── svg_output/ # Raw version (external references) -└── svg_final/ # Derived self-contained visual preview (images embedded) -``` - -### Rounded Corner / Non-rectangular Image Cropping - -`clipPath` **on `<image>` elements** is conditionally allowed — authoritative constraints in [`shared-standards-core.md`](./shared-standards-core.md) §1.2; do not restate or relax here. - -Fallback when `clipPath` doesn't fit: bake rounded corners into the source image (PNG with alpha) before embedding. - ---- - -## FAQ - -**Q: Can't see images when opening SVG directly?** -Browser security blocks cross-directory requests. Serve via HTTP from project root, or run `finalize_svg.py` first and view from `svg_final/`. - -**Q: Base64 file too large?** -Compress the source, use JPEG, reduce resolution to match actual display dimensions. - -**Q: How to reverse-extract a Base64 image?** -```bash -base64 -d image.b64 > image.png -``` +Project layout: `images/` (assets), `sources/` (source files and their `*_files/` images), `svg_output/` (external references), `svg_final/` (Default-only embedded preview). Preview `svg_output/` through `python3 -m http.server -d <project_path> 8000` (browsers block cross-directory images on directly opened files). Native export keeps original image bytes by default (`--image-sizing cap`); explicit compact export uses `--image-sizing display --image-scale 2 --image-quality 85`, and `--no-image-optimize` forces original bytes. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/template-designer.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/template-designer.md index b0094c82..95a7f03d 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/template-designer.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/template-designer.md @@ -4,184 +4,66 @@ ## Core Mission -Generate reusable structured page templates inside the workspace selected by Create Template's Create Layout or Create Deck child workflow, and write the resolved Design Spec that captures the source-derived rules that make the template reusable. For Deck, include descriptive recurring-application context; for Layout, keep structure brand-neutral and application-neutral. - -> This is a standalone role: only triggered by the Create Layout or Create Deck child workflow under `/create-template`. Create Brand never invokes it. Library and project outputs share one spec schema and asset routing with scope-resolved spec filenames; this is not the template selection step in the main PPT generation pipeline. +Generate reusable structured page templates inside the workspace selected by Create Template's Create Layout or Create Deck child, and write the Design Spec that captures the source-derived rules making the template reusable — for Deck with descriptive recurring-application context, for Layout brand-neutral and application-neutral. A standalone role triggered only by those two children; Create Brand never invokes it, and this is not the template-selection step of the main pipeline. ## Usage -- **Trigger**: `/create-template` → Create Layout or Create Deck child workflow -- **Workspace root**: `library` (default) → `skills/ppt-master/templates/<kind_dir>/<template_name>/`; `project` → the confirmed `<target_project>/` -- **Template source**: `<template_workspace>/templates/` in both scopes -- **Design Spec**: use the parent-resolved `<design_spec_path>` — library `templates/design_spec.md`; project `templates/design_spec.<kind>.<id>.md` -- **Input**: finalized template brief (output scope, target project when project-scoped, template ID, display name, kind, structural use cases or Deck application context, tone, theme mode, canvas format, optional reference assets, accepted basic template norms) +- **Workspace root**: `library` → `skills/ppt-master/templates/<kind_dir>/<template_name>/`; `project` → the confirmed `<target_project>/`; template source is `<template_workspace>/templates/` in both; the Design Spec is the parent-resolved `<design_spec_path>` (library `templates/design_spec.md`, project `templates/design_spec.<kind>.<id>.md`). +- **Input**: the finalized brief (scope, target project, template ID, display name, kind, structural use cases or Deck application context, tone, theme mode, canvas, optional reference assets, accepted norms) plus, for a PPTX reference, the import workspace described in [`template-tools.md`](../scripts/docs/template-tools.md) — `analysis/manifest.json`, `analysis/native_structure.json`, `sources/source.pptx` (never a template asset), `validation/conversion-report.json`, exported resources, immutable `svg/` layered backing and `svg/inheritance.json`, optional `svg-flat/`, and the editable `authoring-svg/` bundle with model-readable `authoring_summary.json` and tool-only `authoring_manifest.json`. -**Hard rule — scope is execution metadata**: Use `output_scope` and `target_project` to route files, but do not write either field into `<design_spec_path>` frontmatter. Do not create a new PPTX structure mode; deck/layout output declares `native_structure_mode: structured`. +**Hard rule — scope is execution metadata**: route files by `output_scope` / `target_project` but never write them into frontmatter. Deck/layout output always declares `native_structure_mode: structured`; never invent another structure mode. -**Workspace precondition**: The workflow has already resolved `<design_spec_path>` and checked all destinations. Library `templates/` is empty. The active authoring root contains no bare spec, selected-kind spec, or SVG roster; unique qualified roster-free siblings may remain untouched. When the target project already has the other structural kind, the parent workflow supplies an isolated project-shaped authoring root and owns the later Layout-over-Deck atomic install. Check collision-free destinations in `images/`, `icons/imported/`, and `exports/` when applicable. Optional directories may be absent until their first real file is written. Project scope additionally requires an initialized target project. Do not begin final writes before that all-at-once preflight passes. +**Workspace precondition**: the parent has resolved `<design_spec_path>` and checked all destinations (library `templates/` empty; the authoring root free of a bare spec, selected-kind spec, or roster; collision-free `images/`, `icons/imported/`, `exports/`; an isolated project-shaped root supplied when the other structural kind exists). Never begin final writes before that preflight passes. -When the workflow provides a PPTX reference source, the effective input package comes from the unified `pptx_template_import.py` preparation workspace and becomes: - -- finalized template brief -- `analysis/manifest.json` — source-deck facts (slide size, theme, per-master themes, resources, image map, placeholders, layouts, masters, slides, SVG file paths, page-type candidates) -- `analysis/native_structure.json` — stable source master/layout keys, picker names, parent-master relationships, placeholder type/index/geometry, source hash, and source-graph quality facts -- `sources/source.pptx` — byte-preserved backing package for visual/package cross-checking; never a final template asset -- `validation/conversion-report.json` — source-recovery and fidelity diagnostics, when present -- exported `images/` plus other populated semantic resource directories -- `svg/master_*.svg` / `svg/layout_*.svg` — immutable layered native-payload backing; every master / layout in the deck rendered once, including ones no sample slide references -- `svg/slide_NN.svg` — immutable slide-local native-payload backing; do not bulk-read because opaque native payload is retained -- `svg/inheritance.json` — which layout / master each slide consumes -- optional `svg-flat/slide_NN.svg` — immutable complete-page verification backing generated only when explicitly requested; do not use it as the editable source -- `authoring-svg/` and optional `authoring-svg-flat/` — new compact SVG bundles generated from parsed PPTX evidence by `pptx_template_import.py` for Type A input or by the standalone `svg_authoring_view.py` migration path; the layered bundle is Template_Designer's editable authoring surface and also contains model-readable `authoring_summary.json` plus tool-only `authoring_manifest.json` -- optional screenshots for visual cross-checking - -PPTX import interpretation: - -- Placeholder guides in master / layout SVGs are layout signals. Use `analysis/manifest.json` placeholder records for type / index / geometry / base style; do not copy dashed guide boxes into final templates unless the visual design truly uses dashed boxes. -- Charts, SmartArt, diagrams, and OLE objects may appear as typed placeholders in layered SVGs. In flat SVGs they may show preview images. Treat them as source intent markers, not reusable decorative assets. -- The asset filenames referenced by SVGs are governed by the manifest asset map. Prefer those references over inventing duplicate asset names. - -Input priority for PPTX-backed template creation depends on the AI-derived internal strategy recorded as `replication_mode`: +**PPTX import interpretation**: placeholder guides in master/layout SVGs are layout signals — use manifest placeholder records for type/index/geometry/base style and copy no dashed boxes unless the design uses them; charts, SmartArt, diagrams, and OLE objects are source intent markers, not reusable decoration; asset filenames follow the manifest map. Use manifest facts for orientation; open screenshots or the PPTX only for visual cross-checking. | Mode | Authoritative inputs | Model-facing inputs | |---|---|---| -| `standard` / `fidelity` | Finalized brief for the newly designed output; `analysis/manifest.json` for factual canvas/theme/resources | `authoring-svg/authoring_summary.json`, every layered source Master/Layout as structural and visual evidence, layered source Slides, optional flat spot checks, and exported resources. Do not read `authoring_manifest.json`. `standard` authors a compact result; `fidelity` authors broader useful source-aligned coverage. Neither copies source identities merely because they exist. | -| `mirror` | Inline native Chart/Table JSON plus `analysis/manifest.json`, `analysis/native_structure.json`, and `svg/inheritance.json`; the publisher validates the tool-only authoring manifest | `authoring-svg/authoring_summary.json` plus every reachable layered compact SVG as the editable authoring source; optional `authoring-svg-flat/` for complete-page verification; matching lossless `svg/` only for source/package validation and supported non-visible payload recovery, never visible-subtree copying. | +| `standard` / `fidelity` | The brief for the newly designed output; `analysis/manifest.json` for canvas/theme/resources | `authoring_summary.json`, every layered source Master/Layout as structural and visual evidence, layered Slides, optional flat spot checks, exported resources — never `authoring_manifest.json`. `standard` authors a compact result, `fidelity` broader source-aligned coverage; neither copies source identities merely because they exist | +| `mirror` | Inline native Chart/Table JSON plus `manifest.json`, `native_structure.json`, `svg/inheritance.json`; the publisher validates the tool-only manifest | `authoring_summary.json` plus every reachable layered compact SVG as the editable source; optional `authoring-svg-flat/` for verification; lossless `svg/` only for validation and non-visible payload recovery, never visible-subtree copying | -**Mandatory — authored construction bundle**: As soon as `replication_mode` -resolves to `standard` or `fidelity`, and before selecting any page or template -contour, read [`native-shape-authoring.md`](./native-shape-authoring.md) and -[`preset-shape-vocabulary.md`](./preset-shape-vocabulary.md) completely and -retain both for the active authoring context. Do not load this bundle for -`mirror`; it preserves source-owned geometry and never selects or authors -replacement contours. +**Mandatory — authored construction bundle**: as soon as `replication_mode` resolves to `standard` or `fidelity`, and before selecting any contour, read [`native-shape-authoring.md`](./native-shape-authoring.md) and [`preset-shape-vocabulary.md`](./preset-shape-vocabulary.md) completely; never load them for `mirror`. -Use the compact facts in `analysis/manifest.json` for orientation. Open screenshots or the original PPTX only for visual cross-checking. - -**Native structure output**: Always set `native_structure_mode: structured`. - -**Hard rule — native objects are compiled output**: Treat Theme, Master, -Layout, and Placeholder as PowerPoint implementation objects, not template -kinds. Layout owns topology, placement, semantic text roles, and spatial text -behavior. Deck identity owns paint, typeface identity, and fixed identity -assets; its application context describes the recurring presentation family. Under -downstream `layout` scope, resolve final placeholder formatting from the Layout -roles plus the confirmed identity, reading mode, and type scale; downstream -`mirror` scope preserves source structure and comparable presentation while -allowing compact SVG spelling. Compile -the applicable rules into the same native graph without merging their source -ownership. +**Hard rule — native objects are compiled output**: Theme, Master, Layout, and Placeholder are PowerPoint implementation objects, not template kinds. Layout owns topology, placement, semantic text roles, and spatial text behavior; Deck identity owns paint, typeface identity, and fixed identity assets, with application context describing the recurring family. Downstream `layout` scope resolves placeholder formatting from the Layout roles plus confirmed identity, reading mode, and type scale; `mirror` scope preserves source structure and comparable presentation in compact SVG. Compile the rules into one native graph without merging ownership. | Mode | Output structure contract | |---|---| -| `standard` / `fidelity` | Review the complete source Master/Layout inventory, then author complete project-canonical Slide SVG prototypes and an intentional new Master/Layout/slot system. Every retained Layout has at least one Slide prototype. `standard` stays compact; `fidelity` retains broader useful source-aligned families. Source identities do not define the output topology. Choose page-fit contours from the full native vocabulary before their authoring forms; keep exact native atoms independent, materialize a Boolean result only where one contour requires it, and use freeform last. | -| `mirror` | Review and author one complete compact SVG per validated source Slide, retaining only its referenced Layout and parent Master. Keep reachable identities, parentage, assignment, placeholder facts, inline JSON native authority, and source meaning. Presentation should remain recognizably similar, but SVG nodes and code need not be isomorphic. Publication completes inherited context and maps fixed-layer groups into direct atoms without inventing facts or semantically redesigning the reachable graph. | +| `standard` / `fidelity` | Review the complete source Master/Layout inventory, then author complete Slide SVG prototypes and an intentional new Master/Layout/slot system; every retained Layout has at least one prototype; `standard` stays compact, `fidelity` retains broader useful families; source identities never define output topology. Choose page-fit contours from the full native vocabulary before their authoring forms: exact native atoms independent, a Boolean result only where one contour requires it, freeform last | +| `mirror` | Review and author one complete compact SVG per validated source Slide with only its referenced Layout and parent Master, keeping reachable identities, parentage, assignment, placeholder facts, inline JSON authority, and meaning; presentation recognizably similar, nodes and code not isomorphic; publication completes inherited context and maps fixed-layer groups into direct atoms without inventing facts | -Every output is a complete standalone Slide SVG preview that resolves Master + -Layout + Slide context. Explicit layer markers retain ownership; standalone -Master/Layout definition SVGs are not template artifacts. +Every output is a complete standalone Slide preview resolving Master + Layout + Slide context with explicit layer markers; standalone Master/Layout definition SVGs are not template artifacts. -**Authored preset rule**: In `standard` / `fidelity`, when one registered -PowerPoint preset exactly expresses one complete object, use -`preset_shape_svg.py` as defined by -[`native-shape-authoring.md`](./native-shape-authoring.md). Its compact -canonical `<g>` is one semantic atom after validation: it may remain -Slide-local, serve as the one direct carrier of an `object` slot, or carry -Master/Layout fixed-layer ownership. This is the only `<g>` exception to the -fixed-layer atomicity rule; ordinary groups remain forbidden there. Preset -paint comes from the confirmed brief and `<design_spec_path>` -color scheme. Do not copy an expanded import carrier/preview/fingerprint -bundle into an authored template. `mirror` instead uses the new compact parsed -SVG as its visible authoring source and never transplants the expanded lossless -visible subtree. The exact syntax and validation -contract remain owned by -[`shared-standards-core.md`](./shared-standards-core.md) and the native-shape reference. -When one preset is insufficient, apply the same reference's compound-page gate: -keep faithful atoms independent unless one contour requires Boolean -materialization, then use freeform only if neither construction succeeds. +**Authored preset rule**: in `standard` / `fidelity`, when one registered preset exactly expresses one complete object, use `preset_shape_svg.py` per [`native-shape-authoring.md`](./native-shape-authoring.md); its compact canonical `<g>` is one semantic atom after validation — Slide-local, the one carrier of an `object` slot, or a Master/Layout fixed layer — and the only `<g>` exception to fixed-layer atomicity. Paint comes from the brief and spec color scheme. Never copy an expanded import carrier/preview/fingerprint bundle into an authored template; `mirror` authors from the compact parsed SVG and never transplants the lossless subtree. When one preset is insufficient, apply the same reference's compound-page gate. Syntax and validation are owned by `shared-standards-core.md` and the native-shape reference. -**Hard rule — reachable mirror graph**: Emit exactly one complete source-page -prototype per source Slide and preserve only the transitive chain `Slide → -Layout → Master`. Source Master/Layout identities outside that closure remain -analysis evidence and produce no SVG. Use `standard` / `fidelity` when useful -unreferenced source structures must be re-authored as complete Slide prototypes. +**Hard rule — reachable mirror graph**: exactly one prototype per source Slide, preserving only the transitive `Slide → Layout → Master` chain; identities outside that closure produce no SVG (re-author useful ones through `standard` / `fidelity`). -**Hard rule — no duplicate authored Layout contracts**: In `standard` / `fidelity`, distinct output Layout keys must differ in fixed Layout atoms or slot topology/type/index/bounds/binding. Topic, sample wording, or Slide-local content alone never justifies another authored key. Mirror keeps distinct reachable source Layout identities even when two source contracts are visibly equivalent. +**Hard rule — no duplicate authored Layout contracts**: distinct authored keys differ in fixed atoms or slot topology/type/index/bounds/binding; topic, sample wording, or Slide-local content never justifies another key. Mirror keeps distinct reachable source identities even when visibly equivalent. -**Downstream boundary**: Stage 1 independently confirms the current communication contract. Strategist then inspects the installed prototypes, the Deck's descriptive application context, and the current content to author one application plan. It records `mirror`, `layout`, or `style` and, where applicable, `strict` or `adaptive` only as internal exporter values. Explicit user language overrides AI judgment, but the confirmation UI never asks the user to choose these implementation labels. Template_Designer does not preselect that project-level plan. - -For `mirror`, `<design_spec_path> §V` must be followed by a `Source Preservation Map` that records each source Slide's retained Master/Layout assignment and output file. When source identities fall outside the reachable closure, one sentence may note that they exist but were not materialized; no per-identity analysis is required. The map is execution evidence, not a design-decision log. `standard` and `fidelity` record only their newly authored output roster and structure. +**Downstream boundary**: Stage 1 independently confirms the communication contract; Strategist inspects the installed prototypes, Deck context, and content, authors one application plan, and records `mirror` / `layout` / `style` and `strict` / `adaptive` only as internal exporter values. Template_Designer never preselects that plan. For `mirror`, `§V` is followed by a `Source Preservation Map` (each Slide's retained Master/Layout assignment and output file, one optional sentence for unmaterialized identities); authored modes record only their new roster. --- ## Page Roster -The output page set is determined by the confirmed natural-language creation intent. Template_Designer derives one internal `replication_mode` so the deterministic authoring tools can execute: +| Mode | When | Roster | +|------|------|--------| +| `standard` (default) | A clean, reusable, compact system | Cover, chapter, ending, optional TOC, and one or a small required set of distinct content Layouts; typically 4–6 prototypes | +| `fidelity` | Broader, source-aligned but newly designed coverage | Canonical roles plus intentionally designed variants covering the useful source composition range | +| `mirror` | Preserving validated native source facts and a similar presentation | One compact prototype per source slide, `<NNN>_<page_type>.svg` in source order | -| Mode | When to use | Roster | -|------|-------------|--------| -| `standard` (default internal strategy) | The requested result is a clean, reusable, compact system | Cover, chapter, ending, optional TOC, and one or a small explicitly required set of distinct content Layouts; typically 4–6 prototypes | -| `fidelity` | The natural-language intent calls for broader, source-aligned but newly designed coverage | Canonical roles plus intentionally designed variants that cover the useful source composition range | -| `mirror` | The natural-language intent calls for preserving validated native source facts and a similar presentation | One compact SVG prototype reviewed/authored from parsed evidence per source slide, named `<NNN>_<page_type>.svg` by source order | - -**Hard rule — mode controls authorship**: `standard` and `fidelity` inspect the complete source structure but create new SVG documents and their own Master/Layout system. `mirror` also authors compact new SVG from parsed evidence, but it must retain the validated reachable identities, assignments, slots, meaning, and similar presentation rather than distilling, supplementing, or redesigning that closure. Code and node identity are not preservation requirements. +**Hard rule — mode controls authorship**: `standard` / `fidelity` inspect the complete source but create new SVGs and their own Master/Layout system; `mirror` authors compact new SVG from parsed evidence while retaining the validated closure rather than distilling, supplementing, or redesigning it. ### Standard mode -| # | Filename | Purpose | Description | -|---|----------|---------|-------------| -| 01 | `01_cover.svg` | Cover | Fixed structure: title, subtitle, date, organization | -| 02 | `02_chapter.svg` | Chapter page | Fixed structure: chapter number, chapter title | -| 03 | `03_content.svg` | Content page | Flexible structure: only defines header/footer; content area freely laid out by AI | -| 04 | `04_ending.svg` | Ending page | Fixed structure: thank-you message, contact info | -| -- | `02_toc.svg` | Table of contents | Optional: TOC title, chapter list (number + title) | - -**Default — compact authored roster (may override when the confirmed Deck application requires distinct roles)**: Keep Layout content pages structurally flexible. For Deck, add only the distinct prototypes needed to express its confirmed recurring narrative/content roles; do not manufacture variants from hypothetical future uses. - -**Intent-derived compact variants**: `standard` may include more than one Layout for the same canonical role when the brief requires genuinely different reusable structures, such as two-column evidence and three-card KPI content. Keep the roster compact and brief-driven rather than mining the source page set. When siblings exist, suffix every sibling (`03a_content_two_col.svg`, `03b_content_three_card.svg`) instead of treating one arbitrary variant as the unsuffixed default. This does not require `fidelity`; derive `fidelity` when the broader roster is driven by complete PPTX/SVG page evidence. - -**Naming note**: The numeric prefix is the template's own presentation order. Its base sequence stays contiguous; sibling variants share their parent's number only through unique lowercase suffixes such as `03a` / `03b`. When the optional TOC page is included it takes `02_toc.svg` and the later types shift by one: `01_cover`, `02_toc`, `03_chapter`, `04_content`, `05_ending`. Numbers carry no meaning across templates — tooling derives the page type from the token after the underscore, so both spellings of each type are equivalent. +`01_cover.svg` (title, subtitle, date, organization), `02_chapter.svg` (chapter number and title), `03_content.svg` (header/footer only; content area free), `04_ending.svg` (thank-you, contact), optional `02_toc.svg` (TOC title, chapter list) which shifts later types by one (`01_cover`, `02_toc`, `03_chapter`, `04_content`, `05_ending`). **Default — compact authored roster (may override when the confirmed Deck application requires distinct roles)**: keep Layout content pages structurally flexible; for Deck add only the prototypes its confirmed roles need, never variants from hypothetical uses. `standard` may hold several Layouts for one canonical role when the brief requires genuinely different structures (two-column evidence vs three-card KPI), suffixing every sibling (`03a_content_two_col.svg`, `03b_content_three_card.svg`) rather than leaving one unsuffixed; this does not require `fidelity`. The numeric prefix is the template's own order with a contiguous base sequence; tooling reads the page type from the token after the underscore. ### Fidelity mode -When the derived implementation writes `replication_mode: fidelity`, design a broader reusable roster that stays close to the source's visual language and useful composition examples. The output Master/Layout system is authored independently from source topology. - -**Variant naming**: append a lowercase letter suffix to the parent type's index, preserving sort order: - -| Parent type | Example variants | -|-------------|------------------| -| Chapter | `02a_chapter_full.svg`, `02b_chapter_minimal.svg` | -| Content | `03a_content_two_col.svg`, `03b_content_data_card.svg`, `03c_content_quote.svg` | -| Ending | `04a_ending_thanks.svg`, `04b_ending_contact.svg` | - -Extension page types beyond the canonical four (transition / appendix / disclaimer / divider) take the next free index after the roster: `05_section_break.svg`, `06_appendix.svg`, `07_disclaimer.svg` in a four-page roster (one higher when `02_toc` is present). - -**Roster decision**: - -- Choose variants from useful visual composition types such as two-column content, hero image, icon grid, data card, and quote -- Keep only variants that add a genuinely useful authored composition; source Layout keys and repeated source chrome are not clustering inputs -- Design each variant's Master/Layout/slot contract directly from its intended reusable behavior -- Record every emitted page in `<design_spec_path> §V Page Roster`; in library scope, `register_template.py` generates the corresponding index entry from `<template_workspace>/templates/*.svg`. Project scope skips registration - -> Variants reuse the parent type's placeholder set — see §4 (Placeholder Reference) below. +Design a broader roster close to the source's visual language with an independently authored Master/Layout system. Variants append a lowercase letter to the parent index (`02a_chapter_full.svg`, `02b_chapter_minimal.svg`, `03a_content_two_col.svg`, `03b_content_data_card.svg`, `03c_content_quote.svg`, `04a_ending_thanks.svg`); extension types (transition / appendix / disclaimer / divider) take the next free index (`05_section_break.svg`, `06_appendix.svg`). Choose variants from useful composition types (two-column, hero image, icon grid, data card, quote); keep only genuinely useful authored compositions — source Layout keys and repeated chrome are not clustering inputs; design each variant's contract from its reusable behavior; record every page in `§V` (library registration derives the index entry from `templates/*.svg`). Variants reuse the parent placeholder set (§4). ### Mirror mode -When the derived implementation writes `replication_mode: mirror`, author a new compact template workspace from validated parsed evidence rather than designing a different system: - -- Kind eligibility: Create Layout mirror is legal only when the validated source contract is already brand-neutral and application-neutral. If supported source facts retain organization-specific identity or reusable application policy, stop and return to Create Template dispatch: use `standard` / `fidelity` to author a new Layout, or Create Deck to retain those facts. Removing, repainting, retyping, or discarding application rules is never mirror. -- Model-facing authoring source: `authoring-svg/authoring_summary.json`, every reachable layered `authoring-svg/*.svg`, `svg/inheritance.json`, and `analysis/native_structure.json`. Template_Designer must actually inspect and, where needed, redraw/normalize these new compact SVGs before publication. Do not read `authoring-svg/authoring_manifest.json`; the publisher validates it internally. When present, use `authoring-svg-flat/` only for full-page verification. Matching lossless `svg/` files are immutable source/package evidence and non-visible payload backing, never visible authoring input. -- Precondition: the import evidence identifies every source Slide and its referenced Layout/Master, picker names, placeholder contract, and fixed visual layers. Stop when required reachable facts or supported mirrored geometry are missing; unused source identities are out of scope. -- Output: `<template_workspace>/templates/<NNN>_<page_type>.svg` for every source Slide and no standalone Master/Layout SVG. `<NNN>` is the zero-padded source slide index (3 digits) and `<page_type>` comes from `analysis/manifest.json` `pageTypeCandidates` — `cover` / `toc` / `chapter` / `content` / `ending`, falling back to `content`. Preserve source Slide order. -- Context completion: each source-page SVG resolves Master + Layout + Slide context while retaining explicit layer markers, so completion does not flatten ownership. -- Required preservation: within the reachable closure, preserve source Master/Layout keys and picker names, Layout-to-Master parentage, slide assignments, placeholder type/index/bounds, original example meaning, sprite-sheet crop behavior, and supported native facts. Imported/template-owned Chart/Table inline JSON is authoritative; its compact SVG preview may be approximate. -- Allowed authoring: redraw or normalize visible SVG geometry, paint spelling, grouping, root declarations, asset paths, and fixed-layer wrappers when the resulting presentation remains similar and ownership/paint intent stays intact. Complete inherited context and emit direct structural atoms; code, node count, and exact path identity need not match the import. -- Forbidden: commonality extraction, semantic synthesis, promotion/demotion, renaming, re-parenting, placeholder invention, changes to authoritative Chart/Table JSON without matching intent, or any visible redesign that changes the source communication result. -- `<design_spec_path>` §V gives each emitted source-Slide prototype a roster row. If relevant, one sentence notes source Master/Layout identities outside the mirror closure; `Source Preservation Map` records each retained source-Slide assignment. - -**Mirror consumption boundary**: `replication_mode: mirror` describes source-to-workspace fidelity and only makes literal downstream reuse technically possible. Strategist independently derives the application plan from the current communication contract, content, actual prototype roster, and any explicit natural-language instruction. It may select, repeat, skip, reorder, or reorganize prototypes; no internal scope forces source page count, source order, or one output slide per source slide. - -**What mirror is not**: a redesign, topology-cleanup, or recovery mode. It is a new compact SVG authoring pass over parsed evidence, followed by deterministic validation/publication; neither byte identity nor SVG-code identity is promised. Charts, SmartArt, OLE objects, and EMF / WMF media that fail to enter the parsed evidence cannot be recovered by mirror. If the import workspace has missing media or unsupported objects, mirror inherits those gaps — report them before authoring begins. +Author a new compact workspace from validated parsed evidence rather than a different system. Create Layout mirror is legal only when the source contract is already brand-neutral and application-neutral; otherwise return to dispatch (author a Layout through `standard` / `fidelity`, or retain a Deck) — removing, repainting, retyping, or discarding rules is never mirror. Model-facing source: `authoring_summary.json`, every reachable layered `authoring-svg/*.svg`, `svg/inheritance.json`, `native_structure.json`; inspect and where needed redraw these before publication; never read `authoring_manifest.json`; lossless `svg/` is immutable evidence. Precondition: the evidence identifies every source Slide with its Layout/Master, picker names, placeholder contract, and fixed layers — stop when reachable facts or supported geometry are missing. Output `<template_workspace>/templates/<NNN>_<page_type>.svg` per source Slide (type from `pageTypeCandidates`, fallback `content`), no standalone Master/Layout SVG, each resolving full context with explicit layer markers. Preserve within the closure: keys and picker names, parentage, assignments, placeholder type/index/bounds, example meaning, sprite-sheet crop behavior, supported native facts; imported Chart/Table JSON is authoritative with an approximate preview. Allowed: redrawing geometry, paint spelling, grouping, root declarations, asset paths, and fixed-layer wrappers while presentation and ownership stay intact. Forbidden: commonality extraction, synthesis, promotion/demotion, renaming, re-parenting, placeholder invention, JSON changes without intent, visible redesign. Mirror describes source-to-workspace fidelity and only makes literal reuse possible; Strategist independently decides selection, repetition, order, and reorganization. Mirror is not a recovery mode: charts, SmartArt, OLE, and EMF/WMF that fail to enter the parsed evidence stay gaps — report them before authoring. --- @@ -189,21 +71,9 @@ When the derived implementation writes `replication_mode: mirror`, author a new ### 1. Must Generate design_spec.md -**Scope rule — package-specific rules only.** A Deck `design_spec.md` describes its recurring application plus integrated identity and structure. A Layout spec describes only brand-neutral reusable structure and may state supported content shapes/delivery settings without owning a communication objective or narrative. Neither restates generic constraints — those live in the canonical references and are already loaded by every downstream role: +**Scope rule — package-specific rules only.** A Deck spec describes its recurring application plus integrated identity and structure; a Layout spec only brand-neutral reusable structure with supported content shapes. Neither restates generic constraints already in every downstream reader's context — SVG rules and module routing (`shared-standards-core.md`), the layout-structure vocabulary (`executor-base.md`), spacing bands and font-size ratio bands (`strategist.md`), the canonical placeholder table (§4), content methodology (`strategist.md`), usage-instruction boilerplate, created-date / page-count rows. If a rule is generic, omit it; if the template breaks a generic rule, write only the deviation. When rewriting an existing template, delete such sections rather than leaving pointers. -- Always-on SVG rules and conditional-module routing → [`shared-standards-core.md`](./shared-standards-core.md) -- Generic layout pattern library, spacing bands, font-size ratio bands → [`strategist.md`](strategist.md) (used when authoring the **project** design spec) -- Canonical placeholder vocabulary → §4 below -- Content methodology (pyramid / SCQA / MECE) → [`strategist.md`](strategist.md) - -Re-declaring any of these in a template `design_spec.md` is noise — Strategist already has them in context, and duplication forces every relaxation to sweep N templates instead of one source. **If a rule is generic, omit it. If this template breaks a generic rule, write only the deviation.** - -**Required skeleton by kind:** - -The frontmatter is portable across library and project scope. Do not add -`output_scope` or `target_project`; those belong only to the workflow execution -brief. Use `deck_id` or `layout_id`; do not invent a generic `template_id` -field that the registrar cannot bind to its library kind. +Frontmatter is portable across scopes: never `output_scope`, `target_project`, or a generic `template_id`; use `deck_id` / `layout_id`. **Deck**: @@ -219,19 +89,14 @@ canvas_format: ppt169 canvas_width: 1280 canvas_height: 720 canvas_viewbox: "0 0 1280 720" -# Required when a PPTX/SVG source canvas is known; keep equal to canvas_* unless explicitly normalized. -source_canvas_width: 1280 +source_canvas_width: 1280 # required when a PPTX/SVG source canvas is known source_canvas_height: 720 source_viewbox: "0 0 1280 720" replication_mode: standard | fidelity | mirror -# Required for every deck/layout template. Source packages remain analysis-only. native_structure_mode: structured page_count: <N> -# Optional — only when this template overrides canonical placeholder vocabulary. -# Omit the map when canonical vocabulary is sufficient; use [] for an intentional zero-marker page. -# placeholders: +# placeholders: # optional vocabulary override; [] asserts an intentional zero-marker page # 01_cover: ["{{TITLE}}", "{{SUBTITLE}}", "{{BRAND_LOGO}}"] -# 03_content: ["{{KEY_MESSAGE}}", "{{CONTENT_AREA}}"] --- # [Template Name] — Design Specification @@ -239,387 +104,109 @@ page_count: <N> ## I. Template Overview | Application context | Definition | |---|---| -| Recurring presentation family | <repeatable situations this Deck serves> | -| Intended audiences and outcomes | <who it serves and what the presentation should enable> | +| Recurring presentation family | <repeatable situations> | +| Intended audiences and outcomes | <who and what it enables> | | Delivery and reading assumptions | <presented / close-read / handoff / mixed> | -| Representative narrative/page roles | <roles commonly present in this presentation family; descriptive, not mandatory> | - -- Design tone, theme mode (light / dark / mixed), and the visual identity visible at a glance +| Representative narrative/page roles | <descriptive, not mandatory> | +- Design tone, theme mode, and the visual identity visible at a glance ## II. Color Scheme -- HEX values with role labels (primary / accent / background / text / etc.) -- Brand-specific application rules when present (e.g. "KPI cards rotate blue→green→red→yellow") +- HEX values with role labels; brand-specific application rules when present ## III. Typography (omit without template-owned typeface identity) -- Per-role stacks for identity (display serif, brand face, etc.) -- A non-preinstalled face may lead only after user-confirmed target installation/approved install; no auto-embedding -- Otherwise export a safe face; unavailable proprietary faces stay references. CSS tails aid preview, not deterministic PowerPoint fallback -- Body baseline px (informational; `spec_lock.md` owns the actual values per project) +- Per-role stacks; a non-preinstalled face leads only after user-confirmed installation, no auto-embedding; otherwise a safe face, with proprietary faces as references (CSS tails aid preview only); body baseline px (informational — `spec_lock.md` owns project values) ## IV. Signature Design Elements -- Decorative motifs that ARE this template — top bar, gradient underline, logo treatment, brand emblem placement -- Source-derived layout grammar — grid / column rhythm, page chrome, image zones, crop/clip behavior, scrim/overlay or baked-alpha treatment, and density rhythm that make the template recognizable -- Optional XML snippet for any reusable component unique to this template +- Motifs that ARE this template; source-derived grammar — grid/column rhythm, chrome, image zones, crop/clip, scrim/overlay or baked alpha, density rhythm; optional XML for a unique reusable component ## V. Page Roster -One row per complete Slide SVG describing what this template's version of cover / chapter / content / ending looks like: background treatment, decorative anchors, layout rhythm, image behavior, content density, intended role, reusable slots, and structural capacity. Do not add required/optional/repeatable status or fixed/replaceable/example-only content policy. For `standard` / `fidelity`, record the newly authored Layout key and PowerPoint picker name. For `mirror`, record the preserved reachable Master/Layout keys and picker names without redesigning them. Roster entries must match every SVG on disk. - -For `mirror`, add `### Source Preservation Map` immediately after the roster with columns `Source slide`, `Source Master`, `Source Layout`, `Output SVG`, and `Preservation status`. When relevant, add one sentence that unreferenced source identities were not materialized by mirror; do not add individual disposition rows or synthesis rationale. Do not add source-structure disposition rows to `standard` / `fidelity` templates. +One row per Slide SVG: background, decorative anchors, rhythm, image behavior, density, role, reusable slots, capacity; the authored Layout key and picker name (mirror: the preserved keys). No required/optional/repeatable status or fixed/replaceable/example-only policy. Entries match every SVG on disk. Mirror adds `### Source Preservation Map` (`Source slide | Source Master | Source Layout | Output SVG | Preservation status`) plus one optional sentence for unmaterialized identities. ## VI. Assets (omit when none) -Logos, cover backgrounds, brand textures bundled with the template package — file name, dimensions, intended usage. - ## VII. Placeholder Overrides (omit when none) -Reference the `placeholders:` frontmatter declaration and explain the rationale (e.g. "consulting decks lead with `{{KEY_MESSAGE}}` instead of `{{PAGE_TITLE}}`"). ``` -**Layout**: - -```markdown ---- -layout_id: <id> -kind: layout -category: general | scenario | government | special -summary: <one-line structural use case> -keywords: [tag1, tag2, tag3] -canvas_format: ppt169 -canvas_width: 1280 -canvas_height: 720 -canvas_viewbox: "0 0 1280 720" -# Required when a PPTX/SVG source canvas is known. -source_canvas_width: 1280 -source_canvas_height: 720 -source_viewbox: "0 0 1280 720" -replication_mode: standard | fidelity | mirror -native_structure_mode: structured -page_count: <N> -page_types: [cover, toc, chapter, content, ending] -# Optional vocabulary override. -# placeholders: -# 01_cover: ["{{TITLE}}", "{{SUBTITLE}}"] ---- - -# [Layout Name] — Design Specification - -## IV. Signature Design Elements -- Structure-specific grid, zones, page chrome, image behavior, density rhythm, semantic text roles, alignment/wrapping/capacity behavior, and slot conventions -- Neutral preview paint/font/size may expose hierarchy, but it is not a color, typeface, or final type-scale identity - -## V. Page Roster -One row per emitted SVG with Layout key, picker name, supported content shape, and slot behavior. Roster entries must match the actual files on disk. - -For `mirror`, append the same `### Source Preservation Map` required above. - -## VII. Placeholder Overrides (omit when none) -Reference the `placeholders:` frontmatter declaration and explain the structural vocabulary deviation. -``` - -**Layout boundary**: Omit Template Overview, Color Scheme, Typography, Logo, -Voice & Tone, and Icon Style. A scenario category records geometric fit only. -Structural text roles, alignment, wrapping, and capacity remain valid Layout -rules; final font families, weights, colors, and absolute sizes do not. -Do not prescribe communication objectives, audience outcomes, required -narrative order, fixed boilerplate, or example-content retention. The -frontmatter `summary` carries concise structural selection context; the -deck-only Template Overview remains the application segment read during -template application. - -Sections to **omit** from template `design_spec.md` (sourced elsewhere — listing them here is noise): - -| Don't write | Source | -|---|---| -| Always-on SVG rules and conditional-module routing | `shared-standards-core.md` | -| Generic layout pattern library (centered card / three-column / timeline / …) | `strategist.md` §4 | -| Generic font-size hierarchy (cover 2.5-5x body, page title 1.5-2x, …) | `strategist.md` §g | -| Canonical placeholder table (`{{TITLE}}`, `{{PAGE_NUM}}`, …) | §4 below | -| Content methodology (pyramid / SCQA / MECE) | `strategist.md` | -| "Usage Instructions" boilerplate (copy template / select page / …) | `create-template.md` | -| Created Date / Page Count rows | not a library-level field | - -When rewriting an existing template that contains an omitted generic section, -delete it rather than leaving a pointer. Keep a template-specific boundary only -inside the package-owned section it qualifies (asset system, motif, image -treatment, or page roster); do not preserve a generic technical-rules heading. +**Layout**: `layout_id`, `kind: layout`, `category: general | scenario | government | special`, `summary`, `keywords`, the canvas and source-canvas fields, `replication_mode`, `native_structure_mode: structured`, `page_count`, `page_types: [cover, toc, chapter, content, ending]`, optional `placeholders:`; body sections **IV** (structure-specific grid, zones, chrome, image behavior, density, semantic text roles, alignment/wrapping/capacity, slot conventions; neutral preview paint is not identity), **V** (one row per SVG with Layout key, picker name, content shape, slot behavior; mirror map as above), and **VII** when overrides exist. Omit Template Overview, Color Scheme, Typography, Logo, Voice & Tone, and Icon Style; a scenario category records geometric fit only; never prescribe objectives, outcomes, narrative order, boilerplate, or example retention — the frontmatter `summary` carries selection context. ### 2. Inherit Design Specification -Templates must strictly follow the finalized template brief and the generated `<design_spec_path>`: -- **Canvas dimensions**: `canvas_format` is not enough; root SVG `viewBox` matches `canvas_viewbox` in the design spec. Root `width` / `height` are optional compatibility attributes and are not PPT Master canvas authority. -- **Source canvas**: when a PPTX/SVG reference is used, record `source_canvas_width`, `source_canvas_height`, and `source_viewbox`. If the output canvas differs from the source, normalize all geometry, typography, line heights, strokes, and image crop coordinates explicitly instead of relying on the shared aspect ratio. -- **Color scheme**: Uses primary, secondary, and accent colors from the spec -- **Font plan**: Uses the per-role font families declared in the spec -- **Layout principles**: Margins and spacing conform to the spec -- **Image system**: Image placement, crop/clip behavior, full-bleed zones, and scrim/overlay or baked-alpha treatment follow the source-derived norms in the spec -- **Deck application**: Template Overview describes the recurring situations, audiences/outcomes, and representative roles; Page Roster factually describes the actual prototypes and reusable slots without prescribing future use +Templates strictly follow the brief and `<design_spec_path>`: root `viewBox` equals `canvas_viewbox` (`width` / `height` optional and non-authoritative); with a PPTX/SVG reference record `source_canvas_*` and `source_viewbox`, and normalize all geometry, typography, strokes, and crops explicitly when the output canvas differs; colors, fonts, margins, image system, and Deck application follow the spec. With import output, prefer imported theme values over guesses, reuse exported `images/` directly, and treat `pageTypeCandidates` as hints. Preconditions: `standard` inspects the complete lightweight Master/Layout inventory plus enough page IR to understand direction and assets; `fidelity` inspects every Master/Layout and page; `mirror` verifies every Slide and chain against the summary, `native_structure.json`, and `inheritance.json`, reports retained/omitted identities before authoring, then publishes only that graph. -If PPTX import output exists: -- Prefer imported theme colors and fonts over visually guessed values -- Reuse exported `images/` directly — raster images and SVG/EMF/WMF image media use the same canonical pool, and `<image>` references in `svg/` already point at it -- Treat page-type candidates from `analysis/manifest.json.pageTypeCandidates` as hints, not guarantees +#### 2.1 PPTX Import Mode Rule -**Precondition**: +`standard` reviews complete evidence, then authors a compact canonical roster and structure; `fidelity` authors a broader source-aligned roster matching the visual language without one-to-one identity retention; `mirror` preserves validated Slides, inheritance, placeholders, native facts, meaning, and presentation while authoring a compact workspace — visible SVG may be redrawn, retained structure cannot be renamed, gaps cannot be invented. **Hard rule — mirror publication is mechanical, visual authoring is not**: the materializer validates identity/SHA, refs, graph, assignments, and closure, composes inherited context, strips IR-only refs, and publishes the current tree; it never replaces an unchanged visible subtree with lossless XML. -- For `standard`, inspect the complete lightweight source Master/Layout inventory plus enough complete-page IR documents to understand the requested visual direction, structural vocabulary, and reusable assets. Author a compact new structure; source identities are evidence, not output requirements. -- For `fidelity`, inspect every lightweight source Master/Layout and complete-page IR document so the newly designed roster covers the useful source structure and composition range. Author broader source-aligned families without automatically copying every source identity. -- For `mirror`, verify every source Slide and its referenced Layout/Master against `authoring_summary.json`, `analysis/native_structure.json`, and `svg/inheritance.json`; then review/author every reachable compact SVG and publish only that graph. Lossless backing may validate provenance and recover supported non-visible payload, but never replaces the visible authored tree. Before authoring begins, report source Slide indexes plus retained and omitted Master/Layout identities. - -### 2.1 PPTX Import Mode Rule - -The imported PPTX has a different authority level in each replication mode. - -| Mode | Required behavior | -|---|---| -| `standard` | Review the complete source Master/Layout and visual evidence, then author a compact project-canonical roster and its Master/Layout/slot structure from the confirmed brief. Do not preserve source identities merely because they exist. | -| `fidelity` | Review the complete source Master/Layout and visual roster, then author a broader canonical roster and its own useful source-aligned Master/Layout/slot families. Match the source visual language closely without implying one-to-one identity retention. | -| `mirror` | Preserve validated source Slides and their reachable inheritance, placeholders, native facts, meaning, and similar presentation while authoring a compact new workspace. Complete each standalone SVG's inherited context; visible SVG may be redrawn/normalized without code isomorphism, but retained structure cannot be renamed and semantic gaps cannot be invented. | - -**Hard rule — mirror publication is mechanical, visual authoring is not**: -Template_Designer owns the compact visible SVG created from parsed evidence. -The materializer validates source identity/SHA, refs, graph, assignments, and -closure; composes inherited context; strips IR-only refs; and publishes that -current tree. It must never replace an unchanged visible subtree with lossless -source XML. Redrawing for compactness is allowed only while structure, meaning, -ownership, and a similar presentation remain intact. - -### 2.2 Native Shape Payload and Authoring IR +#### 2.2 Native Shape Payload and Authoring IR | Representation | Purpose | Payload rule | |---|---|---| -| Lossless import SVG | Immutable source/package evidence | Retain complete imported metadata, native object boundaries, hidden carriers, and source-scope identity for validation and supported non-visible payload recovery. Never copy its ordinary visible subtree into final templates. | -| Authoring IR bundle | Editable template-creation source | New compact SVG generated from parsed PPTX evidence. Omit opaque native payload and duplicate hidden carriers from model context; retain visible shape intent and stable document-local source refs. Models read `authoring_summary.json`; tools read `authoring_manifest.json` for source paths and initial hashes. | -| `standard` / `fidelity` output | Newly authored contract | Use editable basic primitives directly and `preset_shape_svg.py` compact canonical `<g>` output for exact preset matches. Keep faithful atoms independently composed when one contour is unnecessary; use `shape_boolean_svg.py` only where one compound closed contour must become an object, then allow a necessary freeform only if neither construction is faithful. Paint comes from the confirmed brief / `<design_spec_path>`. Reuse exported image/vector assets, not opaque source shape payload or source topology. | -| `mirror` output | Authored compact preservation contract | Publish the reviewed current authoring SVG, preserve validated structure/native facts, recover only supported non-visible semantics, and normalize fixed structural layers into semantic atoms. Strip IR-only source refs; never rehydrate ordinary visible source subtrees. | +| Lossless import SVG | Immutable evidence | Retains complete metadata, native boundaries, hidden carriers, scope identity for validation and non-visible recovery; its visible subtree is never copied into templates | +| Authoring IR bundle | Editable source | Compact SVG from parsed evidence without opaque payload or duplicate carriers; retains visible intent and document-local source refs; models read the summary, tools the manifest | +| `standard` / `fidelity` output | Newly authored contract | Editable primitives, compact canonical preset groups for exact matches, `shape_boolean_svg.py` only where one compound contour must become an object, necessary freeform last; paint from the brief/spec; exported assets reused, never opaque payload or source topology | +| `mirror` output | Compact preservation contract | Publishes the reviewed tree, preserves validated structure/native facts, recovers only supported non-visible semantics, normalizes fixed layers into semantic atoms, strips IR-only refs | -**Validation**: Mirror does not silently use stale metadata. Materialization -validates source-document hashes, known refs, graph/assignment closure, and -classifies authoring subtree hashes; a changed subtree is a legitimate authored -edit, not permission to copy the old visible tree back. If an imported object -cannot use the converter's supported non-visible metadata after normalization, -keep its current SVG fallback and report the -limitation. For exact registered preset matches, `standard` / `fidelity` -regenerate the compact helper group instead of transplanting opaque source -payload; otherwise they keep faithful atoms independently composed unless one -contour requires the Boolean gate, with necessary freeform last. -`data-pptx-replace-with` remains reserved for optional PowerPoint-native -Chart/Table replacement markers. - -**Explicit template SVG contract**: +Materialization validates document hashes, refs, and closure and classifies subtree hashes — a changed subtree is a legitimate edit, never permission to copy the old tree back; an object that cannot use supported non-visible metadata keeps its SVG fallback and is reported. `data-pptx-replace-with` stays reserved for Chart/Table replacement markers. | Authored/preserved fact | Template SVG declaration | |---|---| -| Master/Layout identity | Root `data-pptx-master` / `data-pptx-master-name` plus `data-pptx-layout` / `data-pptx-layout-name`; authored keys for `standard` / `fidelity`, source keys for `mirror` | -| Authored Master/Layout visual | In `standard` / `fidelity`, use a direct atomic child with `data-pptx-layer="master|layout"` and `data-pptx-editable="false"`. An ordinary `<g>` is forbidden; one validated compact canonical authored-preset `<g>` is a semantic atom and is the sole group exception. | -| Preserved source Master/Layout visual | In `mirror`, author direct atoms with the same Master/Layout ownership and comparable paint order/presentation. Compact grouping, geometry, and style spelling may differ; semantic regrouping or ownership changes are forbidden. | -| Content slot | Direct `<g id>` with `data-pptx-placeholder` and explicit `data-pptx-bounds`; `standard` / `fidelity` author the slot, while `mirror` preserves source type/index/bounds and carrier identity | +| Master/Layout identity | Root `data-pptx-master` / `-master-name` / `data-pptx-layout` / `-layout-name`; authored keys for `standard` / `fidelity`, source keys for `mirror` | +| Authored Master/Layout visual | Direct atomic child with `data-pptx-layer="master|layout"` and `data-pptx-editable="false"`; ordinary `<g>` forbidden, one validated compact preset `<g>` the sole exception | +| Preserved source visual | Direct atoms with the same ownership and comparable paint order; grouping and spelling may differ, regrouping and ownership changes may not | +| Content slot | Direct `<g id>` with `data-pptx-placeholder` and explicit `data-pptx-bounds`; authored modes author the slot, mirror preserves source type/index/bounds and carrier identity | | Page-only background | Direct full-canvas solid rect with `data-pptx-layer="slide"` | -| Structural page-frame hint | Optional `data-pptx-role` only when background/decoration/header/footer/logo/watermark/chrome/page-number behavior is not already expressed by layer/placeholder metadata; stable unique `id` required | +| Structural hint | Optional `data-pptx-role` only when layer/placeholder metadata cannot express background/decoration/header/footer/logo/watermark/chrome/page-number behavior; stable unique `id` | -Repeat inherited visuals in every standalone SVG so browser preview remains complete. Template export validates their equality and materializes the declared Master/Layout parts. It does not infer ownership. - -**Forbidden — legacy structure contract**: Do not carry `data-pptx-layout-kind`, `distilled`, `utility`, unmapped `baseline`, `preserve`, or direct atomic placeholders into a reusable template package. In `standard` / `fidelity`, treat such Type B inputs only as visual reference and author a complete current contract in a new workspace. Require the original PPTX Type A path when mirror must preserve existing native topology; see [`create-template`](../workflows/create-template.md). - -**Composite slot boundary**: A normal slot group has exactly one compatible -direct carrier. A validated compact canonical authored-preset `<g>` counts as -one carrier for an `object` slot because it compiles to one native shape; an -ordinary multi-object `<g>` does not. Only a genuinely composite region may -declare `data-pptx-placeholder="object"` with -`data-pptx-binding="proxy"`; the visible group stays Slide-local -and export creates a hidden transparent binding proxy. Do not use proxy binding -as the default template slot form. - -In `mirror`, preserve imported placeholder types, indices, bounds, and carrier -identity exactly when the importer supports them. Do not replace source -`subTitle`, `obj`, `media`, or `dt` roles with generic body content. In -`standard` / `fidelity`, assign the canonical authored types deliberately: -`title`, `subtitle`, `body`, `picture`, `chart`, `table`, `object`, `media`, -`date`, `footer`, and `slide-number`. An authored title normally has no index; -assign stable indices only when repeated roles need disambiguation inside the -new Layout. - -**Hard rule — explicit design-zone bounds**: Every slot carries `data-pptx-bounds="x y width height"` with at most two decimals per value. Mirror uses the source Layout placeholder frame. `standard` / `fidelity` author bounds from the intended safe area, column, panel inset, or media frame. Do not use character count, glyph width, current wrapping, or the tight sample-content box. An authored Layout may intentionally have zero slots. +Repeat inherited visuals in every standalone SVG so preview stays complete; export validates their equality and infers no ownership. **Forbidden — legacy contract**: never carry `data-pptx-layout-kind`, `distilled`, `utility`, unmapped `baseline`, `preserve`, or direct atomic placeholders into a package; such Type B input is visual reference only, and native topology requires the Type A path. **Composite slot boundary**: a normal slot has exactly one compatible carrier (a validated preset `<g>` counts for `object`; an ordinary group does not); only a genuinely composite region uses `data-pptx-placeholder="object"` + `data-pptx-binding="proxy"`, never as the default form. Mirror preserves imported types, indices, bounds, and carriers exactly (never replacing `subTitle`, `obj`, `media`, or `dt` with generic body); authored modes assign `title`, `subtitle`, `body`, `picture`, `chart`, `table`, `object`, `media`, `date`, `footer`, `slide-number` deliberately, with indices only to disambiguate repeated roles. **Hard rule — explicit design-zone bounds**: every slot carries `data-pptx-bounds="x y width height"` (≤ two decimals) from the source Layout frame (mirror) or the intended safe area, column, panel inset, or media frame (authored) — never from character count, glyph width, wrapping, or the sample-content box; zero-slot Layouts are valid. ### 3. Placeholder Markers -> Mirror retains literal source example text and source placeholder metadata. It does not insert `{{...}}` markers. The rest of this section defines the preferred authoring vocabulary for standard and fidelity modes. - -Use clear placeholder markers for replaceable content: +Mirror retains literal source text and placeholder metadata and inserts no `{{...}}`. Authored modes mark replaceable content: ```xml -<!-- Text slot --> -<g id="title-slot" data-pptx-placeholder="title" - data-pptx-bounds="80 280 1120 96"> - <text id="title-carrier" data-pptx-carrier="true" - x="80" y="320" fill="#FFFFFF" font-size="48" font-weight="bold"> - {{TITLE}} - </text> +<g id="title-slot" data-pptx-placeholder="title" data-pptx-bounds="80 280 1120 96"> + <text id="title-carrier" data-pptx-carrier="true" x="80" y="320" fill="#FFFFFF" font-size="48" font-weight="bold">{{TITLE}}</text> </g> - -<!-- Content area placeholder (content page only) --> <rect x="40" y="90" width="1200" height="550" fill="#FFFFFF" rx="8"/> -<g id="body-slot" data-pptx-placeholder="body" - data-pptx-bounds="40 90 1200 550"> - <text id="body-carrier" data-pptx-carrier="true" - x="640" y="365" text-anchor="middle" fill="#CBD5E1" font-size="16"> - {{CONTENT_AREA}} - </text> +<g id="body-slot" data-pptx-placeholder="body" data-pptx-bounds="40 90 1200 550"> + <text id="body-carrier" data-pptx-carrier="true" x="640" y="365" text-anchor="middle" fill="#CBD5E1" font-size="16">{{CONTENT_AREA}}</text> </g> ``` ### 4. Placeholder Reference (canonical convention, overridable per template) -This is the **default vocabulary** used across template packages. Newly created templates SHOULD prefer these names so downstream projects find familiar slots; designers MAY substitute or extend them when a style genuinely needs different vocabulary (e.g. consulting decks lead with `{{KEY_MESSAGE}}` instead of `{{PAGE_TITLE}}`; a brand cover may need `{{BRAND_LOGO}}`). +Default vocabulary; new templates SHOULD prefer it and MAY substitute or extend when a style genuinely needs different names (`{{KEY_MESSAGE}}`, `{{BRAND_LOGO}}`). `svg_quality_checker.py --template-mode` warns when a page lacks its conventional placeholder; a `placeholders:` frontmatter map (`03a_content_dual_col: []` asserts none) silences it and documents the contract. -`svg_quality_checker.py --template-mode --canonical-authoring` emits **advisory warnings** when a page lacks the conventional placeholder for its type. To silence those warnings — and document the template's actual contract — declare a `placeholders:` map in `<design_spec_path>` frontmatter: +| Placeholder | Purpose | Page | Role | +|------------|---------|------|------| +| `{{TITLE}}`, `{{SUBTITLE}}`, `{{DATE}}`, `{{AUTHOR}}` | Title, subtitle, date, author/organization | Cover | Default | +| `{{CHAPTER_NUM}}`, `{{CHAPTER_TITLE}}` / `{{CHAPTER_DESC}}` | Chapter number, title / description | Chapter | Default / Optional | +| `{{PAGE_TITLE}}`, `{{CONTENT_AREA}}`, `{{PAGE_NUM}}` | Page title, content area, page number | Content (page number also ending) | Default | +| `{{KEY_MESSAGE}}` | Key takeaway | Content (consulting) | Style-specific | +| `{{SECTION_NAME}}`, `{{SOURCE}}` | Section name, data source | Content footer | Optional | +| `{{THANK_YOU}}`, `{{CONTACT_INFO}}` / `{{ENDING_SUBTITLE}}`, `{{COPYRIGHT}}` / `{{CLOSING_MESSAGE}}` | Ending content | Ending | Default / Optional / Style-specific | -```yaml -placeholders: - 01_cover: ["{{TITLE}}", "{{SUBTITLE}}", "{{BRAND_LOGO}}"] - 03_content: ["{{KEY_MESSAGE}}", "{{CONTENT_AREA}}"] - 03a_content_dual_col: [] # explicitly assert "no required placeholders" -``` - -| Placeholder | Purpose | Applicable page | Convention role | -|------------|---------|-------------------|--------| -| `{{TITLE}}` | Main title | Cover | Default | -| `{{SUBTITLE}}` | Subtitle | Cover | Default | -| `{{DATE}}` | Date | Cover | Default | -| `{{AUTHOR}}` | Author / Organization | Cover | Default | -| `{{CHAPTER_NUM}}` | Chapter number | Chapter page | Default | -| `{{CHAPTER_TITLE}}` | Chapter title | Chapter page | Default | -| `{{CHAPTER_DESC}}` | Chapter description | Chapter page | Optional | -| `{{PAGE_TITLE}}` | Page title | Content page | Default | -| `{{CONTENT_AREA}}` | Content area | Content page | Default | -| `{{PAGE_NUM}}` | Page number | Content page, ending page | Default | -| `{{KEY_MESSAGE}}` | Key takeaway | Content page (consulting style) | Style-specific | -| `{{SECTION_NAME}}` | Section name | Content page footer | Optional | -| `{{SOURCE}}` | Data source | Content page footer | Optional | -| `{{THANK_YOU}}` | Thank-you message | Ending page | Default | -| `{{CONTACT_INFO}}` | Contact info | Ending page | Default | -| `{{ENDING_SUBTITLE}}` | Ending subtitle | Ending page | Optional | -| `{{CLOSING_MESSAGE}}` | Closing message | Ending page | Style-specific | -| `{{COPYRIGHT}}` | Copyright | Ending page | Optional | - -For TOC pages in **newly created templates**, use indexed placeholders: - -- `{{TOC_ITEM_1_TITLE}}`, `{{TOC_ITEM_1_DESC}}` -- `{{TOC_ITEM_2_TITLE}}`, `{{TOC_ITEM_2_DESC}}` -- ... - -Do **not** create new TOC placeholder families such as `{{CHAPTER_01_TITLE}}` for new templates. Existing templates may contain legacy placeholder variants, but new output should converge on the indexed TOC contract. - -Variants reuse their parent type's placeholder set by default: every `03*_content*.svg` shares the content placeholder list above, unless the spec frontmatter declares an override for that specific stem. - -For `standard` / `fidelity`, canonical placeholder insertion takes priority over visual mimicry; adjust the newly designed layout or declare an intentional vocabulary override. Mirror preserves the source placeholders and literal text instead of inserting canonical authoring markers. +TOC pages use indexed `{{TOC_ITEM_N_TITLE}}` / `{{TOC_ITEM_N_DESC}}`, never new families such as `{{CHAPTER_01_TITLE}}`. Variants reuse the parent set unless the frontmatter overrides that stem. In authored modes canonical insertion takes priority over visual mimicry; mirror preserves source placeholders and text. --- ## Output Requirements -### File Save Location - -Both scopes use one complete workspace shape. Only the workspace root differs: - -| Scope | `<template_workspace>` | -|---|---| -| `library` | `skills/ppt-master/templates/<kind_dir>/<template_name>/` | -| `project` | `<target_project>/` | - -Standard mode (default): +Both scopes share one workspace shape; only the root differs: ``` <template_workspace>/ -├── templates/ -│ ├── design_spec.md -│ │ # project scope uses design_spec.<kind>.<id>.md instead -│ ├── 01_cover.svg -│ ├── 02_toc.svg # Optional; without it: 02_chapter, 03_content, 04_ending -│ ├── 03_chapter.svg -│ ├── 04_content.svg -│ └── 05_ending.svg -├── images/ # Optional; omit when unused -│ └── *.png / *.jpg # SVG href is ../images/<name> -├── icons/ # Optional; omit when unused -│ └── imported/ -│ └── *.svg # Canonical imported vectors, when used -└── exports/ # Optional; requested review or required multi-Master evidence - └── <deck_id|layout_id>_template_preview.pptx +├── templates/ design_spec.md (project: design_spec.<kind>.<id>.md) + 01_cover.svg, [02_toc.svg,] 02|03_chapter.svg, 03|04_content.svg, 04|05_ending.svg +│ fidelity adds lettered variants and extension pages; mirror emits 001_cover.svg … 050_ending.svg +├── images/ optional; SVG href ../images/<name> +├── icons/imported/ optional canonical imported vectors +└── exports/ <deck_id|layout_id>_template_preview.pptx when requested or multi-Master ``` -Fidelity mode changes only the roster under `templates/`, e.g.: +**Hard rule — common routing**: spec, SVGs, and non-bitmap template-source assets in `templates/`; every bitmap in `images/`; each imported vector once in `icons/imported/` referenced as `data-icon="imported/<name>"`; never `templates/icons/`; a review deck in `exports/` on request and always for multi-Master; no optional directory created merely to exist; no asset placement branching by scope. -``` -<template_workspace>/templates/ -├── design_spec.md # project scope: design_spec.<kind>.<id>.md -├── 01_cover.svg -├── 02_toc.svg -├── 03a_chapter_full.svg -├── 03b_chapter_minimal.svg -├── 04a_content_two_col.svg -├── 04b_content_data_card.svg -├── 04c_content_quote.svg -├── 05_ending.svg -└── 06_section_break.svg -``` +**Template Preview**: on request or for multiple Masters, run `template_preview_pptx.py <template_workspace>` after validation ([`template-tools.md`](../scripts/docs/template-tools.md#template_preview_pptxpy)); include the path in the completion summary and omit `exports/` only for an unrequested one-Master package. For import-based templates, note which extracted assets were reused, which references influenced the authored roster, what mirror could not preserve, and any page-type mapping that needed judgment. -Mirror mode emits one SVG per source slide, named by source order: - -``` -<template_workspace>/templates/ -├── design_spec.md # project scope: design_spec.<kind>.<id>.md -├── 001_cover.svg -├── 002_toc.svg -├── 003_content.svg -├── 004_content.svg -├── 005_chapter.svg -├── 006_content.svg -├── ... -├── 049_content.svg -└── 050_ending.svg -``` - -Filenames preserve the source slide order via the 3-digit prefix; `<page_type>` is derived from `analysis/manifest.json` `pageTypeCandidates`. Source meaning and validated native structure facts are preserved while Template_Designer authors the compact new SVG; code/node identity is not required, and IR-only refs plus its manifest are not copied into template output. - -**Hard rule — common routing**: Keep `<design_spec_path>`, template SVGs, and non-bitmap template-source assets in `templates/`; place every bitmap in `images/`; place each imported vector exactly once in `icons/imported/` and reference it as `data-icon="imported/<name>"`. Never create `templates/icons/`. Write a review deck to `exports/` when explicitly requested and always for a multi-Master package gate. Create Template must not create optional directories or placeholder files solely to retain empty paths. An initialized project may already contain empty scaffolding; leave it untouched and omit it from completion unless real template files were written or adopted there. Do not branch asset placement by output scope. - -### Template Preview - -When the user requests a PowerPoint review file or the validated roster declares multiple Masters, run `template_preview_pptx.py <template_workspace>` after SVG validation. The default review keeps visible SVG Chart/Table fallbacks. To verify JSON-first native capability, write a separately named review with `--native-charts-and-tables -o <distinct_path>`; marker presence alone never activates replacement. The command creates `exports/` on demand and verifies one slide per SVG prototype plus the expected Master/Layout counts. In authored modes, it shortens canonical marker text only in ephemeral review copies so prompts remain readable without changing the source SVG, carrier typography, or placeholder frames. The first export refuses a collision; an intentional post-fix replacement uses `--force`. The review PPTX is derived evidence and never a template-application input. - -When a review deck was generated, include its path in the completion summary. Omit `exports/` only for an unrequested one-Master package. - -If the template is based on PPTX import output, briefly note: -- which extracted assets were reused directly -- for `standard` / `fidelity`, which visual references influenced the newly authored roster -- for `mirror`, whether any source feature could not be preserved and the exact affected source object/page -- whether any page-type filename mapping required judgment beyond the import heuristic - ---- - -## Using Pre-built Template Library (Optional) - -If suitable template resources already exist, use them directly instead of generating new ones: - -1. **Copy template workspace**: copy or stage `templates/` plus any existing `images/` and `icons/`; exclude `exports/` from template application. -2. **Adjust colors**: Modify colors per the project design spec -3. **Customize**: Make project-specific adjustments - -This section describes downstream reuse of an existing workspace. Library and project scopes carry the same portable template contract. - -**Example library structure** (query the appropriate kind's index — `templates/brands/brands_index.json` for identity, `templates/styles/styles_index.json` for roster-free direction/method, `templates/layouts/layouts_index.json` for brand-neutral structure, and `templates/decks/decks_index.json` for recurring applications with integrated identity/structure): - -``` -templates/ -├── brands/ -│ ├── anthropic/ # Anthropic brand identity (logo + colors + typography) -│ └── google/ # Google brand identity -├── styles/ -│ └── <style_id>/ # Communication method and design direction; no SVG roster -├── layouts/ -│ └── presentation_core/ # General structure system (no identity) -└── decks/ - ├── <bank_deck>/ # Example banking deck - └── <engineering_deck>/ # Example engineering deck -``` +**Using an existing library workspace** (downstream reuse, not this role's authoring): copy or stage `templates/` plus `images/` / `icons/` (never `exports/`), adjust colors to the project spec, then customize; query the matching kind index (`brands_index.json`, `styles_index.json`, `layouts_index.json`, `decks_index.json`). --- @@ -627,19 +214,14 @@ templates/ ```markdown ## Template_Designer Phase Complete - -- [x] Read `references/template-designer.md` -- [x] Output scope confirmed: `library` | `project`; the common workspace preflight passed before final writes -- [x] Internal creation strategy derived from the confirmed natural-language intent: `standard` | `fidelity` | `mirror`; Layout mirror source is already brand-neutral and application-neutral -- [x] Every page listed in `<design_spec_path>` §V Page Roster saved to `<template_workspace>/templates/` -- [x] Naming convention applied (standard / fidelity: letter-suffix variants; mirror: `<NNN>_<page_type>.svg`) -- [x] Templates follow design spec (colors, fonts, layout) -- [x] Deck Template Overview and factual Page Roster describe the recurring application and actual prototypes without mandatory use policy; Layout output contains no application or identity contract -- [x] `standard` / `fidelity` inspected complete source Master/Layout evidence and represented each retained Layout through a newly authored Slide prototype; `mirror` SVGs preserve only source Slides and their reachable structure without semantic redesign -- [x] Placeholder markers are clear and standardized for `standard` / `fidelity`; preview-only sample text remains readable without changing source markers, while mirror preserves literal source text plus source placeholder type/index/bounds -- [x] Every SVG is a complete preview with explicit root Master/Layout identity and `native_structure_mode: structured`; authored modes use canonical fixed layers/slots, while mirror preserves source ownership and mechanically expands fixed-layer groups into direct atoms -- [x] Authored `standard` / `fidelity` Layout keys are non-duplicative; mirror keeps distinct reachable source Layout identities even when their current visible contracts are equivalent -- [x] Template creation used the authoring IR; lossless expanded imports remained immutable payload backing for mirror materialization, while `standard` / `fidelity` used helper-generated compact canonical preset groups and `<design_spec_path>` paint -- [x] Both scopes route bitmaps to `images/` and keep one canonical copy of every imported vector under `icons/imported/` -- [ ] **Next step**: Validate assets, export review evidence when requested or required for multiple Masters, then register only library scope +- [x] Scope confirmed (`library` | `project`); preflight passed before final writes +- [x] Strategy derived from natural-language intent: `standard` | `fidelity` | `mirror`; Layout mirror source is brand/application-neutral +- [x] Every §V page saved to `<template_workspace>/templates/` with the naming convention applied +- [x] Templates follow the spec (colors, fonts, layout); Deck Overview and Roster describe without mandatory policy; Layout carries no application or identity contract +- [x] Authored modes inspected complete source evidence and represented each retained Layout through a new prototype; mirror preserved only Slides and their reachable structure +- [x] Placeholder markers clear and standardized for authored modes; mirror preserved literal text and source placeholder facts +- [x] Every SVG is a complete preview with explicit root identity and `native_structure_mode: structured`; authored Layout keys non-duplicative +- [x] Creation used the authoring IR; lossless imports stayed immutable; authored modes used helper-generated preset groups and spec paint +- [x] Bitmaps in `images/`, one canonical copy of each imported vector in `icons/imported/` +- [ ] **Next**: validate assets, export review evidence when requested or required, register library scope only ``` diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/topology-assembly.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/topology-assembly.md index 5f81a7ca..347a351e 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/topology-assembly.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/topology-assembly.md @@ -2,274 +2,55 @@ # Topology Assembly Reference -Generative material for turning one resolved qualitative topology into editable native-shape components with coherent relative registration before coordinates. +Generative material for turning one resolved qualitative topology into editable native-shape components with coherent relative registration, before coordinates. Default and Quick read it once with `executor-structure.md` at the first `Structure=yes` page and reuse it for every later assembly. -**Load**: Default and Quick read this reference once with the fixed construction -bundle before SVG authoring and reuse it for every `Structure=yes` assembly. +**Hard rule — relative constraints, never copyable geometry**: state exact preset or primitive identities, semantic counts, inter-component relations, and only the relative geometry that makes the assembly hold; never coordinates, points, sizes, ratios, adjustment values, path data, SVG fragments, full-page frames, copy, color, styling, or page composition. Materialize every adopted call through `native-shape-authoring.md`. -**Hard rule — relative constraints, never copyable geometry**: State exact -preset or primitive identities, semantic counts, inter-component relations, and -only the relative geometry required to make the assembly hold together. Never -provide coordinates, concrete sizes or ratios, adjustment values, points, path -data, SVG fragments, copy, color, styling, page composition, or full-page -frames. Materialize every adopted call fresh through -[`native-shape-authoring.md`](./native-shape-authoring.md). +**Mandatory — two-step assembly test**: preserve the topology resolved by `executor-structure.md`, then (1) split every piece that needs independent editing, movement, paint, animation, or reuse; (2) from outline and region semantics choose one continuous shape, one shape with dividers, stacked siblings, seamed pieces, overlapping siblings, or independently retained Boolean regions. -**Mandatory — two-step assembly test**: Preserve the topology resolved by -[`executor-structure.md`](./executor-structure.md); do not select or rename it -here. Then decide in order: +**Mandatory — registration closure**: after the test, resolve only the relative conditions that make the pieces read as one construct — shared datum, center, taper, or contour; aligned endpoints and seams; fitted contact or intentional clearance; nesting margin; overlap depth; joint type; direction continuity; cutters that fully cross the parent silhouette. Valid individual shapes are not an assembly until their contacts and boundaries register. -1. Split every piece that needs independent editing, movement, paint, animation, or reuse. -2. From outline and region semantics, choose one continuous shape, one shape with dividers, stacked siblings, seamed pieces, overlapping siblings, or independently retained Boolean regions. +**Hard rule — no assembly lookup, counts from semantics, information-model boundary**: never recall a paragraph below as a named structure or match the page to the nearest mechanism — generate from the active atoms and the two-step test, adapting or inventing calls even when no paragraph resembles the result. Derive every call count from real units, runs, turns, boundaries, junctions, owners, or regions; a count never implies equal size, spacing, angle, weight, or symmetry, and closure, mirroring, centrality, taper, interlock, and contact require meaning already resolved upstream. Value-derived position, length, width, area, angle, radius, or color stays Chart; row × column facts stay Table. -**Mandatory — registration closure**: After the two-step test, resolve only the -relative conditions that make the chosen pieces read as one construct: shared -datum, center, taper, or contour; aligned endpoints and seams; fitted contact or -intentional clearance; nesting margin; overlap depth; joint type; direction -continuity; and cutters that fully cross the parent silhouette. A set of valid -individual shapes is not an assembly until its required contacts and boundaries -register. - -**Hard rule — no assembly lookup**: Never recall a paragraph as a named -structure, resolve a key, or match the page to the nearest mechanism. Generate -from the active atoms and the two-step test; adapt, combine, or invent calls and -relative constraints even when no paragraph resembles the result. - -**Reference — not a constraint**: The mechanisms below are common generative -material rather than an exhaustive set, ranking, recommendation, or allowed -combination list. A primitive, another registered preset, necessary freeform, -or no drawn carrier may still win the current contour comparison. - -**Hard rule — semantic counts, not balance**: Derive every call count from real -units, runs, turns, boundaries, junctions, owners, or retained regions. A count -never implies equal size, spacing, angle, weight, or symmetry. Closure, -mirroring, centrality, taper, interlock, and contact require the relationship -meaning already resolved upstream. - -**Hard rule — information-model boundary**: Value-derived position, length, -width, area, angle, radius, or color remains Chart geometry; row-header × -column-header facts remain Table. The assemblies below carry only qualitative -relationships. +**Reference — not a constraint**: the mechanisms below are common generative material, not an exhaustive set, ranking, or allowed-combination list; a primitive, another preset, necessary freeform, or no drawn carrier may still win. --- ## 1. `order` -For independently owned stages on one directional path, call `chevron` once per -stage and keep the calls as siblings. On a continuous handoff, register each -tip into the next notch and keep the entry / exit direction coherent through -the joint; let the tip enter far enough to close the carrier without occluding -the next stage's independently owned interior. Preserve an intentional gap when -the boundary is a pause, reset, or discontinuity. The per-stage split preserves -independent edit, paint, animation, and reuse duties; continuity versus boundary -semantics decides fitted interlock versus clearance. Stage bodies may vary with -their duties while every adopted joint still fits. - -For a path that wraps and reverses, call `rightArrow` once per forward run, -`leftArrow` once per return run, `downArrow` once per turn, and `roundRect` once -per independently owned stop. Place successive runs on distinct parallel -baselines; align each turn's entry with the preceding run endpoint and its exit -with the next run entry so the path neither doubles back ambiguously nor jumps -across a gap. Attach each stop to its owning run without covering the carrier's -entry, exit, or turn joint. Stops split for independent duties; run and turn -pieces split because each owns a distinct direction / continuation duty. -Contact at a turn means continuation, while clearance means a stage break; run -lengths and offsets follow the resolved path rather than a regular wrap. - -For recurrence with independently owned stages, call `blockArc` once per stage -and seam the siblings into one closed reading path. Make every segment share one -center and registered inner / outer contours; meet adjacent end faces on both -contours so the ring has neither accidental steps nor overlaps. Segment spans -may differ, but their sequence and seam direction must remain legible. Retain a -gap only for a semantic reset. When recurrence is one indivisible duty, call one -`circularArrow` instead. Stage independence decides one versus many pieces; -recurrence and direction decide closure, while shared-center registration makes -the segmented result one carrier rather than unrelated arcs. - ---- +- **Stages on one directional path**: `chevron` once per stage, kept as siblings. On a continuous handoff register each tip into the next notch with coherent entry/exit through the joint, entering only far enough to close the carrier without occluding the next stage's interior; keep an intentional gap where the boundary is a pause, reset, or discontinuity. Bodies may vary with their duties while every joint fits. +- **A path that wraps and reverses**: `rightArrow` per forward run, `leftArrow` per return run, `downArrow` per turn, `roundRect` per independently owned stop, runs on distinct parallel baselines. Align each turn's entry to the preceding run's endpoint and its exit to the next run's entry so the path neither doubles back ambiguously nor jumps a gap; attach each stop to its run without covering an entry, exit, or turn. Contact at a turn means continuation, clearance a stage break; run lengths follow the resolved path, not a regular wrap. +- **Recurrence with independent stages**: `blockArc` once per stage, seamed into one closed path — every segment shares one center and registered inner/outer contours, adjacent end faces meet on both contours, spans may differ while sequence and seam direction stay legible, and a gap marks only a semantic reset. One indivisible recurrence is one `circularArrow` instead. ## 2. `link` -For a qualitative split or merge, call `roundRect` once per semantic source or -target and `line` once per necessary edge. Call `ellipse` zero or one time for -each junction: omit it when edges merely share a meeting point, and retain it -when the junction is independently editable, reusable, or animatable. Terminate -each edge on its node boundary rather than inside the node; make converging edge -endpoints meet the same junction, preserve a collinear shared trunk when one -exists, and separate branches soon enough that they do not read as one line. -An apparent crossing must either remain visibly non-joining or receive a real -semantic junction. Nodes, edges, and retained junctions split by ownership; -junction and outline semantics decide an implied meeting, one visible node, or -separate passing paths. - -For a two-way exchange owned as one relationship, call one `leftRightArrow` -between two independently owned `roundRect` nodes. Register both arrow ends to -the facing node boundaries and preserve one uninterrupted exchange corridor. -When the two directions need independent editing, paint, animation, or reuse, -call one `rightArrow` and one `leftArrow` as parallel siblings instead. Keep the -two directional corridors distinct, align each endpoint to its own node port, -and prevent either arrowhead from covering the other carrier or a node interior. -Directional responsibility decides whether the edge splits; reciprocal-single- -duty versus two owned transfers decides one contour or two, while endpoint and -corridor registration preserves the exchange. - ---- +- **Split or merge**: `roundRect` per source or target, `line` per necessary edge, `ellipse` zero or once per junction — omitted when edges merely meet, retained when the junction is independently editable, reusable, or animatable. Terminate edges on node boundaries, bring converging edges to the same junction, keep a collinear shared trunk where one exists, and separate branches early enough that they never read as one line; an apparent crossing is either visibly non-joining or a real junction. +- **Two-way exchange**: one `leftRightArrow` between two `roundRect` nodes when the exchange is one relationship, both ends registered to the facing boundaries with one uninterrupted corridor; one `rightArrow` plus one `leftArrow` as parallel siblings when the directions need independent editing, paint, animation, or reuse, each end on its own port and neither head covering the other carrier or a node. ## 3. `parent` -For enclosure hierarchy or nested bubbles, call `ellipse` once per unit that -owns a visible boundary and nest each child inside its immediate parent. Keep -all ellipses as independent siblings rather than unioning parent and child. -Preserve a visible containment margin around every child, keep its complete -boundary inside the parent, and prevent sibling interiors from touching unless -another active atom requires contact or overlap. Deeper levels may move, -contract, or cluster asymmetrically; they need only preserve unambiguous -containment and enough parent field to remain perceptible. Independent node -ownership requires separate edit, movement, paint, animation, and reuse; -enclosure semantics requires nesting while preserving every outline. - -For an indented decomposition without explicit relationship edges, call -`roundRect` once per independently owned node and `leftBrace` once for each -parent whose child group needs a visible shared boundary. Register siblings to -one depth datum, place the child group deeper than its parent, and make the brace -span only that parent's actual children with its open side facing their shared -entry edge. Nested braces must remain distinct and must not cross a node -boundary. Nodes split for independent duties; the brace remains a separate -shared ownership mark because one outline governs several children. Depth and -group extent, not equal offsets or repeated widths, carry the hierarchy. - ---- +- **Enclosure hierarchy / nested bubbles**: `ellipse` once per unit with a visible boundary, each child nested inside its immediate parent as an independent sibling (never unioned), with a visible containment margin, its complete boundary inside the parent, and sibling interiors apart unless another atom requires contact. Deeper levels may move, contract, or cluster asymmetrically while containment stays unambiguous. +- **Indented decomposition without edges**: `roundRect` per node, `leftBrace` per parent whose children need a shared boundary; siblings registered to one depth datum, the child group deeper than its parent, the brace spanning only that parent's children with its open side toward their entry edge, nested braces distinct and never crossing a node. Depth and group extent carry the hierarchy, not equal offsets. ## 4. `membership` -For independently owned qualitative lanes, call `rect` once per lane and -`roundRect` once per member that needs a carrier. Keep lane fields as parallel -siblings; make adjacent long boundaries share one seam when membership is -continuous, or preserve a clear gap when the groups are separate fields. Keep -each member's complete contour inside its owning lane with a visible nesting -margin; cross a lane boundary only when the member truly has multiple ownership -or changes owner. If all lanes form one indivisible field and only boundaries -carry meaning, call one `rect` for the field and `line` once per semantic lane -boundary instead. Independent lane / member duties require siblings; one-field -semantics permits dividers. Lane width and occupancy follow responsibility, not -uniform partitioning. - -For membership that needs a light grouping boundary rather than a closed field, -call `leftBrace` once per group and `roundRect` once per independently owned -member. Keep the brace separate, face its open side toward the members, span the -complete member group but no adjacent group, and maintain clearance so neither -the brace nor a nested brace touches a member contour. Members split for -independent edit, movement, paint, animation, and reuse; one brace is the shared -ownership mark because the group boundary itself is one duty. Member count does -not require repeated contours, equal spacing, or equal weight. - ---- +- **Owned lanes**: `rect` per lane, `roundRect` per member needing a carrier; lanes as parallel siblings whose long boundaries share one seam when membership is continuous or keep a clear gap when the groups are separate fields; each member's complete contour inside its lane with a nesting margin, crossing a boundary only for true multiple ownership or a transfer. One indivisible field with meaningful boundaries is one `rect` plus `line` per boundary instead. Lane width and occupancy follow responsibility, not uniform partition. +- **Light grouping boundary**: `leftBrace` per group, `roundRect` per member; the brace separate, open side toward the members, spanning the whole group and no neighbor, with clearance so no brace touches a member contour. Member count implies no repeated contours, equal spacing, or equal weight. ## 5. `contrast` -For opposing fields on one comparison baseline, call `rect` once per field when -the sides need independent editing, movement, paint, animation, or reuse. Align -the comparable anchors to a shared baseline and register the facing boundaries -as parallel edges separated by either a semantic gap or one explicit `line` -divider; do not let an incidental offset become a false rank. If the field is -one indivisible duty and only the state boundary matters, call one `rect` plus -one `line` at that boundary instead. Independent side responsibility decides -two siblings versus one divided field; opposing-field semantics decides the -facing joint. Shared framing and counterweight never require equal dimensions -or mirrored content. - -For a tapered rank or support stack, call `trapezoid` once per independently -owned tier and stack the siblings with semantic seams. Register all tier side -edges to one shared taper, make each adjacent seam meet across the complete -current width, and vary tier width monotonically in the rank direction without -assuming equal change, height, or area. Do not substitute one `triangle` plus -divider lines when tiers need independent paint or animation. If the whole -stack is one duty, call one `triangle` plus one `line` per semantic tier -boundary; make every divider cross the interior and terminate on both outer -edges so no tier leaks into the next. If one registered outer silhouette and -independently retained tier regions are both required, call one `triangle` plus -one `rect` strip per tier region, make every strip fully cross the parent -silhouette and meet the next strip without an accidental sliver, run `fragment`, -and retain the required triangle-covered regions. Independent tier duty decides -the split; continuous-outline versus retained-region semantics decides stacked -siblings, dividers, or Boolean regions. Shared taper and complete crossings keep -all three routes registered as one stack. - ---- +- **Opposing fields on one baseline**: `rect` per side when the sides need independent editing, paint, animation, or reuse, comparable anchors on a shared baseline, facing boundaries as parallel edges separated by a semantic gap or one `line` divider, no incidental offset that reads as rank; one `rect` plus one `line` at the state boundary when the field is one duty. Shared framing and counterweight never require equal dimensions or mirrored content. +- **Tapered rank or support stack**: `trapezoid` per independently owned tier, stacked with semantic seams — all side edges on one shared taper, each seam meeting across the full current width, tier width monotonic in the rank direction without assumed equal change, height, or area. One `triangle` plus one `line` per tier boundary when the stack is one duty (every divider crossing the interior and ending on both outer edges); one `triangle` plus one `rect` strip per region, every strip fully crossing the silhouette and meeting the next without a sliver, then `fragment`, when one outer silhouette and independently retained regions are both required. Never substitute a triangle plus dividers for tiers that need independent paint or animation. ## 6. `overlap` -When each owner must remain independently editable and the shared area needs no -separate treatment, call `ellipse` once per owner and overlap the calls as -siblings without Boolean materialization. Preserve enough of every complete -owner boundary to identify it, make each intended common area substantial -enough to read as a region rather than an accidental tangent, and avoid full -containment unless subset meaning is active. Choose overlap order and depth so -one owner does not erase another owner or create unintended micro-regions. -Owner responsibility requires the split; outline semantics preserves each -complete boundary, while the common area remains a consequence of overlap. -Paired, chained, or layered ownership does not imply equal ellipses or symmetric -intersection. - -When exclusive and shared regions need independent editing, paint, animation, -or reuse, call `ellipse` once per owner, run `fragment` across the overlapping -set, and retain every required exclusive / shared result as an independent -shape. Register the owner overlaps before fragmenting so their crossings produce -only the semantic regions; eliminate accidental tangencies, hidden owners, and -unintended slivers rather than retaining them as topology. Region -responsibility—not owner count alone—requires the further split; exact retained- -region semantics requires `fragment` rather than ordinary siblings or -`intersect`, which keeps only the common region. Retain no region merely to -complete a symmetric pattern. - ---- +- **Independently editable owners, shared area untreated**: `ellipse` per owner, overlapped as siblings without Boolean — enough of every boundary visible to identify each owner, each common area substantial enough to read as a region, no full containment unless subset meaning is active, overlap order and depth chosen so no owner erases another or creates unintended micro-regions. Paired, chained, or layered ownership never implies equal ellipses or symmetric intersection. +- **Exclusive and shared regions need independent treatment**: `ellipse` per owner, register the overlaps so their crossings produce only the semantic regions (no accidental tangencies, hidden owners, or slivers), then `fragment` and retain every required exclusive/shared result as its own shape — `fragment`, not `intersect`, which keeps only the common region. Retain no region merely to complete a pattern. ## 7. Combined atoms -**Mandatory — compose active topologies, not reference paragraphs**: Generate -each active atom's topology from its own relationship duties, then resolve how -those topologies share a field, nest, run in parallel, cross orthogonally, or -intersect. Preserve each atom's ownership and reading direction. Let one -component carry several atoms only when its edit, movement, paint, animation, -reuse, outline, and region duties never need to separate; otherwise keep the -atom systems as registered siblings. Re-run the two-step test at every contact, -crossing, shared boundary, and retained region. A shared field does not make one -atom dominant, and authoring convenience never justifies merging them. - -For an actual `order` path crossing `membership` lanes, call `rect` once per -independently owned lane, `roundRect` once per process unit, `line` once per -necessary transition, and `line` once per semantic phase boundary. Keep all -lane bands parallel and register the process axis orthogonally across them. -Place each process unit fully inside its current owner's lane; let only a real -responsibility transfer cross a lane seam, and terminate every transition on -the process-unit boundaries rather than using a lane boundary as an edge. -Phase boundaries must cross the lane field coherently and remain distinguishable -from process transitions. If lane regions are one field duty, use one `rect` -plus lane dividers instead of independent lane rectangles. Lane ownership and -process-unit responsibility decide the splits; orthogonal registration keeps -the two atom systems readable without implying equal bands, phases, or steps. - -For two independent `contrast` dimensions partitioning one field, call one -`rect` plus one `line` per axis when only the axes carry meaning. Make both axes -cross the complete field, keep them orthogonal, and let their intersection move -with the semantic thresholds rather than centering it. When the four resulting -regions need independent editing, movement, paint, animation, or reuse, call -four `rect` siblings instead; tile them to one shared outer field with one -continuous seam per axis, no accidental gaps or overlaps, and the same -non-central intersection when required. Axis-only semantics chooses one body -with dividers; region responsibility chooses four siblings. Orthogonality and -continuous seams create one partition while unequal region extents remain -legal. - -For a radial `parent` topology whose ancestry requires explicit `link` edges, -call `ellipse` once per semantic node and `line` once per parent-child relation. -Only after radial organization is resolved upstream, register depth to -concentric bands around the actual root; the bands and sibling sectors may vary -with role and content. Start and end every edge on node boundaries, keep each -branch moving outward to the child's depth, and make shared branch junctions -coincide only when the relations truly share a trunk. Nodes split for -independent content and motion duties; edges remain separate because ancestry -is a relation rather than a shared silhouette. Concentric registration makes -depth legible, while root centrality, even fan-out, mirrored branches, and equal -radial spacing remain forbidden unless the relationship itself requires them. +**Mandatory — compose active topologies, not reference paragraphs**: generate each active atom's topology from its own duties, then resolve how those topologies share a field, nest, run in parallel, cross orthogonally, or intersect, preserving each atom's ownership and reading direction. One component may carry several atoms only when its edit, movement, paint, animation, reuse, outline, and region duties never need to separate; otherwise keep the systems as registered siblings, re-running the two-step test at every contact, crossing, shared boundary, and retained region. A shared field makes no atom dominant, and convenience never justifies merging. +- **`order` path across `membership` lanes**: `rect` per independently owned lane (or one `rect` plus lane dividers when lanes are one field duty), `roundRect` per process unit, `line` per transition and per phase boundary. Lanes parallel, the process axis orthogonal across them; each unit fully inside its owner's lane, only a real responsibility transfer crossing a seam; transitions ending on unit boundaries rather than using a lane boundary as an edge; phase boundaries crossing the whole field and distinguishable from transitions. Equal bands, phases, or steps are never implied. +- **Two independent `contrast` dimensions partitioning one field**: one `rect` plus one `line` per axis when only the axes carry meaning — both crossing the full field, orthogonal, their intersection at the semantic thresholds rather than the center; four `rect` siblings tiled to one outer field with one continuous seam per axis and the same non-central intersection when the regions need independent editing, paint, animation, or reuse. Unequal region extents remain legal. +- **Radial `parent` with explicit `link` edges**: `ellipse` per node, `line` per parent–child relation, depth registered to concentric bands around the actual root only after radial organization is resolved upstream; every edge starting and ending on node boundaries and moving outward to the child's depth, junctions coinciding only for a true shared trunk. Root centrality, even fan-out, mirrored branches, and equal radial spacing stay forbidden unless the relationship requires them. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/video-design.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/video-design.md index 1edd89df..4fa01e3a 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/video-design.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/video-design.md @@ -1,246 +1,105 @@ # Video-delivery Design Reference Manual -Conditional design guidance for presentations whose intended use is a recorded, -self-running, or video delivery. +Conditional design guidance for presentations whose intended use is recorded, self-running, or video delivery. -**Trigger**: load this reference when the effective delivery purpose is video, -recorded narration, or unattended playback. Also load its script rules for an -explicit final/literal narration input. Speaker notes, animation, or audio -requested for an otherwise ordinary deck do not activate it alone. Explicit -video/MP4 delivery does; Quick additionally activates §3's direct-delivery -contract. +**Trigger**: load when the effective delivery purpose is video, recorded narration, or unattended playback, and load its script rules for an explicit final/literal narration input. Speaker notes, animation, or audio requested for an ordinary deck do not activate it alone; explicit video/MP4 delivery does, and Quick additionally activates §3's direct-delivery contract. -**Ownership**: this is a conditional Generate reference, not a profile or a new -artifact route. Default keeps its Strategist and confirmation flow; Quick keeps -its one-pass active-context flow. Existing notes, animation, audio, and native -PowerPoint export stages retain their schemas and commands. -When Beautify is active, its wording/page/order invariants still bind; apply -this reference only inside the design and motion freedom that profile permits. +**Ownership**: a conditional Generate reference, not a profile or artifact route. Default keeps Strategist and confirmation; Quick keeps its one-pass flow; notes, animation, audio, and native export stages keep their schemas and commands. Under Beautify, its wording/page/order invariants still bind — apply this reference only inside the freedom that profile permits. --- ## 1. Intake and Script State -Classify supplied spoken material before planning: - | Material | Treatment | |---|---| -| Ordinary source or rough transcript | Use as source material; edit, condense, and reorganize under the selected route's normal content-divergence contract | +| Ordinary source or rough transcript | Source material: edit, condense, reorganize under the route's normal content-divergence contract | | Explicit final/literal narration script | Preserve every spoken word and its order; segment only at semantic scene boundaries | -| SRT used to generate new TTS | Preserve cue text when it is explicitly final; use source timecodes only as pacing evidence because the new synthesis timing becomes authoritative | -| SRT bound to an existing recording | Preserve its text/audio timing authority; do not regenerate TTS or pretend that one long recording was split automatically | -| Already page-separated final script | Preserve the supplied page boundaries unless the user explicitly permits restructuring | -| Target platform, canvas, or duration | Use the existing canvas registry; resolve scene granularity, page count, and notes length together | +| SRT used to generate new TTS | Preserve cue text when explicitly final; source timecodes are pacing evidence only, the new synthesis timing is authoritative | +| SRT bound to an existing recording | Preserve its text/audio timing authority; do not regenerate TTS or pretend one long recording was split automatically | +| Already page-separated final script | Preserve supplied page boundaries unless the user permits restructuring | +| Target platform, canvas, or duration | Use the canvas registry; resolve scene granularity, page count, and notes length together | -**Hard rule — final means explicit**: freeze wording only when the user identifies -the script as final, literal, or verbatim. Never promote ASR output, subtitles, -or a draft transcript into a literal contract by inference. +**Hard rule — final means explicit**: freeze wording only when the user identifies the script as final, literal, or verbatim; never promote ASR output, subtitles, or a draft transcript into a literal contract by inference. -**Default — semantic segmentation (may override for a user-authored page -plan)**: one scene represents one coherent visual state or mental-map step, not -one sentence, subtitle cue, or effect. Several cues may share a scene; one scene -may contain several ordered reveals. +**Final-script production input**: after the page roster is final and before SVG authoring, write the resolved per-slide script once to `notes/total.md` with `# Slide <number>` headings and `---` separators, each body segment verbatim. It is a production input, not a storyboard or substitute Design Spec; run `total_md_split.py` only after the SVG roster exists. -**Final-script production input**: after the page roster is final but before SVG -authoring, write the resolved per-slide script once to `notes/total.md`. Use -`# Slide <number>` headings and `---` separators so the file can exist before SVG -filenames do; preserve each body segment verbatim. It is a production input, not -a storyboard or substitute Design Spec. Run `total_md_split.py` only after the -SVG roster exists. +**Default — semantic segmentation (may override for a user-authored page plan)**: one scene is one coherent visual state or mental-map step, not one sentence, cue, or effect; several cues may share a scene and one scene may hold several ordered reveals. --- ## 2. Scene and Page Planning -**Default — quality follows purpose (may override)**: explanation prioritizes -understanding; promotion or brand work may prioritize emotion, recall, or -impact. Give every change a communication job. +**Default — quality follows purpose (may override)**: explanation prioritizes understanding; promotion or brand work may prioritize emotion, recall, or impact. Give every change a communication job. | Narrative relationship | Page treatment | |---|---| -| Several lines explain one idea | Keep one page/scene and reveal only the semantic units needed for that explanation | -| One system persists | Before roster/notes freeze, derive states from the prior composition; keep orienting cues and change the semantic delta | -| New evidence expands a known map | Retain orienting cues; adapt the active region and context as needed | +| Several lines explain one idea | One page/scene; reveal only the semantic units the explanation needs | +| One system persists | Derive states from the prior composition before roster/notes freeze; keep orienting cues, change the semantic delta | +| New evidence expands a known map | Retain orienting cues; adapt the active region and context | | The same object changes position, scale, containment, or state | Consider compatible Morph endpoints when movement improves orientation | -| The audience must adopt a genuinely new mental map | Start a new composition and make the transition explicit | +| The audience must adopt a new mental map | Start a new composition and make the transition explicit | -**Default — stable visual anchors (may override when the mental map resets)**: -within one explanation, preserve recognizable roles, relationships, or spatial -cues. Position, scale, and style may change while identity and orientation -remain legible; reset for a new map. +**Defaults (each may override for the stated reason)**: -**Default — one semantic focus change per beat (may override for one inseparable -idea)**: change several elements together only for one communication unit. Do -not alter unrelated regions merely for busyness. +- *Stable anchors* — within one explanation preserve recognizable roles, relationships, or spatial cues; position, scale, and style may change while identity and orientation stay legible; reset for a new map. +- *One semantic focus change per beat* — change several elements together only for one inseparable communication unit; never alter unrelated regions for busyness. +- *Scene chrome earns its place* — newly authored scenes do not carry a report-style header, footer, or page number by convention; let the semantic title join the composition and drop running chrome on cover, ending, and breathing scenes. Keep chrome the active profile's fidelity boundary requires, or that genuinely orients, identifies, or attributes. +- *Screen for orientation, notes for speech* — keywords, structure, evidence, and relationships on the slide; full explanation in notes; never duplicate the narration as body copy, except literal on-screen copy. -**Default — scene chrome earns its place (may override for navigation, identity, -attribution, or fidelity)**: for newly authored recorded, self-running, or video -scenes, do not carry a report-style fixed header, footer, or page number merely -by deck convention. Let the semantic title participate in the scene composition, -and omit nonessential running chrome especially on cover, ending, and breathing -scenes. Retain source or template chrome when the active profile's fidelity -boundary requires it, and retain new chrome when it genuinely orients the -audience or carries required identity or attribution. - -**Default — screen for orientation, notes for speech (may override for literal -on-screen copy)**: place keywords, structure, evidence, and relationships on the -slide; keep full explanation in notes. Do not duplicate the narration script as -body copy. - -**Page-count rule**: derive page/notes boundaries from scenes, mental-map arcs, -endpoints, and duration—not cues or sentences. Profile-fixed count/order/content, -including 1:1/fidelity, permits only existing-neighbor evaluation; never alter -those invariants for motion. +**Page count**: derive page/notes boundaries from scenes, mental-map arcs, endpoints, and duration — not cues or sentences. Profile-fixed count/order/content (1:1/fidelity) permits only existing-neighbor evaluation; never alter those invariants for motion. --- ## 3. Default and Quick Planning Handoff -**Default**: Stage 1 confirms the existing open-text `delivery_context`; it does -not ask a separate video question. When the confirmed value identifies -recorded/self-running/video delivery, load this reference before authoring the -three Stage-2 whole solutions. Apply its scene grammar to every direction; it -does not add a style catalog or confirmation field. Record delivery context and -afterlife in §I, visible states and optional motion jobs in §IX, and script/notes -policy plus target duration in §X. When the final-script branch is active, -create the frozen `notes/total.md` after the approved roster/lock is final and -before Step 5 or split-mode handoff. +**Default**: Stage 1 confirms the existing open-text `delivery_context`, no separate video question. When the confirmed value identifies recorded/self-running/video delivery, load this reference before authoring the three Stage-2 solutions and apply its scene grammar to every direction; it adds no catalog or confirmation field. Record delivery context and afterlife in §I, visible states and optional motion jobs in §IX, script/notes policy plus target duration in §X. On the final-script branch, create the frozen `notes/total.md` after the approved roster/lock and before Step 5 or split-mode handoff. Reading mode leans `presentation`; choose `balanced` when close-reading afterlife materially outweighs video delivery. -**Default — reading mode (may override for durable close reading)**: recorded -explanation leans `presentation`; choose `balanced` when close-reading afterlife -materially outweighs video delivery. - -**Quick**: there is no Stage 1 or separate video-purpose confirmation. Explicit -video/recorded/self-running intent activates this reference after source -sufficiency is known and before the one-pass roster, resource, and motion -decisions; absent that intent, keep ordinary Quick behavior. Load the script -rules alone when an explicit final/literal narration will become notes/audio. -Keep the applicable scene grammar and final-script handling in active context. -A pre-SVG `notes/total.md` is an enabled production artifact, not a forbidden -planning checkpoint; Quick still creates no root Design Spec, lock, -confirmation payload, or storyboard. - -**Hard rule — Quick video Custom Animations**: when Quick generates a PPTX for -recorded, self-running, or video delivery, enable Custom Animations before SVG -authoring and complete the custom-animation stage before base export. Use -semantic groups and page-specific choreography; deck-wide `-a auto` and page -transitions do not satisfy this requirement. Individual pages or groups may -remain static, so this is not an animation-coverage quota. A validated -`animations.json` is required unless the user explicitly requests static or -page-transition-only playback. - -**Mandatory — Quick direct video input**: when Quick must deliver a narrated -video or MP4 rather than only a deck for later recording, enable Speaker Notes, -Narration Audio, and video export; write the complete per-scene narration to -`notes/total.md` before P01 and use it as page-design input. After the SVG -roster, only agent-authored wording may be finalized; final/literal input remains -verbatim. Before audio, complete the required Custom Animations configuration -and decide whether narration governs any group timing. +**Quick**: no Stage 1 or video-purpose confirmation. Explicit video/recorded/self-running intent activates this reference after source sufficiency is known and before the one-pass roster, resource, and motion decisions; absent that intent, ordinary Quick behavior. Load the script rules alone when an explicit final/literal narration becomes notes/audio. A pre-SVG `notes/total.md` is an enabled production artifact; Quick still creates no Design Spec, lock, confirmation payload, or storyboard. **Production outcomes**: | Need | Decision | |---|---| | Spoken delivery or a supplied final script | Enable Speaker Notes | -| User asks the workflow to synthesize narration | Enable Narration Audio; Speaker Notes is its dependency | +| User asks the workflow to synthesize narration | Enable Narration Audio (Speaker Notes is its dependency) | | Progressive reveal, continuing geometry, or timed emphasis materially aids explanation | Enable/load the appropriate animation capability | -| Quick generates a PPTX for recorded, self-running, or video delivery | Enable Custom Animations before SVG authoring and validate `animations.json` before base export | -| Quick directly delivers a narrated video or MP4 | Also enable Speaker Notes, Narration Audio, and video export; resolve narration-governed timing before audio, requiring timestamped page-local SRT for cue sync or subtitle delivery | -| The user explicitly requests static playback or disables object motion | Keep object animation off; retain the remaining notes/audio/video outcomes as requested | +| Quick generates a PPTX for recorded, self-running, or video delivery | **Hard rule**: enable Custom Animations before SVG authoring, use semantic groups and page-specific choreography, and complete the stage with a validated `animations.json` before base export; deck-wide `-a auto` and page transitions do not satisfy it; pages or groups may stay static — no coverage quota | +| Quick directly delivers a narrated video or MP4 | **Mandatory**: also enable Speaker Notes, Narration Audio, and video export; write the complete per-scene narration to `notes/total.md` before P01 as page-design input (agent-authored wording may be finalized after the roster, final/literal input stays verbatim); resolve narration-governed timing before audio, requiring timestamped page-local SRT for cue sync or subtitle delivery | +| The user explicitly requests static or page-transition-only playback | Keep object animation off; retain the remaining notes/audio/video outcomes | -**Capability boundary**: Default generation does not force object animation or -generated audio merely because a deck may later be recorded. Quick with an -effective recorded/self-running/video delivery purpose does require Custom -Animations, while explicit user instructions for static or -page-transition-only playback remain authoritative. This requirement selects -the capability, not motion coverage or one effect for every page. +Default never forces object animation or audio merely because a deck may later be recorded; the Quick requirement selects the capability, not motion coverage. --- ## 4. SVG, Notes, and Motion Realization -When §3 created `notes/total.md` before SVG, read it once before the first SVG -and design each page around its corresponding spoken segment. Give every -independently narrated or timed semantic unit a descriptive direct-root `<g -id>`; keep inseparable units grouped. Preserve a final/literal script exactly; -agent-authored direct-video narration may change only during its final-SVG -validation before audio. +When §3 created `notes/total.md` before SVG, read it once before the first SVG and design each page around its spoken segment. Give every independently narrated or timed semantic unit a descriptive direct-root `<g id>`; keep inseparable units grouped. Preserve a final/literal script exactly; agent-authored direct-video narration changes only during final-SVG validation before audio. -**Hard rule — script/design consistency**: a final script is literal content. -If the finished visual page introduces an independent claim or relationship the -script does not explain, repair the page or return to planning; never rewrite or -pad the final script during the late notes pass. Conversely, every spoken idea -that requires visual orientation must have a visible state or deliberate -speech-only treatment. +**Hard rule — script/design consistency**: a final script is literal content. If a finished page introduces a claim or relationship the script does not explain, repair the page or return to planning — never rewrite or pad the script in the late notes pass. Every spoken idea needing visual orientation has a visible state or a deliberate speech-only treatment. -**Motion readiness**: load `animations.md` before SVG authoring whenever the -plan needs compatible Morph endpoints or page/object-specific motion. Author -every required start/end state and real semantic group before the final checker; -post-processing cannot invent missing visual endpoints or target IDs. +**Motion**: load `animations.md` before SVG authoring whenever the plan needs Morph endpoints or page/object-specific motion, and author every required start/end state and semantic group before the final checker — post-processing cannot invent endpoints or target IDs. Use transitions, reveals, emphasis, and Morph only for a named communication job; `effect: none` remains valid. Auto-running narration uses `after-previous` / `with-previous`, never `on-click`. -**Motion restraint**: use transitions, reveals, emphasis, and Morph only for a -named communication job. There is no motion-coverage quota, and `effect: none` -remains valid. Auto-running narration uses `after-previous` / `with-previous`, -never `on-click`. +**Mandatory when narration governs object motion**: before SVG, load `animations.md` and preserve semantic groups; before audio, create and validate canonical `animations.json`. After the base PPTX/report and timestamped page audio/SRT, map timed groups in `narration_timing.json`, derive `narration_animations.json`, and export the narrated PPTX/MP4. Only derived triggers/delays wait for SRT; identity, effect, and order do not. `-a auto` or inherited fixed stagger is not semantic synchronization. For a user-selected static/page-transition-only Quick exception, or ordinary Default narration-independent deck-wide motion, omit these sidecars and the object-sync claim. -**Mandatory when narration governs object motion**: before SVG authoring, load -`animations.md` and preserve real semantic groups; before audio, create and -validate canonical `animations.json`. After the base PPTX/report and timestamped -page audio/SRT, map timed groups in `narration_timing.json`, derive -`narration_animations.json`, and export the narrated PPTX/MP4. Only derived -triggers/delays wait for SRT; object identity, effect, and order do not. `-a -auto` or inherited fixed stagger is not semantic synchronization. For an -explicit user-selected static/page-transition-only Quick exception, or for -ordinary Default narration-independent deck-wide motion, omit these sidecars -and the object-sync claim. +**Sound effects**: excluded from this pass and planning artifacts. After final SVG/motion, animation post-processing owns on-demand selection and native configuration. For direct narrated MP4, `generate-audio` owns the sound-delivery branch (§5); gain and limiting never enter `animations.json`. -**Sound effects**: exclude them from this pass and planning artifacts. After -final SVG/motion, animation post-processing owns on-demand selection and native -PPTX configuration; otherwise remain silent. For direct narrated MP4 delivery, -`generate-audio` owns the selected sound-delivery branch: native PowerPoint -encoding plus triggered post-export mix, or an explicitly requested real-time -PowerPoint slideshow capture. Video gain and limiting never enter -`animations.json`; capture uses the balance actually heard during Slide Show. - -**Production sequence**: after the final SVG check, validate any pre-SVG -narration against the visible pages; ordinary draft-source runs instead use the -final-SVG-grounded notes generation. Split notes, execute the resolved motion -path, and export the editable PPTX. Direct Quick video continues -through audio and, when required, timestamped SRT. Custom Animations use the -narrated-sidecar flow when narration governs group timing; -narration-independent custom motion exports its canonical timing without an -object-sync claim before the narrated PPTX and MP4. +**Production sequence**: after the final SVG check, validate pre-SVG narration against the visible pages (draft-source runs use final-SVG-grounded notes generation instead); split notes, execute the resolved motion path, export the editable PPTX; direct Quick video continues through audio and, when required, timestamped SRT. Narration-governed Custom Animations use the narrated-sidecar flow; narration-independent custom motion exports its canonical timing without an object-sync claim before the narrated PPTX and MP4. --- ## 5. Delivery Boundary -**Canonical artifact**: the editable PPTX remains canonical. `generate-audio` -owns provider/voice/rate selection, page audio/SRT generation, semantic -narration timing, narrated PPTX export, optional native PowerPoint video export, -the explicit slideshow-capture handoff, and the triggered sound-effects mix for -direct MP4 delivery. +**Canonical artifact**: the editable PPTX. `generate-audio` owns provider/voice/rate selection, page audio/SRT, semantic narration timing, narrated PPTX export, optional native PowerPoint video export, the slideshow-capture handoff, and the triggered sound-effects mix. -**Conditional MP4**: run `powerpoint_video.py --check` only for the native-export -branch. If native Windows PowerPoint export is unavailable, keep the narrated -PPTX as the successful upstream artifact. An explicit slideshow-capture choice -may hand that artifact to a user-operated Windows PowerPoint recorder; it is not -complete until the capture is returned and accepted. Do not substitute -screenshots, HTML, or a third-party renderer and call it equivalent. +**Conditional MP4**: run `powerpoint_video.py --check` only for the native-export branch. Without native Windows PowerPoint export, the narrated PPTX is the successful upstream artifact; an explicit slideshow-capture choice hands it to a user-operated PowerPoint recorder and is complete only when the capture is returned and accepted. Never substitute screenshots, HTML, or a third-party renderer. **Hard rule — choose one PowerPoint video sound boundary**: | Delivery branch | Sound contract | |---|---| -| Native encoder | PowerPoint supplies visual animation and narration but may omit transition/object sounds. With resolved cues, treat its MP4 as raw and require the verified `video_sound_mix.py` output. | -| Real-time slideshow capture | PowerPoint remains the renderer and audio player; a recorder captures the full-screen Slide Show and exactly one application/system-audio source. The accepted capture must contain narration and every configured cue once, and must not enter `video_sound_mix.py`. | +| Native encoder | PowerPoint supplies visual animation and narration but may omit transition/object sounds; with resolved cues its MP4 is raw and requires the verified `video_sound_mix.py` output | +| Real-time slideshow capture | PowerPoint renders and plays audio; a recorder captures the full-screen Slide Show and exactly one application/system-audio source; the accepted capture contains narration and every cue once and never enters `video_sound_mix.py` | -The branches are mutually exclusive because mixing a capture would duplicate -its cues. Keep the native cue configuration in the canonical PPTX. Slideshow -capture is explicit and human-audited; it does not inherit the native mix -receipt or become an automatic fallback. +The branches are mutually exclusive because mixing a capture would duplicate its cues. Keep the native cue configuration in the canonical PPTX; capture is explicit and human-audited, never an automatic fallback. -**Current boundary**: importing and automatically splitting one long finished -recording is unsupported. Require page-level audio or an explicit page/time map; -otherwise deliver the designed deck and frozen notes without claiming audio -integration. +**Current boundary**: importing and automatically splitting one long finished recording is unsupported. Require page-level audio or an explicit page/time map; otherwise deliver the deck and frozen notes without claiming audio integration. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/visual-review.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/visual-review.md index 450d1f7f..ddd6c7cf 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/visual-review.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/visual-review.md @@ -1,251 +1,121 @@ # Visual Review Rubric -> Per-page visual self-check rubric for slide SVGs. Read by the subagents spawned during the `visual-review` stage. Companion to the [`visual-review` stage](../workflows/stages/visual-review.md) and the [`visual_review.py`](../scripts/visual_review.py) renderer. +> Per-page visual self-check rubric for slide SVGs, read by the subagents spawned during the [`visual-review` stage](../workflows/stages/visual-review.md). The renderer contract lives in [`svg-pipeline.md`](../scripts/docs/svg-pipeline.md#visual_reviewpy). ## §0 Prerequisites -This rubric **does not repeat** what `svg_quality_checker.py` already covers. Required upstream order: - -``` -Executor finishes page → svg_quality_checker.py passes → visual_review.py renders PNG → this rubric runs -``` - -If the static checker has not been run or has failed, the subagent must abort with status `prereq_failed` and not start the rubric. Topics already enforced by the static checker (do **not** re-check here): - -- font-size anchor drift (more than `2px` from every declared role anchor) -- id uniqueness, XML well-formed -- canvas/structural typography validation and informational spec-lock anchor comparison (contextual colors/fonts are allowed) -- animation_config compliance +Required order: Executor finishes page → `svg_quality_checker.py` passes → `visual_review.py` renders PNG → this rubric runs. If the static checker has not run or failed, abort with status `prereq_failed`. Do not re-check what it already enforces: font-size anchor drift (`2px` from every declared role anchor), id uniqueness and XML well-formedness, canvas/structural typography and informational spec-lock comparison, `animation_config` compliance. ## §0.1 Subagent inputs -Each review subagent processes a **batch** of pages (see §6.1 for batch sizing). The inputs are: +Each subagent processes a batch of pages (§6.1) with these inputs: (1) the page batch — `(svg_path, png_path, page_role, canvas)` records, `svg_path` under `<project>/svg_output/`, `png_path` under `<project>/.preview/`, `page_role` one of `cover` / `chapter` / `tldr` / `content` / `data` / `closing` / `breathing` parsed from `design_spec.md §IX` by the orchestrator (never guessed), `canvas` copied verbatim from the renderer record (`view_box`, `width` / `height`, `png_width` / `png_height`; never assumed or recomputed); (2) this rubric's path; (3) `<project>/design_spec.md` read-only — §IX is the truth for what the page should deliver; (4) `<project>/spec_lock.md` read-only; (5) a Style Review Focus excerpt, only when an installed `templates/design_spec.style.<id>.md` exists, with its source path and exact §VII wording; (6) writable `<project>/.review/`. -1. **Page batch** — a list of `(svg_path, png_path, page_role, canvas)` records, one per assigned page. `svg_path` resolves under `<project>/svg_output/<page>.svg`, `png_path` under `<project>/.preview/<page>.png`. `page_role` is one of `cover` / `chapter` / `tldr` / `content` / `data` / `closing` / `breathing`, parsed from `design_spec.md §IX` by the orchestrator — subagents do **not** guess. `canvas` is copied verbatim from that page's successful renderer record and contains the root-SVG `view_box`, exact `width` / `height`, and raster `png_width` / `png_height`; subagents never assume a fixed canvas or recompute it from the PNG. -2. **Path to this rubric file** -3. **`<project>/design_spec.md`** (read-only) — §IX outline is the source of truth for "what should this page deliver" -4. **`<project>/spec_lock.md`** (read-only) — brand-locked values -5. **Style Review Focus excerpt** (conditional, read-only) — supplied by the orchestrator only when an installed `<project>/templates/design_spec.style.<id>.md` exists; it retains the source path and exact §VII wording -6. **`<project>/.review/`** (writable) — where backups and findings JSON go - -The subagent reads inputs 2–5 **once** at the start of its turn (input 5 may be absent), then iterates over the page batch sequentially (one page at a time): apply the rubric → apply any Style supplement → write `<project>/.review/<page>.json` → move on. This is the core token-saving move — fixed context is read N/K times instead of N times. - -Style Review Focus is supplemental acceptance context, not a second rubric. It cannot create new Hard rules, weaken §§1–3, or authorize content, identity, or structural edits. Record a clearly unmet focus item as `rule: "STYLE"`: apply a fix only when the existing rubric already permits that atomic edit; otherwise add a `needs_human_items` entry with a concise suggested fix. +Read inputs 2–5 once at the start, then iterate the batch sequentially: apply the rubric → apply any Style supplement → write `<project>/.review/<page>.json` → next page. Style Review Focus is supplemental acceptance context, not a second rubric: it cannot add Hard rules, weaken §§1–3, or authorize content, identity, or structural edits. Record a clearly unmet focus item as `rule: "STYLE"`; fix it only when the rubric already permits that atomic edit, otherwise add a `needs_human_items` entry with a suggested fix. ## §1 Hard rules (fix every hit) | # | Category | Trigger | Permitted fix | |---|----------|---------|---------------| -| H1 | Out-of-bounds | element bbox falls outside the bounds declared by `canvas.view_box` | shrink or reposition into canvas | +| H1 | Out-of-bounds | element bbox outside `canvas.view_box` | shrink or reposition into canvas | | H2 | Text overflow | text bbox extends past its visual container | reduce font-size or line-break | -| H3 | Text overlap | two `<text>` elements' bboxes intersect (tspans within one text excluded) | reposition or resize | -| H4 | Readability | contrast < 4.5 (small text) / < 3.0 (font-size ≥ 24px); OR text directly atop a complex image with no scrim | if **neither** the foreground nor the background color is a brand token: position-only escape — add a `<rect>` scrim under the text, or raise the offending text's font-size to ≥ 24px so the 3.0 threshold applies. If **either** color is a brand token: do not edit the SVG → goto §1.1 escalation. | -| ~~H5~~ | Font-ramp drift | *covered by `svg_quality_checker.py` — see §0 prerequisites* | n/a (do not re-check) | +| H3 | Text overlap | two `<text>` bboxes intersect (tspans within one text excluded) | reposition or resize | +| H4 | Readability | contrast < 4.5 (small text) / < 3.0 (font-size ≥ 24px), or text directly atop a complex image with no scrim | when neither color is a brand token: position-only escape — add a `<rect>` scrim under the text, or raise the text to ≥ 24px so the 3.0 threshold applies; when either color is a brand token: do not edit → §1.1 | +| ~~H5~~ | Font-ramp drift | covered by `svg_quality_checker.py` (§0) | n/a | | H6 | Element collision | rect/circle/path bboxes overlap with z-order violating semantics | open spacing | -| H7 | Declared page chrome displaced | page number / header / footer is explicitly declared by `design_spec §IX`, `spec_lock.md`, or the installed template with a concrete anchor, but is covered, missing, or outside `canvas.view_box` | restore only that declared chrome to its declared anchor; never invent undeclared chrome | -| H8 | Image rendering broken | `<image>` empty / broken-image / severe distortion | fix `href`; for `adaptive`, choose `meet` or a safer crop; a new complete-display requirement returns to §VIII `Crop Policy` and lock projection | -| H9 | Missing key element | element required by `design_spec §IX` outline is absent from rendered slide | recreate from spec | +| H7 | Declared page chrome displaced | page number / header / footer explicitly declared by `design_spec §IX`, `spec_lock.md`, or the installed template with a concrete anchor is covered, missing, or outside `canvas.view_box` | restore only that declared chrome; never invent undeclared chrome | +| H8 | Image rendering broken | `<image>` empty / broken / severely distorted | fix `href`; for `adaptive`, choose `meet` or a safer crop; a new complete-display requirement returns to §VIII `Crop Policy` and lock projection | +| H9 | Missing key element | element required by `design_spec §IX` absent from the render | recreate from spec | -Detection order (run sequentially, do not parallelize within a single subagent): - -``` -H1 → H2 → H7 (structure) -H3 → H6 (collisions) -H4 (readability) -H8 → H9 (content) -``` +Detection order, sequential within one subagent: H1 → H2 → H7 (structure), H3 → H6 (collisions), H4 (readability), H8 → H9 (content). ### §1.1 Brand-token contrast escalation -If H4 fires and the foreground or background color is a **brand token** (defined in `spec_lock.md`) — i.e., the violation will repeat on every page using that token — do **not** touch the SVG. Brand decisions are §3 Don't-Touch; even position-only escapes (scrim insertion, font-size escalation) shift the page's visual weight in ways that should be a brand-level decision, not a per-page subagent decision. Instead: - -1. Record the finding in the page JSON under `needs_human_items` with `rule: "H4"`, the offending element selector, and `suggested_fix_summary` describing the brand-level options (e.g., "raise body-text token from `#6E7681` to `#8B949E` deck-wide" or "introduce a scrim style in the brand"). -2. Append the finding to `<project>/.review/brand_review.json` (append-only log; one entry per distinct token+context pair). The orchestrator aggregates and surfaces this to the main agent at the end of the run so the user can make one cross-deck decision instead of N per-page ones. -3. The page's `status` is `needs_human` if H4 is the only Hard hit on the page; if other (non-brand) Hard hits were fixed, the page still finishes as `fixed` and the brand-token H4 entry sits in `needs_human_items` alongside. - -The aggregated brand review is the responsibility of the orchestrator at the end of the run, not the per-page subagent. +If H4 fires and the foreground or background is a brand token from `spec_lock.md`, the violation repeats on every page using that token, so do not touch the SVG — even a scrim or size escalation is a brand-level decision. Record the finding under `needs_human_items` with `rule: "H4"`, the element selector, and a `suggested_fix_summary` naming brand-level options (e.g. "raise body-text token from `#6E7681` to `#8B949E` deck-wide"), and append it to `<project>/.review/brand_review.json` (append-only, one entry per distinct token+context pair). The page's `status` is `needs_human` when H4 is its only Hard hit; otherwise it finishes `fixed` with the H4 entry alongside. The orchestrator aggregates brand findings at the end of the run. ## §2 Soft rules (act only when clearly bad) -Subagents must apply the **clearly bad** threshold — when in doubt, leave it. Better to under-fix than to oscillate. +When in doubt, leave it — under-fixing beats oscillation. | # | Category | Trigger | Fix direction | |---|----------|---------|---------------| -| S1 | Vertical rhythm tight | Within the **same logical text block**, consecutive baselines have gap < 1.05× larger font-size | open to 1.15–1.3× | -| S2 | Vertical rhythm hollow | Within one logical block, > 150 px non-decorative whitespace; `breathing` pages exempt | tighten | -| S3 | Intended anchor missed | hero/title block is clearly displaced from a concrete anchor explicitly declared by `design_spec §IX`, `spec_lock.md`, or the installed template. Canvas center counts only when the plan explicitly calls for centered placement; intentional asymmetry, negative space, and image-focal placement are exempt. | restore toward the declared anchor | -| S4 | Alignment drift | same-column elements differ in `x` by > 4 px (or same-row baselines by > 4 px) **and** are semantically meant to be on the same grid line | snap to grid | +| S1 | Vertical rhythm tight | within one logical text block, consecutive baselines gap < 1.05× the larger font-size | open to 1.15–1.3× | +| S2 | Vertical rhythm hollow | within one block, > 150 px non-decorative whitespace; `breathing` pages exempt | tighten | +| S3 | Intended anchor missed | hero/title block clearly displaced from a concrete anchor explicitly declared by §IX, the lock, or the template; canvas center counts only when the plan calls for centering — intentional asymmetry, negative space, and image-focal placement are exempt | restore toward the declared anchor | +| S4 | Alignment drift | same-column `x` or same-row baselines differ by > 4 px and are meant to share a grid line | snap to grid | | S5 | Grid non-uniform | N-card row: neighbor `x`-spacing differs by > 5% of the average | re-distribute | -| S6 | CJK letter-spacing | CJK characters with `letter-spacing / font-size > 5%` | reduce to ≤ 2% | -| S7 | Decorative accents compete | multiple unlocked colors with no semantic role visibly compete with one another and with the intended primary emphasis. Brand colors, natural-media colors, data-series/category colors, status encoding, and other semantic colors are exempt. | consolidate only the competing decorative colors into existing page/deck accents; never recolor locked or semantic elements | -| S8 | Emphasis mismatch | most visually prominent element ≠ the element `design_spec §IX` declares as the page's primary | rescale to match intent | -| S9 | Image-text relationship | caption > 60 px from its image; text on busy image without scrim; image clearly purposeless | tighten / add scrim / remove | -| S10 | Breathing violation | only when `page_role = breathing`: ≥3 rounded card grid | replace with naked text / single hero | +| S6 | CJK letter-spacing | CJK `letter-spacing / font-size > 5%` | reduce to ≤ 2% | +| S7 | Decorative accents compete | several unlocked colors with no semantic role visibly compete with each other and the intended primary emphasis; brand, natural-media, data-series, status, and other semantic colors are exempt | consolidate only the competing decorative colors into existing accents; never recolor locked or semantic elements | +| S8 | Emphasis mismatch | most prominent element ≠ the element §IX declares as the page's primary | rescale to match intent | +| S9 | Image-text relationship | caption > 60 px from its image; text on a busy image without scrim; image clearly purposeless | tighten / add scrim / remove | +| S10 | Breathing violation | `page_role = breathing` with a ≥ 3 rounded-card grid | replace with naked text / single hero | ## §3 Don't-touch -Hard boundary, equal weight to §1. - -- **Brand decisions** — color tokens, font families, geometry style (decided by `spec_lock.md` / brand directory) -- **Layout restructure** — do not change column counts, replace chart types, add/remove sections -- **Content** — do not add or remove copy; only adjust position, font-size (within the mapped role's anchor `±2px`), spacing, letter-spacing, alignment, scrim -- **Other files** — never edit `design_spec.md` / `spec_lock.md` / `animations.json` / `image_prompts.json` / `images/` / other pages' SVGs -- **Atomicity** — one edit per fix, no bulk multi-element replacements - -If a "violation" requires reinterpreting `design_spec.md` to fix → mark `needs_human` with a one-line `suggested_fix_summary`. +Equal weight to §1: brand decisions (color tokens, font families, geometry style from `spec_lock.md` / brand directory); layout restructure (column counts, chart types, sections); content (no added or removed copy — only position, font-size within the role anchor `±2px`, spacing, letter-spacing, alignment, scrim); other files (`design_spec.md`, `spec_lock.md`, `animations.json`, `image_prompts.json`, `images/`, other pages' SVGs); atomicity (one edit per fix, no bulk multi-element replacement). A "violation" that requires reinterpreting `design_spec.md` → `needs_human` with a one-line `suggested_fix_summary`. ## §4 Iteration protocol ### §4.0 Iteration 0 — PNG sanity check -Run before applying any rule: - -- PNG file exists and is non-zero bytes -- PNG dimensions = that page record's `canvas.png_width` × `canvas.png_height` -- PNG is **not** all-background (a histogram check: count of background-color pixels < 99% of total) — guards against blank/white-out renders only, **does not** filter sparse dark layouts - -Any check fails → status = `render_failed`, abort without scanning rules. +Before any rule: the PNG exists and is non-empty; its dimensions equal the record's `canvas.png_width` × `canvas.png_height`; it is not all-background (background-color pixels < 99% — guards blank renders only, not sparse dark layouts). Any failure → `render_failed`, abort. ### §4.1 Iteration loop -The full loop is defined here but the **default budget is 1 iteration**. Multi-iteration runs require an explicit opt-in in the orchestrator prompt and roughly double render cost per added iteration. - -``` -iteration 1: scan all Hard + Soft → fix → (re-render only if budget ≥ 2) -iteration 2 (opt-in): re-verify changed elements + scan for new Hard hits → fix → re-render -iteration 3 (opt-in): report only, no further fix -``` - -Per-iteration fix caps: - -- **Hard rules**: no per-round cap — every Hard hit must be addressed in the iteration it was found in -- **Soft rules**: ≤ 2 fixes per iteration; remaining Soft hits go to `untouched_concerns` +Default budget is **1 iteration**; more requires explicit opt-in in the orchestrator prompt and roughly doubles render cost per iteration. Iteration 1: scan all Hard + Soft → fix → re-render only if budget ≥ 2. Iteration 2 (opt-in): re-verify changed elements + scan for new Hard hits → fix → re-render. Iteration 3 (opt-in): report only. Hard rules have no per-round cap; Soft rules ≤ 2 fixes per iteration, remainder to `untouched_concerns`. ### §4.2 Termination conditions -- **Rollback trigger**: any iteration's fix introduces a **new Hard hit** that did not exist before → immediately `cp` the backup back over the SVG, status = `needs_human`, finding records "rolled back fix X — created Hard Y" -- **Soft thrash trigger** (iteration budget ≥ 2 only): iteration 2's fix introduces a **new Soft hit** that did not exist before → stop, status = `needs_human` with note "fixes are competing" -- **Clean exit**: iteration ends with zero Hard hits and ≤ 1 Soft hit remaining → status = `ok` if no fixes were applied, `fixed` if any were applied +Rollback: a fix introduces a new Hard hit → `cp` the backup back, status `needs_human`, record "rolled back fix X — created Hard Y". Soft thrash (budget ≥ 2): iteration 2 introduces a new Soft hit → stop, `needs_human`, "fixes are competing". Clean exit: zero Hard hits and ≤ 1 Soft hit remaining → `ok` if nothing was applied, `fixed` otherwise. ### §4.3 Backup discipline -Before the **first** `Edit` on a page in any iteration `N`, the subagent must: - -```bash -cp <project>/svg_output/<page>.svg <project>/.review/backup/<page>.iter<N>.svg -``` - -The backup path is recorded in every finding's `backup_path` field. Backups are the rollback anchor for §4.2. +Before the first edit on a page in iteration `N`: `cp <project>/svg_output/<page>.svg <project>/.review/backup/<page>.iter<N>.svg`; record the path in every finding's `backup_path`. ## §5 Output schema -Each subagent writes exactly one file to `<project>/.review/<page>.json`: +One file per page at `<project>/.review/<page>.json`; every `needs_human_items` entry carries a `suggested_fix_summary`, never a bare problem description. ```json { "page": "02_three_steps.svg", "page_role": "content", - "canvas": { - "view_box": [0, 0, 1242, 1660], - "width": 1242, - "height": 1660, - "png_width": 1242, - "png_height": 1660 - }, + "canvas": {"view_box": [0, 0, 1242, 1660], "width": 1242, "height": 1660, "png_width": 1242, "png_height": 1660}, "status": "ok" | "fixed" | "needs_human" | "render_failed" | "prereq_failed", "iterations_run": 1, - "screenshot_paths": [ - ".preview/02_three_steps.png", - ".preview/02_three_steps.iter1.png" - ], - "findings": [ - { - "iter": 1, - "rule": "S6", - "severity": "soft", - "evidence": "letter-spacing=10 on font-size=84, ratio=11.9% > 5%", - "fix_applied": { - "element": "#hero-statement text[font-size='84']", - "before": "letter-spacing=\"10\"", - "after": "letter-spacing=\"2\"" - }, - "verified_in_iter": 2, - "backup_path": ".review/backup/02_three_steps.iter1.svg" - } - ], - "untouched_concerns": [ - { - "rule": "S1", - "evidence": "...", - "reason": "soft-cap reached" | "ambiguous_design_intent" - } - ], - "needs_human_items": [ - { - "rule": "H9", - "suggested_fix_summary": "Hero subtitle declared in spec §IX.4 missing; add a <text> at (80,496) per design language" - } - ], - "design_intent_check": { - "spec_says": "TL;DR — emphasize 意图 as the core abstraction", - "render_delivers": true, - "note": "..." - } + "screenshot_paths": [".preview/02_three_steps.png", ".preview/02_three_steps.iter1.png"], + "findings": [{ + "iter": 1, "rule": "S6", "severity": "soft", + "evidence": "letter-spacing=10 on font-size=84, ratio=11.9% > 5%", + "fix_applied": {"element": "#hero-statement text[font-size='84']", "before": "letter-spacing=\"10\"", "after": "letter-spacing=\"2\""}, + "verified_in_iter": 2, + "backup_path": ".review/backup/02_three_steps.iter1.svg" + }], + "untouched_concerns": [{"rule": "S1", "evidence": "...", "reason": "soft-cap reached" | "ambiguous_design_intent"}], + "needs_human_items": [{"rule": "H9", "suggested_fix_summary": "Hero subtitle declared in spec §IX.4 missing; add a <text> at (80,496) per design language"}], + "design_intent_check": {"spec_says": "TL;DR — emphasize 意图 as the core abstraction", "render_delivers": true, "note": "..."} } ``` -`needs_human_items` must include a `suggested_fix_summary` for every entry — never bare problem descriptions. - ## §6 Dispatch & messaging contract -This rubric is consumed by subagents spawned via the `visual-review` stage. Mandatory dispatch invariants: - ### §6.1 Orchestrator → subagent (batched dispatch) -The orchestrator partitions the N pages into `ceil(N/K)` batches of ≤ K pages each (default **K = 5**; configurable per run via the orchestrator prompt) and spawns one subagent per batch. +The orchestrator partitions N pages into `ceil(N/K)` batches of ≤ K pages (default **K = 5**, configurable per run) and spawns one subagent per batch, all in one assistant message (parallel `Agent` calls). Each prompt is self-contained — absolute paths for inputs 1–5 plus the full batch records; no prior context assumed. `subagent_type: general-purpose`; tools Read, Edit, Bash (`cp` backups), Write (JSON); no playwright — the orchestrator pre-renders. Dispatch must work with anonymous subagents when `name` / `team_name` are unavailable. -- Spawn all batch subagents in **one assistant message** (parallel `Agent` calls). Sequential dispatch breaks pipelining. -- Each subagent prompt is **self-contained** — no prior conversation context. Inline the absolute paths for §0.1 inputs 1–5 explicitly, plus the full `(svg_path, png_path, page_role, canvas)` records for that batch. Do not assume the subagent knows the project root. -- `subagent_type: general-purpose`. Tool restrictions: Read, Edit, Bash (for `cp` backups), Write (for JSON output). MCP playwright is **not** required by subagents — orchestrator pre-renders PNGs. -- `name` / `team_name` parameters may be unavailable from nested teammate context. Dispatch must remain functional with anonymous subagents — do not require named addressing. - -**Why batched, not per-page**: the rubric (~2.5K tokens), `design_spec.md` (~4–5K), and `spec_lock.md` (~1K) are identical inputs across all pages and do **not** share a prompt cache between sibling subagents. A 20-page deck with per-page dispatch re-reads ~150K tokens of fixed documents; batched dispatch with K=5 cuts that by ~75% while staying inside default parallel-subagent limits (~10). Batches also bound failure blast radius — one crashed subagent loses K pages, not the entire run. - -**Batch size guidance**: -- `K = 5` (default) — balanced; safe for decks up to ~50 pages -- `K = 3` — high-fidelity / small decks (≤ 12 pages); slightly higher parallelism -- `K = 10` — token-sensitive / large decks (50+ pages); fewer subagents, larger blast radius per failure - -Larger K is **not** always better: subagent context fills with prior pages' SVG / PNG / findings as the batch progresses, and beyond ~10 pages context auto-compression starts dropping early findings. Keep K such that `K × (avg_svg_size + image_token_cost + report_size)` stays well under the subagent context budget. +Batched dispatch exists because the rubric (~2.5K tokens), `design_spec.md` (~4–5K), and `spec_lock.md` (~1K) are identical across pages and do not share a prompt cache between siblings: K=5 cuts fixed-document re-reads by ~75% on a 20-page deck and bounds failure blast radius. Guidance: K=5 default (decks to ~50 pages), K=3 for high-fidelity short decks, K=10 for token-sensitive large decks; beyond ~10 pages subagent context compression starts dropping early findings, so keep `K × (avg_svg_size + image_token_cost + report_size)` well under the subagent budget. ### §6.2 Subagent → orchestrator -- Subagent's **final action before going idle** must be `SendMessage(to=<lead>)` listing one JSON path per processed page (e.g., `<project>/.review/<page>.json`) and a ≤150-word text summary covering all pages in the batch. Going idle without messaging — or messaging with a partial batch — is a protocol violation. -- If the subagent aborts mid-batch (rule §4.2 rollback, tool error, etc.), it must still send the batch report covering both completed and aborted pages, with the aborted pages marked `needs_human` or `render_failed` as appropriate. +The subagent's final action before idling is `SendMessage(to=<lead>)` listing one JSON path per processed page and a ≤150-word summary of the batch; idling without messaging or with a partial batch is a violation. A mid-batch abort still sends the report with aborted pages marked `needs_human` or `render_failed`. ### §6.3 Orchestrator → main agent -- Orchestrator's **final action before going idle** must be `SendMessage(to=<lead>)` containing: - - the aggregate Markdown table (page × status × hard_hits × soft_hits × fixes_applied × needs_human_reason) - - one ≤150-word "plumbing verdict" paragraph - - path to `brand_review.json` if any §1.1 aggregations occurred +The orchestrator's final action is `SendMessage(to=<lead>)` with the aggregate table (page × status × hard_hits × soft_hits × fixes_applied × needs_human_reason), one ≤150-word plumbing verdict, and the `brand_review.json` path if any §1.1 aggregation occurred. ### §6.4 Concurrency -- Pre-rendering is serialized by `visual_review.py`'s file lock at `<project>/.preview/.render.lock`. Subagents must **not** call the renderer concurrently. Re-renders during iteration loop go through the same lock. +Rendering is serialized by `visual_review.py`'s lock at `<project>/.preview/.render.lock`; subagents never call the renderer concurrently, and iteration re-renders go through the same lock. -## §7 Renderer expectations *(script contract)* +## §7 Renderer expectations -`visual_review.py <project> [pages...]` must guarantee: - -- Output PNG matches what the user would see in the live-preview browser (inlined `<use data-icon>`, resolved `<image href>`) -- The root SVG `viewBox` is the canvas source of truth; each successful page record includes its exact `view_box`, `width` / `height`, and raster `png_width` / `png_height` -- Output dimensions = that page record's `png_width` × `png_height` -- File-lock serialization at `<project>/.preview/.render.lock` -- Clean exit codes: - - `0` — all requested pages rendered - - `2` — live-preview server not running for this project (subagent should not retry; surfaces to the orchestrator) - - `3` — rendering backend (playwright + chromium) missing or unable to launch (config error, surface to user) - - `4` — page-level render failure (specific failures listed in stderr; partial output is acceptable) - -The renderer never edits SVGs and never reads any rule from this rubric — it is a pure render-and-validate tool. +`visual_review.py` is a pure render-and-validate tool: it never edits SVGs and reads no rule from this rubric. Its output, canvas, lock, and exit-code contract is documented in [`svg-pipeline.md`](../scripts/docs/svg-pipeline.md#visual_reviewpy). diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/visual-styles/_index.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/visual-styles/_index.md index 5d2a00c2..9bda6037 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/visual-styles/_index.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/visual-styles/_index.md @@ -21,7 +21,7 @@ Each style keeps its own authoritative file with: shape & decoration, typography > The **`visual_style` value is only ever a first-column `id`** (`swiss-minimal`, `editorial`, …). The "Paired rendering" column lists **image-rendering** names (`flat`, `minimalist-swiss`, `digital-dashboard`, …) — never treat one of those as the `visual_style`. Default records rendering under confirmation h; Quick keeps the selected rendering only in active context and any required image manifest. > -> The **`Illus.`** column describes illustration's role only after page-carrier selection activates it — `core` (illustration may lead the look), `supportive` (illustration may share the composition), or `sparse` (illustration stays selective so the style's lead visual remains clear). It tunes selected illustration's centrality and recurrence; it never recommends adding illustration, selects an AI source or image row, or narrows eligible page types, element scale, or carrier combinations. An explicit user request to use / skip illustrations overrides it either way, and `image_usage: none` always writes no illustration rows. Full per-style rule in each file's §6. +> The **`Illus.`** column describes illustration's role only after the resource-need review selects illustration — `core` (illustration may lead the look), `supportive` (illustration may share the composition), or `sparse` (illustration stays selective so the style's lead visual remains clear). It tunes selected illustration's centrality and recurrence; it never recommends adding illustration, selects an AI source or image row, or narrows eligible page types, element scale, or carrier combinations. An explicit user request to use / skip illustrations overrides it either way, and `image_usage: none` always writes no illustration rows. Full per-style rule in each file's §6. > > **Typography character applies to editable native text.** Decorative > lettering is a separate carrier decision; a selected style informs its @@ -107,11 +107,7 @@ an exact authoring preset here. ## 3. Editable `custom` projection -Each coordinated Default Stage-2 direction authors one visible, non-empty `custom` aesthetic whose paragraph names its executable shape language, composition geometry, decoration density, whitespace, typographic character, and texture — **no HEX, no color names as values**. `custom` is not constrained by its relationship to the catalog: it may use catalog material in any way or none, including carrying one fitting preset unchanged. The three complete directions are plainly different designs; this axis expresses that difference whenever their aesthetics genuinely differ, and catalog bases may coincide. A different name, note, reference count, or palette alone is not another aesthetic. Style behaviors may also coincide when other components carry the direction difference or authoritative user/template truth forbids visual variation; state that boundary in the direction note instead of fabricating difference. Use this index to freeze any catalog bases before reading their detail files. A template-backed direction stays inside the inherited identity and confirmed application plan. Record the confirmed current aesthetic in the Design Spec first, then project `- visual_style: custom` plus `- visual_style_behavior:`. The 18 fixed styles remain lower-level single-select alternatives; do not create a fourth AI-custom proposal. - -Quick does not display a candidate spectrum. It reads this index, resolves one preset or custom behavior, then reads only the selected detail files and persists nothing. - -**Mandatory — select before detail reading**: Freeze every catalog source actually used from this index, then read only those exact files before writing the behavior. One source may supply the complete aesthetic unchanged; when several are named, each contributes a distinct executable job across shape language, composition, decoration, whitespace, typography, or texture. Reference count has no fixed cap; count is an outcome, not a target. A coherent three-basis direction may assign `swiss-minimal` to grid and whitespace, `soft-rounded` to selective surface contours and elevation, and `editorial` to evidence hierarchy and rules. Default persists every actual id as `visual_style_references`; Quick retains them only in active context. Omit every source whose contribution cannot be stated, never add a second merely to imply synthesis, and do not open candidates for comparison after this gate. A custom using no catalog source names and reads none. +Each Default Stage-2 direction authors one visible, non-empty `custom` aesthetic under [`strategist.md`](../strategist.md) §d — its executable shape language, composition geometry, decoration density, whitespace, typography character, and texture — naming only the catalog bases it actually uses; freeze those ids from this index, then read only their files before writing the behavior. Quick resolves one preset or custom behavior the same way and persists nothing. --- diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/docs/confirm_ui.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/docs/confirm_ui.md index c1c2425a..ebf6b31a 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/docs/confirm_ui.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/docs/confirm_ui.md @@ -26,77 +26,7 @@ **Hard rule**: Keep detailed Confirm UI behavior here. The Generate route may summarize orchestration, but it should not duplicate the full JSON schema, catalog behavior, or launcher lifecycle. -**Mandatory surface decision — before any UI command**: Resolve the most recent -explicit confirmation-surface instruction for this run before running -`--daemon` or `--wait-only`. Unrelated later messages do not reset the selected -branch. A new explicit selection may change it before launch; once confirmation -starts in chat or UI switches to chat, keep chat for the rest of this run. - -| Most recent explicit surface instruction | Branch | -|---|---| -| The user explicitly delegates confirmation | Make the combined Stage-1 communication/template decision, install it, then present one complete final summary. Do not launch the page or fabricate UI receipts. | -| Otherwise, the user asks for or agrees to personally confirm in chat, or declines the confirmation page | Use chat for both Strategist stages; Stage 1 includes the template/free-design choice. Do not launch the page, run `--wait-only`, or require UI-authored receipts. | -| No explicit confirmation-surface instruction exists for this run | Use the page as the default. | - -Interpret the instruction semantically: “confirm here”, “use the chat window”, or -“do not open the confirmation page” are sufficient; no literal `chat-only` -keyword is required. Invoking a chat-question tool by itself does not select the -chat branch—the user's instruction does. Both branches preserve the same -Stage-1 communication/template decision, installation handoff, and template-aware -final Stage 2; the chat branch records the same `design_spec_depth` value in its -confirmation summary. - -**Chat/delegated Stage-1 listing**: Author the communication recommendation -before reading the four indexes, then present that recommendation together with -an explicit free-design/template-mode choice. Only template mode expands the -registered candidates and supplied exact roots, and it requires at least one -selection. Ordinary requests initialize free design; explicit template intent -or any supplied exact root initializes template mode. Exactly one supplied root -may also seed that candidate, while multiple roots remain unselected. Under -explicit delegation, make the same decision, install -it, and only then derive Stage 2. Do not launch the page or fabricate receipts. - -**Fallback rule**: When no surface was selected before launch, the page is the -default. Use chat when the user answers either always-on handoff in chat, or -after launch failure/timeout and one re-check of `result.json` plus the -Stage-1-sidecar `template_selection.json` when Stage 1 is active. A chat-question -tool alone is not a launch failure. Preserve the combined Stage-1 decision and -keep communication prompts open-ended. - -**In-run UI → chat switch — any phase or stage**: If the user explicitly selects chat -after the UI server has launched—while `--wait-only` is active, before that wait -starts, or after it times out while the server remains live: - -1. If a wait is active, interrupt it and confirm that its process has exited. - Only the return code from this deliberate wait interruption is expected to - be non-zero. -2. Run `server.py <project_path> --shutdown` and require that cleanup to - succeed. The browser tab may remain open, but its stopped server makes it - inactive. -3. Re-check the active receipt once. During Stage 1, require both `result.json` - and `template_selection.json` from the same submission; during Stage 2, check - `result.json`. Retain only values persisted before shutdown; an unsubmitted - browser draft is not confirmed. -4. Continue the unresolved current phase/stage and everything remaining in chat. Do - not call `--wait-only` again, recover the server, or relaunch the page during - this run. - -**Always-on Stage-1 chat handoff**: After writing `template_options.json` and -template-independent `recommendations.stage1.json`, launch the healthy daemon -without `--wait`. Immediately post its actual URL plus one compact localized -summary of the current communication recommendation and template choice state: -audience, communication intent, audience outcome, core message, delivery -context, artifact afterlife, `content_divergence`, canvas, and whether the -default is free design or template mode, including any sole preselected root. Explain -that template mode expands the registered-kind and supplied-root selectors. -Show a blank prose value as “not specified” without changing it. End with an -explicit localized line saying that, if the page did not open, the user may -confirm or revise the same communication and template choices in chat. Only -then run `--wait-only --wait-stage stage1`. A chat -reply to that handoff applies the in-run switch above without waiting for -timeout. The handoff is context, not confirmation, and silence confirms -nothing. After launch failure/timeout and the required result re-check, present -the same combined Stage-1 items as open chat questions and wait explicitly. +**Model-facing procedure lives elsewhere**: the surface decision, chat/delegated listing, always-on Stage-1 chat handoff, in-run UI → chat switch, and the authoring shapes of `recommendations.stage1.json`, `recommendations.stage2.json`, and `result.json` are owned by [`confirm-surface.md`](../../references/confirm-surface.md), which the Strategist reads. This document keeps the server lifecycle, the template-selection sidecar, catalogs, the progression guard, and the complete field semantics that the server validates. ## `confirm_ui/server.py` diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/docs/narration.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/docs/narration.md new file mode 100644 index 00000000..a7ddd6e9 --- /dev/null +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/docs/narration.md @@ -0,0 +1,88 @@ +# Narration Tools + +Tool behavior behind the [`generate-audio`](../../workflows/stages/generate-audio.md) stage: `notes_to_audio.py`, `narration_sync.py`, the narrated `svg_to_pptx.py` export, `powerpoint_video.py`, `video_sound_mix.py`, and `video_subtitles.py`. The stage owns when each runs and what the user confirms; this page owns what the tools do. Model and audio-parameter recommendations live in [`docs/audio-narration.md`](../../../../docs/audio-narration.md). + +## Prerequisites + +- `edge-tts` for the default backend (`python3 -m pip install edge-tts`); `ffprobe` for recorded-narration export (slide timings come from actual audio duration); `ffmpeg` plus `numpy` for post-export video calibration and the sound mix. +- Cloud keys: ElevenLabs `ELEVENLABS_API_KEY`; MiniMax `MINIMAX_API_KEY` (China endpoint by default; `MINIMAX_TTS_BASE_URL=https://api.minimax.io/v1/t2a_v2` for overseas); Qwen `QWEN_API_KEY` or `DASHSCOPE_API_KEY`; CosyVoice `COSYVOICE_API_KEY` or `DASHSCOPE_API_KEY`. Keys come from the process environment or the first `.env` found in: current working directory, skill directory (e.g. `~/.agents/skills/ppt-master/.env`), clone repo root, `~/.ppt-master/.env`. +- Automatic video export requires Windows PowerPoint 2016+. macOS PowerPoint has no `CreateVideo` automation contract and its manual movie export drops animation effects; UI scripting is not a substitute. + +## `notes_to_audio.py` + +```bash +python3 skills/ppt-master/scripts/notes_to_audio.py --list-voices --locale <locale> # edge +python3 skills/ppt-master/scripts/notes_to_audio.py --provider <elevenlabs|minimax|qwen|cosyvoice> --list-voices +python3 skills/ppt-master/scripts/notes_to_audio.py <project_path> --voice <ShortName> --rate <rate> [--concurrency <N>] +python3 skills/ppt-master/scripts/notes_to_audio.py <project_path> --provider elevenlabs --voice-id <id> --elevenlabs-model eleven_multilingual_v2 +python3 skills/ppt-master/scripts/notes_to_audio.py <project_path> --provider minimax --voice-id <id> --minimax-model speech-2.8-hd +python3 skills/ppt-master/scripts/notes_to_audio.py <project_path> --provider qwen --voice-id <voice> --qwen-model qwen3-tts-flash --qwen-language-type Chinese +python3 skills/ppt-master/scripts/notes_to_audio.py <project_path> --provider cosyvoice --voice-id <voice> --cosyvoice-model cosyvoice-v3-flash [--cosyvoice-audio-only] +``` + +- **Roster preflight**: the notes roster comes from `svg_output/*.svg` on Generate projects or from `page_plan.json` / the identity roster on round-trip workspaces (copies inherit source notes). Every expected note must exist, be readable, and contain spoken text before any TTS request; exit code `2` returns the caller to notes generation. Narration text is read verbatim; only `# ...` heading lines are skipped. +- **Outputs**: one `audio/<stem>.<ext>` per note plus `audio/<stem>.srt` on provider-timed paths (edge, ElevenLabs, MiniMax, timestamp-capable CosyVoice); Qwen and explicit `--cosyvoice-audio-only` write audio only. The flat `audio/` directory is the single active set — no provider subdirectories unless the user asks to keep variants. Stale `audio/manifest.json` and `audio/total.srt` are removed before generation; a successful audio-only run also removes same-stem stale SRT; the manifest (provider/model, formats, voice settings, SHA-256 voice fingerprint — no per-slide inventory, hashes, or keys) is published atomically only after the complete roster succeeds. +- **Formats**: PowerPoint-reliable audio is `m4a` (AAC), `mp3`, or `wav`; edge defaults to `mp3`; provider `pcm` / `opus` / `flac` output must be transcoded before embedding. +- **Edge SRT**: MP3 and page SRT come from the same `edge-tts` stream using `WordBoundary` timing. Sentence-ending punctuation always closes a cue; text over the 20-visible-character default (`--subtitle-max-chars`) splits at commas, semicolons, or colons, then at the nearest word boundary. Adjacent overlap up to 100 ms moves the later cue start to the previous end; larger overlap fails. Each SRT uses a page-local timeline starting at `00:00:00,000` including leading silence. Default concurrency is three slide pairs (`--concurrency 1` for serial troubleshooting); cloud providers stay serial. +- **Provider timing**: MiniMax reads word timing from its synchronous subtitle file; ElevenLabs uses `/with-timestamps` with original-text character alignment; CosyVoice enables HTTP streaming plus `word_timestamp_enabled` and uses the final audio URL and word timing — unsupported model/voice pairs fail without replacing the prior pair unless `--cosyvoice-audio-only` was explicit (model and voice families must match; cloned voices need a supported v3.5/v3/v2 model or a timestamp-supported system voice); Qwen exposes no timing and never gets estimated SRT. Provider-timed paths share punctuation-first, `--subtitle-max-chars`-bounded regrouping, exact-text validation, and rollback-safe pair publication. + +## `narration_sync.py` + +```bash +python3 skills/ppt-master/scripts/narration_sync.py fingerprint <project_path> +python3 skills/ppt-master/scripts/narration_sync.py animations <project_path> --narration-start-floor 0.8 --narration-padding 0.5 --force +python3 skills/ppt-master/scripts/narration_sync.py subtitles <project_path> --pptx <final_narrated_pptx> --force +``` + +- `animations` deep-copies read-only `animations.json` to `narration_animations.json`, preserving transitions, effects, durations, order, and explicit `effect: none`, and changes only the derived trigger/delay values needed for click-free playback. `<project_path>/narration_timing.json` maps each animated content group (not each effect row) to the 1-based SRT `cue` that speaks about it; for `effects[]` the cue anchors the group's first active row and later rows keep global order and relative delay; an omitted `cue` keeps the group's canonical relative delay. The file is fingerprinted to the ordered SRT set (`srt_sha256`, from the `fingerprint` subcommand); reuse a complete current mapping when fingerprint and group semantics remain valid, rebuild only affected pages otherwise. Without a timing sidecar the command maps groups positionally (group N → cue N) and warns when later objects may reveal during an earlier topic — treat that warning as required repair. The command may read an affected SVG page to resolve structural group order for a sparse sidecar; it never edits SVG, notes, or `animations.json`. +- `subtitles` merges page-local SRT against timing read from the final PPTX and may write `audio/total.srt` as a PPTX-timeline diagnostic; it is not the delivery subtitle for a finished video. + +```json +{ + "version": 1, + "srt_sha256": "<sha256 of the ordered page-local SRT set>", + "narration_start_floor": 0.8, + "narration_padding": 0.5, + "slides": {"01_title": {"groups": [{"id": "page-title", "cue": 1}, {"id": "supporting-visual"}]}} +} +``` + +## Narrated `svg_to_pptx.py` export + +```bash +python3 skills/ppt-master/scripts/svg_to_pptx.py <project_path> --recorded-narration audio --narration-start-floor 0.8 --narration-padding 0.5 --inherit-motion-from "<base_postflight_report>" +# [--animation-config animations.json] canonical narration-independent motion +# [--no-animations] explicit all-motion-off +# [--quick-generate --with-notes] Quick projects +# [--conversion-trace <final_narrated_trace>] native-export mix branch +``` + +- `--recorded-narration audio` prepares PowerPoint's recorded timings and narrations: every slide needs a matching supported audio file with an `ffprobe`-readable duration, and object animations may not use `--animation-trigger on-click` (use `after-previous` / `with-previous`). Narration changes only the slide-advance layer — the page-transition effect is unchanged, `-t none` stays transition-free, and advance disables click while using page-start lead-in + audio duration + page-tail padding. Output is `exports/<project_name>_<timestamp>_narrated.pptx`. +- **Pacing**: `narration_start_floor` (default `0.8` s) and `narration_padding` (default `0.5` s) are independent. For a destination-page transition of `T` seconds the post-transition lead-in is `max(0, narration_start_floor - T)` — narration never starts during the transition and a longer transition is not stretched; the same lead-in applies to embedded narration, cue-bound object animation, subtitle offsets, and slide advance; uncued title or decorative animation keeps canonical relative timing; a floor of `0` starts narration as soon as the transition completes. +- `--inherit-motion-from` preserves source-bound deck motion from the base export report: inherited `-a none` preserves explicit objects-off, while a final Stage-2 `false` does not; only explicit all-motion-off uses `--no-animations`; invalid reports block. Text uses the default flow mode (authored line breaks in one editable no-wrap frame). +- Edit Native PPTX exports with `--roundtrip --recorded-narration audio --use-narration-timings`. + +## `powerpoint_video.py` + +```bash +python3 skills/ppt-master/scripts/powerpoint_video.py --check +python3 skills/ppt-master/scripts/powerpoint_video.py <final_narrated_pptx> -o <raw_powerpoint_video.mp4> +``` + +Opens the final narrated PPTX in local Windows PowerPoint, requests the native encoder with recorded timings and narrations, and polls `CreateVideoStatus` until success, failure, or timeout — synchronous to its caller. It preserves the native visual-animation and narration path but does not reliably write transition or object-animation sounds into the MP4 audio track. A native-export failure leaves the narrated PPTX as a successful upstream artifact; do not regenerate audio or the PPTX unless their own validation failed. + +## `video_sound_mix.py` + +```bash +python3 skills/ppt-master/scripts/video_sound_mix.py <project_path> --pptx <final_narrated_pptx> --trace <final_narrated_trace> --video <raw_powerpoint_video.mp4> -o <final_mixed_video.mp4> --stem-output <final_sfx_stem.wav> --report-output <sound_mix_report.json> --force +``` + +Cross-checks the final narrated trace against the PPTX read-back, extracts the exact embedded sound relationships, calibrates every page against the raw video's narration, renders a float SFX stem, and mixes it with narration at unity gain — transition cues about 35%, object cues about 25%, no `amix` normalization or ducking, a -1 dBFS peak limiter after the mix. The receipt must prove a non-silent stem, preserved video-stream hash, changed and present final audio, duration parity, non-clipping true peak, and correlation between the added audio component and the stem; a valid `animations.json` or OOXML package alone is not MP4 audio acceptance. Audio-only narration can still calibrate from its complete per-page tracks. A slideshow capture must never enter this tool. + +## `video_subtitles.py` + +```bash +python3 skills/ppt-master/scripts/video_subtitles.py <project_path> --video <final_delivery_video.mp4> --language <language> --force +``` + +Force-aligns the narration text frozen in the page SRT set against the finished video's audio track with `stable-ts` — the mixed MP4 when mixing ran, the accepted capture when slideshow recording ran, otherwise the raw PowerPoint MP4. Long cues may be split for display here. Writes a same-stem external SRT without changing the MP4, notes, page SRT, or animation files; subtitles are never burned in. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/docs/pptx-animations.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/docs/pptx-animations.md index ef6146b2..80325599 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/docs/pptx-animations.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/docs/pptx-animations.md @@ -280,3 +280,37 @@ See [`pptx-transitions.md`](./pptx-transitions.md) for the symmetric page-motion core, MCE handling, and slide-advance contract. See [`video-motion-plan.md`](./video-motion-plan.md) for the downstream animation-to-video contract. + +## 8. Sidecar Field Reference + +`animations.json` fields as validated by `animation_config.py validate` and consumed by export; the [`customize-animations`](../../workflows/stages/customize-animations.md) stage owns when and why each is written. + +| Field | Behavior | +|---|---| +| `defaults.transition` / `slides.<slide>.transition` | Deck-wide or slide-specific page transition object | +| `transition.effect` | One of the 48 canonical native effects, or `none` (removes only the visual effect; timed advance remains) | +| `transition.effect_options` | Only the selected effect's PowerPoint Effect Options (`pptx_animations.py --describe-transition <effect>`); requires an explicit `effect` | +| `transition.duration` | Finite seconds greater than zero | +| `transition.auto_advance` | Optional finite non-negative seconds before automatic advance; click stays enabled; valid with `effect: none` | +| `transition.sound` | Optional project-relative `.wav` cue; valid with `effect: none`; a slide override of `null` clears an inherited default sound | +| `morph.from` | Immediately preceding SVG stem for an explicit deterministic Morph transition | +| `morph.pairs.<key>.from` / `.to` | Unique source/destination direct-root group ids receiving the shared PowerPoint name `!!<key>`; Morph by object only | +| `defaults.animation` / `slides.<slide>.animation` | Deck-wide or slide-specific default object-animation behavior | +| `animation.effect` | Default object effect: one canonical key, `auto`, `mixed`, `random`, or `none` | +| `animation.duration` / `animation.stagger` / `animation.trigger` | Default schedule duration, delay between rows, and Start mode (`after-previous`, `with-previous`, `on-click`) | +| `groups.<id>.effects[]` | Non-empty ordered array for a multi-duty lifecycle; every row names `effect`; cannot coexist with legacy single-effect fields in the same group | +| `groups.<id>.effect` | Backward-compatible single-row form; old short names are read-only compatibility inputs | +| `effects[].trigger` / legacy `trigger` | Row-specific Start mode; omitted values inherit `animation.trigger` | +| `order` | Page-wide order for ordinary rows; ties keep SVG group order, then `effects[]` index; `trigger_shape` rows keep relative order in separate interactive sequences; SVG layer order never changes | +| `delay` | Row-specific seconds added to the resolved Start or shape trigger | +| `duration` | Per-row schedule duration; scalable native trees keep internal ratios, while `entrance_appear` and instantaneous presets keep their authored duration and use the value for `after-previous` spacing | +| `effect_options` | Effect-specific parameters (`direction`, `amount`, `color`, `font_name`, `relative`, `size`) limited to what the selected effect supports (`pptx_animations.py --describe <effect>`); requires an explicit canonical `effect` in the same block or row; `font_name` is one target-installed face | +| `trigger_shape` | Different top-level group id for native **On Click of**; row-only, not inherited; implies `on-click` and accepts an explicit row `trigger` only when it is also `on-click` | +| `repeat_count` / `repeat_duration` | Repeat count or total repeat span; mutually exclusive | +| `auto_reverse`, `rewind` | Reverse each cycle and/or restore the pre-animation state | +| `accelerate`, `decelerate`, `bounce_end` | `0..1` timing ratios; acceleration plus deceleration ≤ `1`; bounce needs an interpolated effect and cannot combine with deceleration | +| `restart` | `always`, `when-not-active`, or `never` | +| `after_effect` | `none`, `dim` with `color`, `hide`, or `hide-on-next-click` | +| `sound` | Object-animation cue: project-relative or absolute `.m4a` / `.mp3` / `.wav` on low-level inputs; bundled selections use the synced project-relative `.wav` path | + +An unlisted SVG inherits the resolved deck-wide settings; a listed slide may contain only the `transition`, `animation`, `groups`, or `morph` fields it overrides; chrome groups (`bg` / `*-header` / `*-footer` / `*-decor` / `nav` / `watermark` / `logo` / `pagenumber`) are pinned to `none` unless explicitly named without a structural marker; a group carrying `data-pptx-layer` or a static role/placeholder marker never animates. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/docs/project.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/docs/project.md index ac6ca02a..35047966 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/docs/project.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/docs/project.md @@ -57,10 +57,13 @@ Notes: - `validate` parses the existing Markdown artifacts against `templates/schemas/design_spec.schema.json` and `templates/schemas/spec_lock.schema.json`. It reports missing sections and - fields, illegal enums, malformed page keys, and unmet conditional sections. + fields, including per-slide `Audience move` and `Relationships` lines, + illegal enums, malformed page keys, and unmet conditional sections. When optional custom reference lists are present, it also requires every id to resolve to the matching mode, visual-style, or image-rendering catalog, rejects duplicates, and rejects reference rows on non-custom selections; + under `## forbidden` on versioned locks, every non-empty, non-baseline list + item must end with `(user)`; it does not rewrite either artifact or compare their values for textual equality. It also does not prove final-confirmation → Design Spec fidelity or Design Spec/context → lock semantic fidelity; Generate Step 4 owns those two diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/docs/svg-contract.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/docs/svg-contract.md new file mode 100644 index 00000000..5072796e --- /dev/null +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/docs/svg-contract.md @@ -0,0 +1,807 @@ +# SVG Compatibility Contract Reference + +The complete closed grammar that `svg_quality_checker.py` and the +`svg_to_pptx.py` exporter preflight enforce on generated SVG. The always-read +authoring rules — the canonical form the model writes — live in +[`shared-standards-core.md`](../../references/shared-standards-core.md) and +[`svg-effects.md`](../../references/svg-effects.md); this reference holds the +mapping tables, accepted-but-warned spellings, rejection boundaries, and +import-side behavior that those files no longer repeat. Enforcement is shared: +the checker imports the same validators as the exporter +(`svg_to_pptx/drawingml/utils.py`, `converter.py`, `text_properties.py`), so a +failing check reports the same boundary that export would reject. + +Section numbers below mirror the owning section of +`shared-standards-core.md` (`§1.x`, `§2.x`) so cross-references resolve in +either direction. + +--- + +## §1 Inline properties and text grammar + +**Registered inline `style` properties** (names only; values follow the +element contract): + +| Property family | Allowed inline `style` properties | +|---|---| +| Paint and line | `fill`, `stroke`, `stroke-width`, `stroke-dasharray`, `stroke-linecap`, `stroke-linejoin`, `fill-opacity`, `stroke-opacity`, `vector-effect` | +| Text | `font-family`, `font-size`, `font-weight`, `font-style`, `text-anchor`, `letter-spacing`, `text-decoration` | +| Alpha and definition paint | `opacity`, `stop-color`, `stop-opacity`, `flood-color`, `flood-opacity` | +| Literal geometry | The element-specific properties in §2.1 | +| Preview-only | `shape-rendering`; it does not change native geometry | + +Conditional properties with a required XML form stay out of inline style: +`filter="url(#id)"`, `clip-path="url(#id)"`, `marker-start` / `marker-end`, +and `baseline-shift="super|sub"` on `<tspan>` are direct attributes. +`!important`, unknown CSS properties, blend modes, isolation, and backdrop +filters fail quality check. + +**Text value grammar**: ordinary generated text uses a non-empty +`font-family`, a finite positive unitless-px `font-size`, `font-weight` of +`normal` / `bold` / an integer hundred from `100` through `900`, `font-style` +of `normal` / `italic`, and `text-anchor` of `start` / `middle` / `end`. +Inheritable text declarations belong only on `<svg>`, `<g>`, `<text>`, or +`<tspan>`; `text-anchor` is invalid on `<tspan>`. Unknown or unmapped +declarations fail checker preflight and native export. Tracking, +underline/strike, text outline/alpha, gradient text, and text filter effects +follow `svg-effects.md` §6.7. + +**Compact inherited authoring**: `--canonical-authoring` reports drift from +the compact form (common typography on `<svg>`, shared paint on the nearest +meaningful `<g>`, explicit child overrides) as an advisory warning; +`compact_svg_styles.py --inplace` applies the same normalization on request to +authored project pages, never to structured template rosters. + +DrawingML has no arbitrary per-pixel alpha-compositing path. A registered +single-image text picture/texture fill follows `svg-effects.md` §6.3; +arbitrary text-knockout composites, multi-layer image text, and arbitrary +alpha composites remain bake-required before SVG export. + +--- + +## §1.1 Line-end markers + +`marker-start` and `marker-end` are supported on `<line>` and `<path>` only +when the referenced marker fits this native-arrow contract: + +| Concern | Required form | +|---|---| +| Reference | Exact local `url(#id)` to a `<marker>` in `<defs>` | +| Orientation | `orient="auto"` or `orient="auto-start-reverse"`; the latter reverses `marker-start` while behaving like `auto` at `marker-end` | +| Shape | One direct shape representing a DrawingML `triangle`, `stealth`, `arrow`, `diamond`, or `oval` line end: a 3-vertex `<polygon>` / closed path (triangle), a simple concave 4-vertex `<polygon>` / closed path (stealth), an open 3-vertex path (arrow), a simple convex 4-vertex `<polygon>` / closed path (diamond), or one `<circle>` / `<ellipse>` (oval) | +| Path grammar | One explicit `M`/`L` command per vertex. Triangle, stealth, and diamond paths end in `Z`; arrow paths remain open after the third vertex. No `H`, `V`, curves, or implicit multi-point `L` inside a marker path | +| Color parity | Triangle, stealth, diamond, and oval use a fill matching the parent line stroke. The open arrow uses `fill="none"` and a stroke matching the parent line stroke. DrawingML line ends inherit the line color | + +The converter maps these five shapes to their corresponding DrawingML line-end +types. Prefer `<polygon>` for the closed triangle, stealth, and diamond forms; +the open arrow form requires `<path>`. Four-vertex shapes must be simple and +non-degenerate: convex geometry maps to diamond and concave geometry maps to +stealth. Other marker shapes have no native mapping and block export instead +of being silently dropped. Marker type is `Native-normalized`; size is +`Approximate` (`sm` / `med` / `lg`). + +PPTX import compatibility, tolerant recovery, strict-mode rejection, and +diagnostic behavior are indexed in +[`conversion.md`](conversion.md#import-compatibility-and-recovery-boundary). + +--- + +## §1.2 Image clipping + +`clip-path` maps natively only on SVG `<image>` (including an exact crop +wrapper's inner image). Legacy imported crops may retain an outer-wrapper clip +as compatible input. + +| Concern | Required form | +|---|---| +| SVG-namespace `<clipPath>` defined inside `<defs>` | Converter looks up one exact local id; missing, duplicate, foreign-namespace, or malformed references fail | +| Contains exactly one direct SVG-namespace supported shape child | Multiple shapes are not composited | +| Shape is one of: `<circle>`, `<ellipse>`, `<rect>` (optional rx/ry), `<path>`, `<polygon>` | These map to DrawingML geometry (preset or custom) | +| No `clip-rule` or `fill-rule`, whether direct or in inline `style` | DrawingML picture geometry has no equivalent winding-rule control | +| Used only on `<image>` or a compatible legacy imported crop wrapper | Shapes, groups, text, and generalized nested SVG targets are forbidden | + +| SVG clip shape | DrawingML output | +|---|---| +| `<circle>` / `<ellipse>` | Full-frame `<a:prstGeom prst="ellipse"/>`; the child must exactly cover the image frame. A `userSpaceOnUse` circle requires a square physical frame; a normalized `objectBoundingBox` circle may fill any frame | +| `<rect>` / `<rect rx="..."/>` | A plain full-frame rect is a compatible no-op; rounded form maps to full-frame `<a:prstGeom prst="roundRect"/>` with one physical radius adjustment. The rect must exactly cover the image frame and cannot express non-uniform physical corner radii | +| `<path>` / `<polygon>` | `<a:custGeom>` with coordinates mapped into the image frame | + +A contour that depends on even-odd or another explicit winding rule is outside +this mapping and must be rebuilt as one unambiguous visible contour or +pre-rendered. + +--- + +## §1.3 Static same-document `<use>` + +Static local reuse is compile-time authoring shorthand. `finalize_svg.py` and +native export replace each qualifying instance with cloned primitive content; +PPTX-to-SVG import emits the resulting primitives and does **not** reconstruct +the original `<use>` / `<symbol>` structure. + +| Concern | Required form | +|---|---| +| Reference syntax | SVG 2 form `href="#id"`. Legacy `xlink:href="#id"` remains read-compatible and Live Preview normalizes it to `href`; if both attributes exist, their values MUST match | +| Referenced target | One of `<symbol>`, `<g>`, `<use>`, `<rect>`, `<circle>`, `<ellipse>`, `<line>`, `<path>`, `<polygon>`, `<polyline>`, `<text>`, or `<image>`. Nested local `<use>` is recursively expanded | +| Instance position | Generated `<use x>` / `<use y>` use finite unitless values; an explicit `px` suffix is read-compatible. Omitted values default to `0` | +| Symbol viewport | A referenced `<symbol>` MUST have a finite four-number `viewBox` with positive width/height. Its `<use>` MUST have positive finite unitless `width` and `height`; an explicit `px` suffix is read-compatible | +| Aspect ratio | Default/aligned `meet` values and plain `preserveAspectRatio="none"` are supported. `slice`, `refX`, and `refY` are forbidden | +| Viewport boundary | Symbol artwork MUST stay inside its `viewBox`; expansion does not reproduce symbol overflow clipping | +| Internal references | Author exact `href="#id"` and `url(#id)` fragments. The expander also reads legacy `xlink:href="#id"` and rewrites all instance-local cloned IDs | +| Structural metadata | Neither the `<use>` instance nor its referenced subtree may carry `data-pptx-layer*`, chart/table replacement metadata (`data-pptx-replace-with`, `data-pptx-replacement-*`, `data-pptx-import-source`, or `data-pptx-fallback-*`), or `data-pptx-placeholder*`. Author those objects directly instead | +| Safety limits | A reachable reference chain may contain at most 64 instances, and one SVG may expand at most 10,000 local `<use>` instances | + +**Forbidden — unsafe local references**: external/file/data URLs, missing +targets, conflicting `href` / `xlink:href`, unsupported target elements, +circular reference chains; duplicate IDs on the referenced target, the `<use>` +instance, or anywhere in the reused subtree; quoted/whitespace CSS fragment +variants such as `url('#id')`. + +--- + +## §1.4 Imported native PowerPoint shapes + +`pptx_to_svg.py` emits rendering-neutral metadata when a visible SVG object +originates from `p:sp`, `p:cxnSp`, or `p:grpSp`. This contract is for lossless +import SVGs and unchanged imported objects that remain Slide-local or inside a +slot during mirror materialization. Ordinary authored SVG does not need these +attributes, and no separate source-payload opt-in marker exists. + +| Metadata | Placement | Required behavior | +|---|---|---| +| `data-pptx-object` | Logical `<g>` and native carrier | `shape`, `connector`, `group`, or `picture`; never infer the object kind from path appearance. | +| `data-pptx-shape-id` + `data-pptx-shape-scope` | Logical `<g>` and carrier | Preserve the source part-scoped identity. Export remaps duplicate Master/Layout/Slide ids into page-unique ids before rebinding connector references. | +| `data-pptx-frame="x y width height"` | Logical `<g>` and carrier | Own native `a:xfrm` position and size. Lossless import SVGs and tool-side native records use sufficient precision for exact EMU recovery; the model-facing authoring IR may use the compact page-coordinate spelling defined below. Path bounds, stroke, markers, shadows, and text glyph bounds never replace this frame. | +| `data-pptx-prst` | Preset carrier and logical `<g>` | One of the locked 187 DrawingML `ST_ShapeType` values. | +| `data-pptx-av-*` | Preset carrier and logical `<g>` | Preserve the complete validated DrawingML adjustment formula, including non-`val` formulas. | +| `data-pptx-part="geometry"` | One hidden carrier path | The single native export authority for frame, base fill/line/effect, preset/custom geometry, and object identity. | +| `data-pptx-part="geometry-preview"` / `geometry-detail` | Visible preview group/paths | Render the preset's independent path fill/stroke layers. A hash-locked preview group may mirror the carrier's one filter so a multi-path preset renders one aggregate imported effect; these elements are never emitted as duplicate PowerPoint shapes. | +| `data-pptx-preview-sha256` | Logical preset `<g>` and carrier | Detect edits to visible preset paths or paint. A stale preview fails quality check/export instead of silently reusing old native metadata. | +| `data-pptx-geometry-kind="custom"` + `data-pptx-custgeom` or `data-pptx-custgeom-ref` | Custom-geometry carrier | Preserve the validated original `a:custGeom` subtree. If the visible path hash is unchanged, export writes formulas, handles, connection sites, text rectangle, and path list exactly; edited paths compile from current SVG geometry. | +| `data-pptx-start/end-shape-id/site` | Connector logical `<g>` and carrier | Restore `a:stCxn` / `a:endCxn` after scoped shape-id allocation. A connector may retain one zero frame axis; it must not be expanded from visible stroke or marker bounds. | +| `data-pptx-shape-style` or `data-pptx-shape-style-ref` | Native carrier | Preserve a relationship-free `p:style` independently of text, including shapes with no visible text. | +| `data-pptx-effect-status="unsupported"` + `data-pptx-effect-reason` | Imported `p:sp` / `p:cxnSp` logical object and native carrier; imported `p:pic` carrier and logical object; imported `p:grpSp` logical group; imported table `p:graphicFrame` logical group | Record why an encountered source object or text-run `effectLst` / `effectDag` cannot enter the registered target-specific effect mapping without changing semantics. Checker and export stop with the recorded reason; these attributes are diagnostics, not a preserved effect payload or authoring syntax. | +| `metadata[data-pptx-part="txbody"]` with inline Base64 or `data-pptx-ref` | Logical shape `<g>` | Preserve unchanged `p:txBody`, including an empty text body. Content, whitespace, positioning, visible typography, or incompatible child-topology edits invalidate the payload. A source payload with run-level effects then blocks checker/export instead of losing those effects; an effect-free payload uses the normal SVG text fallback. | + +**Compact native metadata transport**: Type A mirror materialization moves +`p:txBody`, relationship-free `p:style`, and `a:custGeom` payloads into the +content-addressed `templates/native_payloads.json.gz` store. It also +deduplicates repeated native restoration fields — object identity, frame, +preset/custom-geometry guards, preview/text hashes, connector endpoints, +payload references, and adjustment formulas — into short +`data-pptx-native-ref` records in the same store. Checker, template-structure +validation, and export validate and hydrate both layers in memory. Keep +Master/Layout, placeholder, layer, editable-object, diagnostic, and editable +chart/table metadata inline; authoritative Chart/Table JSON stays inside its +SVG marker, never in the payload store. Legacy inline Base64 and v1 +payload-only stores remain readable. + +One effect reason remains its existing plain token. If one imported object has +multiple independent unsupported reasons, both marker copies store the same +deduplicated, lexicographically sorted compact JSON string array in +`data-pptx-effect-reason`; adding a later reason must not overwrite an earlier +one. This array is diagnostic metadata, not an authoring surface. + +**Import/authoring representation split**: + +| Representation | Contract | +|---|---| +| Lossless import SVG | Immutable native payload and preview evidence in the temporary analysis workspace; never editable template source. | +| Authoring IR bundle | Editable SVG plus model-readable `authoring_summary.json` and tool-only `authoring_manifest.json`. Keep visible intent and document-local `data-pptx-source-ref`, but omit opaque/duplicate carriers. Before hashing, compact safe imported frame/transform coordinates to two decimals. Summary indexes current files; manifest owns source paths/hashes and stays outside model context. | +| `standard` / `fidelity` output | Use §1.5 compact presets; never transplant opaque payload or source topology. | +| `mirror` output | Template_Designer reviews/authors the compact parsed IR; materialization validates refs/graph and publishes that tree without restoring visible lossless subtrees. Recover only supported non-visible semantics; expand fixed Master/Layout wrappers without changing ownership or intended presentation. | + +**Model-facing page-coordinate precision** (the canonical checker reports +over-precision as an advisory warning): + +| Surface | Precision contract | +|---|---| +| Imported `data-pptx-frame` in authoring IR | At most two decimals; the compact frame owns visible geometry. | +| `data-pptx-bounds` in generated and final template SVG | At most two decimals. | +| `translate(...)`, `rotate(... cx cy)`, and `matrix(... e f)` | Translation/center values use at most two decimals; keep angle and matrix `a b c d` unchanged. | +| Protected values | Never compact path/points geometry, crop/nested-`viewBox` ratios, gradient offsets, opacity, scale, canonical preset frames, or lossless/tool-side frames. | + +**Authoring source refs**: `data-pptx-source-ref` is create-template IR-only +and unique per document. Tools resolve it through that document's +`authoring_manifest.json`; models never read the manifest. Extract/re-inline +preserves the ref and vector inventory mapping. Final templates and +`svg_output/` contain no source refs. + +**Decoration extraction**: move text-free imported vectors to +`icons/imported/` and leave an inventoried `<use data-icon="imported/...">`. +The editor expands it; unchanged assets restore source objects and edited ones +become page-local vector units. + +**Imported source proxy fallback**: only unsupported, text-free, schema-free, +unmarked ornament may use an atomic +`<image data-pptx-source-proxy="native-restore">` preview under +`images/source-object-previews/`. Meaning-bearing content stays readable inline +or reports a conversion gap. Unchanged proxies restore; removing a Slide-local +proxy deletes it, while inherited proxies remain. Proxy edits fail export. +Extraction/proxies are import-time only, never free-authored `svg_output/`. + +**Structural-layer boundary**: An unchanged imported logical object may keep +currently supported metadata while it remains Slide-local or inside a slot. An +imported logical `<g>` cannot be assigned to Master/Layout because those layers +require direct semantic atoms. Mechanically expand a fixed-layer source group +into direct atoms, rebuilding a preset when supported and otherwise retaining +the visible SVG fallback. A newly authored compact preset `<g>` from §1.5 is +the sole group exception: validation proves that it compiles to exactly one +native shape/connector. Do not use this normalization to change ownership or +appearance. + +**Selective payload**: Keep the lossless import SVG as immutable evidence; do +not copy every metadata block into a template. Mirror publishes the compact +authored subtree and recovers only converter-supported non-visible metadata, +never ordinary visible source XML. Unsupported/edited objects use the SVG +fallback. `data-pptx-replace-with` remains reserved for optional native +Chart/Table replacement. + +**Registry and rendering rules**: + +- The hash-locked shared registry must equal the independent 187-value shape + catalog. Missing, duplicate, unknown, or corrupt definitions fail closed. +- Preset preview paths come from the shared DrawingML formula evaluator; do not + add per-shape Python geometry handlers. +- Preset size is controlled only by `data-pptx-frame` / `a:xfrm`. Adjustment + formulas control the contour inside that frame and are not rescaled when the + frame changes. +- A group transform may move, scale, rotate, or flip the complete logical + shape without invalidating its preview fingerprint. Editing a generated + `geometry-detail` path directly is unsupported unless the carrier metadata + and preview fingerprint are regenerated together. +- Unknown or malformed SVG transform operations fail closed. DrawingML cannot + represent arbitrary shear, so a non-orthogonal transform must stop native + export instead of being silently approximated as rotation and scale. +- Opaque XML payloads containing any `r:*` relationship attribute are never + copied into a new slide part. Relationship-bearing text content and + shape-level `a:blipFill` use the existing rebuilt visual fallback and are + not covered by atomic `p:sp + p:txBody` rehydration. +- Unknown future presets and explicit `unsupported` geometry status never + downgrade silently to `rect`; native export stops with the recorded reason. + +**Fidelity boundary**: native preset/custom geometry, logical frame, scoped +identity, connector topology, and relationship-free unchanged horizontal +text-body semantics on ordinary shape fills are `Native-stable`. The SVG +preview paint for gradient/pattern `darken`/`lighten` layers is +`Native-normalized`; original group child coordinates, shape-level image-fill +reconstruction, and vertical-text reconstruction are also normalized rather +than byte-identical OOXML. + +--- + +## §1.5 Authored native PowerPoint presets — machine contract + +Selection behavior lives in +[`native-shape-authoring.md`](../../references/native-shape-authoring.md); +this section owns the machine contract of the compact canonical fragment that +`preset_shape_svg.py` prints. + +| Metadata / structure | Required behavior | +|---|---| +| `data-pptx-authoring="preset"` | Appears once on the logical `<g>`; distinguishes strict project authoring from legacy/imported metadata. | +| `data-pptx-object` | `shape` or `connector`; connector-family presets must use `connector`, and `connector` must use a connector-family preset. Authored connectors require `fill="none"` plus a visible stroke and export as unconnected `p:cxnSp`. | +| `data-pptx-prst`, `data-pptx-frame`, `data-pptx-av-*` | Generated together from the locked registry and written once on the logical group. The frame is the helper's exact four-part, space-separated ordinary-decimal spelling and remains authoritative even when visible path bounds differ; commas, scientific notation, leading `+`, and redundant decimal spellings are rejected. | +| Local `fill` / `stroke` plus supported paint attributes | Base paint is written once on the group; a visible stroke also carries an explicit width. Canonical page/template authoring keeps channel paint local. Compatible ancestor paint/opacity may compose under the general SVG rules and receives a recommendation warning. | +| Optional direct `filter="url(#id)"` | Shape presets only: the helper writes one exact local reference to a direct `svg-effects.md` §6.4 filter definition. It compiles once on the complete native shape; connector presets, inline style, ordinary group filters, and child-path filters remain unsupported. | +| Ordered direct `<path>` children | Browser-visible registry layers only. Each child writes just its required path-level fill/stroke override; labels and decorations stay outside the atomic group. | +| No carrier / wrapper / fingerprint | `data-pptx-part`, hidden geometry carriers, preview wrappers, and `data-pptx-preview-sha256` belong to expanded import/compatibility transport, not canonical project authoring. | + +Template ownership metadata is orthogonal to preset geometry. After inserting +the complete helper output, `create-template` may add only the registered +`data-pptx-layer`, `data-pptx-editable`, `data-pptx-carrier`, or +`data-pptx-role` attribute needed by the surrounding structured contract. It +must not change preset/frame/adjustment/paint metadata, the filter reference, +or any direct path. + +**Reusable-template boundary**: a project-owned canonical template may retain +one complete helper-generated atomic fragment when the stock preset is an exact +semantic match and both its paint and optional effect stay inside the authoring +boundary. The fragment is an executable exemplar and one semantic atom, not a +freely editable template primitive. It may be Slide-local, the one carrier of +an `object` slot, or a direct Master/Layout fixed atom. An adaptation may reuse +it unchanged only when preset, frame, adjustments, paint, and the optional +filter reference are unchanged; otherwise regenerate the whole fragment with +the helper. Imported, mirror, and third-party templates are never upgraded by +contour inference. + +**Authoring paint/effect boundary**: v1 accepts `none` or six-digit solid HEX +fill and stroke, optional fill/stroke opacity, stroke width, line cap, line +join, and one shape-only local filter id under `svg-effects.md` §6.4. Use +ordinary SVG for gradients, patterns, or other treatments outside this narrow +contract. Registry-derived multi-path darken/lighten colors and other +contextual derivatives need no separate lock row unless they become a +recurring named role. Mirror preserves source paint under §1.4 instead. + +**Validation**: quality check and export both rerender authored fragments from +`preset + frame + adjustments + group paint` and compare every visible path and +path-level paint override directly. They separately validate the optional +effect reference through `svg-effects.md` §6.4. Registry-path edits, geometry +metadata that leaves those paths stale, unknown adjustments, invalid or +unresolved filter references, out-of-range frames/transforms, zero-scale +transforms, and shear/skew fail closed. Export expands the validated compact +group only in memory and reuses the lossless native-shape conversion path. +Older authored carrier/preview fragments remain compatible as ordinary +Slide-local input and receive a non-blocking migration warning; they do not +gain the new compact group's structured-atom exception. `pptx_to_svg` expanded +output remains the lossless round-trip form and is not warned as authored +input. + +**Fidelity boundary**: an unchanged authored fragment is `Native-stable` as +one `p:sp` or `p:cxnSp`. Text remains outside the atomic fragment and may +export as a grouped editable text box. Authoring v1 creates only unconnected +`p:cxnSp`; it does not accept hand-written endpoint/site metadata. An +`actionButton*` preset maps visual geometry only. Preset appearance never +invents connector attachment, action behavior, navigation targets, or +hyperlinks; link behavior is authored under +[`native-hyperlinks.md`](../../references/native-hyperlinks.md). + +--- + +## §2.1 Literal geometry lengths and inline geometry + +**Direct geometry length grammar**: generated SVG writes the following XML +geometry values and `stroke-width` as finite unitless ordinary decimals in the +page `viewBox` coordinate space. The explicit `px` suffix is read-compatible +and receives a recommendation warning. No other unit is registered for this +surface. + +| Element / surface | Direct length attributes | +|---|---| +| `<svg>`, `<rect>`, `<image>`, `<use>` | `x`, `y`, `width`, `height`; `<rect>` also `rx`, `ry` | +| `<circle>` | `cx`, `cy`, `r` | +| `<ellipse>` | `cx`, `cy`, `rx`, `ry` | +| `<line>` | `x1`, `y1`, `x2`, `y2` | +| `<text>` / positional `<tspan>` | `x`, `y`; `<tspan>` also `dx`, `dy` | +| Any supported painted element | `stroke-width` | + +`width`, `height`, `r`, `rx`, `ry`, and `stroke-width` must be non-negative; +the stricter positive `<use>` symbol-viewport rule remains in §1.3. `pt`, +`pc` / `pica`, `in`, `cm`, `mm`, `q`, `em`, `rem`, percentages, unknown units, +non-finite values, expressions, scientific notation, leading plus signs, and +trailing decimal points are invalid here even when generic SVG/CSS defines +them. A missing attribute may use its documented SVG/project default; an +explicitly supplied invalid value never falls back to that default. + +**Inline geometry in `style`**: the following properties may appear in the +same element's `style="..."`. The pipeline materializes them as XML geometry +attributes before SVG post-processing and native PPTX conversion; an inline +declaration overrides an existing same-name XML attribute. + +| Element | Recognized properties | +|---|---| +| `<rect>` | `x`, `y`, `width`, `height`, `rx`, `ry` | +| `<circle>` | `cx`, `cy`, `r` | +| `<ellipse>` | `cx`, `cy`, `rx`, `ry` | +| `<image>` | `x`, `y`, `width`, `height` | +| `<svg>` | `x`, `y`, `width`, `height` | +| `<use>` | `x`, `y`, `width`, `height` | + +Every non-zero inline geometry value is one finite `px` literal, such as +`120px` or `-8.5px`; exact zero may be unitless. `width`, `height`, `rx`, +`ry`, and `r` must be non-negative. Percentages, `auto`, `calc()`, `var()`, +`!important`, `inherit`, and every other unit are forbidden. Line endpoints, +text positions, path data, and polygon/polyline points remain XML attributes. + +`<style>`, `class`, selector rules, external stylesheets, and imported styles +remain forbidden. This contract is only for literal declarations in an +element's own `style` attribute; PPT Master does not compute CSS cascade or +custom properties. Root canvas authority remains the `viewBox`, regardless of +root `<svg>` compatibility width/height values. The shared coordinate and +geometry implementation is +[`utils.py`](../svg_to_pptx/drawingml/utils.py). + +--- + +## §2.2 Group opacity + +DrawingML has no isolated group-alpha model. The converter accepts +`<g opacity="...">` and inline group `opacity` by multiplying group alpha into +descendants. That path is `Approximate`; nested group/child alpha multiplies, +and `--native-charts-and-tables` rejects transparent native table/chart +markers. The quality checker reports a non-blocking fidelity warning so +existing or intentionally authored input can continue without modification. +New `svg_output/` puts alpha on the affected descendant paint, text run, +picture, or supported effect instead. + +--- + +## §4 Canvas and packaging boundaries + +**Canvas authority**: `viewBox="0 0 W H"` with positive integer pixels. +Numerically equivalent spellings and positive fractional imported dimensions +remain compatible; export quantizes once at `1 SVG px = 9,525 EMU`. +Invalid/non-finite values, non-zero origin, non-positive size, or unsupported +PowerPoint dimensions are errors. Optional root `width`/`height` do not +override `viewBox`. Root `<svg>` transform is forbidden; nested crop and +`<symbol viewBox>` keep their own contracts. + +**Native PowerPoint background promotion**: outside structured mode, the first +eligible visual layer may be a direct full-canvas `<rect>` or one inside a +simple single-child group. Its fill must have a registered native mapping +(solid, linear/radial gradient, or preset pattern), and it must have no +transform, filter, clip, rounding, or visible stroke. Export writes the fill as +Slide `p:bg`; image elements remain pictures. Structured routes use the +narrower explicit solid-background ownership contract in +[`pptx-structure-interface.md`](../../references/pptx-structure-interface.md). + +**Flat packaging**: `pptx_structure.mode: flat` keeps represented objects +Slide-local; export emits one clean Master plus Blank Layout, removes stock +content placeholders/Layout inventory, and retains the standard +date/footer/slide-number hooks. Without a Layout/Deck owner, Quick uses the +same ownership with converter-default theme scaffolding. Reusable Layouts are +mapped through `page_layouts` / `page_pptx_layouts` in Default and inferred +from the complete structured SVG roster in Quick; ownership is never inferred +from repeated Slide-local geometry. + +**Root-group bounds checks**: every visible direct root `<g>` except a compact +helper-authored preset atom declares root-coordinate +`data-pptx-bounds="x y width height"`. The checker fails ordinary root-group +overlap exceeding `1px` on both axes (structured slots, structural-role groups, +and off-canvas Morph staging groups are exempt; structured Slide-local groups +are not). It compares each subcanvas with the root `viewBox`, and estimable +descendant text — including both multiline `<tspan>` forms — with the +subcanvas using the shared per-run width estimate, inline-formula height +envelope, and DrawingML wrapping headroom; it separately compares estimable +visible text with the root `viewBox` before that headroom. Per side, overflow +through `1px` is ignored; module-boundary overflow warns through `5%` and +fails above `5%`, while any larger root-`viewBox` text overflow fails. Bounds +do not clip or reflow; unestimable visible text receives an advisory warning. +Only a wholly off-canvas direct-root Morph endpoint may set +`data-pptx-morph-staging="true"`; its own module bounds still apply, retained +Morph uses an explicit pair, and the marker never excuses partial page +overflow. Primitive fallback (a root with no top-level `<g>` at all) is capped +at 8 visible primitives. + +--- + +# Part II — Effects and Geometry Grammar (`svg-effects.md` §6) + +Section numbers mirror [`svg-effects.md`](../../references/svg-effects.md). +The shared converter implementation for §§6.2–6.8 is +[`utils.py`](../svg_to_pptx/drawingml/utils.py); paths use +[`paths.py`](../svg_to_pptx/drawingml/paths.py). + +## §6.2 Color, alpha, and opacity + +Compatible paint grammar includes recognized named colors, `rgb()` / `rgba()`, +`hsl()` / `hsla()`, and `#RGB` / `#RGBA` / `#RRGGBB` / `#RRGGBBAA`; the +converter also tolerates legacy bare 3/4/6/8-digit hexadecimal tokens. The +generated canonical form is uppercase six-digit `#RRGGBB`; the checker prints +an optional canonical rewrite as a recommendation warning that never blocks +export. Explicit empty, malformed, or unrecognized paint values are errors in +both checker and exporter preflight; neither converts unknown intent into +`noFill` or default black. + +| Intent | Canonical authoring | Native result / fidelity | +|---|---|---| +| Solid fill or text paint | `fill="#RRGGBB"` | Solid DrawingML paint; `Native-stable` | +| Fill/text alpha | Opaque `fill` + `fill-opacity="0..1"` | Fill/run alpha; `Native-stable` | +| Stroke alpha | Opaque `stroke` + `stroke-opacity="0..1"` | Line/outline alpha; `Native-stable` | +| Gradient-stop alpha | Opaque `stop-color` + `stop-opacity="0..1"` | Per-stop alpha; `Native-stable` | +| Shadow/glow alpha | Opaque `flood-color` + `flood-opacity="0..1"` | Glow `Native-stable`; outer shadow visually calibrated `Approximate` | +| Picture fade | `<image opacity="0..1">` | Picture `<a:alphaModFix>`; `Native-stable` | +| One atomic whole-object fade | Non-group element `opacity="0..1"` | Alpha compiled into its supported paint/effect channels; `Native-normalized` | +| Pattern alpha | Opaque pattern child paint + child fill/stroke opacity | Conditional; `native-data-interface.md` | +| CSS color alpha | Alpha-bearing named/functional/HEX paint | `Native-normalized`; recommendation warning only | +| Group fade | `<g opacity>` compatibility | `Approximate`; fidelity warning; §2.2 | + +```text +effective fill alpha += color alpha × ancestor group opacity × element opacity × fill-opacity +``` + +`opacity`, `fill-opacity`, `stroke-opacity`, `stop-opacity`, and +`flood-opacity` are finite unitless numbers from `0` to `1`; the converter also +accepts finite numeric values that SVG/CSS clamps into that interval, and +`stop-opacity` / `flood-opacity` additionally accept finite percentages (the +checker reports those spellings as recommendation warnings). Malformed or +non-finite values are errors. `fill="transparent"` / `stroke="transparent"` +become no fill/line. PPTX import is a user-input boundary: tolerant mode +retains recognized color semantics, omits only unsupported paint properties, +and records the decision in `conversion-report.json`; `--strict` keeps the +closed parser checks. + +## §6.3 Gradients and text picture fill + +| Concern | Contract | +|---|---| +| Definition | Direct `<linearGradient>` / `<radialGradient>` child of `<defs>` with unique `id` | +| Reference | Exact local `url(#id)` | +| Stops | ≥2 direct `<stop>` children; explicit color; finite non-decreasing offset in `0..1` or `0%..100%` (ties form hard edges); optional alpha | +| Coordinates | `objectBoundingBox` only. Generated values `0..1`; omitted linear axis = `(0,0) → (1,0)`. Only import-normalized linear projections may reach `-0.105..1.105`; radial values stay in `0..1`, and the effective focus must lie inside the circle centered at `(0.5,0.5)` with radius `0.5` | +| Forbidden | External/quoted refs, `href` inheritance, `gradientTransform`, `spreadMethod`, CSS gradients | + +| Target | Contract and fidelity | +|---|---| +| `<rect>`, `<circle>`, `<ellipse>`, `<path>`, `<polygon>` fill/stroke | Linear `Native-normalized`; radial `Approximate` | +| `<line>` / `<polyline>` | Gradient stroke only; linear `Native-normalized`, radial `Approximate` | +| `<text>` / non-positional `<tspan>` | Gradient fill only; no gradient text outline | +| `<image>` | No gradient paint; use §6.5 overlays | + +Linear export preserves stops/alpha and reduces direction to an angle; +coincident endpoints are invalid. Radial export preserves the effective focus +(`fx/fy`, otherwise `cx/cy`) as a point-focused circle; its outer center and +radius normalize to `0.5`, so distinct outer `cx/cy` and `r` are dropped. A +focus outside that canonical circle is invalid because SVG renderers clamp it +to the circumference while DrawingML retains the rectangle coordinates; reverse +import centers such a focus and records a diagnostic. Gradient strokes stay +editable; reverse import may keep the first stop only. Stop alpha multiplies +element opacity. An `objectBoundingBox` gradient stroke requires non-zero +intrinsic width and height (a perfectly horizontal or vertical gradient ribbon +disappears); checker and exporter reject the degenerate form. + +**Native text picture/texture fill**: + +| Concern | Contract | +|---|---| +| Target | Direct `fill="url(#id)"` on `<text>` or a non-positional `<tspan>`; the text remains editable | +| Definition | Direct `<pattern>` child of `<defs>` with unique `id` and exact `data-pptx-text-image-fill="stretch"` or `"tile"` | +| Image | Exactly one direct SVG-namespace `<image>` child; project-local or data-URI source; explicit positive `width` / `height` | +| Native result | `stretch` → run-level `a:blipFill/a:stretch`; `tile` → run-level `a:blipFill/a:tile` | +| Alpha | Text `fill-opacity` multiplies the native picture-fill alpha | +| Forbidden | Preset-pattern attributes; `patternTransform`; additional pattern children; image style/alpha/clip/filter/mask/transform; use outside text; unannotated custom image patterns; multi-image/layer knockout composites | + +`stretch` is `Native-normalized`; `tile` may normalize tile scale or phase and +needs visual review. Forward SVG→PPTX export is native; PPTX→SVG does not +reconstruct run-level picture fills yet. Preset patterns are a separate +interface in `native-data-interface.md`. + +## §6.4 Shadows and glow + +Filters are native-effect metadata, not a general pixel-filter surface. + +| Concern | Contract | +|---|---| +| Definition/reference | Direct `<defs><filter id="...">` child with unique id; direct `filter="url(#id)"` attribute, never inline style | +| Public targets | `<rect>`, `<circle>`, `<image>`, `<path>`, `<text>`; one validated compact authored shape-preset `<g>`; an exact outer `<g filter>` whose sole visual child is one clipped `<image>` | +| Required primitive | `feDropShadow` or `feGaussianBlur` | +| Generated glow form | Zero-offset `feDropShadow` with flood paint, or the complete blur + flood + composite + merge graph; never bare blur | +| Required parameters | Explicit `stdDeviation` on either effect primitive; explicit `dx`, `dy`, and `flood-opacity` on `feDropShadow`; explicit `flood-opacity` on `feFlood`; explicit `slope` on linear `feFuncA` | +| Accepted helpers | `feOffset`, `feFlood`, `feComposite`, `feMerge`, `feMergeNode`, `feComponentTransfer`, linear `feFuncA` | +| Alpha transfer | Linear `feFuncA` maps multiplicative `slope` only; `intercept` is unsupported | +| Blur sampling | `feGaussianBlur edgeMode` is unsupported | +| Primitive coordinates | Omit `primitiveUnits` or use `userSpaceOnUse`; `objectBoundingBox` coordinates are unsupported | +| Numeric values | Finite unitless values; non-negative `stdDeviation`; finite `dx` / `dy`; `feFuncA slope` within `0..1`; mapped glow `rad = stdDeviation × 9525`, shadow `blurRad = stdDeviation × 2 × 9525`, and shadow `dist = hypot(dx,dy) × 9525` must round into DrawingML `0..27273042316900` | +| Classification | Meaningful non-zero offset → one outer shadow; zero/no offset → one glow | +| Fidelity | `Approximate`; one filter becomes one DrawingML effect | + +Flood opacity, linear `feFuncA slope`, and element opacity multiply; the +converter-only historical path may also multiply flood-color alpha and +ancestor group opacity. Native export does not preserve filter-region, +`in/in2/result`, merge order, or composite topology. Other primitives, +multiple independent effects, and filters on `<tspan>` / ordinary `<g>` / +unsupported targets are forbidden. Special `<g filter>` targets are limited to +the helper-authored compact shape preset, the exact single clipped-image form, +the hash-locked `data-pptx-part="geometry-preview"` transport of an imported +preset, and the exact imported picture-crop carrier. Bare `feGaussianBlur` +remains compatible input but is never generated: preview blurs the object +while export emits glow. PPTX import maps one classifiable +shape/connector/picture outer shadow or glow to this contract; unsupported +effects and outer-shadow variants whose scale, skew, alignment, or rotation +semantics cannot be retained become import diagnostics. Checker and exporter +preflight enforce the same definition, reference, primitive, target, and +numeric-value contract; missing required geometry is never replaced by effect +defaults. + +## §6.5 Image carriers and crop transport + +| Need | Authoring contract | Fidelity | +|---|---|---| +| Cover/crop | Readable raster dimensions + aligned `slice` | Native `srcRect`; `Native-stable`; otherwise native crop cannot be guaranteed | +| Contain/fit | Aligned `meet` | Fitted picture frame; `Native-normalized` | +| Stretch | `preserveAspectRatio="none"` | Native stretched frame | +| Uniform fade | `<image opacity="...">` | Native picture alpha | +| Shaped picture | §1.2 image-only `clip-path` | Preset/custom picture geometry | + +**Closed aspect-ratio grammar**: on `<image>`, omit `preserveAspectRatio` for +the default `xMidYMid meet`, use `none` alone for stretch, or use one of the +nine case-sensitive alignments (`xMinYMin`, `xMidYMin`, `xMaxYMin`, +`xMinYMid`, `xMidYMid`, `xMaxYMid`, `xMinYMax`, `xMidYMax`, `xMaxYMax`) +followed by explicit `meet` or `slice`. An alignment without a mode and values +needing whitespace normalization are compatible input with a recommendation. +Empty values, `defer`, unknown/wrong-case alignments or modes, `none` with a +mode, and extra tokens are errors. + +**Fit/clip interaction**: a non-trivial clip disables `meet` frame-fit; match +the image box to the source ratio or use `slice`. Put one §6.4 filter directly +on an unclipped `<image>`; for a clipped picture keep `clip-path` on the +`<image>` and put the filter on an exact outer `<g>` whose sole visual child is +that image. Never combine `filter` and `clip-path` on the same `<image>`. The +carrier may keep object-local id, role, transform, and `data-pptx-carrier`; it +may own `data-pptx-layer="master|layout"` only when the carrier itself is the +direct fixed atom, and never `data-pptx-placeholder`, `data-pptx-binding`, or +chart/table replacement metadata. + +**Decodable sources**: every `<image>` has explicit positive `width`/`height` +and exactly one non-empty `href` or compatible `xlink:href`. A data URI must use +a supported `image/*` MIME type, valid strict base64 when marked `base64`, a +non-empty payload, and bytes that decode as the declared format. An external +asset must resolve, use a supported extension, be non-empty, and decode as +that extension. Registered formats: PNG, JPEG, GIF, WebP, BMP, TIFF, SVG, EMF, +WMF. Explicit template substitution tokens may remain unresolved only during +template checking. Missing, ambiguous, corrupt, mislabeled, or unsupported +sources are errors and are never packaged as zero-byte media. + +**Nested SVG is picture-crop transport, not a general viewport**: every +non-root `<svg>` is the exact wrapper accepted by the shared crop parser: + +| Part | Required form | +|---|---| +| Outer | Registered `x`, `y`, positive `width`/`height`; four ordinary-decimal unit coordinates in `viewBox`; `preserveAspectRatio="none"`; `overflow="hidden"` | +| Child | Exactly one direct empty `<image>` with one non-empty `href`/`xlink:href`, `x="0" y="0" width="1" height="1" preserveAspectRatio="none"` | +| Context | Only root SVG / ordinary visual `<g>` ancestors; outer may add `id`, supported `transform`, registered layer/carrier metadata, and `data-pptx-frame`, `data-pptx-object`, `data-pptx-shape-id`, `data-pptx-shape-name`, `data-pptx-shape-scope`; an exact imported picture carrier may hold its one §6.4 filter outside this viewport | +| Shape crop | Exact outer `data-pptx-crop="1"`; authored wrappers put the registered, locally resolving image-only clip on the inner image, using `userSpaceOnUse` geometry matching the visible `viewBox`; legacy imported outer clips remain compatible | + +The inner image may add only registered `opacity` and that clip. Quantize the +`viewBox` without clamping: every signed crop fits +`-2147483648..2147483647`, with `l + r < 100000` and `t + b < 100000`. Retain +negative/outside-source crops exactly; write redundant `0 0 1 1` as a plain +`<image>`. Extra, indirect, or character content; unknown attributes; +malformed or unrepresentable crops; and general nested viewports fail. + +## §6.6 Lines, dashes, caps, joins, markers + +| Surface | Contract / native result | +|---|---| +| Solid stroke/width/alpha | `Native-stable` editable line | +| `4,4`; `6,3`; `2,2`; `8,4`; `8,4,2,4` (comma or space separators) | `dash`; `dash`; `sysDot`; `lgDash`; `lgDashDot` (`Native-normalized`) | +| Canonical custom dash | Exactly two positive finite unitless ordinary decimals (`dash gap`); export scales/quantizes against stroke width; `Native-normalized` | +| Compatible custom dash | Three or more positive finite unitless values reduce to the first pair with a checker recommendation; compatible numeric spellings also warn | +| `stroke-linecap` | `butt`, `round`, `square`; `Native-stable` | +| `stroke-linejoin` | `miter`, `round`, `bevel`; `Native-stable` | +| `vector-effect` | Exactly `none` or `non-scaling-stroke`; export resolves the choice into native line width (`Native-normalized`) | +| `stroke-dashoffset` | No general line mapping; allowed only as a direct finite unitless ordinary-decimal attribute on a §6.10 thick-circle shorthand (`px` suffix warns) | +| Gradient stroke | §6.3; re-import may flatten to first stop | +| `marker-start` / `marker-end` | §1.1 native line end; type `Native-normalized`, size `Approximate` (`sm/med/lg`) | + +The dash grammar is closed: exact lowercase `none`, or at least two finite +unitless numbers separated by whitespace or one comma. A leading plus sign, +exponent, trailing decimal point, surrounding whitespace, or longer custom list +is compatible input with a non-blocking normalization recommendation. Unknown +units, one-value arrays, empty or repeated comma fields, non-finite values, +and negative or zero entries are errors (the only zero exception is a gap on +the §6.10 thick-circle element). Cap, join, and `vector-effect` accept only the +exact lowercase tokens above; surrounding whitespace warns, every other token +is an error. PPTX import treats unsupported line properties as source +diagnostics: tolerant mode retains the object and omits only the unsupported +outline; `--strict` retains the closed rejection behavior. + +## §6.7 Text property grammar + +| Property | Canonical authoring | Compatible input | DrawingML mapping / rejection boundary | +|---|---|---|---| +| `font-weight` | `normal`, `bold`, or an exact integer hundred from `100` through `900` | `medium` → `500`; `semibold` → `600` | `normal` and `100..500` map to regular; `bold` and `600..900` map to `b="1"`; numeric weights are `Native-normalized` | +| `font-style` | `normal` or `italic` | None | `italic` maps to `i="1"`; oblique, angle, relative, and CSS-wide values are invalid | +| `text-anchor` | `start`, `middle`, or `end` on `<svg>`, `<g>`, or `<text>` | None | Maps to left/center/right paragraph alignment plus normalized frame position; invalid on `<tspan>` | +| `text-decoration` | `none`, `underline`, `line-through`, or `underline line-through` | `line-through underline` → canonical order | Maps to the single underline and strike run properties; unknown, repeated, or substring-like tokens are invalid | +| `baseline-shift` | Exact direct `super` or `sub` on `<tspan>` | None | Maps to editable `a:rPr@baseline` at `30000` or `-25000`; does not resize the run; invalid as inline style or on any other element; cannot combine with an inline formula marker | +| `letter-spacing` | Finite unitless ordinary decimal SVG px | The same decimal with `px`, `pt`, or `em`; normalized to unitless px | Maps to `a:rPr@spc`; the final value must fit DrawingML `-400000..400000`, and negative tracking must leave every generated run with a positive estimated advance and its text frame with a positive extent; keywords, percentages, exponents, leading plus signs, trailing decimal points, non-finite values, and other units are invalid | +| `font-size` | Finite unitless SVG px | `px`, `pt`, `pc`/`pica`, `in`, `cm`, `mm`, `q`, `em`, `rem` (recommendation warning) | Converted to SVG px, then editable DrawingML point size; unsupported units/percentages error | + +Registered inheritable text properties follow SVG inheritance, including +declarations on the root `<svg>`: inline `style` overrides the same element's +direct attribute, which overrides its ancestor. `baseline-shift` is the narrow +exception: declare it directly on the owning `<tspan>`. Every declaration is +validated even when a later declaration overrides it. + +**Negative tracking**: after run assembly, each output run must retain a +positive estimated advance using the quantized `sz` and `spc` values that will +be written; a wider sibling run or paragraph line cannot hide a run whose +aggregate advance would reverse or collapse. The generated text frame must +retain a positive horizontal and vertical extent. The checker rejects directly +measurable single-line violations, and the converter revalidates every run and +frame before writing OOXML without clamping or hiding a non-positive value. +Adjacent authored runs with identical final run properties form one output run +before sizing; splitting text across equivalent `<tspan>` nodes is not a +tracking escape hatch. Width estimates count the registered project text +clusters (combining marks, variation selectors, emoji modifiers and ZWJ +sequences, paired regional indicators, same-script virama conjuncts receive no +internal spacing). An unchanged imported native text body reuses the geometry +carrier's frame and attaches the preserved `txBody` payload. + +**Element-specific text surface**: + +- Inheritable text declarations belong only on `<svg>`, `<g>`, `<text>`, or `<tspan>`; placing them on geometry, image, definition, or reuse elements is an error. +- `<text>` accepts `x`, `y`, registered paint/alpha/run properties, the text properties above, `font-family`, `font-size`, direct `filter`, direct `transform`, `xml:space`, `id`, and project `data-*` metadata. +- `<tspan>` accepts `x`, `y`, `dx`, `dy`, registered paint/alpha/run properties, `font-family`, `font-size`, `font-weight`, `font-style`, `letter-spacing`, `text-decoration`, direct `baseline-shift`, `xml:space`, `id`, and project `data-*` metadata. It does not accept `text-anchor`, `filter`, or `transform`. +- `word-spacing`, `dominant-baseline`, `alignment-baseline`, font shorthand/variant/stretch/feature/variation/synthesis controls, `font-kerning`/`kerning`, `font-size-adjust`, `line-height`, text alignment, indent/shadow/rendering controls, white-space/word-break/hyphenation controls, `writing-mode`, `vertical-align`, `direction`, `unicode-bidi`, `text-transform`, and any other unregistered `font-*` / `text-*` property are errors as direct attributes or inline style. + +**Project text whitespace**: `xml:space` is valid only as an exact direct +attribute on `<text>` or `<tspan>`, accepts only `default` and `preserve`, +inherits through the text tree, and may be reset on a child `<tspan>`. The +project maps it to the visible Chromium/SVG2 behavior used by Live Preview: +XML line endings and tabs become U+0020; in `default` mode contiguous spaces +collapse across inline run boundaries and leading/trailing default-mode spaces +in the resulting chunk are removed; in `preserve` mode every U+0020 remains +significant. Only XML whitespace is normalized — NBSP, ideographic space, and +other Unicode spacing characters remain literal. Source line breaks do not +create PowerPoint paragraphs. + +Bullet detection allows optional leading whitespace, requires non-empty +content, and leaves non-leading decorative glyphs as ordinary text; `·`/`•` +become `•`, the other registered leaders (`● ▪ ■ ◆ ◇ ◦ ‣`) stay unchanged, and +the marker run supplies color/alpha. Imported double underline/strike +normalizes to single. Text outline is solid only; shadow/glow applies to +`<text>` only and is `Approximate`. + +## §6.8 Closed transform grammar + +| Surface | Contract / fidelity | +|---|---| +| `rotate(angle[, cx, cy])` | Geometry/image/text/ordinary group; `Native-normalized` | +| `translate(x y)` | Geometry/image/group; pure translation also safe on text; `Native-normalized` | +| Positive scale / negative mirror | Geometry/image or a group/use whose expanded visual subtree is geometry/image only; explicit pivot; `Native-normalized` | +| `matrix(a b c d e f)` | Geometry/image or the same geometry/image-only group/use; transformed axes finite, non-zero, orthogonal; excludes rounded rectangles and subtrees containing them; `Native-normalized` | +| Source order | Back-to-front PPT z-order; `Native-stable` | +| `<g opacity>` | Compatible approximate mapping; §2.2 | +| Local `<use>` | §1.3 compile-time reuse; `Native-normalized` | + +Use only lowercase `translate`, `scale`, `rotate`, and `matrix` with exact +finite unitless argument counts: `translate` 1/2, `scale` 1/2, `rotate` 1/3, +`matrix` 6. Separate arguments and operations with whitespace or one comma. +Leading/trailing/repeated commas, adjacent operations without a separator, +units, unknown functions, and incomplete input fail quality check and export. +A supported leading `+`, exponent, or trailing decimal point is compatible +input with a normalization warning. Model-facing translation values, rotation +centers, and matrix `e/f` use at most two decimals (§1.4); angles, scale +arguments, and matrix `a/b/c/d` retain the precision the transform requires. + +A text transform is either a translate-only list or one rotate operation; a +group containing text follows the same limit. `skewX`, `skewY`, zero or +non-orthogonal axes, and shear matrices are forbidden. Native chart/table +markers allow translate/scale only. The §6.10 thick-circle shortcut does not +inherit general transform support. Positive rotation is clockwise and pivoted +rotation normalizes the native frame. Every cumulative matrix, including +transforms split across ancestors, must remain finite, non-zero, and +orthogonal; importer/live-editor matrices do not expand the hand-authored +contract. During mirror materialization, imported PowerPoint groups with an +axis flip keep their geometry reflection while each descendant SVG text node +receives the matching counter-reflection; the tool-side native record retains +the source group flip. + +## §6.9 Freeform grammar and rounded rectangles + +| Input | Native normalization | Fidelity | +|---|---|---| +| `M/L/H/V`, absolute or relative | Absolute `M/L` | `Native-normalized` | +| `C` | Cubic Bézier | `Native-normalized` | +| `S/Q/T` | Explicit cubic controls | `Native-normalized` | +| `A` | Cubic segments of at most 90° | `Approximate` | +| `Z`; polygon/polyline | Closed/open freeform | `Native-normalized` | + +Generated `path@d` and `polygon` / `polyline@points` use finite unitless +ordinary decimals and only the commands above; each command accepts its +uppercase absolute and lowercase relative form. Native export consumes the +complete attribute and never extracts recognizable fragments while ignoring +other characters. Finite scientific notation, a leading plus sign, and a +trailing decimal point are read-compatible with recommendation warnings. +Unknown commands or characters, misplaced/repeated commas, non-finite numbers, +missing attributes, incomplete command groups, and odd point counts are +invalid. A path starts with `M` / `m`; `A` radii are non-negative and both arc +flags are exactly `0` or `1` (separator-free flag sequences parse as +individual tokens). A polygon has at least three coordinate pairs and a +polyline at least two. Command identity, relative coordinates, shorthand, arc +parameters, and original handles are not retained; geometry needs non-zero +bounds. Do not depend on `fill-rule="evenodd"`. + +| Rounded rect input | Result | +|---|---| +| One positive radius, or `0 < rx == ry <= min(width,height)/2` | `Native-stable` adjustable `roundRect` without distorting transforms; the same short-side limit applies to one-radius input | +| `0 < abs(rx-ry) < 0.5px` after scaling | One normalized native radius; `Approximate` | +| `abs(rx-ry) >= 0.5px`, either positive | Cubic custom geometry; no radius handle; `Approximate` | +| Equal radius above half the short side | Native short-side clamp may differ from SVG; `Approximate` | + +## §6.10 Thick-circle shorthand + +`Approximate`, non-position-sensitive use only: + +- One circle per segment; `fill="none"`; the circle may use one `rotate` for its start angle, and ancestor transforms must be translate-only. +- Exactly two non-preset finite unitless ordinary-decimal values (`dash gap`); `stroke-dashoffset` is a direct finite unitless ordinary-decimal attribute. +- `0 < stroke-width < 2r`, `stroke-width/r >= 0.15`, `0 < dash < 2πr`, `gap >= 0`, and `dash + gap >= 2πr - 1` SVG unit (the one-unit tolerance exists only for integer-rounded circumference values). +- Native construction uses only the first dash and re-imports as a freeform. Its native start is 90° counterclockwise from the SVG preview; use explicit arcs whenever start angle, cap, or radial precision matters. + +Explicit arc sectors are editable `Approximate` freeforms; calculated endpoints +survive subject to EMU rounding, and `A` curves remain cubic approximations. +Thin circles using a §6.6 preset/two-number dash stay `Native-normalized` +ellipse lines. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/docs/svg-pipeline.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/docs/svg-pipeline.md index 76499c78..3c550a25 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/docs/svg-pipeline.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/docs/svg-pipeline.md @@ -885,7 +885,7 @@ Behavior: - Native export writes to a temporary file first and publishes the requested PPTX only after conversion succeeds. A failed conversion does not replace the main output file. - `--conversion-trace` without a path writes `validation/<output_stem>.trace.json`. `--conversion-trace <path>` respects the explicit destination; relative paths are resolved from the project root, so `exports/<name>.trace.json` remains available when intentionally requested. - Formal default and `--quick-generate` release export compute the exact SVG source fingerprint and refuse a missing, unreadable, unsupported, non-final, blocking, stale, or unverifiable final quality report before PPTX creation. A project without `validation/svg_quality_report.json` exits nonzero with the `not-provided` gate status; run the final checker against its current `svg_output/` first. An explicit non-`output` `--source` remains outside this release gate. Dangerous compatibility export also stays outside it even when reading the default `svg_output/`: it automatically writes a conversion trace, marks postflight `passed-with-warnings`, and records its normalization count; it never claims that the source passed the normal authoring quality gate. -- The final quality report carries an informational `carrier_receipt` aggregate plus each page's `files[].info.carrier_receipt`: actual text/image/icon counts, SVG geometry, native preset names, marker use, native Chart/Table/Formula markers, and largest image-frame share. The terminal prints only the compact aggregate. These facts never affect exit status, create coverage quotas, or score design; the active Generate profile compares them with its retained page decisions before export. +- The final quality report carries an informational `carrier_receipt` aggregate plus each page's `files[].info.carrier_receipt`: actual text/image/icon counts, SVG geometry, native preset names, marker use, native Chart/Table/Formula markers, largest image-frame share, and effect use. `effects.inline_emphasis_runs` counts `<tspan>` elements inside `<text>` with no `x`/`y`/`dx`/`dy` that set `fill`, `font-weight`, `font-size`, `font-style`, `text-decoration`, or `letter-spacing`; `effects.gradient_uses` counts visible fill/stroke references that resolve to same-document linear/radial gradients; `effects.filter_uses` counts visible filter references that resolve to same-document filters; and `effects.text_effects` counts visible `<text>`/`<tspan>` elements with gradient/pattern paint, a filter, or a non-`none` stroke. Content inside `defs`, `clipPath`, `mask`, `pattern`, `marker`, or `symbol` is excluded. The terminal prints only the compact aggregate. These facts never affect exit status, create coverage quotas, or score design; the active Generate profile compares them with its retained page decisions before export. - After publication, native export writes `validation/<output_stem>.report.json`. The report distinguishes authored Slides from internal Layout definitions, reruns ZIP integrity and published Slide-count checks, records slide/layout/master/notes part counts, labels relationship/structured/transition/animation validation as enforced at build time, links the final SVG quality report only when its SHA-256 source fingerprint matches the exact export inputs, and surfaces stale/unverified gates, unresolved template tokens, generic-only font stacks, and external image references. A matching final quality report with introduced warnings yields `passed-with-warnings` and a `quality_introduced_warnings=<N>` receipt instead of a clean `passed` claim. - By default, a successful command also prints a compact receipt instead of requiring a report read: `[POSTFLIGHT] status=<...> quality_gate=<...> slides=<N> warning_categories=<N>`, followed by one compact line per warning category and the `[PPTX]` / `[REPORT]` paths. Resource-warning lines carry counts; a non-passing quality gate carries its status. Routine agents use this receipt and do not load either complete validation JSON into model context. Full reports remain cold audit artifacts; failure investigation and explicit audits extract only the required fields. `--quiet` keeps suppressing successful-run output. - Before publishing structured template output, export reopens the temporary PPTX and validates the Slide → Layout → Master graph and registrations, Layout identity, placeholder identity, reusable bounds, and prompt/level-one sizes. A mismatch aborts publication. Flat release instead validates its single referenced Master/Layout shell and exact date/footer/slide-number hook roster before packaging. @@ -939,6 +939,53 @@ Dependency: pip install python-pptx ``` +### Structured export mechanics + +Checker and exporter behavior behind [`pptx-structure-interface.md`](../../references/pptx-structure-interface.md) §2. + +**Master text styles**: the effective `title` anchor maps to every `a:defRPr@sz` in Master `p:titleStyle`. Level 1 in `p:bodyStyle` and `p:otherStyle` uses the `body` anchor; levels 2–9 descend deterministically from `15/16` through `8/16` of that size, rounded to 0.5 pt and floored at the smaller of 8 pt or the body size. Only `p:txStyles//a:defRPr@sz` changes; indentation, bullets, margins, paragraph settings, and direct run sizes on generated slides are untouched. Default reads the anchors from `spec_lock.md`; missing `title` / `body` rows fail flat or structured export. Structured Quick infers anchors from semantic slot carriers with deterministic fallbacks; flat Quick keeps stock defaults. + +| Master style | Effective source | XML field changed | +|---|---|---| +| `p:titleStyle` | title anchor | every `a:defRPr@sz` | +| `p:bodyStyle` | body anchor | level 1 plus derived level 2–9 `a:defRPr@sz` | +| `p:otherStyle` | body anchor | level 1 plus derived level 2–9 `a:defRPr@sz` | + +**Layout level-one text default**: for every text-bearing placeholder whose first prototype run has a direct `a:rPr@sz`, export copies that size to the generated Layout prompt run and `p:txBody/a:lstStyle/a:lvl1pPr/a:defRPr@sz`; Slide direct runs and Layout levels 2–9 are not rewritten. + +**Placeholder identity**: export writes the semantic type on both the Layout and Slide carrier (except `obj`, already the OOXML default). Date, footer, and slide-number placeholders enable the matching Layout `p:hf` flags; a date placeholder also gets a `datetimeFigureOut` field in the Layout while the Slide keeps its authored date text. An omitted `p:ph@idx` has effective value `0`, so an omitted-index title reserves `0`; every other indexed placeholder on that Layout uses a unique OOXML UInt32 index. An imported title with an explicit index keeps that exact index. + +**Text carriers**: a multiline text placeholder stays one native text frame under default export and `--reflow-text`; `--no-merge` cannot supply several line shapes as one placeholder. A whitespace-only marked carrier materializes one invisible U+200B run so it still becomes a native text shape. On a materialized mirror, an imported text carrier may keep the source shape's positive `data-pptx-frame="x y width height"`; that frame owns the Slide carrier `a:xfrm` and the converter reconstructs text-body insets from the visible anchor/baseline instead of shrinking to glyph bounds, while `data-pptx-bounds` remains the reusable Layout default. + +**Visibility attributes**: `data-pptx-show-master-shapes` writes the Layout's `p:sldLayout@showMasterSp` and must repeat the same value on every SVG sharing that Layout key; `data-pptx-show-inherited-shapes` writes this Slide's `p:sld@showMasterSp`. Both accept only exact lowercase `true` / `false`; omission means `true`. + +**Static structure consistency**: the same master element ids on every slide and the same layout element ids on every slide sharing a layout must compile to identical OOXML within that group. Static objects may carry shapes, text, or images; non-image/external relationships are rejected. Interleaved layers fail: paint order is Master background, Layout background, optional Slide background, remaining Master atoms, remaining Layout atoms, then slot groups and Slide-local content. Structured export narrows background ownership to a direct full-canvas solid `<rect>` and disables the generic conversion-level promotion; an unmarked full-canvas solid rect in the background plane is treated as Slide scope. + +**Final-package read-back gate**: before publishing, export reopens the temporary structured PPTX and verifies that each Slide targets exactly one Layout, one Layout key resolves to one part, distinct keys do not collapse, and every declared Layout—including unused ones—is registered through its Master and the Presentation; that physical Slide/Layout/Master part rosters, content-type overrides, and registrations are exact; the Layout picker name, Master picker identity, placeholder type and effective index, `p:hf` flags, design-zone frame, prompt size, and level-one default size; every owned `p:bg` as an exact zero-or-one payload against the pre-promotion result (preserving the base Master background when none replaces it); the exact top-level shape-name roster and order of every Slide, Layout, and Master; carrier-bound slot bindings, ordinary composite visible carriers, hidden composite proxies, and zero-slot Layouts with no placeholder. Later Slides may keep different Slide-local geometry; only the reusable Layout frame is checked. Any mismatch fails export without replacing the requested output. + +### Native formula compiler + +Behind [`native-formula.md`](../../references/native-formula.md) §3. The compiler implements every explicitly named LaTeX-to-OMML input in Microsoft's documented [Microsoft 365 LaTeX profile](https://learn.microsoft.com/en-us/office/math/latex) (Windows 2606 / Mac 16.110) and [mhchem profile](https://learn.microsoft.com/en-us/office/math/latex.mhchem) (Windows 2605 / Mac 16.109): outer delimiters, listed symbols and relations, fractions and binomials, roots, right and left scripts, delimiters and `\middle`, accents, bars and group characters, limits, all 21 listed n-ary operators, standard/custom functions, matrices and equation-array environments, CD diagrams, fonts and local colors, boxes and phantoms, spacing, global 0–9 argument macros, and the documented `\ce` chemistry grammar. Microsoft's open-ended "etc." wording defines no undisclosed names; only explicitly named commands and retained project aliases are contractual. The closed command tables in `svg_to_pptx/native_objects/formula_profile.py` are the executable vocabulary; the compiler facade and OMML structure gate are `formula_compiler.py` and `formula_omml.py`, with `formula.py`, `formula_ast.py`, `formula_parser.py`, `formula_run_properties.py`, and `inline_formula.py` alongside. + +**Normalization**: `\dfrac` / `\tfrac`, `\dbinom` / `\tbinom`, and continued-fraction alignment normalize to the corresponding OMML structure; explicit big-delimiter grades become auto-sizing delimiters; `\mathscr` → `\mathcal`; `smallmatrix` → `matrix`; array columns become centered; style/size commands and equation tags are accepted but not stored. Color is stored in generated formula runs and structural control properties; `\boldsymbol` / `\bm` applies bold-italic to structural control glyphs. + +**Fail-closed**: unknown commands or environments, Microsoft's explicitly unsupported commands, unsupported mhchem arrows, unescaped `%` comments, invalid macros, and resource-limit overflow block conversion — stricter than Microsoft 365's literal-text passthrough and macro-limit behavior. + +**Compatibility**: the package uses standard editable Office Math and keeps the PowerPoint 2010+ target; the executable profile is pinned to the documentation versions above. Repository verification covers compilation, OMML structure, and PPTX packaging, not a Microsoft 365 UI rendering/editability certification. Earlier PowerPoint versions are not the source-profile baseline; WPS, Keynote, LibreOffice, and other clients receive no embedded fallback. Reverse import is described in [`conversion.md`](conversion.md#native-formula-reverse-import). + +## `visual_review.py` + +Pure render-and-validate tool for the [`visual-review`](../../workflows/stages/visual-review.md) stage; it never edits SVGs and reads no rubric rule. + +```bash +python3 scripts/visual_review.py <project_path> [--pages <token> ...] [--server-url http://127.0.0.1:<P>] +``` + +- Requires `playwright` plus chromium and a running live-preview server for the same project; without `--server-url` it discovers the port from `<project>/live_preview/lock.json`, and in either case validates `/api/health` against the target project and rejects a server for another project. +- Output PNG matches the live-preview browser (inlined `<use data-icon>`, resolved `<image href>`); the root SVG `viewBox` is the canvas source of truth, and each successful page record carries `view_box`, `width` / `height`, and raster `png_width` / `png_height`; output dimensions equal that record's raster size. A record with `"all_background": true` rendered to a blank surface. +- Renders are serialized by `<project>/.preview/.render.lock`, so concurrent invocation is safe. +- Exit codes: `0` all requested pages rendered; `2` live-preview server unreachable or serving a different project; `3` playwright/chromium missing or unable to launch; `4` page-level render failure (details on stderr, partial output on disk). + ## `total_md_split.py` Split `total.md` into per-slide note files. @@ -954,7 +1001,7 @@ Requirements: - Heading text matches the SVG filename - Sections are separated by `---` -## Measuring and wrapping text before authoring +## Measuring, wrapping, and calibrating text before authoring `text_measure.py` imports the same single-line DrawingML width estimator used by the SVG quality checker. @@ -965,11 +1012,17 @@ the SVG quality checker. includes the outer `<text>` element, and `--json` prints line metrics. - `box` prints a `data-pptx-bounds` attribute plus numeric `top` and `bottom`, or a JSON bounds object with `--json`. +- `calibrate` measures fixed CJK and Latin samples for every typography role + from `spec_lock.md` or repeatable `--role NAME:FAMILY:SIZE` overrides, writes + `validation/text_calibration.json`, and prints a compact table or JSON. Add + `--outline` to include the longest planned line per mapped role from Design + Spec §IX. ```bash python3 scripts/text_measure.py measure "Editable DrawingML text" --size 22 python3 scripts/text_measure.py wrap "Editable DrawingML text stays measurable" --size 22 --max-width 240 --x 96 --dy 30 --y 140 python3 scripts/text_measure.py box "First line" "Second line" --x 96 --y 140 --size 22 --lines 2 --dy 30 +python3 scripts/text_measure.py calibrate projects/example --outline ``` ## `svg_quality_checker.py` @@ -1050,6 +1103,53 @@ python3 scripts/svg_position_calculator.py analyze <svg_file> Use this after SVG generation to inspect existing SVG geometry when manual comparison needs more context. +### Verification recipes + +Used by the [`verify-charts`](../../workflows/stages/verify-charts.md) stage for chart objects whose geometry reduces to repeated direct calculations (`decomposable-calc` / `partial-calc`), a closed formula (`formula-verify`), or inspection only (`manual-verify`). Every recipe produces one receipt line; a page that cannot be reduced cleanly is marked `manual-verify` with the reason, never dropped. + +**Stacked bar** — for N stacked series on the same categories, run `calc bar` N times. Pass each segment's height as the data value and shift `--area`'s `y_max` down by the sum of all lower segments for that category; compare each segment's `(x, y, width, height)`. + +```bash +# two-series stack at "Q1" with bottom=30, top=20, plot y from 100 to 500 +python3 scripts/svg_position_calculator.py calc bar --data "Q1:30,Q2:..." --area "x_min,100,x_max,500" --bar-width 80 --value-range=0,axis_max +python3 scripts/svg_position_calculator.py calc bar --data "Q1:20,Q2:..." --area "x_min,100,x_max,<500 - bottom_height_px>" --bar-width 80 --value-range=0,axis_max +``` + +**Stacked area** — run `calc line` N times on cumulative y-values (series 1 raw; series 2 = s1+s2; …); each call yields one band's top boundary, and each band's path closes to the previous band's top, not `y_max`. Negative segments or percent-stacked totals other than 100 are `manual-verify`. + +**Dumbbell** — the two endpoints are points, not bar ends (`calc bar --horizontal` anchors at `x_min`). Number categories `0.5, 1.5, …, N-0.5` with `--y-range=0,N` (swap axes for vertical dumbbells), set `--x-range` from ticks, run `calc line` once per endpoint series with identical `--area` / ranges; each `(SVG_X, SVG_Y)` is the endpoint circle's `(cx, cy)`, and the connector is `x1=cx_left, x2=cx_right, y1=y2=cy`. + +```bash +python3 scripts/svg_position_calculator.py calc line --data "42:0.5,55:1.5,37:2.5" --area "100,100,700,460" --x-range=0,100 --y-range=0,3 +python3 scripts/svg_position_calculator.py calc line --data "68:0.5,71:1.5,49:2.5" --area "100,100,700,460" --x-range=0,100 --y-range=0,3 +``` + +**Pareto** — `calc bar` on the descending values with the bar-axis range; precompute cumulative percentages; `calc line` on `0.5:cum1,…,N-0.5:cumN` with `--x-range=0,N`, the right-side percentage axis as `--y-range` (usually `0,100`), and the same `--area` (the `n - 0.5` offset centers each point on its bar). Compare bars, line, and markers separately. + +**Dual-axis line** — read each Y-axis tick range independently; run `calc line` once per series with its own `--y-range` and a shared `--x-range` / area; never apply the left scale to the right series. + +**Bullet** — bands overlap in one y row, so run `calc bar --horizontal` once per band with a single data point: `--data "<band>:<right_edge_value>" --area "<x_min>,<band_y>,<x_max>,<band_y+band_height>" --bar-width <band_height>` (widest band's right edge = axis max). Run once more for the actual bar with its inset area; the target marker is a `<line>` at `x = x_min + target/axis_max × area_width`. + +**Butterfly** — read the value range and center-line `cx`; run `calc bar --horizontal` once per side with `x_min = cx`, `x_max = cx + side_width`; right bars map directly, left bars mirror as `x = cx - width`; verify both sides share `y + height/2` per category. + +**Grouped bar** — with N series and group width `W`, each series bar is `W/N` wide at offset `(i - 1) × W/N`; run `calc bar` once per series with the same `--area` / `--value-range` and `--bar-width` set to the inner width; the per-category center is the group center, so `x = group_center - W/2 + (i-1) × W/N`. + +**Box plot** — five y-values per category on one axis. Run `calc bar` once treating the box (Q3 − Q1) as a synthetic segment with `y_max` shifted to the Q1 baseline; median and whisker y = `y_axis_top + (axis_max - value) × pixels_per_unit`. + +**Gantt** — pixels-per-unit from the header tick positions `(x_unit_n - x_unit_1) / (n - 1)`; run `calc line` over `start_index:row_y` and again over `end_index:row_y` — the two `SVG_X` values are `x` and `x + width`; row y is read directly. A qualitative stage/lane plan not derived from dates is not a chart and never enters verification. + +**Waterfall** — compute running totals (`cum[i] = cum[i-1] ± delta[i]`, reset for totals); build `top[i] = max(cum_before, cum_after)` and `bot[i] = min(...)`; run `calc bar` twice with identical parameters — the `top` run's `Y` is `y`, `height = bot.Y - top.Y`; connectors run from `(x + width, Y_i)` to `(x_next, Y_{i+1})` at the shared cumulative value; total bars use `bot = 0`. + +**Bubble / plotted 2×2 matrix** — `calc line` verifies `cx/cy` from x/y values and ticks. For `matrix_2x2`, the axis midpoint must match the quadrant split; Low/High-only axes need an explicit numeric mapping from the active §IX decision or an SVG comment, otherwise record `xy=manual (scale missing)`. Verify radius only when a size scale is declared (`radius = sqrt(value) * k` or min/max mapping) — `spec_lock.md` is not a size-scale authority; otherwise record `radius=manual (scale missing)` and inspect ordering by hand. + +**Bar-of-pie / pie-of-pie** — replace the expanded tail with one aggregate value and `calc pie` the main pie; `pie_of_pie` runs `calc pie` again on the tail at the secondary center/radius, `bar_of_pie` verifies each detail height as `tail_value / sum(tail) × detail_height` with no gaps or overlap; the aggregate slice equals the sum of expanded values and connectors touch both plot regions. + +**Stock** — `calc line` for open, high, low, close on the shared price axis; the wick spans `high_y..low_y`, the body `min(open_y, close_y)..max(...)`; body color follows `close >= open` and stays inside its wick. + +**Formula-verify** (no calc call): progress bar `fill_width = value / max × track_width`; gauge `needle_angle = start_angle + value / max × sweep_angle`, compared against `transform="rotate(α …)"` or the endpoint `(cx + L·cos α, cy + L·sin α)`; funnel `top_width = prev.bottom_width`, `bottom_width = top_width × next_value / curr_value`, inset `(top_width - bottom_width) / 2`, first top width from the outer frame; sunburst arc length `node_value / root_total × 2πr` per ring with offsets from cumulative siblings plus any declared gap, children inside the parent span, siblings summing to the parent. The receipt quotes the formula and result (`formula=0.92×700=644px`). + +**Manual-verify**: sankey — link widths proportional to flow, node totals in = out; heatmap — grid positions are fixed, verify each cell's color falls in the bin matching its value and extremes use the legend's high/low colors; treemap — `width × height ≈ total_area × value / sum(values)` for top-level cells, nested cells summing to the parent; word cloud — font sizes monotonic with declared weights or bins, then inspect bounds for overlap and clipping; position is layout-driven. + ## Advanced Standalone Tools ### `flatten_tspan.py` @@ -1067,7 +1167,10 @@ python3 scripts/svg_finalize/align_embed_images.py --dry-run path/to/slide.svg ``` Use for rare single-file diagnostics when image `slice` / `meet` alignment and -Base64 embedding must be inspected outside `finalize_svg.py`. In normal project +Base64 embedding must be inspected outside `finalize_svg.py`. Embedded hrefs are +`data:<mime>;base64,...` with `image/png`, `image/jpeg`, `image/gif`, +`image/webp`, or `image/svg+xml`; recover an embedded payload with +`base64 -d image.b64 > image.png`. In normal project runs, use `python3 scripts/finalize_svg.py <project_path>`; the old `crop-images`, `fix-aspect`, and `embed-images` names remain accepted only as `finalize_svg.py --only` aliases for the merged `align-images` step. @@ -1090,8 +1193,10 @@ this only for manual checks outside `finalize_svg.py`. The always-on SVG authoring contract lives in [`shared-standards-core.md`](../../references/shared-standards-core.md), with advanced effects, native data objects, and structured PPTX metadata owned by -their conditionally loaded modules. This tool guide does not repeat accepted -syntax, rejected constructs, or conditional limits. +their conditionally loaded modules. The complete closed grammar those files +rely on — mapping tables, accepted-but-warned spellings, rejection boundaries, +and imported native-shape metadata — is documented in +[`svg-contract.md`](svg-contract.md). This tool guide does not repeat it. `svg_quality_checker.py` validates source SVG before finalization. `finalize_svg.py` and native export apply the preprocessing required by that diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/docs/svg_editor.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/docs/svg_editor.md new file mode 100644 index 00000000..f5ba4bdd --- /dev/null +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/docs/svg_editor.md @@ -0,0 +1,39 @@ +# `svg_editor/server.py` + +Browser SVG editor behind the [`live-preview`](../../workflows/stages/live-preview.md) stage and Generate Step 6's `--live` auto-startup. This page documents editor behavior, lifecycle, and remote access; the stage owns when to launch and how to apply annotations. + +## Commands + +```bash +python3 skills/ppt-master/scripts/svg_editor/server.py <project_path> --daemon # plain mode (stage Step 1) +python3 skills/ppt-master/scripts/svg_editor/server.py <project_path> --live --daemon # Generate Step 6 auto-startup +python3 skills/ppt-master/scripts/svg_editor/server.py <project_path> --daemon --no-browser # remote host +python3 skills/ppt-master/scripts/svg_editor/server.py <project_path> --shutdown +``` + +The launcher starts the server in the background, waits for `GET /api/health`, records pid + port in `<project_path>/live_preview/lock.json`, opens the browser when possible, and edits `<project_path>/svg_output/` in place. + +## Lifecycle + +- **Port**: without `--port`, the first free port from `6060`; `--port N` binds strictly and fails if unavailable. Read the actual URL from launch output or `live_preview/lock.json`; never assume `6060`. +- **Idle timeout**: plain mode `900s`, `--live` `7200s`; `--timeout <seconds>` overrides (`0` disables). +- **Single instance per project**: `live_preview/lock.json` is the discovery source for project-local consumers (including `visual_review.py`). A second launch reuses the live instance unless a different explicit `--port N` was requested — that mismatch fails and needs `--shutdown` first. Stale locks (dead pid) are overwritten; legacy `<project_path>/.live_preview.lock` root locks are still detected when live. +- **Stop conditions**: **Exit preview** in the browser (the only UI action that stops Flask), a chat request to stop, the idle timeout, or an external kill. +- **Transient ids**: each element gets a temporary `_edit_N` id while running; on save only annotated elements keep their id. +- **Browser preview**: the server inlines `<use data-icon>` placeholders and serves `images/*`; the on-disk SVG is unchanged by preview. +- **Re-export is chat-driven**: applying changes updates `svg_output/` only; refreshing the PPTX (`finalize_svg.py` + `svg_to_pptx.py`) is a chat step — the editor never runs the export pipeline. + +## Editing surface + +- **UI**: four languages (中文 / 繁體中文 / English / 日本語), auto-detected from `navigator.language`, persisted in `localStorage`, switchable from the right panel. The right panel separates direct SVG edits from AI-needed annotations, with a pending-status strip for staged edits and pages with unsaved annotations. Slide navigation: first/prev/next/last buttons plus `←` / `→` / `Home` / `End` (suppressed while typing in the annotation textarea). +- **Buttons**: `Add annotation` stages annotation text in memory; `Apply changes` writes staged direct edits plus annotation markers (`data-edit-target`, `data-edit-annotation`) to disk and keeps the service running; `Exit preview` stops Flask. +- **Direct edit (no AI)**: single element = full inspector (geometry, safe text content, computed text styles for the selected text node or descendant text, raw attributes except protected fields such as `id`, UI `class`, event handlers, hrefs). `<g>` group = group-level surface, selected via `Alt/Option` + click or **Select parent group**. Multi-select = batch editor over top-level objects only: shared x/y plus `fill` / `stroke` / `opacity`; text style fields appear only when every selected object is `text` / `tspan`. Preview updates immediately; disk writes wait for **Apply changes**. +- **Drag to move**: press and drag an already-selected element (selection stays a separate click, so the background is never dragged by accident); the whole selection moves together. Pointer delta is mapped through each element's CTM, so moves track the cursor regardless of viewport scale or group transforms. Each release stages one direct edit per moved element; dragging on empty canvas is rubber-band selection; a failed stage rolls the canvas back. +- **Arrow-key nudge**: `↑ ↓ ← →` moves the selection 1px, `Shift + arrow` 10px (suppressed while typing); arrow keys navigate slides only when nothing is selected. Same staging/coalescing as drag. +- **Overlap picker**: right-click lists every selectable element under the pointer (top→bottom); hovering highlights, clicking selects, `Esc` or an outside click closes; with one element under the pointer, right-click selects it directly. Left-click selects the topmost. +- **Undo**: `Ctrl+Z` or **Undo** drops the last staged direct edit on the current slide (per-slide LIFO, this session). Consecutive edits to the same element and field set coalesce into one step keeping the original pre-edit value. Applied old→new history goes to `live_preview/edits.jsonl`; annotation save/update/remove history to `live_preview/annotations.jsonl`; un-applied staged edits are memory only. +- **Unsaved-work guard**: staged edits and annotation changes live in server memory until **Apply changes**; closing the tab triggers the browser's "leave site?" prompt while any are unapplied. + +## Remote access + +On a remote Linux host run with `--no-browser`, then with `<P>` from launch output or `live_preview/lock.json`: VS Code / Cursor Remote-SSH — forward `<P>` in the **PORTS** panel; Termius — a Local rule with Binding and Destination both `127.0.0.1:<P>`; plain SSH — `ssh -L <P>:127.0.0.1:<P> <user>@<host>`. Then open `http://localhost:<P>`. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/docs/template-tools.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/docs/template-tools.md new file mode 100644 index 00000000..ee52e4ba --- /dev/null +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/docs/template-tools.md @@ -0,0 +1,65 @@ +# Template Creation Tools + +Tool behavior behind [`create-template.md`](../../workflows/create-template.md) and [`template-designer.md`](../../references/template-designer.md): the PPTX import workspace, the authoring IR, template-mode validation, the review deck, and registration. `mirror_template_materialize.py`, `extract_svg_assets.py`, `extract_svg_pictures.py`, and `svg_authoring_view.py` are documented in [`svg-pipeline.md`](svg-pipeline.md). + +## `pptx_template_import.py` + +```bash +python3 skills/ppt-master/scripts/pptx_template_import.py "<reference_template.pptx>" [--inheritance-mode layered|both|flat] +``` + +Produces one import workspace (typically under `/tmp/pptx_template_import/`; an analysis intermediate, never a final template): + +| Output | Content | +|---|---| +| `analysis/manifest.json` | Source facts: slide size, theme colors, fonts, per-master theme summaries, resource inventory and asset-name map, placeholder metadata, SVG file paths, per-slide / per-layout / per-master metadata (including source-owned inherited-shape visibility), `pageTypeCandidates` | +| `analysis/native_structure.json` | Stable Master/Layout keys, picker names, placeholder type/index/geometry, inherited-shape visibility, source hash, source-graph quality facts | +| `sources/source.pptx` | Byte-preserved backing package for cross-checking and identity validation; never copied into a template | +| `images/` | PowerPoint image media including SVG/EMF/WMF; SVG `href` values reuse the manifest asset map | +| `sounds/`, `audio/`, `video/`, `native-payloads/` | Conditional semantic resource directories, created only when populated | +| `validation/conversion-report.json` | Source-recovery and fidelity diagnostics not duplicated in the structural manifests | +| `svg/master_*.svg`, `svg/layout_*.svg`, `svg/slide_NN.svg`, `svg/inheritance.json` | Immutable layered lossless view: every master and layout rendered once (including ones no sample slide uses), each slide's own shapes only, and the Slide → Layout → Master consumption map with `showInheritedShapes` / `showMasterShapes` (Layout shapes follow the Slide flag; Master shapes need both; backgrounds are independent) | +| `svg-flat/slide_NN.svg` | Optional (`--inheritance-mode both`) self-contained verification view of each complete page | +| `authoring-svg/` (+ `authoring-svg-flat/` with `both`) | Canonical compact editable SVG projected from parsed evidence, with model-readable `authoring_summary.json` and tool-only `authoring_manifest.json` | + +- `layered` (default) emits only the canonical layered view; `both` adds the flat verification tree; `flat` emits a projection-only self-contained `svg/` tree without master/layout/inheritance files. Imported-deck round-trip uses the separate `authoring-svg-flat/` contract of `pptx_to_svg.py --roundtrip`. +- Placeholder metadata lives in the manifest; master/layout SVGs show lightweight dashed guides with labels only in `svg/`. Charts, SmartArt, diagrams, and OLE objects are typed placeholders in `svg/` and preview images with a badge in `svg-flat/`; tables are converted to real SVG. Missing media and external linked images fail the import; EMF/WMF convert to PNG previews when the local toolchain supports it, otherwise the import fails. +- The import transaction publishes `authoring-svg/` already normalized and decoration-factored: large non-semantic decorative vector groups become one canonical asset under `<import_workspace>/icons/imported/` referenced as `<use data-icon="imported/..." data-pptx-asset-role="decoration"/>`; do not run a second readability or compaction pass. `--inheritance-mode both` reuses the layered inventory (`--reuse-inventory`) so only genuinely flat-only vectors create another asset under the `flat` prefix; `--clean-stale` removes obsolete `flat_*` duplicates. Every asset root, placeholder, and v2 inventory record declares the `decoration` role; any subtree with a semantic marker, text, table, chart, or relationship stays inline, and extraction and both consumers fail closed if that boundary is crossed. Eligible records may retain `data-pptx-source-ref` so re-inlining re-establishes their object mapping; referenced defs (`gradient` / `pattern` / `filter` / `clipPath` / `marker`) are copied into each asset and namespaced. +- The projection removes opaque/duplicate/import-only carriers while retaining visible intent, compact frame/preset and structure markers, ids, assets, inline Chart/Table JSON, and per-object source refs. Model-facing page coordinates use at most two decimals; crop/path/matrix values keep required precision. The summary indexes roster and counts; the manifest owns source paths/hashes and initial subtree hashes and never enters model context. After any direct IR edit, refresh the summary: `svg_authoring_view.py "<import_workspace>/authoring-svg" --refresh-summary` (in-place vector/picture normalization refreshes it automatically). +- The importer generates no narrative summary or SVG-size CSV. + +**Artifact roles**: `analysis/manifest.json` is the truth for source-deck facts (slide size, theme, fonts, background inheritance, resource inventory, declared structure, reuse relationships); `analysis/native_structure.json` for source PowerPoint identity (keys, picker names, parents, placeholder types/indices, package hash); `svg/inheritance.json` for consumption and visibility. The three overlap only at contract boundaries so materialization can cross-check identity, ownership, and visibility — never collapse or substitute them. `authoring_summary.json` is the model-facing roster index; `authoring_manifest.json` is machine-only provenance validated by the mirror compiler. Exported `images/` is the canonical reusable image pool; `icons/imported/*.svg` is the canonical decoration pool but not part of the default read set — use `authoring_summary.json` `icon_refs` and cleaned SVGs first, query `*_vector_asset_inventory.json` by exact asset id only when source-ref or fingerprint detail is needed, and open an individual asset only when it affects a design decision. + +## Type B source bundles + +```bash +python3 skills/ppt-master/scripts/svg_authoring_view.py "<normalized_svg_source>" -o "<svg_analysis_workspace>/authoring-svg" --projection-kind generic +python3 skills/ppt-master/scripts/extract_svg_assets.py "<svg_analysis_workspace>/authoring-svg" --icons-dir "<svg_analysis_workspace>/icons" --icon-namespace imported --inplace --id-prefix source --min-decoration-bytes 3000 --clean-stale +``` + +Creates a non-destructive authoring IR bundle in a throwaway analysis workspace and runs the vector readability pass only on that IR; the user's source directory is never rewritten. For an explicitly selected complex subtree that should stay one SVG picture, apply `extract_svg_pictures.py` to the analysis IR with `--resource-root` set to the narrowest directory containing the IR and every local dependency. + +## `svg_quality_checker.py --template-mode` + +```bash +python3 skills/ppt-master/scripts/svg_quality_checker.py "<template_source>" --template-mode --canonical-authoring [--format <canvas_format>] +``` + +Globs `*.svg` in the template directory; skips `spec_lock.md` drift checks; enforces roster ↔ resolved Design Spec consistency as errors (orphan or missing files break the contract and, in library scope, the index); emits advisory warnings when a page lacks a conventional placeholder (silence them with a `placeholders:` frontmatter map); requires every SVG root to declare one output Master and Layout (zero-slot Layouts are valid); rejects ordinary Master/Layout `<g>` elements, nested structure markers, missing slot bounds, and carrier-bound slots without exactly one compatible carrier (a validated compact authored-preset `<g>` is the sole fixed-layer group exception and may be one `object` carrier); validates cross-page Master equality and same-key Layout atom/slot equality; warns when distinct Layout keys have identical static framing/slot contracts. For `kind: brand` it validates the identity-only frontmatter/sections/colors/provenance/asset references; for `kind: style` the frontmatter, section/field shape, conditional custom and fallback values, portable ID, and one-file roster-free boundary. It validates the authoring contract, not the compiled OOXML package. + +## `template_preview_pptx.py` + +```bash +python3 skills/ppt-master/scripts/template_preview_pptx.py "<authoring_workspace>" [--force] [--native-charts-and-tables -o <distinct_path>] +``` + +Consumes `templates/*.svg` directly, compiles the declared structured Master/Layout contract into `<authoring_workspace>/exports/<template_id>_template_preview.pptx` (creating `exports/` on demand), and reopens the result to verify one slide per prototype, the expected Master/Layout counts, exact Presentation → Master → Layout → Slide registration, distinct Theme parts per Master, valid unique `p14:creationId` and registration IDs, and — for `standard` / `fidelity` — that every carrier-bound placeholder on each review Slide has the same type, effective index, and full frame as its registered Layout placeholder. Authored modes use ephemeral SVG copies with concise preview-only sample text so long `{{...}}` markers stay readable; source SVGs, carrier typography, slot metadata, and Layout frames are unchanged. The default review keeps visible Chart/Table fallbacks; `--native-charts-and-tables -o <distinct_path>` writes a separately named JSON-first review. The first export refuses an existing output; `--force` replaces it intentionally. It needs no project `spec_lock.md`, creates no persistent project, and never infers structure. + +## `register_template.py` + +```bash +python3 skills/ppt-master/scripts/register_template.py <template_id> --kind brand|style|layout|deck [--dry-run] +python3 skills/ppt-master/scripts/register_template.py --kind style|deck|layout --rebuild-all +``` + +Derives the index entry from `templates/design_spec.md` (frontmatter preferred; prose fallback) plus the actual `templates/*.svg` roster and updates `templates/brands/brands_index.json`, `styles/styles_index.json`, `layouts/layouts_index.json`, or `decks/decks_index.json`. The JSON index is the single discovery source for Default Stage-1 template controls and chat listing; READMEs describe kinds in prose and are never edited. `--dry-run` checks the directory/index identity without writing. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/project_management/project_specs.py b/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/project_management/project_specs.py index 5b89b5ac..ad7db2ba 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/project_management/project_specs.py +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/project_management/project_specs.py @@ -93,6 +93,7 @@ _MARKDOWN_DATA_LINE_RE = re.compile( r"^[ \t]*-[ \t]+(?:\*\*)?([^:\n*]+?)(?:\*\*)?[ \t]*:[ \t]*(.*)$", re.MULTILINE, ) +_MARKDOWN_LIST_ITEM_RE = re.compile(r"^[ \t]*-[ \t]+(.*)$") _IMAGE_PATH_SUFFIXES = frozenset( { ".bmp", @@ -120,6 +121,14 @@ _LEGACY_IMAGE_METADATA_KEYS = frozenset( } ) _LEGACY_SPEC_LOCK_FORBIDDEN = frozenset({"Mixing icon libraries"}) +_LEGACY_SPEC_LOCK_FORBIDDEN_ANCHORS = ( + "<style>", + "<foreignObject>", + "HTML named entities", + "Mixing icon libraries", + "rgba()", + "<g opacity", +) _SCAFFOLD_TOKEN_RE = re.compile(r"\{\{[A-Z_]+\}\}") _SCHEMA_MARKER_RE = re.compile( r"^<!--[ \t]+ppt-master-schema:[ \t]*([a-z0-9-]+/v[1-9][0-9]*)[ \t]+-->$", @@ -426,6 +435,47 @@ def default_spec_lock_forbidden() -> frozenset[str]: return current | _LEGACY_SPEC_LOCK_FORBIDDEN +def _normalize_forbidden_row(row: str) -> str: + """Collapse whitespace for baseline comparison and diagnostics.""" + return " ".join(row.split()) + + +def _validate_spec_lock_forbidden( + section: Mapping[str, object] | None, +) -> list[str]: + """Require provenance tags on non-baseline rows in a versioned lock.""" + if section is None: + return [] + + baseline = { + _normalize_forbidden_row(row) + for row in default_spec_lock_forbidden() + } + errors: list[str] = [] + row_number = 0 + for line in str(section.get("body", "")).splitlines(): + match = _MARKDOWN_LIST_ITEM_RE.match(line) + if match is None: + continue + row = _normalize_forbidden_row(match.group(1)) + if not row: + continue + row_number += 1 + if ( + row in baseline + or any( + anchor in row for anchor in _LEGACY_SPEC_LOCK_FORBIDDEN_ANCHORS + ) + or row.endswith("(user)") + ): + continue + errors.append( + f"spec_lock.md forbidden: row {row_number} is not a baseline rule " + f"and lacks the (user) tag: {row[:60]}" + ) + return errors + + def _load_markdown_schema(schema_path: Path) -> dict[str, object]: """Load and sanity-check one versioned Markdown schema.""" with schema_path.open("r", encoding="utf-8") as stream: @@ -978,6 +1028,8 @@ def _validate_spec_lock_relations( markdown_name = markdown_path.name errors: list[str] = [] + errors.extend(_validate_spec_lock_forbidden(matched.get("forbidden"))) + def fields(section_id: str) -> dict[str, str]: section = matched.get(section_id) if section is None: diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/project_utils.py b/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/project_utils.py index 20fd7438..664ccb89 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/project_utils.py +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/project_utils.py @@ -342,6 +342,7 @@ def validate_communication_trace( return errors missing_moves = [] + missing_relationships = [] for index, slide_match in enumerate(slide_matches): block_end = ( slide_matches[index + 1].start() @@ -355,12 +356,24 @@ def validate_communication_trace( flags=re.IGNORECASE | re.MULTILINE, ) is None: missing_moves.append(slide_match.group(1)) + if re.search( + r'^[ \t]*-[ \t]+(?:\*\*)?Relationships(?:\*\*)?[ \t]*:', + slide_block, + flags=re.IGNORECASE | re.MULTILINE, + ) is None: + missing_relationships.append(slide_match.group(1)) if missing_moves: errors.append( 'Communication trace: every design_spec.md §IX Slide block must ' 'contain an Audience move line; missing on Slide ' f'{", ".join(missing_moves)}.', ) + if missing_relationships: + errors.append( + 'Communication trace: every design_spec.md §IX Slide block must ' + 'contain a Relationships line; missing on Slide ' + f'{", ".join(missing_relationships)}.', + ) return errors diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/prompt_audit_manifest.json b/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/prompt_audit_manifest.json index 6c2b50fb..305bcd57 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/prompt_audit_manifest.json +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/prompt_audit_manifest.json @@ -17,33 +17,69 @@ }, "file_budgets": { "AGENTS.md": 3250, - "skills/ppt-master/SKILL.md": 1500, - "skills/ppt-master/references/executor-base.md": 12000, + "skills/ppt-master/SKILL.md": 1750, + "skills/ppt-master/references/executor-base.md": 11000, "skills/ppt-master/references/executor-structured.md": 5500, - "skills/ppt-master/references/executor-chart.md": 3500, - "skills/ppt-master/references/executor-visualization.md": 1250, - "skills/ppt-master/references/executor-structure.md": 2250, + "skills/ppt-master/references/executor-chart.md": 1750, + "skills/ppt-master/references/executor-visualization.md": 1000, + "skills/ppt-master/references/executor-structure.md": 1750, "skills/ppt-master/references/topology-assembly.md": 3750, - "skills/ppt-master/references/executor-table.md": 1250, + "skills/ppt-master/references/executor-table.md": 1000, "skills/ppt-master/references/executor-image.md": 2000, "skills/ppt-master/references/executor-web-image.md": 750, "skills/ppt-master/references/executor-notes.md": 1000, "skills/ppt-master/references/shared-standards.md": 500, - "skills/ppt-master/references/shared-standards-core.md": 14000, - "skills/ppt-master/references/svg-effects.md": 16000, - "skills/ppt-master/references/native-data-interface.md": 7750, - "skills/ppt-master/references/pptx-structure-interface.md": 4750, + "skills/ppt-master/references/shared-standards-core.md": 7000, + "skills/ppt-master/references/svg-effects.md": 9500, + "skills/ppt-master/references/native-data-interface.md": 5000, + "skills/ppt-master/references/pptx-structure-interface.md": 3000, "skills/ppt-master/references/preset-shape-vocabulary.md": 2750, - "skills/ppt-master/references/strategist.md": 18000, + "skills/ppt-master/references/strategist.md": 13000, "skills/ppt-master/references/strategist-image.md": 3250, - "skills/ppt-master/references/strategist-template.md": 3000, - "skills/ppt-master/templates/design_spec_reference.md": 4000, - "skills/ppt-master/templates/spec_lock_reference.md": 2750, + "skills/ppt-master/references/strategist-template.md": 2500, + "skills/ppt-master/templates/design_spec_reference.md": 3500, + "skills/ppt-master/templates/spec_lock_reference.md": 2500, "skills/ppt-master/templates/charts/chart-vocabulary.md": 1250, "skills/ppt-master/templates/tables/table-vocabulary.md": 500, "skills/ppt-master/templates/sounds/sound-vocabulary.md": 6250, - "skills/ppt-master/workflows/generate-pptx.md": 18000, - "skills/ppt-master/workflows/stages/apply-template-workspace.md": 3500 + "skills/ppt-master/workflows/generate-pptx.md": 11000, + "skills/ppt-master/workflows/stages/apply-template-workspace.md": 2750, + "skills/ppt-master/references/confirm-surface.md": 3000, + "skills/ppt-master/references/video-design.md": 2500, + "skills/ppt-master/references/native-formula.md": 1500, + "skills/ppt-master/references/semantic-svg.md": 1500, + "skills/ppt-master/references/native-hyperlinks.md": 1250, + "skills/ppt-master/references/canvas-formats.md": 1250, + "skills/ppt-master/workflows/routing.md": 3000, + "skills/ppt-master/references/artifact-ownership.md": 4500, + "skills/ppt-master/workflows/governance/failure-recovery.md": 2750, + "skills/ppt-master/workflows/stages/resume-execute.md": 1750, + "skills/ppt-master/workflows/stages/refine-spec.md": 1000, + "skills/ppt-master/workflows/stages/verify-charts.md": 2500, + "skills/ppt-master/workflows/stages/topic-research.md": 2000, + "skills/ppt-master/workflows/stages/live-preview.md": 1000, + "skills/ppt-master/workflows/stages/web-image-review.md": 750, + "skills/ppt-master/references/visual-review.md": 3500, + "skills/ppt-master/workflows/stages/visual-review.md": 1750, + "skills/ppt-master/workflows/stages/generate-audio.md": 4000, + "skills/ppt-master/workflows/profiles/beautify-pptx.md": 5000, + "skills/ppt-master/workflows/profiles/image-to-pptx.md": 3250, + "skills/ppt-master/workflows/edit-native-pptx.md": 4250, + "skills/ppt-master/workflows/create-template.md": 10000, + "skills/ppt-master/references/template-designer.md": 7000, + "skills/ppt-master/workflows/create-template/create-brand.md": 1500, + "skills/ppt-master/workflows/create-template/create-style.md": 2000, + "skills/ppt-master/workflows/create-template/create-layout.md": 1500, + "skills/ppt-master/workflows/create-template/create-deck.md": 1500, + "skills/ppt-master/workflows/stages/customize-animations.md": 4250, + "skills/ppt-master/references/svg-image-embedding.md": 1750, + "skills/ppt-master/references/image-layout-spec.md": 2500, + "skills/ppt-master/templates/README.md": 1750, + "skills/ppt-master/templates/brands/README.md": 750, + "skills/ppt-master/templates/styles/README.md": 1250, + "skills/ppt-master/templates/layouts/README.md": 1500, + "skills/ppt-master/templates/decks/README.md": 1250, + "skills/ppt-master/templates/icons/README.md": 1750 }, "load_sets": { "bootstrap.routing": { @@ -159,18 +195,15 @@ ], "files": [ "skills/ppt-master/workflows/generate-pptx.md", - "skills/ppt-master/references/artifact-ownership.md", "skills/ppt-master/references/strategist.md", "skills/ppt-master/references/strategist-image.md", "skills/ppt-master/references/canvas-formats.md", - "skills/ppt-master/references/image-layout-spec.md", - "skills/ppt-master/references/image-layout-patterns.md", "skills/ppt-master/templates/design_spec_reference.md", "skills/ppt-master/templates/spec_lock_reference.md", "skills/ppt-master/references/modes/_index.md", "skills/ppt-master/references/visual-styles/_index.md", "skills/ppt-master/references/image-renderings/_index.md", - "skills/ppt-master/scripts/docs/confirm_ui.md", + "skills/ppt-master/references/confirm-surface.md", "skills/ppt-master/templates/icons/README.md", "skills/ppt-master/templates/charts/chart-vocabulary.md", "skills/ppt-master/templates/tables/table-vocabulary.md", @@ -212,18 +245,11 @@ ], "files": [ "skills/ppt-master/workflows/profiles/quick-generate.md", - "skills/ppt-master/references/artifact-ownership.md", "skills/ppt-master/references/shared-standards-core.md", "skills/ppt-master/references/executor-base.md", - "skills/ppt-master/references/svg-effects.md", - "skills/ppt-master/references/native-shape-authoring.md", "skills/ppt-master/references/preset-shape-vocabulary.md", "skills/ppt-master/references/semantic-svg.md", - "skills/ppt-master/references/executor-structure.md", - "skills/ppt-master/references/topology-assembly.md", "skills/ppt-master/references/canvas-formats.md", - "skills/ppt-master/references/image-layout-spec.md", - "skills/ppt-master/references/image-layout-patterns.md", "skills/ppt-master/references/modes/_index.md", "skills/ppt-master/references/visual-styles/_index.md", "skills/ppt-master/references/image-renderings/_index.md", @@ -258,7 +284,7 @@ "registry": "image-renderings" } ], - "max_tokens": 130000 + "max_tokens": 115000 }, "route.generate.quick-generate.beautify": { "description": "Quick Generate with the shared strict 1:1 Beautify profile. Ceiling raised after BUDGET_LOAD_SET reported 136685 tokens.", @@ -395,7 +421,7 @@ "max_tokens": 150000 }, "route.generate.planning-image": { - "description": "Generate-PPTX planning context after a non-none image source is proposed or confirmed; image decision and layout authorities are already in the fixed planning context. Ceiling raised after BUDGET_LOAD_SET reported 116384 tokens.", + "description": "Generate-PPTX planning context after a non-none image source is proposed or confirmed; the image decision authority is already in the fixed planning context (image-layout files are Executor's). Ceiling raised after BUDGET_LOAD_SET reported 116384 tokens.", "scope": "cumulative", "include": [ "route.generate.planning" @@ -413,7 +439,7 @@ "max_tokens": 130000 }, "route.generate.planning-ai": { - "description": "Generate-PPTX planning after AI imagery is confirmed; the fixed context already carries image-layout and resource-planning decision authorities. Ceiling raised after BUDGET_LOAD_SET reported 116384 tokens.", + "description": "Generate-PPTX planning after AI imagery is confirmed; the fixed context already carries the resource-planning decision authorities (image-layout files are Executor's). Ceiling raised after BUDGET_LOAD_SET reported 116384 tokens.", "scope": "cumulative", "include": [ "route.generate.planning-image" @@ -756,17 +782,13 @@ "max_tokens": 200000 }, "stage.generate.executor.flat": { - "description": "Incremental flat Executor core with complete visual-construction authorities and a conservative audit envelope for only the locked preset or exact custom references; selection indexes remain planning-only.", + "description": "Executor resident core for flat pages: execution rules, everyday devices and effects, module triggers, the preset vocabulary, plus the confirmed mode/style catalog file when the confirmation points to one (a custom without references reads none). Deeper modules load on their routing triggers.", "scope": "incremental", "files": [ "skills/ppt-master/references/executor-base.md", "skills/ppt-master/references/shared-standards-core.md", - "skills/ppt-master/references/svg-effects.md", - "skills/ppt-master/references/native-shape-authoring.md", - "skills/ppt-master/references/preset-shape-vocabulary.md", "skills/ppt-master/references/semantic-svg.md", - "skills/ppt-master/references/executor-structure.md", - "skills/ppt-master/references/topology-assembly.md", + "skills/ppt-master/references/preset-shape-vocabulary.md", { "glob": "skills/ppt-master/references/modes/*.md", "exclude": [ @@ -788,7 +810,7 @@ "allow_repeat": true } ], - "max_tokens": 71000 + "max_tokens": 35000 }, "stage.generate.executor.structured": { "description": "Structured template execution layered on the flat/shared core.", @@ -863,8 +885,7 @@ ], "files": [ "skills/ppt-master/workflows/generate-pptx.md", - "skills/ppt-master/workflows/stages/resume-execute.md", - "skills/ppt-master/references/artifact-ownership.md" + "skills/ppt-master/workflows/stages/resume-execute.md" ], "max_tokens": 115000 }, @@ -1137,21 +1158,75 @@ "max_tokens": 1000 }, "stage.generate.executor.native-shape": { - "description": "Complete stock PowerPoint shape vocabulary, selection, and Boolean materialization authority, always included in Generate Executor contexts. Ceiling raised after BUDGET_LOAD_SET reported 9139 tokens.", + "description": "Native-shape selection and Boolean construction; loaded the first time a page's contour reaches beyond basic primitives (the preset vocabulary stays in the resident core).", "scope": "incremental", "files": [ - "skills/ppt-master/references/native-shape-authoring.md", - "skills/ppt-master/references/preset-shape-vocabulary.md" + "skills/ppt-master/references/native-shape-authoring.md" ], - "max_tokens": 10000 + "max_tokens": 5000 }, "stage.shared.svg-effects": { - "description": "Advanced SVG paint, effects, transforms, and geometry authority, always included in Generate Executor contexts and conditionally loaded by other SVG-authoring routes.", + "description": "Advanced SVG paint, effects, transforms, and geometry authority, loaded by Generate Executor contexts on the executor-base trigger (first visual job beyond the everyday block) and conditionally by other SVG-authoring routes.", "scope": "incremental", "files": [ "skills/ppt-master/references/svg-effects.md" ], "max_tokens": 16000 + }, + "governance.artifact-ownership": { + "description": "Global artifact ownership matrix, invariants, and regeneration rules; read on an ownership question, a recovery/resume, or a route that edits existing artifacts.", + "scope": "incremental", + "files": [ + "skills/ppt-master/references/artifact-ownership.md" + ], + "max_tokens": 6000 + }, + "stage.generate.executor.effects": { + "description": "Advanced effects and constructed styles; loaded the first time a page's visual job reaches beyond the everyday block in executor-base.", + "scope": "incremental", + "files": [ + "skills/ppt-master/references/svg-effects.md" + ], + "max_tokens": 10000 + }, + "stage.generate.executor.structure": { + "description": "Qualitative relationship grammar and topology assembly; loaded at the first page whose Structure decision is yes.", + "scope": "incremental", + "files": [ + "skills/ppt-master/references/executor-structure.md", + "skills/ppt-master/references/topology-assembly.md" + ], + "max_tokens": 5000 + }, + "route.generate.quick-generate.effects": { + "description": "Quick Generate plus the effects module on its executor-base trigger.", + "scope": "cumulative", + "include": [ + "route.generate.quick-generate", + "stage.generate.executor.effects" + ], + "files": [], + "max_tokens": 130000 + }, + "route.generate.quick-generate.native-shape": { + "description": "Quick Generate plus the native-shape module on its executor-base trigger.", + "scope": "cumulative", + "include": [ + "route.generate.quick-generate", + "stage.generate.executor.native-shape" + ], + "files": [], + "max_tokens": 130000 + }, + "route.generate.quick-generate.structure": { + "description": "Quick Generate plus the structure module on its executor-base trigger.", + "scope": "cumulative", + "include": [ + "route.generate.quick-generate", + "stage.generate.executor.structure" + ], + "files": [], + "max_tokens": 130000 } }, "duplicates": { @@ -1164,15 +1239,6 @@ "max_exact_results": 100, "max_near_results": 100, "accepted": [ - { - "kind": "exact", - "fingerprint": "7c36a9231d14", - "paths": [ - "skills/ppt-master/templates/decks/README.md", - "skills/ppt-master/templates/layouts/README.md" - ], - "reason": "Shared boilerplate between sibling template-kind docs; kept in lockstep on purpose." - }, { "kind": "exact", "fingerprint": "d886e9fcb8dc", @@ -1273,15 +1339,6 @@ ], "reason": "Corporate brand presets share the same consistent icon convention by design." }, - { - "kind": "exact", - "fingerprint": "6a432b0cc1df", - "paths": [ - "skills/ppt-master/templates/decks/README.md", - "skills/ppt-master/templates/layouts/README.md" - ], - "reason": "Sibling Deck and Layout docs keep the shared replication-mode explanation in lockstep." - }, { "kind": "exact", "fingerprint": "286b55cb84d7", @@ -1378,15 +1435,6 @@ "skills/ppt-master/templates/styles/workshop-teaching/templates/design_spec.md" ], "reason": "Style preset specs share the same method-only scope boundary by design." - }, - { - "kind": "exact", - "fingerprint": "272bdc60fa52", - "paths": [ - "skills/ppt-master/workflows/create-template/create-brand.md", - "skills/ppt-master/workflows/create-template/create-style.md" - ], - "reason": "Mutually exclusive child workflows share the same resolved-workspace handoff contract." } ] }, @@ -1892,26 +1940,26 @@ { "path": "skills/ppt-master/references/executor-base.md", "role": "consumer", - "fingerprint": "d937b965024b", + "fingerprint": "696cdad21077", "reason": "This consumer needs the field contract for deterministic execution." }, - { - "path": "skills/ppt-master/references/strategist.md", - "role": "producer", - "fingerprint": "4c133143e2f2", - "reason": "This producer projects the owner field into the planning contract." - }, { "path": "skills/ppt-master/templates/spec_lock_reference.md", "role": "reference", - "fingerprint": "90feed81f021", + "fingerprint": "71622518b209", "reason": "This reference mirrors the owner field grammar or ownership boundary." }, { "path": "skills/ppt-master/workflows/routing.md", "role": "consumer", - "fingerprint": "a287404b8f1e", + "fingerprint": "b3ea6e828373", "reason": "This consumer needs the field contract for deterministic execution." + }, + { + "path": "skills/ppt-master/references/native-data-interface.md", + "role": "consumer", + "fingerprint": "b52102689f16", + "reason": "Table run typography mirrors the deck font contract for native export." } ] }, @@ -1922,13 +1970,13 @@ { "path": "skills/ppt-master/references/image-generator.md", "role": "compatibility", - "fingerprint": "5a6f2f95be38", + "fingerprint": "f2c2cdc3b2a6", "reason": "This site documents a legacy or omission compatibility boundary." }, { "path": "skills/ppt-master/templates/spec_lock_reference.md", "role": "reference", - "fingerprint": "3d0b27f3d979", + "fingerprint": "c62e64b4caa3", "reason": "This reference mirrors the owner field grammar or ownership boundary." } ] @@ -1940,31 +1988,19 @@ { "path": "skills/ppt-master/references/executor-visualization.md", "role": "compatibility", - "fingerprint": "055ab59c533e", + "fingerprint": "84c1c8a6bec5", "reason": "This site documents a legacy or omission compatibility boundary." }, { "path": "skills/ppt-master/references/strategist-template.md", "role": "compatibility", - "fingerprint": "b0f9494f710a", - "reason": "This site documents a legacy or omission compatibility boundary." - }, - { - "path": "skills/ppt-master/references/strategist.md", - "role": "compatibility", - "fingerprint": "ba50ab71bc88", + "fingerprint": "8f83a50b3f54", "reason": "This site documents a legacy or omission compatibility boundary." }, { "path": "skills/ppt-master/templates/spec_lock_reference.md", "role": "compatibility", - "fingerprint": "39d5baf1e189", - "reason": "This site documents a legacy or omission compatibility boundary." - }, - { - "path": "skills/ppt-master/workflows/stages/resume-execute.md", - "role": "compatibility", - "fingerprint": "023cf4d8ecbd", + "fingerprint": "bed2b489ce81", "reason": "This site documents a legacy or omission compatibility boundary." } ] @@ -1973,47 +2009,29 @@ "field": "page_layouts", "owner_fingerprint": "64d28e112785", "projections": [ - { - "path": "skills/ppt-master/references/artifact-ownership.md", - "role": "reference", - "fingerprint": "be5e3881ee0d", - "reason": "This reference mirrors the owner field grammar or ownership boundary." - }, { "path": "skills/ppt-master/references/executor-structured.md", "role": "consumer", - "fingerprint": "f77d8a752b85", + "fingerprint": "dcbb7a6baae7", "reason": "This consumer needs the field contract for deterministic execution." }, - { - "path": "skills/ppt-master/references/pptx-structure-interface.md", - "role": "reference", - "fingerprint": "2db6a34d15d7", - "reason": "This reference mirrors the owner field grammar or ownership boundary." - }, { "path": "skills/ppt-master/templates/spec_lock_reference.md", "role": "reference", - "fingerprint": "e5c9c162d0ff", - "reason": "This reference mirrors the owner field grammar or ownership boundary." - }, - { - "path": "skills/ppt-master/workflows/create-template.md", - "role": "reference", - "fingerprint": "b26d839b24b9", + "fingerprint": "da8a4f2ca816", "reason": "This reference mirrors the owner field grammar or ownership boundary." }, { "path": "skills/ppt-master/workflows/stages/apply-template-workspace.md", "role": "consumer", - "fingerprint": "2a2c42538a76", + "fingerprint": "8490326d972a", "reason": "This stage documents how each Generate runtime consumes the prototype mapping." }, { - "path": "skills/ppt-master/references/shared-standards-core.md", - "role": "reference", - "fingerprint": "846de4145cbe", - "reason": "This reference distinguishes durable Default mappings from Quick active-context use." + "path": "skills/ppt-master/references/strategist-template.md", + "role": "consumer", + "fingerprint": "bffb5ebb6180", + "reason": "Strategist plans page_layouts rows from complete Slide prototypes." } ] }, @@ -2021,46 +2039,22 @@ "field": "page_pptx_layouts", "owner_fingerprint": "f436e6ae4bb8", "projections": [ - { - "path": "skills/ppt-master/references/artifact-ownership.md", - "role": "reference", - "fingerprint": "e05b75f54145", - "reason": "This reference mirrors the owner field grammar or ownership boundary." - }, { "path": "skills/ppt-master/references/executor-structured.md", "role": "consumer", - "fingerprint": "70d500bb46dc", + "fingerprint": "7213f2c7ffe7", "reason": "This consumer needs the field contract for deterministic execution." }, { "path": "skills/ppt-master/references/pptx-structure-interface.md", "role": "reference", - "fingerprint": "3061c1488d1d", + "fingerprint": "9cef05268f4f", "reason": "This reference mirrors the owner field grammar or ownership boundary." }, - { - "path": "skills/ppt-master/references/shared-standards-core.md", - "role": "reference", - "fingerprint": "e27448d68611", - "reason": "This reference mirrors the owner field grammar or ownership boundary." - }, - { - "path": "skills/ppt-master/references/strategist-template.md", - "role": "producer", - "fingerprint": "fb6d05bac6e4", - "reason": "This producer projects the owner field into the planning contract." - }, { "path": "skills/ppt-master/templates/spec_lock_reference.md", "role": "reference", - "fingerprint": "a67117d67b3e", - "reason": "This reference mirrors the owner field grammar or ownership boundary." - }, - { - "path": "skills/ppt-master/workflows/create-template.md", - "role": "reference", - "fingerprint": "40b13ab57503", + "fingerprint": "54bc291612c1", "reason": "This reference mirrors the owner field grammar or ownership boundary." } ] @@ -2072,19 +2066,19 @@ { "path": "skills/ppt-master/references/executor-base.md", "role": "consumer", - "fingerprint": "0d87db8a5c40", + "fingerprint": "b63e7a4de45e", "reason": "This consumer needs the field contract for deterministic execution." }, { "path": "skills/ppt-master/references/strategist.md", "role": "producer", - "fingerprint": "c326f18fa7c3", + "fingerprint": "8121d65895a2", "reason": "This producer projects the owner field into the planning contract." }, { "path": "skills/ppt-master/templates/spec_lock_reference.md", "role": "reference", - "fingerprint": "25aabdb0ee04", + "fingerprint": "9e8775a83943", "reason": "This reference mirrors the owner field grammar or ownership boundary." } ] @@ -2096,25 +2090,25 @@ { "path": "skills/ppt-master/references/executor-visualization.md", "role": "consumer", - "fingerprint": "8b173848afa7", + "fingerprint": "35b3aa28bcad", "reason": "This consumer needs the field contract for deterministic execution." }, { "path": "skills/ppt-master/references/strategist.md", "role": "producer", - "fingerprint": "1c8aa960c9e4", + "fingerprint": "0bf67e7eef14", "reason": "This producer projects the owner field into the planning contract." }, { "path": "skills/ppt-master/templates/spec_lock_reference.md", "role": "reference", - "fingerprint": "f45f26b4d11c", + "fingerprint": "6232ca5f6243", "reason": "This reference mirrors the owner field grammar or ownership boundary." }, { "path": "skills/ppt-master/workflows/profiles/beautify-pptx.md", "role": "producer", - "fingerprint": "308c0a3ef9d9", + "fingerprint": "e1bd978fcc83", "reason": "This producer projects the owner field into the planning contract." } ] @@ -2123,34 +2117,28 @@ "field": "pptx_layouts", "owner_fingerprint": "1037e878eaa1", "projections": [ - { - "path": "skills/ppt-master/references/artifact-ownership.md", - "role": "reference", - "fingerprint": "447cd531facc", - "reason": "This reference mirrors the owner field grammar or ownership boundary." - }, { "path": "skills/ppt-master/references/executor-structured.md", "role": "consumer", - "fingerprint": "5174447ee0a8", + "fingerprint": "dc21169163b7", "reason": "This consumer needs the field contract for deterministic execution." }, { "path": "skills/ppt-master/references/pptx-structure-interface.md", "role": "reference", - "fingerprint": "f1339baac6db", + "fingerprint": "b10eddc66b34", "reason": "This reference mirrors the owner field grammar or ownership boundary." }, { "path": "skills/ppt-master/references/strategist-template.md", "role": "producer", - "fingerprint": "f97c538adf92", + "fingerprint": "3d83dfd41293", "reason": "This producer projects the owner field into the planning contract." }, { "path": "skills/ppt-master/templates/spec_lock_reference.md", "role": "reference", - "fingerprint": "0e01eedc2c4b", + "fingerprint": "7e10bef30c30", "reason": "This reference mirrors the owner field grammar or ownership boundary." } ] @@ -2159,34 +2147,28 @@ "field": "pptx_masters", "owner_fingerprint": "7cbe6ec7056e", "projections": [ - { - "path": "skills/ppt-master/references/artifact-ownership.md", - "role": "reference", - "fingerprint": "7eba0fa766a6", - "reason": "This reference mirrors the owner field grammar or ownership boundary." - }, { "path": "skills/ppt-master/references/executor-structured.md", "role": "consumer", - "fingerprint": "e5dcb49a9a61", + "fingerprint": "7568538df9f4", "reason": "This consumer needs the field contract for deterministic execution." }, { "path": "skills/ppt-master/references/pptx-structure-interface.md", "role": "reference", - "fingerprint": "d35af1a163ac", + "fingerprint": "51fe75ceb256", "reason": "This reference mirrors the owner field grammar or ownership boundary." }, { "path": "skills/ppt-master/references/strategist-template.md", "role": "producer", - "fingerprint": "29a9e58295a9", + "fingerprint": "5eff475d59c9", "reason": "This producer projects the owner field into the planning contract." }, { "path": "skills/ppt-master/templates/spec_lock_reference.md", "role": "reference", - "fingerprint": "89b01fc1b354", + "fingerprint": "77ed36c8efe8", "reason": "This reference mirrors the owner field grammar or ownership boundary." } ] @@ -2198,19 +2180,19 @@ { "path": "skills/ppt-master/references/executor-base.md", "role": "consumer", - "fingerprint": "96e0f7380de0", + "fingerprint": "fd5bce3b80c9", "reason": "This consumer needs the field contract for deterministic execution." }, { "path": "skills/ppt-master/references/strategist.md", "role": "producer", - "fingerprint": "46405fcad30f", + "fingerprint": "0efce3f9be37", "reason": "This producer projects the owner field into the planning contract." }, { "path": "skills/ppt-master/templates/spec_lock_reference.md", "role": "reference", - "fingerprint": "ebbb28e8b7e7", + "fingerprint": "dfda31146866", "reason": "This reference mirrors the owner field grammar or ownership boundary." } ] @@ -2329,6 +2311,26 @@ { "glob": "skills/ppt-master/templates/schemas/*.json", "reason": "Machine-consumed validation schemas; they are not loaded into model runtime context." + }, + { + "glob": "skills/ppt-master/scripts/docs/svg-contract.md", + "reason": "Closed SVG grammar reference for checker/exporter behavior; the always-read core carries the canonical forms, and generation roles open this file only when a check fails." + }, + { + "glob": "skills/ppt-master/scripts/docs/confirm_ui.md", + "reason": "Confirm UI server/schema reference; the Strategist reads references/confirm-surface.md for the surface decision and authoring payloads." + }, + { + "glob": "skills/ppt-master/scripts/docs/svg_editor.md", + "reason": "Browser editor behavior and lifecycle reference; the live-preview stage carries the launch and annotation procedure." + }, + { + "glob": "skills/ppt-master/scripts/docs/narration.md", + "reason": "Narration tool behavior and flag reference; the generate-audio stage carries the procedure and confirmation contract." + }, + { + "glob": "skills/ppt-master/scripts/docs/template-tools.md", + "reason": "Template creation tool behavior reference; create-template.md and template-designer.md carry the procedure and contract." } ] } diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/svg_quality/checker.py b/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/svg_quality/checker.py index 923f68d5..3340c075 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/svg_quality/checker.py +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/svg_quality/checker.py @@ -816,6 +816,8 @@ SPARSE_UNDECLARED_FONT_SIZE_MAX_OCCURRENCES = 2 # Oversampling alone does not imply distortion and is often harmless for small # logos. Warn about downscaling only when the source also has material on-disk # weight, because PPTX embeds the compressed source asset rather than raw pixels. +# 1280px=96 SVG px/in; at 1.5 device px/SVG px on 1080p, 2x becomes ~3x on-screen—visibly soft; smaller is not warned. +IMAGE_UPSCALE_WARN_RATIO = 2.0 IMAGE_DOWNSIZE_WARN_RATIO = 4.0 IMAGE_DOWNSIZE_WARN_MIN_BYTES = 1024 * 1024 @@ -2410,6 +2412,7 @@ class SVGQualityChecker: 'text_elements': text_count, 'images': image_receipt, 'icons': icon_count, + 'effects': self._carrier_effect_receipt(root, parent_by_id), 'geometry': { 'svg_elements': dict(geometry_counts), 'preset_shapes': sum(preset_names.values()), @@ -2420,6 +2423,139 @@ class SVGQualityChecker: 'native_objects': dict(native_objects), } + @classmethod + def _carrier_effect_receipt( + cls, + root: ET.Element, + parent_by_id: Dict[int, ET.Element], + ) -> Dict: + """Count factual visible effect declarations and resolved references.""" + ignored_tags = frozenset({ + 'clippath', + 'defs', + 'marker', + 'mask', + 'pattern', + 'symbol', + }) + emphasis_properties = ( + 'fill', + 'font-weight', + 'font-size', + 'font-style', + 'text-decoration', + 'letter-spacing', + ) + definition_kinds: Dict[str, str] = {} + for element in root.iter(): + definition_id = (element.get('id') or '').strip() + if definition_id: + definition_kinds[definition_id] = _local_name(element).casefold() + + def declared_value( + element: ET.Element, + style_values: Dict[str, str], + name: str, + ) -> str | None: + if name in style_values: + return style_values[name] + return element.get(name) + + def reference_kind(value: str | None) -> str: + match = re.fullmatch( + r'url\(\s*#([^)]+?)\s*\)', + (value or '').strip(), + re.IGNORECASE, + ) + return definition_kinds.get(match.group(1), '') if match else '' + + def has_ignored_ancestor(element: ET.Element) -> bool: + current: ET.Element | None = element + while current is not None and current is not root: + if _local_name(current).casefold() in ignored_tags: + return True + current = parent_by_id.get(id(current)) + return False + + effects = Counter({ + 'inline_emphasis_runs': 0, + 'gradient_uses': 0, + 'filter_uses': 0, + 'text_effects': 0, + }) + gradient_kinds = {'lineargradient', 'radialgradient'} + text_paint_kinds = gradient_kinds | {'pattern'} + + for element in root.iter(): + if ( + element is root + or has_ignored_ancestor(element) + or cls._has_non_visual_ancestor(element, root, parent_by_id) + or cls._is_hidden_element(element, parent_by_id) + or cls._has_zero_opacity(element, parent_by_id) + ): + continue + + style_values = ( + _parse_inline_style(element.get('style')) + if _parse_inline_style is not None + else {} + ) + fill_kind = reference_kind( + declared_value(element, style_values, 'fill') + ) + raw_stroke = declared_value(element, style_values, 'stroke') + stroke_kind = reference_kind(raw_stroke) + effects['gradient_uses'] += sum( + kind in gradient_kinds for kind in (fill_kind, stroke_kind) + ) + + raw_filter = declared_value(element, style_values, 'filter') + if reference_kind(raw_filter) == 'filter': + effects['filter_uses'] += 1 + + tag = _local_name(element).casefold() + if tag == 'tspan': + current = parent_by_id.get(id(element)) + inside_text = False + while current is not None: + if _local_name(current).casefold() == 'text': + inside_text = True + break + current = parent_by_id.get(id(current)) + if ( + inside_text + and not any( + element.get(name) is not None + for name in ('x', 'y', 'dx', 'dy') + ) + and any( + name in style_values or element.get(name) is not None + for name in emphasis_properties + ) + ): + effects['inline_emphasis_runs'] += 1 + + if tag in {'text', 'tspan'}: + has_filter = ( + 'filter' in style_values + or element.get('filter') is not None + ) + has_stroke = bool( + raw_stroke + and raw_stroke.strip() + and raw_stroke.strip().casefold() != 'none' + ) + if ( + fill_kind in text_paint_kinds + or stroke_kind in text_paint_kinds + or has_filter + or has_stroke + ): + effects['text_effects'] += 1 + + return dict(effects) + @staticmethod def _carrier_native_replacement_kind(element: ET.Element) -> str: """Return one native replacement kind without turning bad data into a check.""" @@ -4619,12 +4755,13 @@ class SVGQualityChecker: ) fit_label = 'meet' - if render_scale > 1.0: + if render_scale > IMAGE_UPSCALE_WARN_RATIO: result['warnings'].append( f"Image {href} is {actual_w}x{actual_h} and renders at " f"{render_scale:.2f}x scale in a " f"{int(display_w)}x{int(display_h)} {fit_label} frame " - "— may appear blurry" + f"— about {render_scale * 1.5:.1f}x on a 1080p projector, " + "visibly soft; use a larger source or a smaller frame" ) elif ( render_scale < 1.0 / IMAGE_DOWNSIZE_WARN_RATIO @@ -8638,6 +8775,10 @@ class SVGQualityChecker: 'preset_shapes': 0, 'page_frame_elements': 0, 'marker_uses': 0, + 'inline_emphasis_runs': 0, + 'gradient_uses': 0, + 'filter_uses': 0, + 'text_effects': 0, }) pages_with = Counter({ 'images': 0, @@ -8646,6 +8787,10 @@ class SVGQualityChecker: 'charts': 0, 'tables': 0, 'formulas': 0, + 'inline_emphasis_runs': 0, + 'gradient_uses': 0, + 'filter_uses': 0, + 'text_effects': 0, }) geometry_counts: Counter[str] = Counter() preset_names: Counter[str] = Counter() @@ -8656,6 +8801,7 @@ class SVGQualityChecker: images = receipt['images'] geometry = receipt['geometry'] native = receipt['native_objects'] + effects = receipt.get('effects', {}) totals['text_elements'] += receipt['text_elements'] totals['image_placements'] += images['placements'] totals['icons'] += receipt['icons'] @@ -8679,6 +8825,16 @@ class SVGQualityChecker: pages_with['tables'] += 1 if native.get('formula_block') or native.get('formula_inline'): pages_with['formulas'] += 1 + for name in ( + 'inline_emphasis_runs', + 'gradient_uses', + 'filter_uses', + 'text_effects', + ): + count = effects.get(name, 0) + totals[name] += count + if count > 0: + pages_with[name] += 1 totals['svg_geometry_elements'] = sum(geometry_counts.values()) frame_share_range = ( @@ -8717,6 +8873,17 @@ class SVGQualityChecker: f"page-frame elements {totals['page_frame_elements']} | " f"marker uses {totals['marker_uses']}" ) + pages_with = receipt['pages_with'] + print( + f" Effects: inline emphasis {totals['inline_emphasis_runs']} " + f"(pages {pages_with['inline_emphasis_runs']}) | " + f"gradients {totals['gradient_uses']} " + f"(pages {pages_with['gradient_uses']}) | " + f"filters {totals['filter_uses']} " + f"(pages {pages_with['filter_uses']}) | " + f"text effects {totals['text_effects']} " + f"(pages {pages_with['text_effects']})" + ) print( f" Native objects: charts {native.get('chart', 0)} | " f"tables {native.get('table', 0)} | formulas " diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/tests/test_spec_lock_forbidden.py b/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/tests/test_spec_lock_forbidden.py new file mode 100644 index 00000000..74189756 --- /dev/null +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/tests/test_spec_lock_forbidden.py @@ -0,0 +1,161 @@ +#!/usr/bin/env python3 +"""Focused tests for spec-lock forbidden-row provenance.""" + +from __future__ import annotations + +import sys +import tempfile +import unittest +from pathlib import Path + + +SCRIPTS_DIR = Path(__file__).resolve().parents[1] +if str(SCRIPTS_DIR) not in sys.path: + sys.path.insert(0, str(SCRIPTS_DIR)) + +from project_management.project_specs import ( # noqa: E402 + SCHEMA_DIR, + default_spec_lock_forbidden, + validate_markdown_schema, + validate_project_artifacts, +) + + +_SPEC_LOCK_V1_MARKER = "<!-- ppt-master-schema: spec-lock/v1 -->" + + +def _spec_lock_text( + extra_forbidden: tuple[str, ...] = (), + *, + marker: str | None = _SPEC_LOCK_V1_MARKER, +) -> str: + forbidden = "\n".join( + f"- {row}" + for row in sorted(default_spec_lock_forbidden()) + list(extra_forbidden) + ) + marker_line = f"{marker}\n" if marker is not None else "" + return f"""{marker_line}# Execution Lock + +## canvas +- viewBox: 0 0 1280 720 +- format: PPT 16:9 + +## communication +- primary_language: zh-CN +- audience: Engineers +- objective: Explain the validator contract +- core_message: User prohibitions retain provenance +- consumption_mode: presentation + +## mode +- mode: briefing + +## visual_style +- visual_style: editorial + +## colors +- bg: #FFFFFF + +## typography +- font_family: Arial +- body: 24 +- title: 36 + +## icons +- library: none +- inventory: none + +## page_rhythm +- P01: anchor + +## pptx_structure +- mode: flat +- template_reuse_scope: style + +## forbidden +{forbidden} +""" + + +class SpecLockForbiddenTests(unittest.TestCase): + def _validate( + self, + extra_forbidden: tuple[str, ...] = (), + *, + marker: str | None = _SPEC_LOCK_V1_MARKER, + ) -> list[str]: + with tempfile.TemporaryDirectory() as temp_dir: + project = Path(temp_dir) / "fixture_ppt169_20260830" + project.mkdir() + lock_path = project / "spec_lock.md" + lock_path.write_text( + _spec_lock_text(extra_forbidden, marker=marker), + encoding="utf-8", + ) + return validate_markdown_schema( + lock_path, + SCHEMA_DIR / "spec_lock.schema.json", + ) + + def test_baseline_only_lock_passes(self) -> None: + self.assertEqual(self._validate(), []) + + def test_user_tagged_extra_row_passes(self) -> None: + self.assertEqual( + self._validate(("不要用任何阴影和发光 (user)",)), + [], + ) + + def test_versioned_legacy_baseline_anchors_pass(self) -> None: + rows = ( + "Legacy `<style>` baseline wording", + "Legacy `<foreignObject>` baseline wording", + "Legacy HTML named entities baseline wording", + "Legacy Mixing icon libraries baseline wording", + "Legacy rgba() baseline wording", + "Legacy <g opacity baseline wording", + ) + for row in rows: + with self.subTest(row=row): + self.assertEqual(self._validate((row,)), []) + + def test_versioned_untagged_extra_row_fails(self) -> None: + row = "不要用任何阴影和发光" + expected = ( + "spec_lock.md forbidden: row " + f"{len(default_spec_lock_forbidden()) + 1} is not a baseline rule " + f"and lacks the (user) tag: {row}" + ) + + self.assertEqual( + self._validate((row,), marker=_SPEC_LOCK_V1_MARKER), + [expected], + ) + + def test_legacy_untagged_extra_row_has_no_forbidden_error(self) -> None: + row = "不要用任何阴影和发光" + with tempfile.TemporaryDirectory() as temp_dir: + project = Path(temp_dir) / "fixture_ppt169_20260830" + project.mkdir() + (project / "spec_lock.md").write_text( + _spec_lock_text((row,), marker=None), + encoding="utf-8", + ) + + errors, warnings = validate_project_artifacts( + project, + project_info={"format": "ppt169"}, + include_design=False, + ) + + self.assertFalse( + any(error.startswith("spec_lock.md forbidden:") for error in errors) + ) + self.assertTrue( + any("legacy artifact has no ppt-master-schema marker" in warning + for warning in warnings) + ) + + +if __name__ == "__main__": + unittest.main() diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/text_measure.py b/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/text_measure.py index d3f803f4..0fcd1bb9 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/text_measure.py +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/text_measure.py @@ -1,12 +1,13 @@ #!/usr/bin/env python3 """PPT Master - Text Measurement -Measure, wrap, or calculate bounds with the SVG checker's width estimator. +Measure, wrap, calibrate, or calculate bounds with the SVG checker's width estimator. Usage: - python3 scripts/text_measure.py <measure|wrap|box> [options] + python3 scripts/text_measure.py <measure|wrap|box|calibrate> [options] Examples: python3 scripts/text_measure.py measure "Editable text" --size 22 + python3 scripts/text_measure.py calibrate projects/example --outline Dependencies: Standard library and PPT Master sibling modules """ @@ -17,8 +18,10 @@ import argparse import html import json import math +import re import sys import unicodedata +from datetime import datetime, timezone from functools import partial from pathlib import Path @@ -28,6 +31,7 @@ if str(_SCRIPTS_DIR) not in sys.path: sys.path.insert(0, str(_SCRIPTS_DIR)) from console_encoding import configure_utf8_stdio # noqa: E402 +from project_specs import parse_markdown_artifact, parse_spec_lock # noqa: E402 from svg_to_pptx.drawingml.elements import estimate_single_line_text_frame_width # noqa: E402 from svg_to_pptx.drawingml.utils import split_project_text_clusters # noqa: E402 @@ -37,6 +41,21 @@ _OPENING_PUNCTUATION = frozenset('([{(《「『【“‘') _PREFERRED_BREAK_PUNCTUATION = frozenset(',。;:') _LATIN_TOKEN_CONNECTORS = frozenset("'’._:/+%@#-") _WEIGHTS = ('normal', 'bold', '100', '200', '300', '400', '500', '600', '700', '800', '900') +_CALIBRATION_CJK_SAMPLE = '天地玄黄宇宙洪荒日月盈昃辰宿列张寒来暑往' +_CALIBRATION_LATIN_SAMPLE = 'Clear Slides Make Big Ideas Easy to See.' +_CORE_CALIBRATION_ROLES = ('body', 'title', 'subtitle', 'annotation') +_SLIDE_HEADING_RE = re.compile( + r'^#{3,6}[ \t]+Slide[ \t]+([0-9]+|NN)\b.*$', + flags=re.IGNORECASE | re.MULTILINE, +) +_OUTLINE_FIELD_RE = re.compile( + r'^(?P<indent>[ \t]*)-[ \t]+(?:\*\*)?' + r'(?P<label>Title|Core message|Content)(?:\*\*)?[ \t]*:[ \t]*(?P<value>.*)$', + flags=re.IGNORECASE, +) +_OUTLINE_DATA_LINE_RE = re.compile( + r'^(?P<indent>[ \t]*)-[ \t]+(?:\*\*)?[^:\n*]+?(?:\*\*)?[ \t]*:', +) def _bounded_float(value: str, *, minimum: float | None = None, strict: bool = False) -> float: @@ -245,6 +264,290 @@ def text_box( return dict(x=left, y=top, width=width, height=bottom - top, top=top, bottom=bottom) +def _role_argument(value: str) -> tuple[str, str, float]: + try: + name_and_family, raw_size = value.rsplit(':', 1) + name, family = name_and_family.split(':', 1) + except ValueError as exc: + raise argparse.ArgumentTypeError('expected NAME:FAMILY:SIZE') from exc + name, family = name.strip().casefold(), family.strip() + if not name or not family: + raise argparse.ArgumentTypeError('expected non-empty NAME and FAMILY') + try: + size = _positive_float(raw_size) + except (argparse.ArgumentTypeError, ValueError) as exc: + raise argparse.ArgumentTypeError('SIZE must be a positive finite number') from exc + return name, family, size + + +def _ordered_roles(roles: dict[str, tuple[str, float]]) -> list[tuple[str, str, float]]: + names = [name for name in _CORE_CALIBRATION_ROLES if name in roles] + names.extend(sorted(set(roles) - set(names))) + return [(name, *roles[name]) for name in names] + + +def _roles_from_spec_lock(lock_path: Path) -> dict[str, tuple[str, float]]: + lock = parse_spec_lock(lock_path, report_duplicate_fields=True) + typography = next( + ( + fields + for heading, fields in lock.items() + if heading.strip().casefold() == 'typography' + ), + {}, + ) + rows = { + str(key).strip().casefold(): str(value).strip() + for key, value in typography.items() + } + roles: dict[str, tuple[str, float]] = {} + for role, raw_size in rows.items(): + if role == 'font_family' or role.endswith('_family'): + continue + try: + size = _positive_float(raw_size) + except (argparse.ArgumentTypeError, ValueError) as exc: + raise ValueError( + f'spec_lock.md typography role {role!r} has invalid size {raw_size!r}' + ) from exc + family = rows.get(f'{role}_family', '') + if not family: + fallback = 'title_family' if 'title' in role else 'body_family' + family = rows.get(fallback, '') or rows.get('font_family', '') + if not family: + raise ValueError( + f'spec_lock.md typography role {role!r} has no resolvable font family' + ) + roles[role] = (family, size) + return roles + + +def _clean_planned_line(raw: str) -> str: + text = re.sub(r'^(?:[-*+]|\d+[.)])[ \t]+', '', raw.strip()) + if not text or re.fullmatch(r'[|:\- \t]+', text): + return '' + text = re.sub(r'!\[([^]]*)\]\([^)]*\)', r'\1', text) + text = re.sub(r'\[([^]]+)\]\([^)]*\)', r'\1', text) + text = text.replace('**', '').replace('__', '').replace('`', '') + return ' '.join(text.split()) + + +def _slide_id(token: str) -> str: + return 'PNN' if token.upper() == 'NN' else f'P{int(token):02d}' + + +def _outline_candidates( + design_path: Path, + role_names: set[str], +) -> dict[str, list[tuple[str, str]]]: + candidates = {name: [] for name in role_names} + if not design_path.is_file(): + return candidates + sections = parse_markdown_artifact(design_path) + outline = next( + ( + str(section.get('body', '')) + for section in sections + if re.match( + r'^IX\.[ \t]+Content Outline\b', + str(section.get('heading', '')), + flags=re.IGNORECASE, + ) + ), + '', + ) + slide_matches = list(_SLIDE_HEADING_RE.finditer(outline)) + for slide_index, slide_match in enumerate(slide_matches): + block_end = ( + slide_matches[slide_index + 1].start() + if slide_index + 1 < len(slide_matches) + else len(outline) + ) + slide = _slide_id(slide_match.group(1)) + lines = outline[slide_match.end():block_end].splitlines() + field_matches = [match for line in lines if (match := _OUTLINE_FIELD_RE.match(line))] + if not field_matches: + continue + base_indent = min(len(match.group('indent').expandtabs()) for match in field_matches) + line_index = 0 + while line_index < len(lines): + field_match = _OUTLINE_FIELD_RE.match(lines[line_index]) + if ( + field_match is None + or len(field_match.group('indent').expandtabs()) != base_indent + ): + line_index += 1 + continue + label = field_match.group('label').casefold() + value = _clean_planned_line(field_match.group('value')) + if label == 'title': + if value and 'title' in candidates: + candidates['title'].append((slide, value)) + line_index += 1 + continue + if label == 'core message': + role = 'subtitle' if 'subtitle' in candidates else 'body' + if value and role in candidates: + candidates[role].append((slide, value)) + line_index += 1 + continue + + content_lines = [value] if value else [] + next_index = line_index + 1 + while next_index < len(lines): + next_field = _OUTLINE_DATA_LINE_RE.match(lines[next_index]) + if ( + next_field is not None + and len(next_field.group('indent').expandtabs()) <= base_indent + ): + break + planned_line = _clean_planned_line(lines[next_index]) + if planned_line: + content_lines.append(planned_line) + next_index += 1 + if 'body' in candidates: + candidates['body'].extend((slide, text) for text in content_lines) + line_index = next_index + return candidates + + +def _truncate_planned_line(text: str, limit: int = 40) -> str: + clusters = split_project_text_clusters(text) + return text if len(clusters) <= limit else ''.join(clusters[:limit - 1]) + '…' + + +def _longest_planned_lines( + project_path: Path, + roles: list[tuple[str, str, float]], +) -> dict[str, dict[str, object] | None]: + candidates = _outline_candidates( + project_path / 'design_spec.md', + {name for name, _family, _size in roles}, + ) + longest: dict[str, dict[str, object] | None] = {} + for name, family, size in roles: + best: tuple[float, str, str] | None = None + for slide, planned_line in candidates[name]: + width = measure_text(planned_line, size=size, family=family) + if best is None or width > best[0]: + best = (width, slide, planned_line) + longest[name] = None if best is None else { + 'px': round(best[0], 1), + 'slide': best[1], + 'text': _truncate_planned_line(best[2]), + } + return longest + + +def _calibration_payload( + roles: list[tuple[str, str, float]], + *, + project_path: Path, + source: str, + include_outline: bool, +) -> dict[str, object]: + longest = ( + _longest_planned_lines(project_path, roles) + if include_outline + else {name: None for name, _family, _size in roles} + ) + cjk_length = len(split_project_text_clusters(_CALIBRATION_CJK_SAMPLE)) + latin_length = len(split_project_text_clusters(_CALIBRATION_LATIN_SAMPLE)) + role_rows = {} + for name, family, size in roles: + cjk_width = measure_text(_CALIBRATION_CJK_SAMPLE, size=size, family=family) + latin_width = measure_text(_CALIBRATION_LATIN_SAMPLE, size=size, family=family) + role_rows[name] = { + 'family': family, + 'size': size, + 'cjk_chars_per_100px': round(100.0 * cjk_length / cjk_width, 1), + 'latin_chars_per_100px': round(100.0 * latin_length / latin_width, 1), + 'longest_planned_line': longest[name], + } + return { + 'roles': role_rows, + 'source': source, + 'generated_at': datetime.now(timezone.utc) + .isoformat(timespec='seconds') + .replace('+00:00', 'Z'), + } + + +def _render_calibration_table(payload: dict[str, object], *, include_outline: bool) -> str: + role_rows = payload['roles'] + assert isinstance(role_rows, dict) + headers = ['role', 'family', 'size', 'CJK ≈chars/100px', 'Latin ≈chars/100px'] + if include_outline: + headers.append('longest planned line (px, slide, text)') + lines = [ + f'[CALIBRATION] roles: {len(role_rows)} | source: {payload["source"]}', + ' | '.join(headers), + ' | '.join('---' for _header in headers), + ] + for name, raw_row in role_rows.items(): + assert isinstance(raw_row, dict) + row = [ + name, + str(raw_row['family']), + _format_number(float(raw_row['size'])), + f'{raw_row["cjk_chars_per_100px"]:.1f}', + f'{raw_row["latin_chars_per_100px"]:.1f}', + ] + if include_outline: + planned = raw_row['longest_planned_line'] + row.append( + '-' + if planned is None + else f'{planned["px"]:.1f}px, {planned["slide"]}, {planned["text"]}' + ) + lines.append(' | '.join(row)) + return '\n'.join(lines) + '\n' + + +def _run_calibrate(args: argparse.Namespace) -> int: + project_path = args.project_path.resolve() + if not project_path.is_dir(): + print( + f'Calibration failed: project path is not a directory: {project_path}', + file=sys.stderr, + ) + return 2 + lock_path = project_path / 'spec_lock.md' + if not lock_path.is_file() and not args.role: + print( + 'Calibration requires spec_lock.md or at least one --role NAME:FAMILY:SIZE entry.', + file=sys.stderr, + ) + return 2 + try: + roles = _roles_from_spec_lock(lock_path) if lock_path.is_file() else {} + for name, family, size in args.role: + roles[name] = (family, size) + ordered_roles = _ordered_roles(roles) + if not ordered_roles: + raise ValueError('no typography size roles were found') + source = 'spec_lock.md' if lock_path.is_file() else '--role' + payload = _calibration_payload( + ordered_roles, + project_path=project_path, + source=source, + include_outline=args.outline, + ) + output_path = project_path / 'validation' / 'text_calibration.json' + output_path.parent.mkdir(parents=True, exist_ok=True) + rendered_json = json.dumps(payload, ensure_ascii=False, indent=2) + output_path.write_text(rendered_json + '\n', encoding='utf-8') + except (OSError, ValueError) as exc: + message = ' '.join(str(exc).splitlines()) + print(f'Calibration failed: {message}', file=sys.stderr) + return 2 + if args.json: + print(rendered_json) + else: + sys.stdout.write(_render_calibration_table(payload, include_outline=args.outline)) + return 0 + + def _add_style_arguments(parser: argparse.ArgumentParser) -> None: parser.add_argument('--size', type=_positive_float, required=True) parser.add_argument('--family', default='Calibri') @@ -258,7 +561,9 @@ def _add_style_arguments(parser: argparse.ArgumentParser) -> None: def build_parser() -> argparse.ArgumentParser: - parser = argparse.ArgumentParser(description='Measure and wrap SVG authoring text.') + parser = argparse.ArgumentParser( + description='Measure, wrap, and calibrate SVG authoring text.' + ) subparsers = parser.add_subparsers(dest='command', required=True) measure = subparsers.add_parser('measure', help='Measure single-line text.') @@ -281,6 +586,12 @@ def build_parser() -> argparse.ArgumentParser: box.add_argument('--dy', type=_positive_float) box.add_argument('--width', type=_nonnegative_float) box.add_argument('--anchor', choices=('start', 'middle', 'end'), default='start') + + calibrate = subparsers.add_parser('calibrate', help='Calibrate project typography roles.') + calibrate.add_argument('project_path', type=Path) + calibrate.add_argument('--outline', action='store_true') + calibrate.add_argument('--role', action='append', type=_role_argument, default=[]) + calibrate.add_argument('--json', action='store_true') for command in (measure, wrap, box): command.add_argument('--json', action='store_true') _add_style_arguments(command) @@ -291,6 +602,8 @@ def main(argv: list[str] | None = None) -> int: configure_utf8_stdio() parser = build_parser() args = parser.parse_args(argv) + if args.command == 'calibrate': + return _run_calibrate(args) style = dict( size=args.size, family=args.family, diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/README.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/README.md index ada3fd66..e5c54bd3 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/README.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/README.md @@ -2,164 +2,55 @@ ## Reusable template kinds -Brand, Style, Layout, and Deck are independent template kinds, not stages of one -inheritance hierarchy. +Brand, Style, Layout, and Deck are independent kinds, not stages of one inheritance hierarchy — each owns a different segment. | Kind | Owns | Does not own | Discovery index | |---|---|---|---| | [`brands/`](./brands/) | Identity: color, typography, logo, voice, icon style | Page structure or SVG roster | [`brands_index.json`](./brands/brands_index.json) | -| [`styles/`](./styles/) | Direction/method: reusable communication method, visual language, composition rhythm, and information-expression defaults | Official brand identity, current-project application, page structure, or SVG roster | [`styles_index.json`](./styles/styles_index.json) | -| [`layouts/`](./layouts/) | Brand-neutral structure: canvas, Master/Layout graph, page types, slots, SVG roster | Brand identity or a recurring communication application | [`layouts_index.json`](./layouts/layouts_index.json) | -| [`decks/`](./decks/) | A recurring presentation family: application contract + integrated identity + structure | — | [`decks_index.json`](./decks/decks_index.json) | +| [`styles/`](./styles/) | Direction/method: communication method, visual language, composition rhythm, information-expression defaults | Official identity, current-project application, structure, or roster | [`styles_index.json`](./styles/styles_index.json) | +| [`layouts/`](./layouts/) | Brand-neutral structure: canvas, Master/Layout graph, page types, slots, SVG roster | Identity or a recurring application | [`layouts_index.json`](./layouts/layouts_index.json) | +| [`decks/`](./decks/) | A recurring presentation family: application context + integrated identity + structure | — | [`decks_index.json`](./decks/decks_index.json) | -A brand is not “a layout minus its pages”, and a Style is not a roster-free -Deck: each owns a different segment. Use a brand for identity with free page -composition, a Style for reusable direction/method without identity truth or -page prototypes, a layout for brand-neutral structure whose identity and -communication purpose remain downstream decisions, and a deck for a recurring -presentation family with an explicit application contract. +PowerPoint package objects are compilation targets, not kinds: Theme values and identity assets project from resolved identity rules (Brand, Deck, or the current project); Layout rules project into Master/Layout/Placeholder topology, semantic text roles, and spatial behavior; Deck combines both with descriptive application context and actual prototypes; Style guides method and expression without creating a package object or overriding resolved identity. Downstream planning decides which prototypes and content to use and records the exporter values, so one compiled Master may hold both structural geometry and brand visuals under separately owned rules. -PowerPoint package objects are compilation targets, not additional template -kinds. Theme values and identity assets are projected from resolved identity -rules supplied by Brand, Deck, or the current project; Layout rules project -into Master/Layout/Placeholder topology, semantic text roles, and -spatial behavior; Deck combines both with descriptive recurring-application -context and actual prototype examples. Style rules guide communication method, -visual language, composition, and information expression; they do not create a -PowerPoint package object or override resolved Brand/Deck identity. Downstream AI planning decides which -prototypes and content to use, then records the required exporter values. -A compiled Slide Master may therefore contain both -structural geometry and brand visuals even though their source rules remain -separately owned. - -New workspaces always enter [`Create Template`](../workflows/create-template.md), -which keeps the fixed route name and dispatches exactly one child workflow: -[`Create Brand`](../workflows/create-template/create-brand.md), -[`Create Style`](../workflows/create-template/create-style.md), -[`Create Layout`](../workflows/create-template/create-layout.md), or -[`Create Deck`](../workflows/create-template/create-deck.md). - -The four indexes are the complete library-discovery source for Default -[`generate-pptx`](../workflows/generate-pptx.md) Stage-1 template selection. -Step 3 prepares candidate input without interaction or reading template -content. The Stage-1 page confirms the communication contract together with an -explicit free-design/template choice; only template mode expands these indexes. -Exact roots supplied for the run or handed off by Create Template appear as -specified candidates. Ordinary requests default to free design; explicit -template intent or any supplied root defaults to template mode. Exactly one root -may be preselected, while multiple roots remain unselected candidates. The user -can always switch modes. The page accepts one registered choice per kind plus -one supplied-root choice, but the complete selection contains at most one -contribution per kind. All four kinds may combine; Layout owns structure when -both Layout and Deck are present. A supplied multi-kind root is atomic. A registered exact root is `library`; any other exact root is -`explicit`. After that combined confirmation, -[`apply-template-workspace`](../workflows/stages/apply-template-workspace.md) -validates and maps every distinct selected root once, preserving each -contribution as `design_spec.<kind>.<id>.md` before Stage 2 starts. Template-aware reading begins in final Stage 2 from -that project-local copy. Quick skips the page, applies supplied exact roots, and -otherwise uses free design. +New workspaces enter [`Create Template`](../workflows/create-template.md), which dispatches exactly one child ([`Create Brand`](../workflows/create-template/create-brand.md), [`Create Style`](../workflows/create-template/create-style.md), [`Create Layout`](../workflows/create-template/create-layout.md), [`Create Deck`](../workflows/create-template/create-deck.md)). Selection, mode defaults, preselection, `library` / `explicit` labels, cardinality, and installation are owned by [`routing.md`](../workflows/routing.md) §7 and [`apply-template-workspace`](../workflows/stages/apply-template-workspace.md): the four indexes are the complete library discovery source for Default Stage 1, every selected root is installed as `design_spec.<kind>.<id>.md` before Stage 2, and Quick applies supplied exact roots directly. ## Orthogonal contracts | Axis | Values | Meaning | |---|---|---| -| Template kind | `brand` / `style` / `layout` / `deck` | Which reusable contract the package owns: identity, direction/method, brand-neutral structure, or a complete recurring application | -| Selection source | `library` / `explicit` | Step-3 discovery provenance only: exact index-derived root or exact unregistered root; it does not change template semantics | -| Internal creation strategy | `standard` / `fidelity` / `mirror` | AI-derived Create Layout/Create Deck implementation: newly author a compact or broad roster, or materialize validated source-package facts into a new workspace; persisted for tools, never presented as a required user choice | -| Internal application plan | `template_reuse_scope` plus optional `template_adherence` | Strategist derives literal, structural, or style-only use and any strict/adaptive exporter behavior after inspecting the installed template and current content | -| PPTX structure | `flat` / `structured` | Derived application plans that use template structure compile declared Masters and Layouts; Style-only, style-scope, brand-only, and free design remain Slide-local. A Style installed alongside Layout/Deck does not change the non-Style structure plan. | +| Template kind | `brand` / `style` / `layout` / `deck` | Which reusable contract the package owns | +| Selection source | `library` / `explicit` | Discovery provenance only (index-derived root vs exact unregistered root); no semantic effect | +| Internal creation strategy | `standard` / `fidelity` / `mirror` | AI-derived Create Layout/Deck implementation (author a compact or broad roster, or materialize validated source facts); persisted for tools, never a user choice | +| Internal application plan | `template_reuse_scope` plus optional `template_adherence` | Strategist-derived literal, structural, or style-only use and strict/adaptive exporter behavior | +| PPTX structure | `flat` / `structured` | Plans using template structure compile declared Masters and Layouts; Style-only, style-scope, brand-only, and free design stay Slide-local; a Style beside Layout/Deck never changes the structure plan | -These axes must not be used as synonyms or exposed as a user mode matrix. In -particular, a mirror-created deck is still an ordinary reusable `deck` package -after creation; it does not force future presentations to keep the source page -count or order. +Never use these axes as synonyms or expose them as a mode matrix; a mirror-created deck is an ordinary reusable `deck` and forces no future page count or order. ## Workspace contract -Every package uses the same portable root under either this library or an -initialized project: - ```text <template_workspace>/ -├── templates/ # the Design Spec (naming below); optional Layout/Deck SVGs and native_payloads.json.gz store -├── images/ # optional bitmaps -├── icons/ -│ └── imported/ # optional imported vectors, one canonical copy -└── exports/ # optional review evidence; never a template input +├── templates/ # the Design Spec (naming below); optional Layout/Deck SVGs and native_payloads.json.gz +├── images/ # optional bitmaps; SVG href ../images/<name> +├── icons/imported/ # optional imported vectors, one canonical copy; data-icon="imported/<name>" +└── exports/ # optional review evidence; never a template input ``` -**Hard rule — the container disambiguates, the filename carries the rest**: one -schema serves both layers. A library root keeps `templates/design_spec.md`, since -`<kind_dir>/<template_id>/` already names its kind and id. A project root shares -one flat `templates/`, so it keeps one `design_spec.<kind>.<id>.md` per kind; -filename kind/id MUST equal frontmatter `kind`/`<kind>_id`. The shapes never -mix. One `templates/` -holds one active SVG roster: Layout when present, otherwise Deck. Both specs may -coexist because Layout overrides only Deck structure. Either shape is a -workspace root, and selecting it takes every kind it exposes. - -Empty optional directories are omitted. Template SVGs reference bitmaps through -`../images/<name>` and imported vectors through `data-icon="imported/<name>"`. -Style contributes only its own Design Spec and no asset or review payload; -sibling scaffolding and other kinds' files are not Style input. -Every kind ignores `exports/`. The conditional -[`apply-template-workspace`](../workflows/stages/apply-template-workspace.md) -stage owns the rest: when installation runs, which roots each kind consumes, -legacy-flat readability, and the boundary that every later consumer reads the -installed project-local files rather than the original root. +**Hard rule — the container disambiguates, the filename carries the rest**: a library root keeps `templates/design_spec.md` (its `<kind_dir>/<template_id>/` names kind and id); a project root shares one flat `templates/` and keeps one `design_spec.<kind>.<id>.md` per kind, with filename kind/id equal to frontmatter `kind` / `<kind>_id`; the shapes never mix. One `templates/` holds one active roster — Layout when present, otherwise Deck — while both specs may coexist because Layout overrides only Deck structure. Either shape is a workspace root, and selecting it takes every kind it exposes. Empty optional directories are omitted; Style contributes only its spec; every kind ignores `exports/`. ## Design specification references -[`design_spec_reference.md`](./design_spec_reference.md) and -[`spec_lock_reference.md`](./spec_lock_reference.md) own normal whole-document -authoring; their schemas own machine validation. Files under `scaffolds/` are -optional overwrite-safe CLI conveniences, not Generate-route starting artifacts. -Reusable template `design_spec.md` files are -deliberately smaller: they contain portable metadata and only the identity, -direction/method, structure, or application rules owned by that package. General SVG rules live -in [`shared-standards-core.md`](../references/shared-standards-core.md), with -effects and PowerPoint interfaces loaded only when triggered. +[`design_spec_reference.md`](./design_spec_reference.md) and [`spec_lock_reference.md`](./spec_lock_reference.md) own project-level authoring; their schemas own validation; `scaffolds/` files are optional CLI conveniences. Template specs are deliberately smaller — portable metadata plus only the rules the package owns; general SVG rules live in [`shared-standards-core.md`](../references/shared-standards-core.md). ## Visualization Templates -Page-local Shape-first references are catalog families, not reusable template -kinds: - -| Family | Owns | Planning map | Machine index | -|---|---|---|---| -| Chart | Value-driven geometry (33) | [`chart-vocabulary.md`](./charts/chart-vocabulary.md) | [`charts_index.json`](./charts/charts_index.json) | -| Table | Row × column fact grid (6) | [`table-vocabulary.md`](./tables/table-vocabulary.md) | [`tables_index.json`](./tables/tables_index.json) | - -[`VISUALIZATION_TEMPLATE_AUTHORING.md`](./VISUALIZATION_TEMPLATE_AUTHORING.md) -is the shared authoring contract. Each machine index owns family membership; -the Chart and Table vocabularies are their complete objective planning -projections. - -Qualitative Structure is a Slide-local Executor method rather than a catalog: -Default and Quick both derive its relationship model and compose shapes for the -current page. Only Layout and Deck workspaces own reusable Master/Layout, page -types, slots, and placeholders. When both are present, Layout supplies the -active SVG roster and overrides only Deck's structure segment. +Page-local Shape-first catalog families, not kinds: Chart — value-driven geometry (33), planning map [`chart-vocabulary.md`](./charts/chart-vocabulary.md), index [`charts_index.json`](./charts/charts_index.json); Table — row × column fact grid (6), [`table-vocabulary.md`](./tables/table-vocabulary.md), [`tables_index.json`](./tables/tables_index.json). [`VISUALIZATION_TEMPLATE_AUTHORING.md`](./VISUALIZATION_TEMPLATE_AUTHORING.md) is the maintainer authoring contract. Qualitative Structure is a Slide-local Executor method, not a catalog; only Layout and Deck own reusable Master/Layout, page types, slots, and placeholders. ## Icon Library -The `icons/` directory contains 12,027 vector icons across five libraries: - -| Library | Style | Count | -|---------|-------|-------| -| `chunk-filled` | fill / compact, chunky 16px silhouettes | 641 | -| `tabler-filled` | fill / bezier-curve forms | 1,055 | -| `tabler-outline` | stroke / line | 5,138 | -| `phosphor-duotone` | duotone / single color + 0.2 opacity backplate | 1,518 | -| `simple-icons` | brand logos (company / product marks) | 3,675 | - -- **Usage & style rules**: [icons/README.md](./icons/README.md) -- **Versions, licenses & attribution**: [icons/THIRD_PARTY_NOTICES.md](./icons/THIRD_PARTY_NOTICES.md) -- **Search icons**: `rg --files skills/ppt-master/templates/icons/<library>/ | rg <keyword>` +[`icons/`](./icons/) holds 12,027 vectors across five libraries (`chunk-filled` 641, `tabler-filled` 1,055, `tabler-outline` 5,138, `phosphor-duotone` 1,518, `simple-icons` 3,675 brand logos); usage and style rules in [icons/README.md](./icons/README.md), licenses in [icons/THIRD_PARTY_NOTICES.md](./icons/THIRD_PARTY_NOTICES.md). ## Sound Library -[`sounds/`](./sounds/) is a post-motion selection resource, not a template or -Strategist resource. Its complete -[cue vocabulary](./sounds/sound-vocabulary.md) is read only after a concrete -auditory job exists; sync selected cues only. See [usage](./sounds/README.md). +[`sounds/`](./sounds/) is a post-motion selection resource, not a template or Strategist resource: read its [cue vocabulary](./sounds/sound-vocabulary.md) only after a concrete auditory job exists and sync selected cues only ([usage](./sounds/README.md)). diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/brands/README.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/brands/README.md index 00029d84..9e76f86f 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/brands/README.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/brands/README.md @@ -1,65 +1,25 @@ # Brand Identity Presets -This directory holds **brand-only templates**: identity bundles (color / typography / logo / voice / icon style) without an SVG page roster. Strategist locks the brand's identity segment as truth; Executor designs pages freely under those constraints. - -Brand is one of four template kinds in the library — alongside -[`styles/`](../styles/) (direction/method defaults), [`layouts/`](../layouts/) -(brand-neutral structure), and [`decks/`](../decks/) (a recurring application -with integrated identity and structure). The shared kind and workspace model -lives in the parent [`README.md`](../README.md). +**Brand-only templates**: identity bundles (color / typography / logo / voice / icon style) without an SVG roster. Strategist locks the identity segment as truth; Executor composes pages freely under it. Brand is one of four kinds alongside [`styles/`](../styles/), [`layouts/`](../layouts/), and [`decks/`](../decks/); the shared kind and workspace model lives in the parent [`README.md`](../README.md). ## How brands are consumed -Brand application follows the parent README's Default Stage-1 -[`generate-pptx`](../../workflows/generate-pptx.md) template-choice contract. -Its Brand choices come only from `brands_index.json`; no -directory scan or bare-name match is allowed. A supplied exact root appears in -the same selector, defaults Stage 1 to template mode, and preselects that -specific candidate only when it is the sole supplied root. -Registered exact roots are `library`; other exact roots remain `explicit`. The conditional -[`apply-template-workspace`](../../workflows/stages/apply-template-workspace.md) -stage owns path normalization, portable-root installation, per-workspace spec naming, -selection-conflict rejection, and provenance after Stage 1 and before Stage 2. Template-aware -reading begins in final Stage 2 from the installed project-local copy. This file owns -only the Brand schema. Quick applies a supplied exact Brand root directly and -otherwise uses free design. +Selection follows the parent contract: Brand choices come only from `brands_index.json` (no directory scan or bare-name match); a supplied exact root joins the same selector, defaults Stage 1 to template mode, and is preselected only when it is the sole root; [`apply-template-workspace`](../../workflows/stages/apply-template-workspace.md) installs it before Stage 2; Quick applies a supplied exact root directly. This file owns only the Brand schema. ## Creating a new brand -Enter the fixed Create Template route, which dispatches the Create Brand child workflow: +Enter [`create-template.md`](../../workflows/create-template.md), which dispatches `kind: brand` to [`create-brand.md`](../../workflows/create-template/create-brand.md), from a brand asset (logo / site / branded PPTX / PDF), a verbal spec, or an explicitly requested empty skeleton. -``` -Read skills/ppt-master/workflows/create-template.md, which dispatches `kind: brand` to skills/ppt-master/workflows/create-template/create-brand.md -``` - -Three input paths are supported: brand asset (logo / brand site URL / branded PPTX / brand PDF), verbal spec dictated in chat, or empty skeleton for the user to fill in later. - -## Workspace structure - -Every brand uses the same workspace routing as layout and deck templates. Brand identity remains roster-free; omit empty optional directories instead of adding placeholder files. - -``` +```text templates/brands/<brand_id>/ -├── templates/ -│ └── design_spec.md # required — brand identity spec -├── images/ # optional — logos and visual assets -│ ├── logo.<ext> # optional — primary logo -│ └── <brand>_wordmark.svg # optional — alternate lockups and visual assets +├── templates/design_spec.md # required — identity spec with YAML frontmatter `kind: brand` +├── images/ # optional — logo.<ext>, alternate lockups, visual assets ├── icons/ # optional — branded icon overrides -└── exports/ # normally absent; real local derived artifacts only; Git-ignored +└── exports/ # normally absent; Git-ignored derived artifacts only ``` -Logo filenames are descriptive, not contractual — `templates/design_spec.md` §IV lists exact `../images/...` paths and usage contexts. Single-lockup brands typically ship one logo; dual-lockup brands ship separately named files. - -`templates/design_spec.md` carries a YAML frontmatter block with `kind: brand` and is the single source of truth for the brand identity. The six required sections are: I Brand Overview / II Color Scheme / III Typography / IV Logo / V Voice & Tone / VI Icon Style. +Logo filenames are descriptive; `design_spec.md` §IV lists the exact `../images/...` paths and usage. The six required sections are I Brand Overview / II Color Scheme / III Typography / IV Logo / V Voice & Tone / VI Icon Style; omit empty optional directories. ## Discovery index -[brands_index.json](./brands_index.json) is a slim machine-readable map (`brand_id → { summary, primary_color }`). Refresh it with `register_template.py --kind brand <brand_id>` after a brand is created or edited. Registration rejects incomplete frontmatter, mismatched IDs, page SVGs, missing required identity sections, invalid or inconsistent colors/provenance, and broken workspace-local asset references. - -The Default Stage-1 template controls read this index as their complete -registered-brand catalog; chat discovery reads the same file and returns exact -workspace roots. Choosing an entry and submitting Stage 1 runs installation. -Exact directory -paths and validated Create Template handoffs remain supported, while a bare ID -never resolves implicitly. +[brands_index.json](./brands_index.json) maps `brand_id → { summary, primary_color }`; refresh with `register_template.py <brand_id> --kind brand`, which rejects incomplete frontmatter, mismatched IDs, page SVGs, missing identity sections, invalid colors/provenance, and broken asset references. Stage-1 controls and chat discovery read this index only; a bare ID never resolves implicitly. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/README.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/README.md index 44069bf3..c16d0af5 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/README.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/README.md @@ -1,62 +1,23 @@ # Deck Templates -**Deck = a reusable solution for a recurring presentation family.** It owns an -application context together with presentation identity and reusable page -structure. The application context states which communication situations the -template serves, which audience outcomes it supports, and which narrative/page -roles commonly appear. It describes the resource; it does not decide which -pages or visible content a future presentation must retain. -A deck template is not a finished content deck, and `kind: deck` does not mean -“mirror the source PPT”. Its construction mode decides whether the system is -newly authored or materialized from validated source facts. +**Deck = a reusable solution for a recurring presentation family**: descriptive application context (which situations it serves, which outcomes it supports, which narrative/page roles commonly appear) together with presentation identity and reusable structure. It describes the resource without deciding which pages or content a future presentation must keep; a deck template is not a finished content deck, and `kind: deck` does not mean "mirror the source PPT" — the creation strategy decides whether the system is newly authored or materialized from validated facts. The shared kind and workspace model lives in the parent [`README.md`](../README.md). | Axis | Deck behavior | |---|---| -| Template kind | `deck`: descriptive application context + integrated identity + structure | -| Internal creation strategy | AI derives `standard` / `fidelity` for a new system or `mirror` for validated source-package materialization; the field is tool provenance, not a user choice | -| Application planning | Strategist automatically decides which prototypes to select, repeat, skip, or reorganize and derives the exporter behavior | -| PPTX structure | The workspace is `structured`; the derived application plan decides whether generated pages compile its structure or use it only as visual reference | +| Template kind | `deck`: application context + integrated identity + structure | +| Internal creation strategy | AI-derived `standard` / `fidelity` for a new system or `mirror` for validated source materialization; tool provenance, not a user choice | +| Application planning | Strategist decides which prototypes to select, repeat, skip, or reorganize and derives the exporter behavior | +| PPTX structure | The workspace is `structured`; the plan decides whether pages compile its structure or use it as visual reference | -The discovery source of truth is [`decks_index.json`](./decks_index.json) -(`deck_id → { summary, canvas_format, page_count, primary_color }`). This README -defines the kind and intentionally does not enumerate installed decks. The -shared kind and workspace model lives in the parent -[`README.md`](../README.md). - -Index `summary` values lead with the recurring presentation family and intended -outcome. Visual tone alone is not enough to select a Deck; open its Template -Overview when application fit must be judged in detail. - ---- +[`decks_index.json`](./decks_index.json) (`deck_id → { summary, canvas_format, page_count, primary_color }`) is the discovery source of truth; this README enumerates no decks. Index summaries lead with the presentation family and outcome — visual tone alone never selects a Deck; open its Template Overview to judge fit. ## Selection and installation -Selection follows the parent README's Default Stage-1 -[`generate-pptx`](../../workflows/generate-pptx.md) template-choice contract. -Its Deck choices come only from `decks_index.json`; no -directory scan or bare-ID/style-phrase match is allowed. A supplied exact root -appears in the same selector, defaults Stage 1 to template mode, and preselects -that specific candidate only when it is the sole supplied root. Registered -exact roots are `library`; other exact roots remain -`explicit`. Choosing and confirming an entry runs the conditional -[`apply-template-workspace`](../../workflows/stages/apply-template-workspace.md) -stage, which owns path normalization, compatibility checks, installation, and -installation after Stage 1 and before Stage 2. Template-aware reading begins in final Stage 2 from the -installed project-local copy. -Quick applies a supplied exact Deck root directly and otherwise uses flat free -design. It authors the installed Master/Layout/slot contract as lockless -structured Slides unless the user explicitly requests visual-only flat use. -This file owns the Deck schema and application-context boundary. Chat discovery -reads the same index and returns exact roots; a bare ID never resolves -implicitly. - ---- +Selection follows the parent contract: Deck choices come only from the index (no directory scan or bare-ID/style-phrase match); a supplied exact root joins the selector and is preselected only when sole; [`apply-template-workspace`](../../workflows/stages/apply-template-workspace.md) installs it before Stage 2; Quick applies a supplied exact root directly and authors the installed Master/Layout/slot contract as lockless structured Slides unless the user explicitly requests visual-only flat use. ## `design_spec.md` contract -The spec stores portable metadata plus package-owned application, identity, -and structure rules. It does not repeat generic SVG rules, spacing libraries, -font-ratio bands, or the canonical placeholder table. +Portable metadata plus package-owned application, identity, and structure rules; no generic SVG rules, spacing libraries, font-ratio bands, or the canonical placeholder table. ```markdown --- @@ -85,66 +46,12 @@ page_count: <N> ## VII. Placeholder Overrides # omit when none ``` -`replication_mode` records how the workspace was produced. Create Template -derives it from the natural-language brief and source evidence; users do not -need to select or understand this field. - -`Template Overview` is descriptive application context, not a style -description or future-use policy. It identifies the recurring presentation -family, intended audiences and outcomes, delivery/reading assumptions, and -representative narrative or page roles. These values may be broad when the -source supports a family of related uses, but they must be specific enough to -help Strategist understand the resource. - -`Page Roster` must list every SVG and its declared Master/Layout identity, then -describe its observed or intended role, visual character, reusable slots, and -structural capacity. It must not mark pages required/optional/repeatable or -content fixed/replaceable/example-only. Strategist inspects the actual roster -and current material and decides what to use. - -Every additional authored Master represents a distinct reusable design family, -not one Layout or an organizational duplicate. - ---- +`replication_mode` records how the workspace was produced. `Template Overview` is descriptive application context — family, intended audiences/outcomes, delivery/reading assumptions, representative roles — broad when the source supports related uses yet specific enough to help Strategist understand the resource. `Page Roster` lists every SVG with its Master/Layout identity, role, visual character, reusable slots, and capacity, never marking pages required/optional/repeatable or content fixed/replaceable/example-only. Every additional authored Master is a distinct reusable design family. ## Structured SVG contract -Every SVG is a complete preview and declares one root Master and Layout. -Master/Layout fixed visuals are direct atoms. Reusable content regions are -top-level slot groups with positive bounds and exactly one compatible carrier; -zero-slot Layouts are valid. `{{...}}` is the authoring vocabulary, while -`data-pptx-placeholder*` is the native reconstruction contract. - -`standard` and `fidelity` author new SVGs and a new Master/Layout/slot system. -`mirror` preserves existing source identities, parentage, assignments, -placeholder facts, and supported visuals in a new workspace without semantic -synthesis. Legacy semantic contracts are not upgraded in place; create a new -workspace through [`create-template`](../../workflows/create-template.md). A -flat directory shape alone is not a legacy signal. - ---- +Every SVG is a complete preview declaring one root Master and Layout; fixed visuals are direct atoms; reusable regions are top-level slot groups with positive bounds and exactly one compatible carrier; zero-slot Layouts are valid; `{{...}}` is the authoring vocabulary and `data-pptx-placeholder*` the native contract. `standard` / `fidelity` author new SVGs and structure; `mirror` preserves source identities, parentage, assignments, placeholder facts, and supported visuals without synthesis; legacy contracts are never upgraded in place, and a flat directory shape alone is not a legacy signal. ## Workspace and creation -```text -<template_workspace>/ -├── templates/ # design_spec.md + SVG prototypes -├── images/ # optional bitmaps; SVG href is ../images/<name> -├── icons/ -│ └── imported/ # optional canonical imported vectors -└── exports/ # review evidence; ignored during template use - └── <deck_id>_template_preview.pptx -``` - -Library scope writes `skills/ppt-master/templates/decks/<deck_id>/` and updates -the index. Project scope uses an initialized `projects/<name>/` workspace and -does not register globally. Empty optional directories are omitted. - -1. Enter [`workflows/create-template.md`](../../workflows/create-template.md), which dispatches recurring-application output with integrated identity and structure to [`create-deck.md`](../../workflows/create-template/create-deck.md). -2. Validate with `svg_quality_checker.py --template-mode`. -3. Run `template_preview_pptx.py` when review is requested and always when the roster declares multiple Masters. -4. In library scope, register with `register_template.py <id> --kind deck`. - -See also [`styles/`](../styles/) for direction/method packages, -[`layouts/`](../layouts/) for structure-only packages, and -[`brands/`](../brands/) for identity-only packages. +`templates/` (spec + prototypes), optional `images/` (`../images/<name>`), optional `icons/imported/`, and `exports/<deck_id>_template_preview.pptx` as review evidence. Library scope writes `skills/ppt-master/templates/decks/<deck_id>/` and updates the index; project scope uses an initialized `projects/<name>/` root without registration. Enter [`create-template.md`](../../workflows/create-template.md) (dispatching to [`create-deck.md`](../../workflows/create-template/create-deck.md)), validate with `svg_quality_checker.py --template-mode`, run `template_preview_pptx.py` on request and always for multiple Masters, and in library scope register with `register_template.py <id> --kind deck`. See [`styles/`](../styles/), [`layouts/`](../layouts/), and [`brands/`](../brands/) for the other kinds. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/design_spec_reference.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/design_spec_reference.md index a78aac52..1c6b66dd 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/design_spec_reference.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/design_spec_reference.md @@ -1,29 +1,21 @@ # Design Spec Structure -Project-level `design_spec.md` is a human-readable English-heading Markdown artifact. This file owns its normal authoring structure. [`schemas/design_spec.schema.json`](./schemas/design_spec.schema.json) provides structural lint for readable sections and page projection; it is not an execution lock and does not require textual equality with `spec_lock.md`. - -Strategist reads the complete final confirmation once, writes this artifact from that retained state plus source analysis, and audits every confirmed field here. Afterward, `spec_lock.md` is authored from the completed Design Spec plus current project/page/template context; normal lock authoring never reopens `result.json`. +Project-level `design_spec.md` is a human-readable English-heading Markdown artifact. This file owns its authoring structure; [`schemas/design_spec.schema.json`](./schemas/design_spec.schema.json) lints readable sections and page projection — it is not an execution lock and requires no textual equality with `spec_lock.md`. Strategist reads the final confirmation once, writes this artifact from that retained state plus source analysis, and audits every confirmed field here; `spec_lock.md` is then authored from the completed Design Spec plus context without reopening `result.json`. ## 1. Author the complete artifact -After final confirmation, compose the entire document in active context from the retained final state, source analysis, and project context. Then create `<project_path>/design_spec.md` once, from the first line through §X. +Compose the entire document in active context, then create `<project_path>/design_spec.md` once, first line through §X. **Depth follows the confirmed `design_spec_depth`** — `brief` (default) or `complete`; both keep every required heading and machine-read field. `brief` serves a continuous run whose author also draws the pages: §I records production mechanics without restating Stage-1 prose, §VI may leave the scenario column empty, §IX `Content` is a short block list (one bullet per block in the phrasing that fits — a sentence for prose, `·`-joined parallel fragments, `/`-joined labels — never full copy), and `Layout` is one optional line; `Relationships` is written at both depths. `complete` writes full wording and layout prose; split mode, `refine_spec: true`, and preservation profiles force it. -**Depth follows the confirmed `design_spec_depth`** — `brief` (default) or `complete`; both keep every required heading and every machine-read field. `brief` serves a continuous run whose author also draws the pages — §I records production mechanics without restating Stage-1 prose, §VI may leave the scenario column empty, §IX `Content` is a short block list — one bullet per block, each in the phrasing that fits it (a real sentence for prose, `·`-joined parallel fragments, `/`-joined labels) — never full page copy, and `Layout` is one optional line. `complete` writes full wording and layout prose; split mode, `refine_spec: true`, and preservation profiles force it. - -**Mandatory — new-project write**: The first non-empty line is exactly `<!-- ppt-master-schema: design-spec/v1 -->`, followed by `# <Project Name> - Design Spec`. Write every required section with final values and the complete page roster; include conditional §VII only when a real catalog reference is selected. Do not create a placeholder-bearing project file, copy example rows, or patch a scaffold field by field. - -`project_manager.py scaffold-spec` remains an optional manual convenience and overwrite-safe troubleshooting tool. It is not part of normal Generate authoring. Resume and refine paths edit an existing completed Design Spec rather than replacing it with a scaffold. +**Mandatory — new-project write**: the first non-empty line is exactly `<!-- ppt-master-schema: design-spec/v1 -->`, then `# <Project Name> - Design Spec`; every required section carries final values and the complete roster; conditional §VII appears only with a real catalog reference. Never write a placeholder-bearing file, copy example rows, or patch a scaffold field by field (`project_manager.py scaffold-spec` is an optional manual troubleshooting tool, not part of Generate authoring; resume and refine edit the existing completed Design Spec). --- ## 2. Exact document contract -Angle-bracketed text below is authoring notation, not project content. Resolve every universal value before writing the file; omit only rows explicitly marked conditional. Keep every required `##` heading; omit §VII when no real catalog reference is selected, while §VIII remains present even with no data rows. Do not copy examples, notation tokens, or a second schema description into the project artifact. +Angle-bracketed text is authoring notation. Resolve every universal value before writing; omit only rows marked conditional; keep every required `##` heading (§VII omitted without a catalog reference; §VIII present even with no data rows); copy no examples, notation, or schema prose into the artifact. ### 2.1 Header and project contract -Start with this exact heading order: - ```markdown <!-- ppt-master-schema: design-spec/v1 --> # <Project Name> - Design Spec @@ -64,12 +56,10 @@ Start with this exact heading order: | Content Area | <usable bounds> | ``` -When a template workspace is active, append exactly one line after the §I table: `- **Template Application**: <confirmed or Strategist-resolved natural-language plan>`. Omit it for free design. Never replace this prose with internal reuse/adherence ids. +With an active template workspace, append exactly one line after the §I table — `- **Template Application**: <confirmed or Strategist-resolved natural-language plan>` — never internal reuse/adherence ids; omit it for free design. ### 2.2 Visual, typography, layout, and icons -Use these exact subsections and field shapes: - ```markdown ## III. Visual Theme @@ -123,7 +113,7 @@ Use these exact subsections and field shapes: - **Composition tendency**: <non-binding macro direction; no coordinates or authoring method> - **Cross-page continuity**: <what may recur or vary across the roster> - **Spacing posture**: <dense, open, or variable by page rhythm> -- **Spacing anchors**: <five deck-wide px values — page margin, block gap, column gutter, corner radius, body leading — kept stable across pages like the color and type anchors> +- **Spacing anchors**: <five deck-wide px values — page margin, block gap, column gutter, corner radius, body leading — kept stable like the color and type anchors> ## VI. Icon Usage Specification @@ -134,9 +124,9 @@ Use these exact subsections and field shapes: | --- | --- | ``` -Preserve Title/Body characters and resolved stacks; omit blank Typography upgrade and never place it in a stack. For each justified recurring family override, add the role to Font Plan plus `- **<Role> stack**: <complete ordered stack>`. Possible roles are `Annotation`, `Footer`, `Footnote`, `Data`, `Emphasis`, `Quote`, and `Code`; add only recurring, intentional differences. Add non-locked `Role rationale` only for an extra family. Do not collapse distinct Title/Body stacks or discard a declared optional role. Each Font Size Hierarchy value is a role anchor: Executor may vary one occurrence `±2px`; a short non-structural Hero/Display size may stay unlisted only while the same value is planned at most twice, and its third occurrence needs a named row. Add every recurring palette role and typography-size anchor established by the plan; do not enumerate one-off paint or font-family garnish. For confirmed custom directions, add the applicable `Mode References`, `Mode Behavior`, `Visual Style References`, and `Visual Style Behavior` lines under Theme Style. Include `Stroke Width` under §VI only for a stroke library. `simple-icons` may accompany the one primary bundled library and is recorded only when actual content requires real brand marks; it is never a separate confirmation choice. The icon table records the synced SVG pool and, at `complete` depth, broad semantic scenarios — never page placement. User-provided, template-carried, imported, custom, and other prepared SVGs under the project `icons/` directory remain usable without being forced into that bundled selection. Leave the §VI table empty when no bundled or brand SVG icons are prepared. Illustrated icons are AI image resources: their production sheet and placed slice rows belong in §VIII, and only placed slices project to `spec_lock.md images`. +Preserve Title/Body characters and resolved stacks; omit a blank Typography upgrade and never place it in a stack. Each justified recurring family override adds its role to Font Plan plus `- **<Role> stack**: <complete ordered stack>` (roles: `Annotation`, `Footer`, `Footnote`, `Data`, `Emphasis`, `Quote`, `Code` — only recurring, intentional differences; a non-locked `Role rationale` only for an extra family); never collapse distinct Title/Body stacks or drop a declared role. Each Font Size Hierarchy value is a role anchor Executor may vary by `±2px` per occurrence; a short non-structural Hero/Display size may stay unlisted only while planned at most twice — its third occurrence needs a named row. Record every recurring palette role and size anchor the plan establishes, never one-off garnish. For confirmed custom directions add `Mode References`, `Mode Behavior`, `Visual Style References`, and `Visual Style Behavior` under Theme Style as applicable. `Stroke Width` under §VI only for a stroke library. `simple-icons` accompanies the one primary library only when real brand marks are required and is never a separate confirmation choice. The §VI table records the synced SVG pool and, at `complete` depth, broad scenarios — never page placement; leave it empty when no bundled or brand icons are prepared. Other prepared SVGs under the project `icons/` remain usable without entering that selection. Illustrated icons are AI image resources: their sheet and placed slice rows belong in §VIII, and only placed slices project to `spec_lock.md images`. -When §VIII contains any `Acquire Via: ai` row, add this subsection under §III and preserve the complete confirmed AI direction: +When §VIII contains any `Acquire Via: ai` row, add under §III: ```markdown ### AI Image Strategy @@ -146,12 +136,10 @@ When §VIII contains any `Acquire Via: ai` row, add this subsection under §III - **Mood**: <confirmed mood and analogy> ``` -For a selected custom rendering, also add `Image Rendering Behavior`; add `Image Rendering References` only when the confirmed custom direction actually uses catalog material. Never add a separate image palette. +A custom rendering adds `Image Rendering Behavior`, and `Image Rendering References` only when catalog material is actually used; never a separate image palette. ### 2.3 Visualization and image resources -Use the §VII table only when at least one real Chart/Table catalog reference is selected. Always keep the §VIII table, including when it has no data rows: - ```markdown ## VII. Visualization Reference List @@ -164,28 +152,13 @@ Use the §VII table only when at least one real Chart/Table catalog reference is | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | ``` -§VII lists at most one `chart|table` reference per page: canonical Template key -plus semantic Usage. Resolve `family/key`; never derive paths from bare keys. -§IX owns child visuals, unmatched fallbacks, and qualitative relationships as -free `Layout` / `Visualization` prose. Layout/Deck alone owns reusable -PowerPoint structure. Omit empty §VII and recall diagnostics; legacy rows stay -readable, while new specs use four columns. +§VII lists at most one `chart|table` reference per page (canonical key plus semantic Usage; resolve `family/key`, never derive paths from bare keys; omit when empty; legacy rows stay readable, new specs use four columns). §IX owns child visuals and unmatched fallbacks in `Visualization`; qualitative relationships live only on the `Relationships` line; Layout/Deck alone owns reusable PowerPoint structure. In §IX `Visualization`, key every independent data chart or pure text-grid table in `kebab-case` and add one `Native-ready` map `<key>=yes|no; ...` — `yes` by default, `no` only when the native payload cannot express the object; qualitative relationships and incidental microvisuals stay unkeyed. -In §IX `Visualization`, key every independent data chart/pure text-grid table -in `kebab-case` and add one `Native-ready` map: `<key>=yes|no; ...`. Decide -`yes` by default; use `no` only when the native payload cannot express that -object. Qualitative relationships/read order remain unkeyed prose, as do -incidental microvisuals. - -In §VIII, author every planned or explicitly required resource from the confirmed source boundary. Write one concise, non-empty `Layout pattern` suggestion in ordinary language; optionally cite hierarchical ids from the layout library when they help recall a technique. An image-led `adaptive` row names the page job the image resolves next to the composition serving it; a `no-crop` or supporting row keeps the concise suggestion alone. Set `Crop Policy` to `adaptive` or `no-crop`; set `Acquire Via` to `ai`, `web`, `user`, `placeholder`, or `slice`. Preserve unresolved required assets as `Pending` or `Needs-Manual` instead of dropping or reclassifying them. Native formulas never enter this table or `spec_lock.md images`. - -§VIII `Layout pattern` is a per-resource preference. When a page uses several images, repeats one image in multiple views, or combines an image with native overlays, describe the page-level relationship and participating resources in §IX `Layout` / `Images`; do not duplicate an unchanged resource row merely to encode animation sequencing. - -Put native paint/overlay intent in §IX `Layout` plus `Images` for imagery—not a new field; state semantic job/layering, while Executor chooses type, stops, opacity, and geometry. +§VIII authors every planned or required resource from the confirmed source boundary: one concise non-empty `Layout pattern` suggestion in ordinary language (optionally citing hierarchical ids from the layout library; an image-led `adaptive` row names the page job the image resolves next to the composition serving it); `Crop Policy` `adaptive` or `no-crop`; `Acquire Via` `ai`, `web`, `user`, `placeholder`, or `slice`; unresolved required assets kept as `Pending` or `Needs-Manual`; native formulas never enter it. `Layout pattern` is per-resource — how several images relate on one page (repeated views, sequencing) is stated once in §IX `Images` as a Reference, never as duplicate rows; paint, overlay, and geometry are Executor's. ### 2.4 Complete page roster and notes -Write one ordered Slide block per page. Slide count and order must equal §I `Page Count`; `Content` is a complete page brief at `complete` depth and a short block list at `brief` depth — neither is a skeleton. +One ordered Slide block per page; count and order equal §I `Page Count`; `Content` is a complete brief at `complete` depth and a short block list at `brief` — never a skeleton. ```markdown ## IX. Content Outline @@ -195,7 +168,8 @@ Write one ordered Slide block per page. Slide count and order must equal §I `Pa #### Slide 01 - <page name> - **Audience move**: <audience state before → after> -- **Layout**: <non-binding macro composition, hierarchy, and visual focus; chosen prototype when template-active; optional at brief depth> +- **Relationships**: <the page's semantic units and the source-stated order / link / parent / membership / contrast / overlap among them, or none; no shape, carrier, or authoring words> +- **Layout**: <Reference — macro composition, hierarchy, and visual focus as a starting sketch; chosen prototype when template-active; optional at brief depth> - **Title**: <preferred page title> - **Core message**: <one governing assertion> - **Content**: <complete content at complete depth; short block list at brief depth> @@ -211,33 +185,12 @@ Write one ordered Slide block per page. Slide count and order must equal §I `Pa - **Presentation purpose**: <the confirmed communication intent from §I> ``` -When Speaker Notes is disabled, keep §X with only -`- **Generation**: disabled`; do not write filename, duration, style, or purpose -placeholders. An explicit notes-off/audio-on conflict blocks before authoring. +With Speaker Notes disabled, §X keeps only `- **Generation**: disabled`; an explicit notes-off/audio-on conflict blocks before authoring. When a final/literal narration script will become notes or audio, §X `Content` names the source and says `preserve verbatim`, with the segmented script kept in `notes/total.md`. -When an explicit final/literal narration script will become notes or generated -audio, make §X `Content` name that source and say `preserve verbatim`; keep the -full segmented script in `notes/total.md`, not in §IX or this Design Spec. - -Append the optional line only when the capability earns a place; never write an -empty or `none` placeholder: - -```markdown -- **Motion suggestion**: <communication job plus desired page-entry or reveal relationship/order> -``` - -Add `Mathematical content` whenever a Slide needs a mathematical expression preserved exactly. Store the expression body as valid LaTeX without `$...$`, `$$...$$`, `\(...\)`, or `\[...\]` source delimiters; the field does not classify inline versus structural use. This is content authority for [`native-formula.md`](../references/native-formula.md), not a formula policy, marker, or implementation request; Executor chooses ordinary text, inline native math, or block native math. Add `Visualization` / `Images` when a Slide consumes §VII/§VIII or uses a page-local visual model. Name every value-driven geometry, qualitative relationship, cell grid, and child visual here; only independent Chart/Table entries use object keys. Describe qualitative order, linkage, hierarchy, grouping, contrast, overlap, and reading path freely—not as a model name or grammar enum. §IX may choose a custom Chart/Table fallback. Native construction creates no Design Spec field; Executor discovers and selects it independently during realization. Add `Motion suggestion` whenever transition/reveal advice strengthens communication, regardless of the Custom Animations outcome; state purpose and semantic order/relationship, not registry keys, options, timing, ids, or coverage. The suggestion never activates animation execution by itself, creates content, or binds implementation. Describe required visible image states in `Layout` / `Images` only for an explicit motion requirement or an enabled Custom Animations outcome. Add keyed `Native-ready` only for independent data charts or pure text-grid tables, `Fact IDs` for sourced claims, and `Data class: scenario` for invented demo values. Except on preservation paths, `Cover impact` carries a binding hook and adaptable composition; apply the same split to `Closing impact` only when the deck genuinely resolves. Roster/order/content stay authoritative. §V/§IX layout, cover/closing composition, capability, motif, §VIII image-layout, and §VII Chart/Table directions remain References unless an explicit user/template/resource constraint promotes the named property; Executor considers each and may adopt, adapt, or decline it without upstream repair. Executor owns final geometry, hierarchy, treatment, and sparse local garnish. - -For free-design pages, describe `Layout` through relationships, hierarchy, visual focus, and optional macro region/span suggestions; do not prescribe element-level `x`, `y`, `width`, or `height`, fixed gaps, or an authoring method. Executor owns the final page composition and may depart from the recommendation while preserving its semantic job. Preserve literal geometry only when the user explicitly requires it or a mirror/template preservation contract owns it. +Optional Slide lines, added only when the capability earns a place (never an empty or `none` placeholder): `Mathematical content` (a valid delimiter-free LaTeX body — content authority for [`native-formula.md`](../references/native-formula.md), not a policy or marker; Executor chooses text, inline, or block); `Visualization` / `Images` when the Slide consumes §VII/§VIII or a page-local visual model, naming every value-driven geometry, cell grid, and child visual (only independent Chart/Table entries carry keys; qualitative relationships stay on the `Relationships` line, never a model name or grammar enum; §IX may choose a custom fallback; native construction is discovered by Executor, never a Design Spec field); `Motion suggestion` (purpose and semantic order/relationship, never registry keys, options, timing, ids, or coverage — it never activates execution, creates content, or binds implementation; required visible image states go in `Layout` / `Images` only for an explicit motion requirement or an enabled outcome); keyed `Native-ready`; `Fact IDs` for sourced claims; `Data class: scenario` for invented values. Except on preservation paths, `Cover impact` carries a binding hook and adaptable composition, and `Closing impact` the same split only when the deck genuinely resolves. Roster, order, content, and `Relationships` stay authoritative; §V/§IX layout, cover/closing composition, capability, motif, non-`ai` §VIII image-layout, and §VII directions are References — starting sketches Executor adjusts or replaces freely for the page's purpose, with no upstream repair or stated reason, carrying no binding semantics. When the user, a template, or a resource contract requires such a property, write `(binding)` after the field label (`- **Layout (binding)**:`) and Executor follows it literally. For free-design pages, `Layout` describes relationships, hierarchy, focus, and optional macro region/span suggestions — never element-level `x` / `y` / `width` / `height`, fixed gaps, or an authoring method; literal geometry is preserved only when the user requires it or a mirror/template contract owns it. --- ## 3. Machine validation -```bash -python3 skills/ppt-master/scripts/project_manager.py validate <project_path> -``` - -Validation reads the Markdown directly. It reports missing or out-of-order I–X sections, unresolved `[fill...]` placeholders, missing per-slide `Audience move`, and a missing §III `AI Image Strategy` when an §VIII table selects `ai` acquisition. - -The schema validates structure only. Strategist role modules own field meaning, recommendation logic, page planning, image policy, and template policy. `spec_lock.md` owns stable execution anchors and routing selected in context; it is not an exhaustive value projection. On divergence, repair the Design Spec from the retained final state when Gate 1 fails, then re-author affected lock anchors from the audited Design Spec and current context. Never reopen `result.json` merely to author or validate the lock, and never use the lock to overwrite a valid Design Spec decision. +`python3 skills/ppt-master/scripts/project_manager.py validate <project_path>` reads the Markdown directly and reports missing or out-of-order I–X sections, unresolved `[fill...]` placeholders, missing per-slide `Audience move` or `Relationships` lines, and a missing §III `AI Image Strategy` when §VIII selects `ai`. The schema validates structure only; Strategist modules own meaning, and `spec_lock.md` owns stable anchors and routing, not an exhaustive projection. On divergence, repair the Design Spec from the retained final state when Gate 1 fails, then re-author affected lock anchors; never reopen `result.json` to author the lock or let the lock overwrite a valid Design Spec decision. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/icons/README.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/icons/README.md index afc0cd8e..6d74eced 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/icons/README.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/icons/README.md @@ -1,125 +1,46 @@ # SVG Icon Library -This directory provides **12,027 high-quality SVG icons** across five libraries that can be directly embedded into SVG files generated by PPT Master. Default Strategist or the Quick Generate main agent chooses at most one primary library from the four stylistic libraries; the brand-logo library (`simple-icons`) is prepared as needed for real brands and may be used alone or alongside it. It is not a separate Confirm UI choice. - -Upstream versions, compatibility overlays, licenses, attribution, and trademark boundaries are recorded in [THIRD_PARTY_NOTICES.md](./THIRD_PARTY_NOTICES.md). - -## Libraries +**12,027 SVG icons** across five libraries, embedded directly into generated SVG. Default Strategist or the Quick main agent chooses at most one primary library from the four stylistic ones; the brand-logo library (`simple-icons`) is prepared as needed for real brands, alone or alongside it, and is never a separate Confirm UI choice. Upstream versions, licenses, attribution, and trademark boundaries: [THIRD_PARTY_NOTICES.md](./THIRD_PARTY_NOTICES.md). | Library | Style | Count | viewBox | Prefix | |---------|-------|-------|---------|--------| -| `chunk-filled` | fill · compact, chunky 16px silhouettes | 641 | primarily `0 0 16 16` | `chunk-filled/` | -| `tabler-filled` | fill · bezier-curve forms (smooth, rounded contours) | 1,055 | `0 0 24 24` | `tabler-filled/` | -| `tabler-outline` | stroke / line | 5,138 | `0 0 24 24` | `tabler-outline/` | -| `phosphor-duotone` | duotone · single color + 0.2 opacity backplate (soft depth) | 1,518 | `0 0 256 256` | `phosphor-duotone/` | -| `simple-icons` | **brand logos** (real company / product marks) — single-color silhouettes, color in via `fill` | 3,675 | `0 0 24 24` | `simple-icons/` | - ---- +| `chunk-filled` | fill · compact, chunky 16px silhouettes; heavy, solid | 641 | primarily `0 0 16 16` | `chunk-filled/` | +| `tabler-filled` | fill · bezier forms, smooth rounded contours; medium, approachable | 1,055 | `0 0 24 24` | `tabler-filled/` | +| `tabler-outline` | stroke / line art (default stroke-width 2); light, refined; best on screen — thin strokes weaken when printed or projected | 5,138 | `0 0 24 24` | `tabler-outline/` | +| `phosphor-duotone` | duotone · full-opacity shape plus a same-color 20% backplate; medium, layered | 1,518 | `0 0 256 256` | `phosphor-duotone/` | +| `simple-icons` | **brand logos** (real company / product marks), single-color silhouettes colored via `fill` | 3,675 | `0 0 24 24` | `simple-icons/` | ## Per-project icons folder -This directory is the **global library**. The active resource owner copies chosen icons into the deck's own `<project>/icons/<lib>/` with `icon_sync.py` before SVG authoring: +This directory is the global library; the resource owner copies chosen icons into `<project>/icons/<lib>/` before SVG authoring: ```bash python3 skills/ppt-master/scripts/icon_sync.py <project_path> tabler-outline/home tabler-outline/bulb simple-icons/github ``` -Missing names and a single selection batch that mixes the four stylistic libraries exit non-zero; `simple-icons` may coexist for real brand marks. Once files are under `<project>/icons/`, they form the prepared project asset pool and may be combined freely with user-provided, custom, or imported icons. `finalize_svg.py --only embed-icons`, preview, validation, and native export resolve only this project-local pool. - -**Custom icons**: drop your own `.svg` into `<project>/icons/<lib>/` (any `<lib>`, e.g. `custom/`) and reference it as `data-icon="<lib>/<name>"` — it embeds like any library icon. - -**Imported vectors**: `create-template` reserves the project-local `imported/` -namespace. Each extracted vector lives once at -`<workspace>/icons/imported/<name>.svg` and is referenced as -`data-icon="imported/<name>"`; do not duplicate it under `templates/` or use -`imported/` as a hand-curated style library. +Missing names, or one batch mixing the four stylistic libraries, exit non-zero; `simple-icons` may coexist. Files under `<project>/icons/` form the prepared pool and combine freely with user-provided, custom, or imported icons; `finalize_svg.py --only embed-icons`, preview, validation, and native export resolve only this pool. **Custom icons**: drop `.svg` files into `<project>/icons/<lib>/` (any `<lib>`, e.g. `custom/`) and reference `data-icon="<lib>/<name>"`. **Imported vectors**: `create-template` reserves `imported/` — one copy at `<workspace>/icons/imported/<name>.svg`, referenced as `data-icon="imported/<name>"`, never duplicated under `templates/` or used as a hand-curated library. ## Usage -Use placeholder syntax **during SVG generation**: - ```xml -<!-- chunk-filled (compact, chunky — strong small-size legibility) --> <use data-icon="chunk-filled/home" x="100" y="200" width="48" height="48" fill="#0076A8"/> - -<!-- tabler-filled (rounded, organic — lifestyle/health/home tone) --> -<use data-icon="tabler-filled/home" x="100" y="200" width="48" height="48" fill="#0076A8"/> - -<!-- tabler-outline (light, line-art — refined screen-only showcases) --> -<use data-icon="tabler-outline/home" x="100" y="200" width="48" height="48" fill="#0076A8"/> - -<!-- phosphor-duotone (soft depth — single color renders the backplate at 20% opacity) --> <use data-icon="phosphor-duotone/house" x="100" y="200" width="48" height="48" fill="#0076A8"/> - -<!-- simple-icons (brand logo — used alone or alongside the deck's primary stylistic library) --> <use data-icon="simple-icons/github" x="100" y="200" width="48" height="48" fill="#181717"/> ``` -**Attributes**: -- `data-icon` — `<library>/<icon-name>` (filename without `.svg`) -- `x`, `y` — Position -- `width`, `height` — Size (recommend 32–48px for legibility) -- `fill` — Color - -`data-icon` is case-sensitive because it resolves a real filename. Bundled library directories and basenames are canonical lowercase: use `tabler-outline/award`, not `tabler-outline/Award`. Custom icons retain the exact case of their files; the resolver intentionally does not lowercase identifiers. - -Every placeholder resolves only against `<project_path>/icons/`. A complete -`library/name` identifier is mandatory; bare names, abbreviated namespaces, -paths into `templates/icons/`, and unsynced bundled-library files fail instead -of falling back to another root. - -`finalize_svg.py` auto-embeds all placeholders during post-processing. To run manually: - -```bash -python3 scripts/svg_finalize/embed_icons.py svg_output/*.svg -``` - ---- +`data-icon` is `<library>/<icon-name>` (filename without `.svg`), case-sensitive because it resolves a real file — bundled names are canonical lowercase (`tabler-outline/award`), custom icons keep their file case; `x`, `y` position; `width`, `height` size (32–48px recommended); `fill` color. A complete `library/name` identifier is mandatory: bare names, abbreviated namespaces, paths into `templates/icons/`, and unsynced bundled files fail rather than fall back. `finalize_svg.py` embeds every placeholder during post-processing (`scripts/svg_finalize/embed_icons.py svg_output/*.svg` runs it manually). ## Searching for Icons -For a known basename, run `icon_sync.py` directly; it copies and validates without a per-file precheck. - -For an uncertain basename, search only the chosen stylistic library; use `simple-icons` only for a real brand mark. - -**Hard rule**: search by the drawable object, not the abstract concept. These libraries store things that can be drawn — `bulb`, `target`, `trending-up`, `alert-triangle` — so concept words such as `idea`, `goal`, `growth`, `warning`, or `innovation` return nothing in most of them. Translate the semantic into an object first, then search. - -**Reference — not a constraint**: one concept usually has several valid objects. Which one fits is a per-deck judgment of page register and visual style, not a fixed mapping. - -**Hard rule**: basenames are not portable across the four stylistic libraries; verify inside the selected one. `alert-*` exists in the tabler libraries but not in `phosphor-duotone`, which uses `warning-*`; `arrow-trend-*` exists in `chunk-filled`, while `tabler-outline` uses `trending-*`. +For a known basename run `icon_sync.py` directly; for an uncertain one search only the chosen stylistic library (`simple-icons` only for a real brand mark): ```bash rg --files "skills/ppt-master/templates/icons/tabler-outline" -g '*chart*.svg' rg --files "skills/ppt-master/templates/icons/simple-icons" -g '*github*.svg' ``` -Do not load a full index or enumerate broad keyword families. Re-pick from the narrow result and rerun the final batch until clean; never switch stylistic libraries for a missing generic icon. - -**Empty result** → translate the semantic into a different drawable object and search the same library again. When several translations stay empty, that semantic has no fit in the selected library: let another carrier take it — a chart, typography, or a shape — rather than forcing a loose icon. Widening the keyword family is not the fallback. - ---- +**Hard rule**: search by the drawable object, not the abstract concept — these libraries store things that can be drawn (`bulb`, `target`, `trending-up`, `alert-triangle`), so `idea`, `goal`, `growth`, `warning`, `innovation` return nothing in most of them; translate the semantic into an object first. **Reference — not a constraint**: one concept usually has several valid objects, chosen per deck from page register and visual style. **Hard rule**: basenames are not portable across the four stylistic libraries — `alert-*` exists in the tabler libraries but `phosphor-duotone` uses `warning-*`; `arrow-trend-*` in `chunk-filled` is `trending-*` in `tabler-outline`. Do not load a full index or enumerate broad keyword families; re-pick from the narrow result and rerun the batch until clean; never switch stylistic libraries for a missing generic icon. An empty result → try another drawable translation in the same library; when several stay empty, let another carrier (chart, typography, shape) take that semantic rather than forcing a loose icon. ## Style Rules -**No default library — actively choose based on the deck's visual needs.** Read the source material first, then pick the library whose visual character best serves the presentation. Each library has a distinct visual personality: - -- **`chunk-filled`** — **fill** style, designed as compact 16px silhouettes. Bold forms may combine rectilinear and curved geometry while staying highly legible at small sizes. Visual weight: heavy, solid, compact. -- **`tabler-filled`** — **fill** style, built from bezier curves and arcs (C/A). Smooth, rounded, organic contours; warmer and softer than `chunk-filled`. Visual weight: medium, approachable. -- **`tabler-outline`** — **stroke** style (line art, default stroke-width 2). Airy, refined, lightweight; uses negative space. Visual weight: light, elegant. Best for screen-only viewing since thin strokes may become hard to read when printed or projected. -- **`phosphor-duotone`** — **duotone** style; main shape at full opacity plus a backplate of the same color at 20% opacity, producing a soft sense of depth. Visual weight: medium, layered, contemporary. - -> **Two axes to consider when choosing**: -> 1. **Geometry**: compact silhouettes (`chunk-filled`) vs. rounded curves (`tabler-filled` / `phosphor-duotone`) vs. open strokes (`tabler-outline`) -> 2. **Visual weight**: heavy solid (`chunk-filled`) → medium solid (`tabler-filled`) → medium layered (`phosphor-duotone`) → light stroke (`tabler-outline`) - -**At most one primary bundled stylistic library per deck selection.** When generic icons are useful, pick one of `chunk-filled` / `tabler-filled` / `tabler-outline` / `phosphor-duotone` (home, chart, users, etc.). If it lacks an exact icon, find the closest available alternative within that library instead of selecting from another bundled stylistic library. This is a catalog-selection rule, not a prohibition on combining assets that already exist in the project's `icons/` directory. - -**Brand-logo exception (`simple-icons`).** `simple-icons` is **not a stylistic library**, does not participate in the "one library" rule, and is not presented as a user-facing library choice. Its job is brand recognition — Slack's purple, GitHub's cat, AWS's color — which is intentionally heterogeneous. Prepare it **alone or alongside** the chosen stylistic library only when actual content needs a company / product / service brand mark. Do **not** reach for it as a substitute when the chosen stylistic library lacks a generic icon. - -| Use `simple-icons` for | Do NOT use `simple-icons` for | -|------------------------|-------------------------------| -| Customer / partner / ecosystem logos on a "trusted by" page | Generic concepts (home, chart, settings, etc.) | -| Tech stack icons on architecture / integration diagrams | Replacing a missing icon in `chunk-filled` / `tabler-*` / `phosphor-duotone` | -| Social media handles in a footer | Decorative / illustrative purposes | - -⚠️ During bundled selection, choose generic icons from only one of the four **stylistic** libraries. Prepare `simple-icons` independently when real brand marks are needed. Project-local assets are already prepared material and are not subject to a runtime mixing ban. +**No default library — choose from the deck's visual needs** after reading the source: compact silhouettes (`chunk-filled`) vs rounded curves (`tabler-filled` / `phosphor-duotone`) vs open strokes (`tabler-outline`); visual weight heavy solid → medium solid → medium layered → light stroke. **At most one primary bundled stylistic library per deck selection**: when it lacks an exact icon, use the closest alternative within it rather than another bundled library — a catalog-selection rule, not a ban on combining assets already in the project's `icons/`. **Brand-logo exception**: `simple-icons` is not a stylistic library and does not count toward that rule; its job is brand recognition (Slack's purple, GitHub's cat), intentionally heterogeneous — prepare it only when content needs a company / product / service mark (customer or partner logos, tech-stack icons in architecture diagrams, social handles in a footer), never as a substitute for a missing generic icon or for decoration. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/README.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/README.md index b6fb85b7..25db0233 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/README.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/README.md @@ -1,78 +1,23 @@ # Layout Templates -**Layout = a structure-only reusable template bundle.** It owns canvas, -Master/Layout structure, page types, slot geometry, semantic text roles, -alignment/wrapping/capacity behavior, and the SVG roster. It does not own -brand color, typeface/weight identity, the final resolved type scale, logo, -voice, or icon style. Those identity decisions come from an explicit -brand/deck source or from the Strategist confirmation stage. - -A layout may describe the content shapes and delivery conditions its geometry -can support. It must not own a communication objective, audience outcome, -scenario-specific narrative sequence, fixed boilerplate, or example content -that downstream generation is expected to preserve. Those application rules -belong to a Deck. A structurally useful “board update” page can remain a -Layout; a board-update sequence with required decision, risk, and action roles -is a Deck. - -Neutral colors, safe fonts, and provisional sizes may appear in SVG prototypes -so the structure is reviewable. They are preview values, not a locked identity -segment or final type scale. The reusable rule is the role hierarchy and its -spatial behavior. When the workspace is used, Strategist inspects the actual -prototypes and current content, decides how much structure to reuse, and writes -the internal exporter plan automatically. +**Layout = a structure-only reusable template bundle**: canvas, Master/Layout structure, page types, slot geometry, semantic text roles, alignment/wrapping/capacity behavior, and the SVG roster — no brand color, typeface/weight identity, final type scale, logo, voice, or icon style (those come from a Brand/Deck or the confirmation stage). A layout may describe the content shapes and delivery conditions its geometry supports but never owns a communication objective, audience outcome, narrative sequence, boilerplate, or example content downstream must preserve — a structurally useful "board update" page stays a Layout; a board-update sequence with required decision, risk, and action roles is a Deck. Neutral colors, safe fonts, and provisional sizes in prototypes are preview values, not identity or a locked scale; Strategist inspects the prototypes and content, decides how much structure to reuse, and writes the exporter plan automatically. The shared kind and workspace model lives in the parent [`README.md`](../README.md). | Axis | Layout behavior | |---|---| | Template kind | `layout`: structure only | -| Internal creation strategy | AI derives `standard` / `fidelity` for a new system or `mirror` for validated source-package materialization; the field is tool provenance, not a user choice | -| Application planning | Strategist automatically decides literal, structural, or style-only use and derives any strict/adaptive exporter value | -| PPTX structure | The workspace is `structured`; the derived application plan decides whether generated pages compile its structure or use it only as visual reference | +| Internal creation strategy | AI-derived `standard` / `fidelity` for a new system or `mirror` for validated source materialization; tool provenance, not a user choice — Layout mirror additionally requires a brand-neutral, application-neutral source (otherwise author through `standard` / `fidelity` or create a Deck; removing rules is never mirror) | +| Application planning | Strategist decides literal, structural, or style-only use and any strict/adaptive value | +| PPTX structure | The workspace is `structured`; the plan decides whether pages compile its structure or use it as visual reference | -The discovery source of truth is [`layouts_index.json`](./layouts_index.json) -(`layout_id → { summary, canvas_format, page_count, page_types }`). This README -defines the kind and intentionally does not enumerate installed layouts. The -shared kind and workspace model lives in the parent -[`README.md`](../README.md). - -Layout mirror has one additional eligibility rule: the validated source -contract must already be brand-neutral and application-neutral. A source -outside that boundary can become a Layout only through `standard` or -`fidelity`, which deliberately authors a new neutral system. If its identity or -application rules must remain literal, create a Deck instead. Removing either -kind of rule is never a mirror operation. - ---- +[`layouts_index.json`](./layouts_index.json) (`layout_id → { summary, canvas_format, page_count, page_types }`) is the discovery source of truth; this README defines the kind and enumerates no layouts. ## Selection and identity boundary -Selection follows the parent README's Default Stage-1 -[`generate-pptx`](../../workflows/generate-pptx.md) template-choice contract. -Its Layout choices come only from `layouts_index.json`; no -directory scan or bare-ID/style-phrase match is allowed. A supplied exact root -appears in the same selector, defaults Stage 1 to template mode, and preselects -that specific candidate only when it is the sole supplied root. Registered -exact roots are `library`; other exact roots remain `explicit`. -Choosing and confirming an entry runs the conditional -[`apply-template-workspace`](../../workflows/stages/apply-template-workspace.md) -stage, which owns path normalization, compatibility checks, installation, and -installation after Stage 1 and before Stage 2. Template-aware reading begins in final Stage 2 from the -installed project-local copy. -Quick applies a supplied exact Layout root directly and otherwise uses flat free -design. It authors the installed Master/Layout/slot contract as lockless -structured Slides unless the user explicitly requests visual-only flat use. -This file owns the Layout schema and its identity/application boundary. Chat -discovery reads the same index and returns exact roots; a bare ID never resolves -implicitly. - ---- +Selection follows the parent contract: Layout choices come only from the index (no directory scan or bare-ID/style-phrase match); a supplied exact root joins the selector and is preselected only when sole; [`apply-template-workspace`](../../workflows/stages/apply-template-workspace.md) installs it before Stage 2; Quick applies a supplied exact root directly and authors the installed Master/Layout/slot contract as lockless structured Slides unless the user explicitly requests visual-only flat use. ## `design_spec.md` contract -The spec stores portable structural metadata plus rules unique to this layout. -It omits the deck-only Template Overview/application contract and every -identity section. The frontmatter `summary` carries the concise selection -context. +Portable structural metadata plus rules unique to this layout; no Template Overview, application contract, or identity section — the frontmatter `summary` carries selection context. ```markdown --- @@ -97,66 +42,12 @@ page_types: [cover, toc, chapter, content, ending] ## VII. Placeholder Overrides # omit when none ``` -`replication_mode` records how the workspace was produced. Create Template -derives it from the natural-language brief and source evidence; users do not -need to select or understand this field. - -`Signature Design Elements` describes only reusable structure: grids, zones, -image behavior, density rhythm, semantic text roles, alignment/wrapping/ -capacity behavior, and slot conventions. It must not introduce a brand -palette, typeface identity, final type scale, communication objective, or -required narrative sequence. `Page Roster` lists every SVG with its Layout -key, PowerPoint picker name, supported content shape, and slot behavior. - ---- +`replication_mode` records how the workspace was produced. `Signature Design Elements` describes only reusable structure (grids, zones, image behavior, density rhythm, text roles, alignment/wrapping/capacity, slot conventions) and introduces no palette, typeface identity, type scale, objective, or narrative sequence; `Page Roster` lists every SVG with Layout key, picker name, content shape, and slot behavior. ## Structured SVG and slot contract -Every SVG is a complete preview and declares one root Master and Layout. -Master/Layout fixed visuals are direct atoms. A reusable slot is a top-level -`<g id>` with positive design-zone bounds and exactly one compatible carrier; -zero-slot Layouts are valid. A typed `picture`, `chart`, or `table` slot does -not by itself promise an inserted picture or native data object: the generated -Slide supplies its content, and Chart/Table native replacement remains an -explicit export choice. - -Use canonical `{{PLACEHOLDER}}` names where they fit. A layout with intentional -vocabulary overrides declares a `placeholders:` map in frontmatter. Full rules: -[`template-designer.md`](../../references/template-designer.md#4-placeholder-reference-canonical-convention-overridable-per-template). - -`standard` and `fidelity` author new SVGs and a new Master/Layout/slot system. -`mirror` preserves existing source identities, parentage, assignments, -placeholder facts, and supported visuals in a new workspace without semantic -synthesis. Legacy semantic contracts are not upgraded in place; create a new -workspace through [`create-template`](../../workflows/create-template.md). A -flat directory shape alone is not a legacy signal. - ---- +Every SVG is a complete preview declaring one root Master and Layout; fixed visuals are direct atoms; a slot is a top-level `<g id>` with positive design-zone bounds and exactly one compatible carrier; zero-slot Layouts are valid; a typed `picture` / `chart` / `table` slot promises no inserted picture or native object — the generated Slide supplies content and native replacement stays an explicit export choice. Use canonical `{{PLACEHOLDER}}` names ([`template-designer.md`](../../references/template-designer.md#4-placeholder-reference-canonical-convention-overridable-per-template)) with a `placeholders:` frontmatter map for overrides. `standard` / `fidelity` author new SVGs and structure; `mirror` preserves source identities, parentage, assignments, placeholder facts, and supported visuals without synthesis; legacy contracts are never upgraded in place, and a flat directory shape alone is not a legacy signal. ## Workspace and creation -```text -<template_workspace>/ -├── templates/ # design_spec.md + SVG prototypes -├── images/ # optional bitmaps; SVG href is ../images/<name> -├── icons/ -│ └── imported/ # optional canonical imported vectors -└── exports/ # review evidence; ignored during template use - └── <layout_id>_template_preview.pptx -``` - -Library scope writes `skills/ppt-master/templates/layouts/<layout_id>/` and -updates the index. Project scope uses an initialized `projects/<name>/` -workspace and does not register globally. Empty optional directories are -omitted. - -1. Enter [`workflows/create-template.md`](../../workflows/create-template.md), which dispatches structure-only output to [`create-layout.md`](../../workflows/create-template/create-layout.md). -2. Validate with `svg_quality_checker.py --template-mode`. -3. Run `template_preview_pptx.py` when review is requested and always when the roster declares multiple Masters. -4. In library scope, register with `register_template.py <id> --kind layout`. - -General SVG/PPT rules remain authoritative in -[`shared-standards-core.md`](../../references/shared-standards-core.md) and -[`pptx-structure-interface.md`](../../references/pptx-structure-interface.md). -See [`styles/`](../styles/) when reusable method and visual direction should be -combined with this structure without becoming identity truth. +`templates/` (spec + prototypes), optional `images/` (`../images/<name>`), optional `icons/imported/`, and `exports/<layout_id>_template_preview.pptx` as review evidence. Library scope writes `skills/ppt-master/templates/layouts/<layout_id>/` and updates the index; project scope uses an initialized `projects/<name>/` root without registration. Enter [`create-template.md`](../../workflows/create-template.md) (dispatching to [`create-layout.md`](../../workflows/create-template/create-layout.md)), validate with `svg_quality_checker.py --template-mode`, run `template_preview_pptx.py` on request and always for multiple Masters, and in library scope register with `register_template.py <id> --kind layout`. General SVG/PPT rules stay in [`shared-standards-core.md`](../../references/shared-standards-core.md) and [`pptx-structure-interface.md`](../../references/pptx-structure-interface.md); see [`styles/`](../styles/) to combine method and direction with this structure. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/schemas/design_spec.schema.json b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/schemas/design_spec.schema.json index 4a561650..53c2b50d 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/schemas/design_spec.schema.json +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/schemas/design_spec.schema.json @@ -86,7 +86,7 @@ "slides": { "section": "content_outline", "heading_pattern": "^Slide[ \\t]+(?:[0-9]+|NN)\\b", - "required_fields": ["Audience move"] + "required_fields": ["Audience move", "Relationships"] } } } diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/spec_lock_reference.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/spec_lock_reference.md index 5df95d46..d78a7ee4 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/spec_lock_reference.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/spec_lock_reference.md @@ -1,16 +1,12 @@ # Execution Lock Structure -`spec_lock.md` projects cross-page anchors/routes from audited `design_spec.md` and context; it excludes local paint/type. This file owns structure; [`schemas/spec_lock.schema.json`](./schemas/spec_lock.schema.json) owns grammar. +`spec_lock.md` projects cross-page anchors and routes from the audited `design_spec.md` and context; it excludes local paint/type. This file owns structure; [`schemas/spec_lock.schema.json`](./schemas/spec_lock.schema.json) owns grammar. ## 1. Author the complete artifact -After Generate Step 4 Gate 1, read the completed Design Spec and current page/resource/template context, compose the entire lock in active context, then create `<project_path>/spec_lock.md` once. +After Generate Step 4 Gate 1, read the completed Design Spec and current page/resource/template context, compose the entire lock in active context, and create `<project_path>/spec_lock.md` once. **Mandatory — new-project write**: the first non-empty line is exactly `<!-- ppt-master-schema: spec-lock/v1 -->`, then `# Execution Lock`; write only final sections and values — no blank lock, inactive optional sections, or scaffold placeholders (`project_manager.py scaffold-lock` is an optional troubleshooting tool); never reopen or reinterpret final confirmation. Repair a credible completed pair by re-projecting only the affected rows after auditing the Design Spec; discard an orphan lock as authority and re-author it completely from the recovered Design Spec. -**Mandatory — new-project write**: The first non-empty line is exactly `<!-- ppt-master-schema: spec-lock/v1 -->`, followed by `# Execution Lock`. Write only final sections and values; do not create a blank lock, copy inactive optional sections, or patch scaffold placeholders. Do not reopen final confirmation or interpret it independently. - -`project_manager.py scaffold-lock` remains an optional manual convenience and overwrite-safe troubleshooting tool. It is not part of normal Generate authoring. When a credible completed Design Spec/lock pair needs correction, repair only the affected projection after auditing the Design Spec. When the Design Spec was missing and an orphan lock survived, discard that lock as authority and re-author the complete lock from the recovered, audited Design Spec plus current context. - -**Hard rule**: A project lock contains only `##` sections and `- key: value` data lines, except `## forbidden`, whose list items are literal rules. Do not copy guidance paragraphs into the lock. +**Hard rule**: a lock contains only `##` sections and `- key: value` lines, except `## forbidden`, whose items are literal rules; never copy guidance paragraphs into it. --- @@ -18,45 +14,42 @@ After Generate Step 4 Gate 1, read the completed Design Spec and current page/re | Section | Required keys | Notes | | --- | --- | --- | -| `canvas` | `viewBox`, `format` | `format` is the canonical display name (for example `PPT 16:9`); `viewBox` is the matching exact geometry | -| `communication` | `primary_language`, `audience`, `objective`, `core_message` | New lock: canonical BCP-47; old lock may omit it. Reject `und` and Chinese without script/region. `objective` merges intent/outcome; `consumption_mode` is optional off PPT | +| `canvas` | `viewBox`, `format` | `format` is the canonical display name (e.g. `PPT 16:9`); `viewBox` the exact geometry | +| `communication` | `primary_language`, `audience`, `objective`, `core_message` | Canonical BCP-47 (reject `und` and Chinese without script/region; old locks may omit it); `objective` merges intent/outcome; `consumption_mode` optional off PPT | | `mode` | `mode` | Preset or `custom` | | `visual_style` | `visual_style` | Preset or `custom` | -| `colors` | Stable semantic color roles | Core identity and recurring roles only, including the standard `secondary_text` and `divider` neutrals; contextual SVG paints need no row; `image_rendering` appears only for AI images | -| `typography` | `font_family`, `body`, `title` | Core family/size anchors; new locks also write explicit `title_family` and `body_family`; size anchors are unitless px numbers | -| `icons` | `library`, `inventory` | `library` is the Strategist's primary bundled style choice or `none`; content-driven `simple-icons/*` may be prepared alone or accompany it; `inventory` indexes the curated synced SVG pool rather than page usage or all usable project-local icons; `stroke_width` is conditional | -| `page_rhythm` | One `P<NN>` row per page | Values: `anchor`, `dense`, `breathing` | -| `pptx_structure` | `mode` | Values: `flat`, `structured` | -| `forbidden` | Literal list items | General standards stay in their owning reference | +| `colors` | Stable semantic color roles | Core identity and recurring roles only, including `secondary_text` and `divider`; contextual paints need no row; `image_rendering` only for AI images | +| `typography` | `font_family`, `body`, `title` | Core family/size anchors; new locks also write `title_family` and `body_family`; sizes are unitless px | +| `icons` | `library`, `inventory` | `library` is the primary bundled style or `none`; `simple-icons/*` may be prepared alone or alongside it; `inventory` indexes the curated synced pool, not page usage or every usable project icon; `stroke_width` conditional | +| `page_rhythm` | One `P<NN>` row per page | `anchor`, `dense`, `breathing` | +| `pptx_structure` | `mode` | `flat`, `structured` | +| `forbidden` | Literal list items | The technical baseline rows stay untagged; every other row is a prohibition the user stated in their own words (request, chat, `image_notes`), quoted verbatim and ending with `(user)`; nothing else enters — general standards stay in their owning reference, a template's rules stay in its installed spec, and a confirmed `visual_style_behavior` binds as identity prose without becoming a lock row | -Optional data sections: `images`, `page_visualizations` (Chart/Table only). New locks never write -legacy `page_charts`; existing locks may retain it for read-only compatibility. -Never declare the same page in both sections. - -The required universal block is: +Optional data sections: `images`, `page_visualizations` (Chart/Table only). New locks never write legacy `page_charts` (existing locks may keep it read-only); never declare one page in both. ```markdown ## forbidden - `mask`, `<style>`, `class`, external CSS, `<foreignObject>`, `textPath`, `@font-face`, `<animate*>`, `<set>`, `<script>` / event attributes, `<iframe>` - HTML named entities in text; write typography as raw Unicode and escape XML reserved characters +- 不要用任何阴影和发光 (user) ``` +A `(user)` row is the user's sentence, not a paraphrase and never widened; a Strategist-drafted direction — even once confirmed — is identity prose in `visual_style_behavior`, not a prohibition, so nothing is projected from it into this section. `project_manager.py validate` rejects an untagged non-baseline row. + --- ## 3. Conditional sections and fields | Trigger | Required addition | | --- | --- | -| `mode.mode: custom` | `mode_behavior` in `mode`; optional `mode_references` only when catalog modes are actually used | -| `visual_style.visual_style: custom` | `visual_style_behavior` in `visual_style`; optional `visual_style_references` only when catalog styles are actually used | -| `colors.image_rendering: custom` | `image_rendering_behavior` in `colors`; optional `image_rendering_references` only when catalog renderings are actually used | +| `mode.mode: custom` | `mode_behavior`; optional `mode_references` only when catalog modes are used | +| `visual_style.visual_style: custom` | `visual_style_behavior`; optional `visual_style_references` | +| `colors.image_rendering: custom` | `image_rendering_behavior`; optional `image_rendering_references` | | `icons.library: tabler-outline` | `stroke_width: 1.5`, `2`, or `3` | -| `pptx_structure.mode: structured` | `template_reuse_scope: layout\|mirror`, `template_adherence`, plus `pptx_masters`, `pptx_layouts`, `page_pptx_layouts`, and `page_layouts` | -| `pptx_structure.template_reuse_scope: mirror` | `mode: structured` and `template_adherence: strict` | -| `pptx_structure.template_reuse_scope: style` | `mode: flat`; omit structured mapping sections | -| `pptx_structure.mode: flat` | Omit all four structured mapping sections | - -Structured section value shapes: +| `pptx_structure.mode: structured` | `template_reuse_scope: layout\|mirror`, `template_adherence`, plus `pptx_masters`, `pptx_layouts`, `page_pptx_layouts`, `page_layouts` | +| `template_reuse_scope: mirror` | `mode: structured` and `template_adherence: strict` | +| `template_reuse_scope: style` | `mode: flat`; omit structured sections | +| `pptx_structure.mode: flat` | Omit all four structured sections | ```markdown ## pptx_masters @@ -70,61 +63,31 @@ Structured section value shapes: ## page_layouts - P01: 03_content -``` -Project each §VII Page/Family/Template into at most one -`page_visualizations` `<chart|table>/<key>` row per page; Usage, children, -no-match, and qualitative relationships stay in §IX. Resolve the reference to -one live SVG. It locks neither type, geometry, nor native output. - -```markdown ## page_visualizations - P03: chart/line_chart - P09: table/record_table ``` -**Legacy compatibility**: keep existing `page_charts` bare keys. Live -Chart/Table keys resolve unambiguously through two registries; retired Structure -keys are semantic-only, have no SVG, and rely on §IX (repair upstream when -insufficient). New locks write `page_visualizations`; dual page declarations -conflict even when they resolve alike. +Project each §VII row into at most one `page_visualizations` `<chart|table>/<key>` row per page, resolved to one live SVG; Usage, children, no-match, and qualitative relationships stay in §IX; the reference locks neither type, geometry, nor native output. **Legacy compatibility**: existing `page_charts` bare keys resolve uniquely across the two live registries; retired Structure keys are semantic-only with no SVG; dual page declarations conflict even when they resolve alike. -Typography projection excludes Character/upgrade References: - -| Design Spec §IV declaration | `spec_lock.md` field | -| --- | --- | -| Title font stack | `title_family` | -| Body font stack | `body_family` and compatibility/default `font_family` | -| Any additional recurring font role `<role>` | `<role>_family` | -| Every Font Size Hierarchy role `<role>` | lowercase `<role>` with its numeric anchor | - -New locks always write `title_family` and `body_family`, even when their values happen to match. Every additional recurring family row and every size-anchor row in the Design Spec must appear under the same lowercase snake_case role; omit only family roles that inherit without an explicit override. Existing locks without family-role fields remain readable through `font_family` fallback. Executor may choose the anchor or a value within that role's `±2px` band; the lock does not enumerate intermediate values. A short non-structural Hero/Display size may remain absent only while the same undeclared value appears at most twice across the deck; its third occurrence requires a named role. +Typography projection (excluding Character/upgrade References): Title font stack → `title_family`; Body font stack → `body_family` plus compatibility `font_family`; each additional recurring role `<role>` → `<role>_family`; each Font Size Hierarchy role → lowercase snake_case `<role>` with its numeric anchor. New locks always write `title_family` and `body_family` even when equal; omit only family roles that inherit without an override; old locks fall back to `font_family`. Executor may use the anchor or a value within `±2px`; a short non-structural Hero/Display size may stay absent only while the same undeclared value appears at most twice — its third occurrence needs a named role. --- ## 4. Field Grammar Index -- `font_family`, `title_family`, `body_family`, and every optional `<role>_family` use one non-empty PPT-safe exported family stack. `font_family` is the body/default compatibility stack, not permission to erase role differences. -- Every non-family `typography` value is a positive finite unitless px anchor. Intermediate values need no lock row when they stay within the mapped role's anchor `±2px`. At most two occurrences of one undeclared short non-structural Hero/Display size may remain sparse; a third occurrence or any structural use requires Design Spec repair and a named anchor. -- `icons.library` records the primary stylistic library selected from `chunk-filled`, `tabler-filled`, `tabler-outline`, or `phosphor-duotone`, or `none` when no generic bundled icons are selected. Content-driven `simple-icons/*` brand marks may appear alone or alongside it in `inventory` without becoming a stylistic library or a separate confirmation choice. The inventory indexes the curated synced SVG pool without assigning page usage; every SVG already under `<project_path>/icons/` remains valid prepared execution material. Illustrated-icon slices create no icon-lock field: their exact paths belong under `images`, and the unplaced parent sheet stays out of the lock. -- `objective` grammar: one concise sentence preserving the deck goal and audience success condition. -- `image_rendering` grammar: one catalog id, or `custom` with `image_rendering_behavior`. -- `images`: `- <key>: <path> | source=<via> | crop=<adaptive|no-crop>`; e.g. `- p04: images/a.png | source=user | crop=no-crop`. Use the canonical `images/<filename>` path; `source` and `crop` exactly project §VIII. The §VIII `Layout pattern` is not projected: Executor reads it from the §VIII row as a recommendation that may be adopted, adapted, or declined. A legacy `pattern=<layout>` segment is still accepted. Omit unplaced sheets. -- Custom reference grammar: comma-separated exact catalog ids with no duplicates. Reference fields are valid only for `custom`; omit them for a genuinely novel direction. -- `stroke_width` grammar: `1.5`, `2`, or `3`; present only for `tabler-outline`. -- `page_rhythm` grammar: `P` + at least two digits (`P01`, `P100`) followed by `anchor|dense|breathing`. -- `page_visualizations` grammar: `P` + at least two digits followed by - `chart|table`, `/`, and one canonical visualization key; the family/key must - resolve to one SVG through the matching live index. -- Legacy `page_charts` grammar: `P` + at least two digits followed by one bare - key. Chart/Table resolves uniquely across two registries; retired Structure - is semantic-only. Never add this section to a new lock. -- `pptx_masters` grammar: `<master_key>: <PowerPoint picker name>`. -- `pptx_layouts` grammar: `<layout_key>: <master_key> | <PowerPoint layout name> | <prototype source>`. -- `page_pptx_layouts` grammar: `P` + at least two digits followed by a declared Layout key. -- `page_layouts` grammar: `P` + at least two digits followed by a complete Slide template SVG basename. Definition-only `layout_<layout_key>` files are obsolete and are also invalid as `pptx_layouts` sources; author a complete Slide prototype for each reusable Layout. - -Catalog-based custom example: +- `font_family`, `title_family`, `body_family`, and every `<role>_family`: one non-empty PPT-safe exported family stack; `font_family` is the body/default compatibility stack, not permission to erase role differences. +- Every non-family `typography` value: a positive finite unitless px anchor; intermediate values within `±2px` need no row; a third occurrence of an undeclared Hero/Display size or any structural use requires Design Spec repair and a named anchor. +- `icons.library`: `chunk-filled`, `tabler-filled`, `tabler-outline`, `phosphor-duotone`, or `none`; `simple-icons/*` marks may appear alone or alongside in `inventory` without becoming a library or confirmation choice; every SVG under `<project_path>/icons/` remains valid material; illustrated-icon slices create no icon field — their paths belong under `images`, and the unplaced sheet stays out. +- `objective`: one concise sentence preserving goal and audience success condition. +- `image_rendering`: one catalog id, or `custom` with `image_rendering_behavior`. +- `images`: `- <key>: <path> | source=<via> | crop=<adaptive|no-crop>` (e.g. `- p04: images/a.png | source=user | crop=no-crop`); canonical `images/<filename>` path; `source` and `crop` project §VIII exactly; `Layout pattern` is not projected (Executor reads it from §VIII as a recommendation); a legacy `pattern=<layout>` segment is accepted; omit unplaced sheets. +- Custom reference fields: comma-separated exact catalog ids without duplicates, valid only for `custom`; omit for a genuinely novel direction. +- `stroke_width`: `1.5`, `2`, or `3`, only for `tabler-outline`. +- `page_rhythm`: `P` + at least two digits (`P01`, `P100`) followed by `anchor|dense|breathing`. +- `page_visualizations`: `P` + at least two digits followed by `chart|table`, `/`, and one canonical key resolving to one SVG through the matching live index. Legacy `page_charts`: `P` + at least two digits and one bare key; never added to a new lock. +- `pptx_masters`: `<master_key>: <PowerPoint picker name>`. `pptx_layouts`: `<layout_key>: <master_key> | <PowerPoint layout name> | <prototype source>`. `page_pptx_layouts`: `P` + at least two digits followed by a declared Layout key. `page_layouts`: `P` + at least two digits followed by a complete Slide template SVG basename; definition-only `layout_<layout_key>` files are obsolete and invalid as sources. ```markdown ## mode @@ -137,18 +100,8 @@ Catalog-based custom example: ## 5. Machine Validation -```bash -python3 skills/ppt-master/scripts/project_manager.py validate <project_path> -``` - -Validation reports unresolved `[fill...]` placeholders, wrong casing, unknown sections or fields, illegal enums, malformed page keys, missing catalog assets, broken structured-layout references, and unmet conditions. It neither rewrites the lock nor checks semantic projection; Generate Step 4 Gate 2 owns that check. - -Field meaning and selection logic stay in the owning Strategist modules. Executor branch references own consumption behavior. The schema owns only artifact grammar and structural conditions. +`python3 skills/ppt-master/scripts/project_manager.py validate <project_path>` reports unresolved `[fill...]` placeholders, wrong casing, unknown sections or fields, illegal enums, malformed page keys, missing catalog assets, broken structured-layout references, and unmet conditions; it neither rewrites the lock nor checks semantic projection (Gate 2 does). Field meaning stays in the Strategist modules; Executor branches own consumption; the schema owns grammar and structural conditions only. ## 6. Anchor and extension semantics -- Confirmed core palette roles and every declared typography family/size role remain stable cross-page anchors. -- Page-local tints, gradient stops, shadow/glow paints, transparency composites, and one-off export-safe display families may be authored from context without adding a lock row. -- Executor may adjust one occurrence within its declared size role's anchor `±2px` while preserving hierarchy and readability; intermediate values are realization choices, not new lock rows. -- When a contextual value becomes a recurring semantic role, or one undeclared display size reaches its third occurrence, add the descriptive role, read back and validate affected planning fragments, then reuse it. Structural typography outside its applicable anchor band returns upstream immediately. -- Do not expand the lock merely to make an informational checker comparison empty. A lock edit should express reuse or identity, not enumerate incidental literals. +Confirmed core palette roles and every declared typography family/size role are stable cross-page anchors. Page-local tints, gradient stops, shadow/glow paints, transparency composites, and one-off export-safe display families may be authored from context without a row. Executor may adjust one occurrence within its size role's `±2px` band. When a contextual value becomes a recurring semantic role, or an undeclared display size reaches its third occurrence, add the descriptive role, read back and validate affected planning fragments, then reuse it; structural typography outside its band returns upstream immediately. Never expand the lock merely to empty an informational checker comparison — a lock edit expresses reuse or identity, not incidental literals. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/styles/README.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/styles/README.md index fa6caef0..a298f8fa 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/styles/README.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/styles/README.md @@ -1,100 +1,31 @@ # Style Workspaces -**Style = a roster-free reusable communication method plus coordinated design defaults.** It can carry argument flow, page-role vocabulary, evidence and data-expression discipline, visual-system defaults, image/icon direction, and additional review focus. It does not own a current project's communication contract, reusable brand identity, page geometry, SVG prototypes, or a recurring application contract. - -Style is a fourth independent template kind alongside [`brands/`](../brands/), [`layouts/`](../layouts/), and [`decks/`](../decks/). It is not a replacement for the mode or visual-style catalogs. +**Style = a roster-free reusable communication method plus coordinated design defaults**: argument flow, page-role vocabulary, evidence and data-expression discipline, visual-system defaults, image/icon direction, and review focus. It owns no current-project communication contract, brand identity, page geometry, SVG prototypes, or application contract, and does not replace the mode or visual-style catalogs. The shared kind and workspace model lives in the parent [`README.md`](../README.md). ## Axis Separation -| Axis | Meaning | -|---|---| -| Template `kind: style` | A portable workspace that coordinates reusable method and non-binding design defaults | -| Final Stage-2 `mode` | The current deck's confirmed narrative and persuasion skeleton | -| Final Stage-2 `visual_style` | The current deck's confirmed shape, composition, whitespace, typography-character, and texture lock | -| Internal `template_reuse_scope: style` | A flat current-project export plan that reuses no Master/Layout structure | - -These names are separate contracts. Style-only and Style + Brand naturally produce a flat application plan, while a Style installed alongside a Layout or Deck may use structured reuse. `kind: style` therefore never forces the internal reuse scope when another workspace supplies structure. +`kind: style` (a portable workspace of method and non-binding defaults), final Stage-2 `mode` (the deck's confirmed narrative skeleton), final Stage-2 `visual_style` (the deck's confirmed composition and texture lock), and internal `template_reuse_scope: style` (a flat export plan reusing no structure) are separate contracts. Style-only and Style + Brand produce a flat plan; a Style beside a Layout or Deck may use structured reuse — `kind: style` never forces the reuse scope when another workspace supplies structure. ## Selection, Precedence, and Installation -Selection follows the parent README's Default Stage-1 -[`generate-pptx`](../../workflows/generate-pptx.md) template-choice contract. -Its Style choices come only from `styles_index.json`; no -directory scan or bare-name match is allowed. A supplied exact root appears in -the same selector, defaults Stage 1 to template mode, and preselects that -specific candidate only when it is the sole supplied root. A -consulting label or visual description remains a brief and does not activate -this workspace. A non-free confirmation runs the -common installation stage after Stage 1 and before Stage 2; template-aware reading begins -in final Stage 2 from the project-local copy. Quick applies a supplied exact -Style root directly and otherwise uses free design; its current agent reads the -installed copy before authoring flat pages. +Selection follows the parent contract: Style choices come only from `styles_index.json`; a supplied exact root joins the selector and is preselected only when sole; a consulting label or visual description is a brief and never activates a workspace; Quick applies a supplied exact root directly and reads the installed copy before authoring flat pages. | Decision | Precedence | |---|---| -| Current project communication contract, mode, visual style, palette, typography, images, and icons | Latest explicit user instruction and confirmed project values | -| Exact identity values | Brand, then Deck identity; both override overlapping Style fallback values | -| Reusable communication method and evidence discipline | Style, applied only where compatible with the current project contract | -| Reusable structure | Layout when present, otherwise Deck; Style never supplies structure | -| Recurring application context | Deck, subordinate to the current project's Stage-1 communication contract | +| Current contract, mode, visual style, palette, typography, images, icons | Latest explicit user instruction and confirmed project values | +| Exact identity values | Brand, then Deck; both override overlapping Style fallbacks | +| Reusable method and evidence discipline | Style, where compatible with the current contract | +| Reusable structure | Layout, otherwise Deck; Style never supplies structure | +| Recurring application context | Deck, subordinate to the Stage-1 contract | -Style fallback values seed the final Stage-2 solution when the corresponding decision remains open. They are not identity truth and do not bypass confirmation. If a Style method and a Deck application contract materially conflict, surface the mismatch; do not silently weaken either one. +Style fallbacks seed the Stage-2 solution when a decision is open; they are not identity truth and never bypass confirmation. Surface a material Style/Deck conflict rather than weakening either. ## `design_spec.md` Contract -The frontmatter is intentionally small: +Frontmatter: `style_id`, `kind: style`, `summary`, `keywords` (three to five) only. Required body sections: I Style Overview (name, best fit, intent, provenance); II Communication Method (argument flow, page-message discipline, claim treatment, optional mode seed); III Page Role Vocabulary (roles with jobs, evidence obligations, non-geometric tendencies); IV Evidence & Data Expression; V Visual System Defaults (composition, density, decoration, color behavior, typography character, optional visual-style seed and `Fallback Color Scheme` / `Fallback Typography` subsections — lower-priority defaults, never identity); VI Image & Icon Direction (rendering, usage, framing, icon treatment without asset selection); VII Review Focus (checks used only after the user activates visual review, containing exactly one non-localized `<!-- visual-review-trigger: explicit-user-only -->` marker). A preset seed resolves to a real catalog ID; a custom seed carries behavior prose and lists only the catalog references it uses (`Mode References`, `Visual Style References`, `Image Rendering References`). -```markdown ---- -style_id: <slug> -kind: style -summary: <one-line reusable method and design-default fit> -keywords: [<three-to-five discovery tags>] ---- -``` - -The seven required body sections are: - -| § | Title | Owned content | -|---|---|---| -| I | Style Overview | Display name, best fit, reusable intent, and provenance | -| II | Communication Method | Argument flow, page-message discipline, claim treatment, and an optional mode seed | -| III | Page Role Vocabulary | Semantic roles with communication jobs, evidence obligations, and non-geometric composition tendencies | -| IV | Evidence & Data Expression | Claim/evidence trace, chart/table/source behavior, and native-editability preference | -| V | Visual System Defaults | Composition, density, decoration, color behavior, typography character, and optional visual-style/fallback seeds | -| VI | Image & Icon Direction | Rendering, usage, framing, and icon treatment without asset selection | -| VII | Review Focus | Extra checks used only after the user explicitly activates visual review | - -`Fallback Color Scheme` and `Fallback Typography` are optional subsections under §V. They remain lower-priority defaults, never Brand identity. A preset mode, visual style, or image rendering resolves to a real ID in its matching catalog. A custom seed includes its behavior prose and lists only catalog references actually used as comma-separated IDs; use `Mode References`, `Visual Style References`, or `Image Rendering References` respectively. - -Section VII contains exactly one non-localized `<!-- visual-review-trigger: explicit-user-only -->` marker. Its surrounding explanation and checks may use the user's language; the marker lets validation enforce that Review Focus is advisory and never activates visual review. - -**Forbidden — identity, structure, or application ownership**: - -- Do not write `primary_color`, official color provenance, Logo, Voice & Tone, Icon Style, canvas fields, page count/types, `replication_mode`, `native_structure_mode`, or placeholder fields. -- Do not write Template Overview, Signature Design Elements, Page Roster, SVG filenames, Master/Layout identities, slot geometry, fixed page sequences, or reusable application audience/outcome rules. -- Do not write the current project's audience, objective, outcome, core message, delivery context, artifact afterlife, content outline, page assignments, icon inventory, or image-resource list. +**Forbidden — identity, structure, or application ownership**: no `primary_color`, color provenance, Logo, Voice & Tone, Icon Style, canvas fields, page count/types, `replication_mode`, `native_structure_mode`, or placeholder fields; no Template Overview, Signature Design Elements, Page Roster, SVG filenames, Master/Layout identities, slot geometry, fixed sequences, or application audience/outcome rules; no current-project audience, objective, outcome, core message, delivery context, afterlife, outline, page assignments, icon inventory, or image list. ## Workspace and Creation -Every Style workspace contains one portable source file and no page or asset payload: - -```text -<template_workspace>/ -└── templates/ - └── design_spec.md -``` - -Do not create empty `images/`, `icons/`, or `exports/` directories. Existing initialized-project scaffolding may remain untouched but is not Style output. - -1. Enter [`workflows/create-template.md`](../../workflows/create-template.md), which dispatches method/default output to [`create-style.md`](../../workflows/create-template/create-style.md). -2. Validate with `svg_quality_checker.py --template-mode`. -3. In library scope, register with `register_template.py <id> --kind style`. - -The discovery source of truth is [`styles_index.json`](./styles_index.json). -Each entry is `style_id → { summary, keywords }`; the index never duplicates -the full method or defaults. The Default Stage-1 template controls read this -file as their complete registered-Style catalog, and chat discovery returns -exact roots from the same entries. Choosing an entry and submitting Stage 1 -activates installation; -reading a name in ordinary prose does not. +A Style workspace is one file — `<template_workspace>/templates/design_spec.md` — with no page or asset payload; never create empty `images/`, `icons/`, or `exports/`. Enter [`create-template.md`](../../workflows/create-template.md), which dispatches to [`create-style.md`](../../workflows/create-template/create-style.md); validate with `svg_quality_checker.py --template-mode`; in library scope register with `register_template.py <id> --kind style`. [`styles_index.json`](./styles_index.json) maps `style_id → { summary, keywords }` and is the only discovery source; reading a name in prose never activates a workspace. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/create-template.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/create-template.md index 1aa2491c..748c998c 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/create-template.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/create-template.md @@ -4,1005 +4,204 @@ description: Create Template entry workflow and shared contract for the Create B # Create Template Workflow -> **Fixed entry name**: user-facing template creation always enters **Create Template**. This workflow selects exactly one child workflow — [`create-brand.md`](./create-template/create-brand.md), [`create-style.md`](./create-template/create-style.md), [`create-layout.md`](./create-template/create-layout.md), or [`create-deck.md`](./create-template/create-deck.md) — and owns their shared execution contract. -> -> **Role invoked for Create Layout/Create Deck**: [Template_Designer](../references/template-designer.md) +> **Fixed entry name**: template creation always enters **Create Template**, which selects exactly one child — [`create-brand.md`](./create-template/create-brand.md), [`create-style.md`](./create-template/create-style.md), [`create-layout.md`](./create-template/create-layout.md), or [`create-deck.md`](./create-template/create-deck.md) — and owns their shared execution contract. Create Layout/Create Deck invoke the [Template_Designer](../references/template-designer.md) role. Tool behavior (import workspace, template-mode checker, review deck, registrar) is documented in [`template-tools.md`](../scripts/docs/template-tools.md). -Create one reusable template workspace under either the **global template library** or `projects/` from one or more reference channels or a direct user brief, then dispatch to exactly one child workflow. - -**Default — library scope**: Write `skills/ppt-master/templates/<kind_dir>/<template_id>/` and register it in the matching discovery index. - -**Project scope**: Write the same portable workspace routing at `<project>/` and do not register any global index. That project root stays an ordinary referenceable workspace root, and its `templates/` may accumulate one Brand, Style, Layout, and Deck over separate runs. When Layout and Deck coexist, Layout owns the active SVG roster; Deck retains identity and reusable application context. - -**Hard rule — one workspace routing contract**: Output scope changes the workspace parent, Design Spec filename placement, and index registration—not the spec schema or asset routes. Both scopes use required `templates/`, optional `images/` / `icons/`, and optional on-demand `exports/`, with the same relative asset references and validation command. Create Template must not create an optional directory or placeholder file solely to retain an empty path. An initialized project may already contain empty `images/`, `icons/`, or `exports/` scaffolding; leave it untouched, do not count it as template output, and omit the path from completion unless this workflow wrote or adopted a real file there. Do not maintain a library-only self-contained-flat package branch or a project-only thin-bundle branch. - -> **Boundary against existing-deck and in-place structure edits**: Create Template does not fill content into a PPTX, add Master/Layout structure to an existing PPTX/SVG, or directly output the user's final generated deck. It authors a separate reusable workspace; an optional PPTX is review evidence only. To generate a deck, return the workspace root as an exact candidate to [`generate-pptx`](./generate-pptx.md) Step 3, confirm it with Stage 1, then author new SVG pages from the installed state. A project-scoped workspace selected for its own project is consumed in place after that confirmation. - -> **Boundary against page-image reconstruction**: screenshots and page visuals -> in this route are evidence for reusable rules and prototypes. When the user -> instead wants each supplied page image reconstructed into one final editable -> slide, use the Codex-supported [`image-to-pptx.md`](./profiles/image-to-pptx.md); -> do not turn a final-deck request into a template workspace. - -## Child Workflow Dispatch - -Create Template is the fixed user-facing entry and common contract. It selects one child workflow, then that child owns the kind-specific lifecycle. Do not execute two children for one workspace or blend their schemas. - -| Child workflow | Select when | Library-scope output | Exclusive responsibility | -|---|---|---|---| -| [`Create Brand`](./create-template/create-brand.md) | Reuse identity only: colors, typography, logo, voice, and icon style | `templates/brands/<brand_id>/` | Identity analysis and identity-only `design_spec.md`; no SVG roster | -| [`Create Style`](./create-template/create-style.md) | Reuse a communication method and visual direction without identity truth or page prototypes | `templates/styles/<style_id>/` | Method, page-role vocabulary, evidence/data expression, visual defaults, image/icon direction, and advisory review focus; no SVG roster | -| [`Create Layout`](./create-template/create-layout.md) | Reuse a brand-neutral structural skeleton without a recurring communication application | `templates/layouts/<layout_id>/` | Canvas, page grammar, semantic text roles, Master/Layout/slot contract, and SVG roster; no brand identity or application contract | -| [`Create Deck`](./create-template/create-deck.md) | Reuse a branded structural system or a recurring presentation application | `templates/decks/<deck_id>/` | Descriptive application context, integrated identity/structure, and SVG roster | - -Select Create Brand only for identity-only intent. Select Create Style when the portable value is a communication method, evidence discipline, and visual direction but there is no official identity, page geometry, or prototype roster to retain. Select Create Layout only when identity remains downstream-selectable and the reusable artifact does not prescribe communication objectives, audience outcomes, a required narrative sequence, or scenario-specific starting content. Select Create Deck when structure carries brand identity or reusable application semantics. A complete source PPTX alone does not determine the kind: classify only the stable rules worth reusing. Ask one discriminator question only when the user's requested reusable artifact is genuinely ambiguous; once selected, enter that child workflow and do not repeat route selection inside its confirmation gate. - -See [`templates/README.md`](../templates/README.md) for the shared kind and -workspace model. Generate Step 4 Stage 1 owns application/installation: -[`apply-template-workspace`](./stages/apply-template-workspace.md). - -## Output scope — library (default) vs project - -Output scope is a shared Create Template execution choice, not a new template kind or PPTX structure mode. Surface it in the Step 2 brief; do not invent a CLI flag or persist `output_scope` / `target_project` into portable `design_spec.md` frontmatter. +Create one reusable template workspace under the global library (default) or `projects/` from one or more reference channels or a direct brief, then dispatch to one child. | Scope | `<template_workspace>` | `<design_spec_path>` | Registration | |---|---|---|---| -| `library` (default) | `skills/ppt-master/templates/<kind_dir>/<template_id>/` | `<template_workspace>/templates/design_spec.md` | Run `register_template.py` against the matching global index | -| `project` | `<target_project>/` | `<template_workspace>/templates/design_spec.<kind>.<id>.md` | Do not update any global index | +| `library` (default) | `skills/ppt-master/templates/<kind_dir>/<template_id>/` | `templates/design_spec.md` | `register_template.py` against the kind index | +| `project` | `<target_project>/` (initialized by `project_manager.py init`) | `templates/design_spec.<kind>.<id>.md` (kind/id equal frontmatter `kind` / `<kind>_id`) | None; the root stays an ordinary explicit workspace whose `templates/` may accumulate one Brand, Style, Layout, and Deck over separate runs — Layout owns the active roster when both coexist, Deck keeps identity and application context | -**Design Spec naming**: follow [`templates/README.md`](../templates/README.md): `library` writes `templates/design_spec.md`; `project` writes `templates/design_spec.<kind>.<id>.md`, whose kind/id MUST equal frontmatter `kind`/`<kind>_id`. One project root carries at most one spec per kind and later contributes every exposed kind. +**Hard rule — one workspace routing contract**: scope changes the parent path, spec filename, and registration — never the spec schema or asset routes. Both scopes use required `templates/`, optional `images/` (every bitmap; SVG href `../images/<name>`) and `icons/imported/` (one canonical copy of each imported decoration vector), and conditional `exports/` (review evidence, required for multi-Master templates, Git-ignored in the library, never consumed by application). Never create an optional directory or placeholder solely to keep an empty path; leave pre-existing empty project scaffolding untouched and omit it from completion. Create Style contributes only its spec. Do not maintain a library-only flat package or project-only thin-bundle branch. -Both scopes write this contract: +**Boundaries**: Create Template never fills content into a PPTX, adds Master/Layout structure to an existing PPTX/SVG, or outputs the user's final deck — it authors a separate workspace whose root returns to [`generate-pptx`](./generate-pptx.md) Step 3 as an exact candidate (a project-scoped workspace selected for its own project is consumed in place). Page images that should become final editable slides use [`image-to-pptx.md`](./profiles/image-to-pptx.md), not a template. -```text -<template_workspace>/ -├── templates/ # library: design_spec.md; project: one qualified spec per kind plus the effective Layout-or-Deck SVG roster -├── images/ # optional; every bitmap; SVG href is ../images/<name> -├── icons/ -│ └── imported/ # optional; one canonical copy of imported decoration vectors -└── exports/ # conditional; required package evidence for multi-Master templates -``` +## Child Workflow Dispatch -Create Style narrows its contribution to the resolved `<design_spec_path>`. It -does not write or adopt images, icons, native payloads, or review exports; -pre-existing empty project scaffolding remains untouched and is not Style -output. +| Child | Select when | Library output | Exclusive responsibility | +|---|---|---|---| +| Create Brand | Reuse identity only: colors, typography, logo, voice, icon style | `templates/brands/<brand_id>/` | Identity-only spec; no SVG roster | +| Create Style | Reuse a communication method and visual direction without identity truth or prototypes | `templates/styles/<style_id>/` | Method, page-role vocabulary, evidence expression, visual defaults, image/icon direction, advisory review focus; no roster | +| Create Layout | Reuse a brand-neutral structural skeleton without a recurring application | `templates/layouts/<layout_id>/` | Canvas, page grammar, semantic text roles, Master/Layout/slot contract, SVG roster; no identity or application contract | +| Create Deck | Reuse a branded structural system or a recurring application | `templates/decks/<deck_id>/` | Descriptive application context, integrated identity/structure, SVG roster | -The review PPTX is derived evidence, not a source template asset. Create `exports/` only when a review deck is requested or the template declares more than one Master; multi-Master templates require the package-level gate in Step 6. Brand/Layout/Deck application reads `templates/` plus any package-owned `images/` and `icons/`; Style reads only its resolved Design Spec. No kind copies or consumes `exports/`. Library `exports/` directories are Git-ignored. - -For `project`, `target_project` is required and must be an existing project initialized by `project_manager.py init`. Before the first final-output write, run one complete preflight. Apply the same collision checks to a library workspace; the only difference is that its root is under the global kind directory: - -1. Resolve `<template_workspace>` from the confirmed scope and confirm its required `templates/` destination plus any needed `images/` / `icons/` destinations. -2. For `library`, confirm `<template_workspace>/templates/` is empty. For `project`, reject a bare `design_spec.md`, any existing spec of the selected kind, or any invalid qualified-name set. All distinct kinds may coexist. Resolve active structure before writing: Layout when present, otherwise Deck. Adding Deck beside Layout leaves the Layout roster untouched; adding Layout beside Deck atomically replaces the active Deck structural payload only after the new Layout passes isolated validation. -3. Resolve every final bitmap and extracted-vector filename, then confirm none would overwrite an existing file in `images/` or `icons/imported/`. Check the review-PPTX destination when preview export was requested or a multi-Master template was confirmed. - -Any failed check aborts before writing the Design Spec, SVGs, images, icons, or the review PPTX. A library source remains empty-before-write; a project source preserves every non-conflicting sibling kind and replaces only a lower-priority Deck structural payload when a validated Layout takes ownership. Never overwrite an unrelated name conflict. Temporary analysis and structural-transition workspaces remain allowed because they are not final outputs. +A complete source PPTX does not determine the kind — classify only the stable rules worth reusing. Ask one discriminator only when the requested artifact is genuinely ambiguous; once selected, never reopen kind selection inside the child's gate, execute two children for one workspace, or blend schemas. Shared kind and workspace model: [`templates/README.md`](../templates/README.md); application: [`apply-template-workspace`](./stages/apply-template-workspace.md). ## Process Overview ``` -Reference Bundle Intake & Analysis -> Fact-Based Brief Proposal -> User Confirmation Gate -> Preflight + Invoke Selected Child -> Validate Child Output -> [Structured Review PPTX: optional for one Master, required for multi-Master] -> [Register Library Index] -> Output +Reference Bundle Intake & Analysis → Fact-Based Brief Proposal → User Confirmation Gate → Preflight + Invoke Selected Child → Validate Child Output → [Review PPTX: optional for one Master, required for multi-Master] → [Register Library Index] → Output ``` -The first three steps derive the brief from facts, not guesses. **No final template directory may be created and no template SVG / `design_spec.md` may be written until `[TEMPLATE_BRIEF_CONFIRMED]` is emitted in Step 3.** Reference-analysis intermediates produced by `pptx_template_import.py` (typically under `/tmp/pptx_template_import/`) are explicitly **not** subject to this gate — they are temporary workspaces feeding Step 2. - -After dispatch, the selected child workflow executes these shared steps with its kind fixed. Child-owned fields and validation rules come from that workflow; Create Template supplies the common mechanics and never reopens the child selection. +**No final template directory, template SVG, or Design Spec may be written until `[TEMPLATE_BRIEF_CONFIRMED]` is emitted in Step 3.** Reference-analysis intermediates (import workspaces under `/tmp/`) are not subject to this gate. --- ## Step 1: Reference Bundle Intake & Analysis -Run every applicable input branch for the reference bundle the user supplied. A bundle may contain one source, several files of one type, multiple source types, direct text in the conversation, or no external file. This step produces analysis artefacts only — it does **not** create the final template directory, write `design_spec.md`, or touch any template index. When Create Brand or Create Style was selected, follow that child workflow's analysis rules and do not run page-topology analysis merely because the reference is a PPTX/PDF. +Run every applicable branch for the bundle (one source, several files, mixed types, direct text, or nothing); produce analysis only. Create Brand/Create Style follow their child analysis rules and never run page-topology analysis merely because the reference is a PPTX/PDF. -### Input source taxonomy +| Type | Supplied | Tool / read path | Strategies the evidence supports | +|---|---|---|---| +| **A** `.pptx` | A `.pptx` path | `pptx_template_import.py` → import workspace ([`template-tools.md`](../scripts/docs/template-tools.md)) | `standard` / `fidelity` / `mirror` | +| **B** SVG assets | `projects/<x>/svg_output/`, a current workspace root, or a loose `.svg` folder | Normalize the source, create an authoring IR bundle with `svg_authoring_view.py`, run the readability pass on that IR only; read companion `design_spec.md` / `spec_lock.md` | `standard` / `fidelity`; `mirror` only with a complete explicit Master/Layout/placeholder/native-object contract | +| **C** Images / visuals | PNG/JPG/WebP, screenshots, moodboards, PDF pages | `ls` + `Read` each visual (multimodal) | `standard` only by itself | +| **D** Text / document / website / assets | Direct text, Markdown/TXT, DOCX/PDF/HTML/URL, brand manuals, logo/icon/font assets | Direct text as-is; convert documents/URLs with `source_to_md.py` into a temporary analysis workspace; inventory explicit assets | `standard` only by itself | +| **E** Nothing | A request with no source and no substantive brief | Skip analysis; collect every Required value in Steps 2–3 | `standard` only | -The rows are evidence channels, not mutually exclusive routes. Run every matching row and retain source-level provenance. The internal-strategy column applies to Create Layout/Create Deck. Create Brand uses the same reference formats for identity evidence, while Create Style extracts portable method and direction; neither has a replication strategy, SVG roster, or native-structure path. +**Bundle rules**: `standard` may combine every confirmed channel — never force one source type. The AI derives the internal strategy from natural-language intent plus evidence (`fidelity` needs A/B page evidence; `mirror` needs A or a complete current B contract; C/D/E supplement but never create native topology) and never asks the user to choose these labels. Keep facts, explicit user decisions, and AI suggestions distinct; surface contradictions in Step 2. Supplemental inputs may explain a confirmed `mirror` source but cannot alter its graph or visuals. -| Type | What the user supplied | Tool / read path | Internal strategies supported by the evidence | -|------|-------------------------|------------------|-----------------------------------------------| -| **A** `.pptx` reference | A `.pptx` file path | `pptx_template_import.py` → `analysis/manifest.json` + `analysis/native_structure.json` + `sources/source.pptx` + layered SVGs + semantic resource directories; flat verification SVGs are opt-in | `standard` / `fidelity` / `mirror` | -| **B** Existing SVG assets | `projects/<x>/svg_output/`, a current template workspace root, or a loose `.svg` folder | Normalize the source directory, create an editable authoring IR bundle with `svg_authoring_view.py`, then use its page SVGs; also read companion `design_spec.md` / `spec_lock.md` when present | `standard` / `fidelity`; `mirror` only when the source already carries a complete explicit Master/Layout/placeholder/native-object contract | -| **C** Image / visual references | PNG/JPG/WebP images, screenshots, moodboards, PDF page visuals, or a visual-reference folder | `ls` + `Read` each supplied visual or PDF (multimodal recognition) | `standard` only by itself | -| **D** Text / document / website / asset references | Direct conversation text, pasted requirements, Markdown/TXT, DOCX/PDF/HTML/URL, brand/design manuals, or supplied logo/icon/font assets | Use direct text as-is; read plain text/Markdown; convert supported documents/URLs with `source_to_md.py` into a temporary analysis workspace; inventory explicit assets | `standard` only by itself | -| **E** No reference material | A template request with no external source and no substantive brief yet | Skip analysis; collect every required value in Steps 2–3 | `standard` only | - -**Roster-free child boundary**: Create Brand and Create Style do not enter the -structured import/materialization path below. Their child workflows may inspect -PPTX/PDF pages, extracted text, screenshots, or other sources as evidence, but -they do not preserve or derive canvas, page count/order, Master/Layout identity, -placeholder geometry, or an SVG roster. Create Brand extracts identity truth; -Create Style extracts only portable communication method and visual defaults. -The Type A/Type B authoring-IR and `standard` / `fidelity` / `mirror` mechanics -below are Create Layout/Create Deck concerns. - -| Bundle rule | Behavior | -|---|---| -| Combine channels | `standard` may use every confirmed visual, textual, documentary, web, and asset source together. Do not force the user to choose one source type. | -| Derive the execution strategy | The AI translates the user's natural-language intent plus source evidence into an internal strategy. `fidelity` requires Type A or B page evidence. `mirror` requires Type A or a complete current Type B structure contract. Type C/D/E evidence may supplement an eligible bundle but never creates native topology. Do not ask the user to choose these implementation labels. | -| Preserve provenance | Keep facts, explicit user decisions, and AI suggestions distinct. Surface contradictions in Step 2 instead of resolving them silently. | -| Protect mirror | Supplemental text, images, websites, or assets may explain the source but cannot alter a confirmed `mirror` graph or visuals. Use `standard` / `fidelity` when the user wants those inputs to change the resulting system. | - -Type A is the canonical mirror path: analysis manifests/inheritance own surviving -native structure; `authoring-svg/` is new compact editable SVG projected from -that evidence. Lossless `svg/` is immutable validation/non-visible-payload -backing, never visible authoring. Optional flat files verify full pages only. In -`standard` / `fidelity`, imported facts/visuals do not define output topology. - -**Type B source normalization**: when the supplied root exposes any `templates/` Design Spec, use `<input>/templates/` as the SVG/spec source and resolve its workspace assets from sibling `<input>/images/` and `<input>/icons/`. Otherwise, treat the supplied directory only as a loose SVG evidence source. Directory flatness is not a semantic-structure signal and never makes it a reusable workspace. - -Type B is supported with caveats: - -- **mirror on type B** — require a complete current explicit source contract. Preserve page count/order, similar presentation, each source Slide's declared Layout/Master chain, slot metadata, supported native-object metadata, and source ownership in the **new** workspace; SVG code and node identity need not match. Page type for `<NNN>_<page_type>.svg` is read from the source filename when it follows the PPT Master naming convention (`01_cover.svg` → `cover`, `03a_content_two_col.svg` → `content`); fall back to `content` otherwise. A loose visual-only SVG folder has no native structure to preserve and cannot use mirror. Unreferenced identities are not mirror output. -- **fidelity on type B** — inspect the complete page roster as visual reference, then design a broader new roster and its own Master/Layout/slot system. Existing keys, families, and repeated source chrome are not output-topology inputs. -- **legacy or unstructured type B** — old `baseline` / `preserve` / `layout_strategy: distill` / `data-pptx-layout-kind` / direct-atomic-placeholder inputs, and SVGs with no root Master identity, are visual/contextual reference for `standard` / `fidelity` only. Author a new current contract in the output workspace. Use the original PPTX Type A path when existing native Master/Layout facts must be mirrored; do not mutate the SVG source or claim topology recovery from incomplete metadata. -- **selected free-design subset on type B** — ingest only the explicitly named pages as visual reference, then author a new current structured contract in the output workspace. Do not scan or copy the whole `svg_output/` directory or silently turn unselected pages into template variants. - -**Internal creation-strategy boundary**: These three labels are internal. -`standard` / `fidelity` review all source structure, then author a compact or -broader source-aligned roster with one Slide prototype per retained Layout. -`mirror` authors compact parsed SVG for every source Slide, preserving reachable -graph, meaning, ownership, and similar presentation—not code identity. Create -Layout mirror requires a brand/application-neutral contract; otherwise re-author -a Layout or retain a Deck. Future decks need not keep source page count/order. +**Internal strategies**: `standard` / `fidelity` review all source structure, then author a compact or broader source-aligned roster with one Slide prototype per retained Layout; `mirror` authors compact parsed SVG for every source Slide, preserving the reachable graph, meaning, ownership, and similar presentation — not code identity. Create Layout mirror requires a brand/application-neutral contract. Future decks need not keep source page count/order. ### 1A. `.pptx` reference -Run the unified preparation helper: +Run `pptx_template_import.py "<reference.pptx>"`. Type A is the canonical mirror path: analysis manifests and inheritance own surviving native structure; `authoring-svg/` is the compact editable projection Template_Designer inspects and may redraw while preserving meaning, structure, and similar presentation; lossless `svg/` is immutable validation and non-visible-payload backing, never visible authoring; optional `svg-flat/` verifies full pages. In `standard` / `fidelity`, imported facts do not define output topology. Never copy lossless or flat pages into `templates/`; for Type A `mirror`, `mirror_template_materialize.py` validates and publishes after review, fidelity edits, and the readability pass, and authored modes never use it. -```bash -python3 skills/ppt-master/scripts/pptx_template_import.py "<reference_template.pptx>" -``` +**Explicit complex-SVG picture normalization** (`standard` / `fidelity` only): when one imported native group is deliberately retained as one complex SVG picture rather than rebuilt as editable paths, select its exact id in the layered IR with `extract_svg_pictures.py ... --select "<group_id>" --resource-root "<import_workspace>" --images-dir "<import_workspace>/picture-assets" --inplace` (repeat `--select` for independent siblings; select the outer group when an ancestor carries a transform, style, clip, or opacity). If chosen for a Master or Layout, copy the asset into the image pool and author the fixed atom as a direct `<image data-pptx-layer="master|layout">`. This is a semantic decision, never automatic, never by repetition, never a way to infer ownership; not for placeholders, individual native shapes, table/chart fallbacks, icon placeholders, authored presets, or `mirror`. -This produces, in one workspace: +**Read order**: `standard` / `fidelity` read `analysis/manifest.json`, exported resources, `svg/inheritance.json`, `authoring_summary.json`, and every cleaned layered IR document (Masters, Layouts, Slides — the complete read surface, including Layouts unused by any sample slide); flat pages are optional spot checks; never `authoring_manifest.json`. `mirror` reads both manifests, inheritance, the summary, every source Slide SVG, and only reachable Master/Layout SVGs. Use manifest facts for orientation and screenshots or the original PPTX only for visual cross-checking; never bulk-read opaque payload. -- `analysis/manifest.json` — source facts: slide size, theme colors, fonts, per-master theme summaries, resource inventory, placeholder metadata, SVG file paths, per-slide / per-layout / per-master metadata (including source-owned inherited-shape visibility), and page-type candidates -- `analysis/native_structure.json` — stable Master/Layout keys, picker names, placeholder type/index/geometry, inherited-shape visibility, source hash, and source-graph quality facts -- `sources/source.pptx` — byte-preserved backing package for visual/package cross-checking and source identity validation; it is not copied into the final template package or used to replace authored visible SVG -- `images/` — PowerPoint image media, including raster images and SVG/EMF/WMF; `analysis/manifest.json` owns the asset-name mapping and SVG `href` values reuse it -- `sounds/`, `audio/`, `video/`, and `native-payloads/` — conditional semantic resource directories; only populated directories are created -- `validation/conversion-report.json` — source-recovery and fidelity diagnostics; retain it for audit because these warnings are not duplicated in the structural manifests -- `svg/` — **primary view** (layered template view): - - `svg/master_*.svg` — every slide master in the deck rendered once, including masters that no sample slide currently uses (template packages routinely ship more masters than the visible samples reference) - - `svg/layout_*.svg` — every slide layout in the deck rendered once (its own contribution; master shapes do **not** repeat here) - - `svg/slide_NN.svg` — each slide's own shapes and slide-local background; master / layout shapes and backgrounds are **not** inlined here - - `svg/inheritance.json` — which Layout/Master each Slide consumes plus source-owned `showInheritedShapes` / `showMasterShapes` booleans; Layout shapes follow the Slide's `showInheritedShapes`, while Master shapes require that value and the referenced Layout's `showMasterShapes`; backgrounds remain independent -- `svg-flat/` — **optional verification view** (only with `--inheritance-mode both`; one self-contained SVG per slide): - - `svg-flat/slide_NN.svg` — effective Master/Layout contributions permitted by the source visibility flags plus Slide-local content, painted into one SVG so opening any slide on its own shows the full page like PowerPoint would. Background inheritance remains independent. Use this for previews / screenshot pipelines / "what does the slide actually look like" sanity checks. -- The default `--inheritance-mode layered` emits only the canonical layered view. Pass `both` when a separate complete-page verification tree is worth the storage cost, or `flat` when a projection-only self-contained `svg/` tree without master/layout/inheritance files is explicitly required. Imported-deck round-trip uses the separate `authoring-svg-flat/` contract. -- The importer does not generate a duplicate narrative summary or persistent SVG-size CSV. Read compact facts from `analysis/manifest.json`; run ad hoc size measurements outside the canonical workspace when needed. - -Import fidelity rules: - -- Placeholder metadata is recorded in `analysis/manifest.json`; master / layout SVGs show lightweight dashed guides with labels only in `svg/`, not in `svg-flat/`. -- Charts, SmartArt, diagrams, and OLE objects are typed placeholders in `svg/`. In `svg-flat/`, they use a preview image with a small badge when one exists; otherwise they stay visible as placeholders. Tables are converted to real SVG. -- Missing media and external linked images fail the import. EMF / WMF Office vector media are converted to PNG previews when supported by the local toolchain; otherwise the import fails. - -It is an analysis aid, not a final direct template conversion. - -**Immutable source evidence + compact editable authoring SVG**: Keep `svg/` -unchanged for validation and supported non-visible payload; it is never visible -template source. Keep optional `svg-flat/` unchanged. The import transaction -also writes canonical compact `authoring-svg/` and, with `both`, its flat view; -no second projection precedes Template_Designer review. - -The bundle contains compact SVGs, model-readable `authoring_summary.json`, and -tool-only `authoring_manifest.json`. Projection removes opaque/duplicate/import- -only carriers while retaining visible intent, compact frame/preset and structure -markers, ids, assets, inline Chart/Table JSON, and per-object source refs. -Model-facing safe page coordinates use at most two decimals; crop/path/matrix -values and lossless evidence retain required precision. The summary indexes the -roster/counts. The manifest owns source paths/hashes and initial subtree hashes, -never duplicates opaque payload, and MUST NOT enter model context. Refs are -document-local and tool-resolved. - -In-place vector and picture normalization refreshes the summary automatically. -After any other direct IR edit, refresh it before the next analysis pass: - -```bash -python3 skills/ppt-master/scripts/svg_authoring_view.py "<import_workspace>/authoring-svg" --refresh-summary -``` - -`authoring-svg/` is canonical visible authoring. Template_Designer inspects each -required document and may redraw/normalize it while preserving meaning, -structure, and similar presentation. Lossless trees support provenance and -non-visible/explicit-break recovery only; never edit/copy them or replace a -visible authored subtree. Validate/publish to `templates/*.svg` before -preview/export. - -For Type A `mirror`, `mirror_template_materialize.py` validates/publishes but -does not author visible design. Run it only after Template_Designer review, -needed fidelity edits, and the vector-readability pass. Never copy lossless or -flat pages into `templates/`. -`standard` / `fidelity` remain newly authored Template_Designer output and do -not use this compiler. - -**Creation-time vector readability**: - -`pptx_template_import.py` factors only large non-semantic decorative vector -groups while the import workspace is still staged. The first published -`authoring-svg/` files therefore already contain compact -`<use data-icon="imported/..." data-pptx-asset-role="decoration"/>` -references; do not run a second in-place readability or compaction pass. -`--inheritance-mode both` reuses the layered inventory while creating the -optional flat view, so only genuinely flat-only vectors create another asset. - -Extracted assets have one canonical copy under -`<import_workspace>/icons/imported/`; never duplicate them under -`templates/icons/`. The root `icons/` directory remains a namespace container -and must not contain rewritten page SVGs or inventories. Every imported asset -root, placeholder, and v2 inventory record declares the `decoration` role. Any -subtree containing a semantic marker, text, table, chart, relationship, or -other meaning-bearing content remains inline; extraction and both consumers -fail closed if that boundary is crossed. Eligible decoration records may -retain `data-pptx-source-ref`, so re-inlining re-establishes their object -mapping before materialization. The existing icon embedding path re-inlines -the extracted assets before final export, preserving multi-color artwork and -non-square viewBox geometry as native SVG shapes. Referenced defs (`gradient` -/ `pattern` / `filter` / `clipPath` / `marker`) are copied into each asset and -namespaced so the asset is self-contained after re-inline. - -The layered pass owns the canonical extracted-vector pool. Each new asset records a source fingerprint before generated ID namespacing. The flat pass MUST consume the layered inventory through `--reuse-inventory`: an exact fingerprint match writes only a `<use>` reference to the existing layered asset, while an unmatched flat-only subtree may create one new asset under the `flat` prefix. Do not independently extract the two views into parallel asset sets. With `--clean-stale`, a rerun also removes obsolete generated `flat_*` duplicates while retaining every reused layered reference. - -**Explicit complex-SVG picture normalization (optional; `standard` / `fidelity` only)**: - -When one imported native group is deliberately being retained as one complex -SVG picture rather than rebuilt as editable paths, select its exact id in the -layered authoring IR and normalize it explicitly: - -```bash -python3 skills/ppt-master/scripts/extract_svg_pictures.py \ - "<import_workspace>/authoring-svg/<layered_svg_file>.svg" \ - --select "<group_id>" \ - --resource-root "<import_workspace>" \ - --images-dir "<import_workspace>/picture-assets" \ - --inplace -``` - -Repeat `--select` for multiple independent sibling groups. The tool uses an -imported `data-pptx-frame` when present; otherwise it measures the target with -Playwright, or accepts `--bounds ID=x,y,width,height`. It creates a tight, -self-contained SVG under `picture-assets/`, embeds reachable local resources, -and replaces the group at the same z-order with one `<image>`. If the object is -chosen for a final Master or Layout, copy that asset into the project image -pool and author the final fixed atom as a direct `<image>` with -`data-pptx-layer="master|layout"`; export then creates one `p:pic`. -Nested targets are allowed only below metadata-only grouping wrappers. If an -ancestor carries a transform, style, clip, opacity, or other visual attribute, -select that outer group so the effect is not applied twice. - -This is a semantic representation decision, not an import heuristic. Never run -it automatically, never select groups by repetition, and never use it to infer -Master/Layout ownership. Do not apply it to placeholders, individual imported -native shapes, native table/chart fallbacks, icon placeholders, or compact -authored presets. `mirror` must keep the source native group/picture identity -and therefore must not use this normalization. The original lossless `svg/` -tree remains immutable source/package evidence; the reviewed compact authoring -tree owns visible output. Any optional `svg-flat/` tree remains unchanged but -is verification-only. - -`extract_svg_assets.py` remains a different operation: it factors vectors out -for model readability and re-inlines them as native shapes before export. It -does not turn those vectors into a picture. - -**Read order during analysis**: - -| Mode | Required read set | -|---|---| -| `standard` / `fidelity` | `analysis/manifest.json`, exported semantic resources, `svg/inheritance.json`, `authoring-svg/authoring_summary.json`, and every cleaned layered IR document (`authoring-svg/master_*.svg` / `layout_*.svg` / `slide_NN.svg`). Do not read `authoring_manifest.json`; it is compiler-only. The layered IR is the complete read surface: it covers Layouts unused by any sample slide (invisible in `svg-flat/` yet still template vocabulary), and per-page composition follows from `inheritance.json`. Cleaned flat pages are optional composition spot checks, not a required second pass over the same shapes. Source topology remains non-binding; the two modes differ in output design (`fidelity` designs a broader roster covering the useful visual range), not in read coverage. | -| `mirror` | Read both analysis manifests, inheritance, authoring summary, every source Slide SVG, and only reachable Master/Layout SVGs. Do not read the tool-only manifest; the publisher validates that set. Layered `authoring-svg/` is the sole visible edit/publication input and Template_Designer may redraw it. Flat views are optional checks; lossless backing validates facts and supplies supported non-visible semantics only. | - -Use the compact facts in `analysis/manifest.json` for orientation. Use screenshots or the original PPTX only for visual cross-checking. Do not bulk-read opaque lossless payload into model context. - -Interpretation rule (carries forward into Steps 2 and 4): - -- `analysis/manifest.json` is the source of truth for facts about the source deck: slide size, theme colors, fonts, background inheritance, reusable resource inventory, declared source layout/master structure, and slide reuse relationships. It dictates which source facts mirror may preserve during materialization, but not `standard` / `fidelity` output topology. -- `authoring_summary.json` is the model-facing index for the current authoring SVG roster and readability statistics. Regenerate it after direct IR edits before analysis. -- `authoring_manifest.json` is machine-only provenance. Do not open or quote it in model context; the mirror compiler validates it internally against the edited IR and immutable backing. -- `analysis/native_structure.json` is the source of truth for source PowerPoint identity: stable layout keys, picker names, parent masters, placeholder types/indices, and the source-package hash. Mirror preserves facts reachable from source Slides one-to-one. `standard` / `fidelity` inspect the complete inventory as evidence but author new identities and ownership. -- `analysis/manifest.json`, `analysis/native_structure.json`, and `svg/inheritance.json` intentionally overlap only at contract boundaries so materialization can cross-check source identity, graph ownership, and visibility; do not collapse them into a cache or substitute one for another -- exported `images/` are the canonical reusable image pool — `<image>` references in `svg/` already point at these files directly; SVG/EMF/WMF image media stay in this pool rather than moving to a generic asset directory -- exported `icons/imported/*.svg` files are the canonical reusable decoration pool, but they are **not** part of the default read set. Use `authoring_summary.json` `icon_refs` and the cleaned SVGs first. Query `*_vector_asset_inventory.json` by an exact asset id only when source-ref or fingerprint detail is required; do not load the complete inventory into model context. Open a specific imported SVG only when that decoration affects the current design decision. -- cleaned layered authoring SVGs are the mirror editing and verification surface; they expose source ownership without requiring the model to read opaque payload. Do not use them to promote, demote, merge, or split source structure. -- cleaned complete-page IR documents are optional composition spot checks for authored modes and verification views for mirror. They never replace the layered editable IR or immutable payload backing. -- screenshots remain useful for judging composition and style, but should not override extracted factual metadata unless the import result is clearly incomplete - -**Mirror reachable-graph gate**: Before offering `mirror`, compare every source -Slide and referenced Layout/Master with the authoring summary. Missing reachable -SVG/evidence or ambiguous parentage blocks. Omit unused identities. The -publisher verifies source SHA, refs, graph/assignment closure, and subtree hash -status; an authored change never triggers visible XML restoration. +**Mirror reachable-graph gate**: before offering `mirror`, compare every source Slide and referenced Layout/Master with the authoring summary; missing reachable evidence or ambiguous parentage blocks; omit unused identities. The publisher verifies source SHA, refs, graph/assignment closure, and subtree hashes; an authored change never triggers visible XML restoration. ### Basic norm extraction (mandatory when reference content exists) -Before composing Step 2, extract the template's reusable norms from the previous content. These norms are not generic design advice; they are the source deck's observable operating rules, and they must flow into `design_spec.md`. - -This table applies to Create Layout/Create Deck. Create Brand extracts only the -identity subset defined by its child workflow. Create Style instead extracts -argument flow, page-message/evidence discipline, open page-role vocabulary, -data-expression rules, composition/density rhythm, visual defaults, and -image/icon direction. It must discard source-specific audience, objective, -page order/count, page mappings, canvas, and native structure. +Extract the source's observable operating rules — not generic design advice — so they flow into `design_spec.md`. Create Brand extracts only the identity subset; Create Style extracts argument flow, message/evidence discipline, open page-role vocabulary, data-expression rules, composition/density rhythm, visual defaults, and image/icon direction while discarding source-specific audience, objective, page order/count, mappings, canvas, and structure. Create Layout/Create Deck extract: | Norm area | Extract from | Record as | |---|---|---| -| Canvas / page geometry | `analysis/manifest.json` slide size, SVG `width` / `height` / `viewBox` | `[fact]` canvas format, pixel dimensions, source `viewBox`, and aspect ratio | -| Identity system | theme colors, font usage, logo / emblem assets, recurring backgrounds | `[fact]` when imported; `[suggested]` only for visual estimates | -| Layout grammar | masters / layouts, repeated chrome, margins, columns, card grids, section dividers | Template-specific rules, not generic spacing boilerplate | -| Image system | image crops/clips, scrim/overlay treatments, baked-alpha treatments, full-bleed zones, hero-image placement, mosaic rules, captions | Template-specific image-placement rules with source examples | -| Density rhythm | title scale, content block count, whitespace balance, dense vs. breathing pages | Page-type guidance for Strategist / Executor | -| Page roster semantics | cover / TOC / chapter / content / ending variants and their intended content slots | `design_spec.md §V Page Roster` rows | -| Asset policy | source images / icons / textures that are part of the template vs. sample-only content | `design_spec.md §VI Assets` or omit sample-only assets | -| Native PowerPoint structure | `analysis/native_structure.json` plus inheritance facts | Mirror maps each source Slide's reachable chain one-to-one. Standard/fidelity review the complete inventory, then author a compact or broader useful graph expressed through Slide prototypes. | +| Canvas / page geometry | Manifest slide size, SVG `viewBox` | `[fact]` canvas format, pixel dimensions, source `viewBox`, aspect ratio | +| Identity system | Theme colors, font usage, logo assets, recurring backgrounds | `[fact]` when imported; `[suggested]` for visual estimates | +| Layout grammar | Masters/layouts, repeated chrome, margins, columns, card grids, dividers | Template-specific rules, not generic spacing | +| Image system | Crops/clips, scrims, baked alpha, full-bleed zones, hero placement, mosaics, captions | Template-specific placement rules with source examples | +| Density rhythm | Title scale, block count, whitespace, dense vs breathing pages | Page-type guidance | +| Page roster semantics | Cover / TOC / chapter / content / ending variants and slots | `design_spec.md §V` rows | +| Asset policy | Template-owned vs sample-only images/icons/textures | `§VI` or omit sample-only assets | +| Native structure | `native_structure.json` plus inheritance | Mirror maps each source Slide's reachable chain one-to-one; authored modes review the inventory and author a new graph through Slide prototypes | -Distinguish observed facts from template rules: "`slide_07` uses a left photo crop" is a fact; "content pages may use a left photo rail for location / product / case-study pages" is the reusable rule. - -**Read gate**: - -- `standard` / `fidelity`: read `authoring_summary.json`, every layered IR Master, Layout, and Slide, and the inheritance map; flat pages are optional spot checks -- `mirror`: read `authoring_summary.json`, verify every source Slide and its referenced Layout/Master plus the inheritance map, report retained and omitted identities, and leave `authoring_manifest.json` to the compiler - -Authoring SVGs are not installed assets. `standard` / `fidelity` author new -SVGs; mirror reviews/edits compact parsed SVG, then publishes it with source -validation and supported non-visible recovery only. - -> **Mirror authoring/publication** — Native structure/inheritance own structure; -> layered `authoring-svg/` owns compact editable visuals; lossless/flat trees are -> validation/non-visible backing only. Template_Designer owns visible fidelity; -> the publisher validates/composes the current tree and reachable graph without -> copying lossless visible subtrees. +"`slide_07` uses a left photo crop" is a fact; "content pages may use a left photo rail for case-study pages" is the reusable rule. ### 1B. Existing SVG assets -First resolve the Type B source directory using the rule above. Create a non-destructive authoring IR bundle in a throwaway analysis workspace, then run the same vector readability pass only on that IR. Do **not** rewrite the user's original source directory in place. - -```bash -python3 skills/ppt-master/scripts/svg_authoring_view.py "<normalized_svg_source>" -o "<svg_analysis_workspace>/authoring-svg" --projection-kind generic -python3 skills/ppt-master/scripts/extract_svg_assets.py "<svg_analysis_workspace>/authoring-svg" --icons-dir "<svg_analysis_workspace>/icons" --icon-namespace imported --inplace --id-prefix source --min-decoration-bytes 3000 --clean-stale -``` - -If the source contains one deliberately selected complex subtree that should -remain a single SVG picture, apply the explicit normalization above only to the -analysis IR. Set `--resource-root` to the narrowest workspace directory -that contains both the IR and every local dependency referenced by the -selected group. This does not authorize automatic group selection or mutation -of the user's original SVG directory. - -Then read `authoring-svg/authoring_summary.json`, `ls` the analysis workspace, -and read every cleaned `authoring-svg/*.svg` to extract: - -- canvas size (`viewBox` on the root `<svg>`) -- recurring colors (`fill` / `stroke` values; identify the dominant 2–4 hex codes as candidate theme colors) -- fonts (`font-family` attributes on `<text>`) -- placeholder usage (existing `{{...}}` strings, if any) -- structural decoration (recurring `<rect>` bars, `<path>` motifs, embedded `<image>` references) - -Use `authoring_summary.json` `icon_refs` before opening individual -`<svg_analysis_workspace>/icons/imported/*.svg`. Query the generated -`*_vector_asset_inventory.json` by exact asset id only when provenance, -source-ref, or fingerprint detail is required. Do not bulk-read the inventory -or extracted vectors unless a specific asset affects a design decision or is -selected for mirror preservation. - -If a `design_spec.md` or `spec_lock.md` accompanies the SVGs, read it too. In mirror it is part of the source contract and must agree with the SVG identities; in `standard` / `fidelity` it is visual/contextual reference only. Record the equivalent of a `manifest.json`'s factual fields in analysis notes so Step 2 can label them `[fact]`. +Resolve the Type B source: a root exposing any `templates/` Design Spec uses `<input>/templates/` plus sibling `images/` / `icons/`; otherwise the directory is loose evidence (flatness is not a structure signal). Build the throwaway IR bundle per [`template-tools.md`](../scripts/docs/template-tools.md), then read `authoring_summary.json`, `ls` the workspace, and every cleaned `authoring-svg/*.svg` for canvas, recurring colors (dominant 2–4 hex as candidate theme colors), fonts, existing `{{...}}` placeholders, and structural decoration; open imported vectors only when a specific asset affects a decision. A companion `design_spec.md` / `spec_lock.md` is part of the mirror source contract and must agree with the SVG identities; in authored modes it is context only. Caveats: `mirror` requires a complete current explicit contract and preserves page count/order, presentation, each Slide's Layout/Master chain, slot metadata, native-object metadata, and ownership in the new workspace (page type from a PPT Master-convention filename, else `content`; a loose visual-only folder cannot mirror); `fidelity` designs a broader new roster and structure after inspecting the complete roster; legacy or unstructured B (`baseline` / `preserve` / `layout_strategy: distill` / `data-pptx-layout-kind` / direct atomic placeholders / no root identity) is visual reference for authored modes only — use the original PPTX to mirror native facts; a selected free-design subset ingests only the named pages and never scans the whole `svg_output/`. ### 1C. Image / visual references -`ls` the folder (or single file) and `Read` each image / PDF page. Extract what's visible: - -- rough theme colors (eyeball the dominant 2–4 hues; do NOT report exact HEX as fact) -- page count (count the supplied images as an approximate slide count) -- dominant typography style (sans / serif / display) — never report a font name -- decorative motifs and composition rhythm - -Be explicit in Step 2 that exact HEX values, font names, and placeholder structure are **estimates from visual inspection** (`[suggested]`), never `[fact]`. +`Read` each image/PDF page: rough theme hues (never exact HEX as fact), approximate page count, typography style (sans / serif / display, never a font name), motifs and rhythm. Every derived value is `[suggested]`. ### 1D. Text, document, website, and asset references -Direct text in the conversation is already a valid input; do not require the user to save it as a file. Read Markdown/TXT directly. Convert supported document or website inputs into a temporary analysis workspace so the reference file or final template workspace is not modified: - -```bash -python3 skills/ppt-master/scripts/source_to_md.py "<file_or_URL_or_dir>" -o "<text_analysis_workspace>" -``` - -Inventory explicitly supplied logo, icon, font, and other brand/design assets. Raster assets also enter the Type C visual pass; readable SVG assets may additionally enter Type B when they are page/template SVGs. Do not infer asset licensing, official status, or native PowerPoint structure from filenames alone. - -Extract only what the source actually states: - -- Identity rules: colors, typography, logo usage, voice, icon style, and explicit exclusions. -- Style method: argument flow, evidence discipline, reusable page-role vocabulary, information hierarchy, composition/density rhythm, visual defaults, image/icon direction, and optional review focus. Do not retain the source's audience, objective, page sequence, page count, or page-specific resource choices as Style rules. -- Structure rules: canvas, page types, grids, zones, placeholders, density, image behavior, and requested variants. -- Deck application: recurring situations, intended audiences/outcomes, delivery or reading assumptions, representative narrative/page roles, examples, and negative requirements. Do not convert these observations into mandatory future-use policy. - -Treat an explicit value authored by the user as `[decision]` regardless of carrier: direct chat, pasted text, or a user-written Markdown/TXT/DOCX/PDF brief all retain user authorship. Merely arriving in a file does not make a statement a fact. Treat a statement as `[fact]` only when it is independently traceable to an identified external authority such as an official manual/site, or when it is machine-observable file/package metadata such as dimensions, hashes, or existing PPTX structure. Any interpretation of vague prose remains `[suggested]` and must pass the Step 3 confirmation gate. Text and asset evidence never supplies Master/Layout topology by itself. +Direct chat text is valid input. Read Markdown/TXT directly; convert documents/URLs with `source_to_md.py "<file_or_URL_or_dir>" -o "<text_analysis_workspace>"`; inventory supplied logo/icon/font assets (raster assets also enter the Type C pass; page/template SVGs may enter Type B); never infer licensing, official status, or native structure from filenames. Extract only what the source states: identity rules; Style method (argument flow, evidence discipline, page-role vocabulary, hierarchy, rhythm, visual defaults, image/icon direction, review focus — never the source's audience, objective, sequence, or page count); structure rules; Deck application (recurring situations, audiences/outcomes, delivery assumptions, representative roles, examples, negative requirements — never converted into mandatory future-use policy). A user-authored value is `[decision]` in any carrier; `[fact]` only when independently traceable to an external authority or machine-observable metadata; vague prose stays `[suggested]`. Text and assets never supply Master/Layout topology. ### 1E. No reference material -Skip the analysis. Step 2 will list every Required item as `[decision]`; nothing is fact-derivable from a non-existent source. Create Brand may emit an incomplete empty skeleton only under its explicit child-workflow rule. Create Style, Create Layout, and Create Deck still require the shared confirmation gate before authoring their workspace. +Skip analysis; Step 2 lists every Required item as `[decision]`. Create Brand may emit an empty skeleton only under its explicit child rule; the other children still require the gate. --- ## Step 2: Fact-Based Brief Proposal -Compose one concise natural-language proposal that states the template the AI intends to create, **labelling each material value's provenance**: - -- **`[fact]`** — independently traceable external authority or machine-observable source metadata (e.g. theme color from `analysis/manifest.json`, image dimensions, or an identified official manual); a user-authored brief file is not a fact merely because it is a file -- **`[suggested]`** — AI-inferred from analysis or context (e.g. tone summary, applicable scenarios; visually estimated values from type C) -- **`[decision]`** — an explicit user-authored instruction, including exact values supplied in conversation, pasted text, or a user-written brief file (e.g. a template name, a preservation requirement, a palette, or a layout rule) -- **`[derived]`** — an internal execution value the AI derives from the request and evidence so tools can run deterministically; it is recorded for provenance but never presented as a choice the user must understand - -**Language adaptation rule**: write the Step 2 proposal in the user's language and describe the intended result in ordinary language. Technical IDs may appear only in a compact implementation note when they are useful for audit or correction; do not require the user to understand them. - -**Natural-language planning rule**: present one recommended creation plan, not a menu of template modes, fidelity levels, or content-policy checklists. Translate requests such as “原样还原”, “提取成可复用母版和版式”, “保留风格但重新设计”, or any equivalent prose directly into the plan. Ask a follow-up only when a missing decision would materially change the artifact and cannot be inferred safely. The user may correct any sentence in the proposal. +Compose one concise natural-language proposal, in the user's language, describing the intended result with every material value labelled: `[fact]` (external authority or machine-observable metadata — a user-written brief file is not a fact), `[suggested]` (AI-inferred), `[decision]` (explicit user-authored, in chat, pasted text, or a brief file), `[derived]` (internal execution value recorded for provenance, never a user choice). Present one recommended creation plan — never a menu of modes, fidelity levels, or checklists; translate "原样还原" / "提取成可复用母版和版式" / "保留风格但重新设计" directly into the plan; ask a follow-up only when a missing decision would materially change the artifact. Technical IDs appear only in a compact audit note. | Field | Must show | |---|---| -| Output scope | Recommended `library` (default) plus `project`; explain that both use the same spec schema and asset routing, while parent path, spec filename placement, and global registration differ | -| Target project | Required only for `project`; show the exact initialized project workspace path, not a project nickname | -| Selected child workflow | Echo the already-dispatched Create Brand, Create Style, Create Layout, or Create Deck workflow; do not reopen kind selection inside the brief | -| Method and direction | Create Style only. Summarize the portable communication method, evidence discipline, page-role vocabulary, information design, visual defaults, image/icon direction, and advisory review focus. Do not include a current audience/outcome, page order/count, canvas, or prototype plan. | -| Category | Create Layout/Create Deck only. State the one discovery category inferred from the intended artifact. For Layout, a scenario category records geometric fit only and never grants application ownership. | -| Application context | Create Deck only. Summarize the recurring presentation family, likely audiences/outcomes, delivery/reading assumptions, and representative page roles. This is descriptive selection context, not a rule saying which template pages or visible content future projects must keep. | -| Theme direction | Create Layout/Create Deck only. Describe the intended light/dark/mixed behavior in plain language. Create Brand records identity colors instead and does not own a page theme mode. | -| Canvas | Create Layout/Create Deck only. State the recommended canvas with exact pixel size and `viewBox`; do not enumerate same-ratio alternatives unless the user asks or the evidence is genuinely ambiguous. | -| Creation plan | Create Layout/Create Deck only. Describe what will be preserved, what will be rebuilt, how broad the prototype roster will be, and how native structure will be handled. The AI derives the internal `replication_mode` from this prose after confirmation; never ask the user to select `standard`, `fidelity`, or `mirror`. | -| Native structure plan | Create Layout/Create Deck only. State the Master/Layout/slot result: compact authored `standard`, broader useful `fidelity`, or source-Slide-reachable `mirror`. Every authored Layout needs a Slide prototype; reject duplicate Masters. | -| Asset bundling | Create Brand/Create Layout/Create Deck only. Recommend included assets, plus excluded candidate assets with a one-line reason when reference assets exist. Create Style records textual provenance only and writes no asset payload. | +| Output scope | Recommended `library` plus `project`; same schema and asset routing, different parent path, spec filename, and registration | +| Target project | `project` only: the exact initialized workspace path | +| Selected child | Echo the dispatched child; never reopen kind selection | +| Method and direction | Style only: portable method, evidence discipline, page-role vocabulary, information design, visual defaults, image/icon direction, review focus — no current audience/outcome, page order/count, canvas, or prototype plan | +| Category | Layout/Deck: one discovery category (Deck `brand` / `general` / `scenario` / `government` / `special`; Layout without `brand`); a Layout scenario category records geometric fit only | +| Application context | Deck only: recurring family, likely audiences/outcomes, delivery assumptions, representative roles — descriptive, not future-use policy | +| Theme direction | Layout/Deck: light/dark/mixed in plain language (Brand records identity colors instead) | +| Canvas | Layout/Deck: the recommended canvas with exact pixels and `viewBox`; no same-ratio alternatives unless asked or genuinely ambiguous | +| Creation plan | Layout/Deck: what is preserved, what is rebuilt, how broad the roster is, how native structure is handled; `replication_mode` is derived from this prose after confirmation | +| Native structure plan | Layout/Deck: compact `standard`, broader `fidelity`, or source-reachable `mirror`; every authored Layout needs a Slide prototype; reject duplicate Masters | +| Asset bundling | Brand/Layout/Deck: included assets plus excluded candidates with a one-line reason; Style records textual provenance only | -Items to surface: +Items to surface: output scope and target project (`[decision]`); template ID (`[decision]` or a filesystem-safe ASCII slug `[suggested]`, the library index key) and display name (`[decision]` when supplied, otherwise `[suggested]`, for Type A often from `analysis/manifest.json.source.name`); category; applicable scenarios (Brand identity use cases; Style broad best-fit context without binding audience/outcome; Layout supported content shapes and delivery settings without communication ownership; Deck recurring situations); Deck application context and representative roles; identity/method/structural summary; Style communication method, visual-system defaults (overrideable seeds, never identity truth or Stage-2 locks), and review focus (applies only if the user enables visual review); theme mode and canvas (A/B `[fact]`, C `[suggested]`, D `[fact]` / `[decision]` / `[suggested]`, E `[decision]` with default `ppt169` `1280x720`); internal creation strategy (`[derived]`); native structure facts for A/structured B (`[fact]`: master/layout counts, parentage, assignments, placeholder identities, multi-master status); structure ownership plan and per-page reference treatment (`[derived]`); basic norms; reference source; theme color and fonts (Brand/Deck only; C fonts are never derivable); design style (required for Style as an overrideable seed); assets list (never for Style); keywords (3–5 tags; not for Brand). For Type A Layout/Deck, also name the authoring documents the derived strategy requires, a one-line source Master/Layout summary, and whether source structure facts will be preserved or used only as evidence. -| Item | Required | Provenance by evidence channel | -|------|----------|--------------------------| -| Output scope | Yes | `[decision]` — `library` (default, globally reusable and indexed) or `project` (qualified Design Spec under one initialized shared project root) | -| Target project | Yes for `project`; N/A for `library` | `[decision]` — explicit path to the initialized target workspace; validate it during the Step 4 preflight | -| New template ID | Yes | `[decision]` when supplied; otherwise propose a filesystem-safe ASCII slug as `[suggested]`. In library scope it also becomes the matching index key | -| Template display name | Yes | `[decision]` when supplied; otherwise `[suggested]`, often from `analysis/manifest.json.source.name` for type A | -| Category | Create Layout/Create Deck only | `[decision]` when explicit; otherwise `[derived]` for indexing — Create Deck: `brand` / `general` / `scenario` / `government` / `special`; Create Layout: `general` / `scenario` / `government` / `special` | -| Applicable scenarios | Yes | Create Brand: identity use cases. Create Style: broad best-fit discovery context only, without binding a target audience, outcome, or recurring application. Create Layout: content shapes and delivery settings its geometry can support, without communication or narrative ownership. Create Deck: recurring presentation situations inside the application contract. `[suggested]` from analysis unless explicitly authored or externally sourced; user confirms. | -| Application context and representative page roles | Create Deck only | `[decision]` when supplied explicitly; otherwise `[suggested]` from recurring source patterns. Describe the source and intended family without assigning required/optional/repeatable status or fixed/replaceable/example-only policy. | -| Identity, method, or structural summary | Yes | Create Brand/Create Deck: identity tone. Create Style: communication method and visual-default summary. Create Layout: structural use case and density/rhythm summary only. | -| Communication method and evidence discipline | Create Style only | `[decision]` when explicit; otherwise `[suggested]` from repeated source behavior. State argument flow, message/evidence discipline, page-role vocabulary, and data-expression rules without fixing a page sequence. | -| Visual-system defaults | Create Style only | `[decision]` when explicit; otherwise `[suggested]` from evidence. Palette, typography, mode, and visual-style values remain overrideable seeds, never Brand identity truth or direct final Stage-2 locks. | -| Review focus | Create Style only | `[decision]` when explicit; otherwise `[suggested]`. These checks apply only if the user separately enables visual review; the Style cannot trigger that stage. | -| Theme mode | Create Layout/Create Deck only | A: `[fact]` from `analysis/manifest.json` background colors. B: `[fact]` from SVG `fill`. C: `[suggested]` from visual estimate. D: `[fact]` from an independently identified external authority, `[decision]` from user-authored text in any carrier, otherwise `[suggested]`. E: `[decision]`. | -| Canvas format and dimensions | Create Layout/Create Deck only | A/B: `[fact]` from slide size or SVG `width` / `height` / `viewBox`; show `canvas_format`, `canvas_width`, `canvas_height`, `canvas_viewbox`, and `source_viewbox`. C: `[suggested]` from image aspect ratio. D: `[fact]` from an independently identified external authority or `[decision]` from user-authored text in any carrier when specified. E: `[decision]`, default `ppt169` (`1280x720`, `0 0 1280 720`). | -| Internal creation strategy | Create Layout/Create Deck only | `[derived]` from the confirmed natural-language plan and evidence. `standard` is the compact authored implementation, `fidelity` requires A/B page evidence for broader source-aligned coverage, and `mirror` requires A or B with a complete explicit structure contract for literal materialization. Create Layout mirror additionally requires a brand-neutral and application-neutral source. Persist `replication_mode` for tools, not as a user-facing mode. | -| Native structure facts | Create Layout/Create Deck with Type A or structured Type B | `[fact]` from `analysis/native_structure.json` / source SVG contract: master/layout counts, parentage, page assignments, placeholder identities, and multi-master status. Mirror preserves the source-Slide-reachable subset in the new workspace and records the remaining identities only as omitted scope; authored modes do not use source topology as output topology. | -| Structure ownership plan | Create Layout/Create Deck only | `[derived]`. Authored output explains each additional Master; mirror maps only source-Slide-reachable ownership. Every Master owns an emitted Layout and every Layout has a complete Slide prototype. | -| Reference treatment | Create Layout/Create Deck when a reference exists | `[derived]` per page from the user's prose: closely reproduce geometry/decoration where requested, otherwise adapt the reference into the newly authored system. Literal materialization preserves supported source facts mechanically. | -| Basic template norms | Yes when reference exists | Create Brand uses the identity fields and provenance rules from its child workflow. Create Style uses portable method, page-role, evidence/data, composition/density, visual-default, and image/icon rules while discarding project-specific context. Create Layout/Create Deck use `[fact]` / `[suggested]` layout grammar, image system, density rhythm, page roster semantics, and asset policy from Step 1. | -| Reference source | Optional | already known if Step 1 ran | -| Theme color | Create Brand/Create Deck only | A: `[fact]` from theme XML. B: `[fact]` from dominant SVG `fill`. C: `[suggested]` from visual estimate (HEX is approximate). D: `[fact]` from an independently identified external authority, `[decision]` from user-authored text in any carrier, otherwise `[suggested]`. E: `[decision]`. Create Layout may use neutral preview paint but stores no identity color. | -| Fonts | Create Brand/Create Deck only | A: `[fact]` from `analysis/manifest.json`. B: `[fact]` from SVG `font-family`. C: font family is not derivable — use `[decision]` if the user supplies one. D: `[fact]` from an independently identified external authority or `[decision]` from user-authored text in any carrier. E: `[decision]` when a custom stack is wanted. Create Layout stores no typeface identity or final type scale; its structural text roles, alignment, wrapping, and capacity remain part of page grammar. | -| Design style | Required for Create Style; optional otherwise | `[decision]` when explicit; otherwise `[suggested]` from analysis. For Style this is an overrideable visual-direction seed, not an exact lookup token or identity lock. | -| Assets list | Optional for Create Brand/Create Layout/Create Deck; N/A for Create Style | A: `[fact]` from `analysis/manifest.json` plus populated semantic resource directories; user picks which to bundle. B/C/D: retain each file's source and let the user confirm adoption. E: none. Style may cite the reference textually but never adopts an asset. | -| Keywords | Create Style/Create Layout/Create Deck only | `[suggested]` from analysis (3–5 short tags); user confirms. Create Brand has no keywords field or keyword index payload. | - -When the bundle includes Type A for Create Layout/Create Deck, also include in this message: - -- the exact authoring-manifest documents required by the derived internal strategy and verified during Step 1 -- a one-line summary of the source Master/Layout structure -- the source structure facts, including master/layout counts, multi-master status, and reason codes; state in plain language whether they will be preserved or used only as design evidence - -The user replies with corrections, additions, or "all good". - -> **Persist the portable brief into `<design_spec_path>`**. In Step 4, declare a YAML frontmatter block with the child-specific ID key (`brand_id`, `style_id`, `deck_id`, or `layout_id`) and only fields owned by that child. Create Brand follows its identity schema. Create Style persists only `style_id`, `kind`, `summary`, and `keywords`; its method and direction live in the required body sections, and it writes no canvas, category, identity, application, replication, native-structure, page-count, or roster fields. Create Layout/Create Deck persist the confirmed portable fields (`kind`, `category`, `summary`, `keywords`, `primary_color` for deck, `page_types` for layout, `canvas_format`, `canvas_width`, `canvas_height`, `canvas_viewbox`, `source_viewbox`, `replication_mode`, `native_structure_mode`, etc.). `replication_mode` is the AI-derived implementation record, not a user selection. A Deck writes descriptive application context in Template Overview and factual prototype descriptions in Page Roster rather than duplicating that prose into frontmatter. Do not persist a generic `template_id` field: it is the parent workflow's cross-kind name, not a registrar schema key. Do not persist the execution-only `output_scope` or `target_project` fields. In library scope, `register_template.py` reads this frontmatter in Step 7 so the brief flows directly into the index without the AI re-deriving it from prose. +**Persist the portable brief into `<design_spec_path>`** in Step 4 as YAML frontmatter with the child ID key (`brand_id` / `style_id` / `layout_id` / `deck_id`) and only child-owned fields: Brand its identity schema; Style only `style_id`, `kind`, `summary`, `keywords`; Layout/Deck the confirmed portable fields (`kind`, `category`, `summary`, `keywords`, `primary_color` for deck, `page_types` for layout, `canvas_format`, `canvas_width`, `canvas_height`, `canvas_viewbox`, `source_viewbox`, `replication_mode`, `native_structure_mode`, …). Never persist a generic `template_id`, `output_scope`, or `target_project`. In library scope `register_template.py` reads this frontmatter in Step 7. --- ## Step 3: User Confirmation Gate -**MANDATORY interactive gate — this step BLOCKS Steps 4 onward.** +**MANDATORY interactive gate — blocks Steps 4 onward.** Echo the finalized brief in one message, then emit `[TEMPLATE_BRIEF_CONFIRMED]` on its own line. Silently inferring values from files, direct text, an opened IDE file, or prior conversation is a route violation: even a complete PPTX, website, or written brief only informs the brief. -1. Echo back the finalized brief (post-corrections) in a single message -2. Emit the marker `[TEMPLATE_BRIEF_CONFIRMED]` on its own line - -Skipping this gate — including silently inferring values from reference files, direct text, an opened IDE file, or prior conversation — is a route violation. Even if the user already supplied a PPTX, image, website, document, asset bundle, or complete written brief, you MUST still surface Step 2 with provenance labels and obtain explicit confirmation here. The reference bundle informs the brief; it does not substitute for it. - -**Required outcome of Step 3** (all must be true before emitting `[TEMPLATE_BRIEF_CONFIRMED]`): - -- [ ] User has been shown every Required item in Step 2 with provenance labels -- [ ] The user saw one concise natural-language creation plan rather than a mode menu or content-policy checklist -- [ ] User-facing language describes the intended result; internal enum IDs are absent or confined to an audit note -- [ ] User has replied with corrections or explicit acceptance of the proposed result -- [ ] Output scope is confirmed; both scopes use the same spec schema and asset routing with their resolved Design Spec names, while `project` includes an explicit initialized target-project path -- [ ] For Create Layout/Create Deck, the canvas format is fixed before SVG generation -- [ ] For Create Layout/Create Deck, the AI-derived internal strategy is consistent with the bundle evidence (`fidelity` requires A/B page evidence; `mirror` requires A or structured B; C/D/E channels alone permit only `standard`); Create Layout mirror evidence is already brand-neutral and application-neutral -- [ ] Every supplied visual, textual, documentary, web, and asset channel has been analyzed or explicitly excluded; mixed-input conflicts are surfaced rather than silently resolved -- [ ] For Create Layout/Create Deck mirror, every source Slide and its reachable Layout/Master chain is valid and context-complete; omitted unreferenced identities and genuinely missing/unsupported reachable facts were reported; Create Layout mirror contains no retained brand identity or reusable application policy -- [ ] Child-specific norms from prior content have been surfaced and accepted, or explicitly marked N/A when no reference exists: identity/provenance for Create Brand; communication/evidence/visual-direction behavior for Create Style; layout/image/density/asset behavior for Create Layout/Create Deck -- [ ] For Create Style, the portable communication method, open page-role vocabulary, evidence/data rules, visual defaults, image/icon direction, and advisory review focus are confirmed; project-specific audience/outcome/page sequence and all identity/structure fields remain N/A -- [ ] For Create Layout/Create Deck, the plan makes structure ownership explicit: authored output creates compact (`standard`) or broader useful (`fidelity`) Slide prototypes after reviewing complete source evidence; literal materialization maps source Slides and their reachable graph one-to-one -- [ ] For Create Deck, the recurring presentation family, intended audiences/outcomes, and representative page roles are understood without turning them into mandatory page/content policies; for Create Layout, no application contract or brand identity has leaked into the structure brief -- [ ] For Create Brand, all required identity fields from its child workflow are confirmed and canvas/replication/native-structure fields remain N/A -- [ ] For `library`, metadata is complete enough to register into the relevant index; for `project`, the same portable template metadata is complete and no global registration is planned -- [ ] Marker `[TEMPLATE_BRIEF_CONFIRMED]` emitted on its own line after the echoed brief - -Step 4 MUST NOT run until `[TEMPLATE_BRIEF_CONFIRMED]` has been emitted in the current conversation. +Before emitting the marker, all must hold: every Required item shown with provenance; one natural-language plan, no mode menu; internal IDs absent or confined to an audit note; the user replied with corrections or acceptance; scope confirmed (project with an explicit initialized path); for Layout/Deck the canvas is fixed and the derived strategy matches the evidence (`fidelity` needs A/B, `mirror` needs A or structured B, C/D/E permit only `standard`; Layout mirror evidence is brand/application-neutral); every channel analyzed or explicitly excluded with conflicts surfaced; for mirror, every source Slide and reachable chain valid and context-complete with omitted identities and missing facts reported; child-specific norms surfaced or marked N/A; for Style, method, vocabulary, evidence rules, defaults, direction, and review focus confirmed with project-specific context and identity/structure N/A; for Layout/Deck, structure ownership explicit; for Deck, application context understood without turning it into policy, and for Layout no application or identity leaked; for Brand, all identity fields confirmed with canvas/replication/structure N/A; library metadata complete enough to register, or project scope with no registration planned. --- ## Step 4: Preflight Output + Invoke the Selected Child -> **Precondition**: `[TEMPLATE_BRIEF_CONFIRMED]` was emitted in Step 3. If not, return to Step 3. +> Precondition: `[TEMPLATE_BRIEF_CONFIRMED]` emitted in Step 3. -Select the final target from the confirmed output scope: +Resolve `<template_workspace>` from scope (`skills/ppt-master/templates/<kind_dir>/<template_id>` or `<target_project>`), `mkdir -p "$template_workspace/templates"`, and create optional roots only when writing a real asset. Normally `<authoring_workspace>` equals `<template_workspace>`; when the project already has the other structural kind, author in an isolated project-shaped root through validation and preview, then install its spec at `<installed_design_spec_path>` and assets atomically (Layout replaces the Deck roster; Deck beside Layout installs no structural payload), deleting staging only after the final root passes. -```bash -# library scope (default) -template_workspace="skills/ppt-master/templates/<kind_dir>/<template_id>" +**Preflight (atomic, parent-level, before any final write)**: resolve `<design_spec_path>` and every destination; for `library` confirm `templates/` is empty; for `project` reject a bare `design_spec.md`, an existing spec of the selected kind, or an invalid qualified-name set (distinct kinds coexist; Layout owns structure when present; adding Layout beside Deck replaces the Deck structural payload only after isolated validation); resolve every bitmap and vector filename and confirm nothing overwrites an existing file in `images/` or `icons/imported/`; check the review-PPTX destination when requested or multi-Master. Any failure aborts before writing anything; never overwrite an unrelated name conflict. -# project scope -template_workspace="<target_project>" +**Create Brand / Create Style branch**: continue in the child's §3 with the confirmed brief and resolved paths, then return to that child's branch in Step 5 — no Template_Designer, no SVG, no structure. -# identical in both scopes; create optional roots only when writing an asset -mkdir -p "$template_workspace/templates" -``` - -Normally `<authoring_workspace>` equals `<template_workspace>`. When the project -already has the other structural kind, use an isolated project-shaped root -through validation and preview. Its `<design_spec_path>` is temporary; -`<installed_design_spec_path>` is the final table path. Create its `templates/` -only after preflight. - -| Scope | Workspace target | Required action before generation | -|---|---|---| -| `library` | `skills/ppt-master/templates/<kind_dir>/<template_id>/` | Resolve `<design_spec_path>` to `templates/design_spec.md`; run the common workspace preflight; the directory name matches the final template ID used in the relevant index | -| `project` | `<target_project>/` | Resolve the final spec destination to `templates/design_spec.<kind>.<id>.md`; run the project coexistence preflight. Author directly unless Layout/Deck precedence requires isolated validation before atomic install | - -The preflight is atomic at the Create Template parent level: settle every output filename and check all destinations before generation. Pass the active `<design_spec_path>` to the selected child. For a project structural transition, validate in the isolated root, then install its spec at `<installed_design_spec_path>` and its assets atomically: Layout replaces the Deck roster; Deck beside Layout installs no structural payload. Delete staging only after the final project root passes. - -**Create Brand branch**: continue in [`create-brand.md`](./create-template/create-brand.md) §3 with the confirmed identity brief and resolved `<template_workspace>` / `<design_spec_path>`. Then return to the Create Brand branch in Step 5. Do not invoke Template_Designer, create SVGs, or apply the Create Layout/Create Deck-only material below. - -**Create Style branch**: continue in [`create-style.md`](./create-template/create-style.md) §3 with the confirmed method/direction brief and resolved `<template_workspace>` / `<design_spec_path>`. Then return to the Create Style branch in Step 5. Do not invoke Template_Designer, create SVGs, retain source page topology, or apply the Create Layout/Create Deck-only material below. - -**Create Layout/Create Deck branch**: continue in the selected child workflow, switch to the Template_Designer role, and generate per role definition. Bind the role's `<template_workspace>` to `<authoring_workspace>` and pass `<design_spec_path>`, the finalized brief from Step 3, and the Step-1 analysis bundle with accepted norms. - -**Mandatory — authored construction bundle**: Immediately after the confirmed -creation strategy resolves to `standard` or `fidelity`, and before -Template_Designer selects any page or template contour, read -[`native-shape-authoring.md`](../references/native-shape-authoring.md) and -[`preset-shape-vocabulary.md`](../references/preset-shape-vocabulary.md) -completely and retain both for the active authoring context. Do not load this -bundle for `mirror`; it preserves source-owned geometry and does not select or -author replacement contours. - -When the bundle includes Type A, pass the following internal package to the role: - -- finalized brief from Step 3 -- `analysis/manifest.json` -- `analysis/native_structure.json` and `sources/source.pptx` -- `validation/conversion-report.json` when source-recovery diagnostics exist -- exported `images/` and any other populated semantic resource directories -- `*_vector_asset_inventory.json`, when the vector readability pass extracted assets, as an exact-id query surface only; do not load it or `icons/imported/*.svg` wholesale -- `authoring-svg/authoring_summary.json` and editable layered IR documents; keep `authoring_manifest.json` bundled for compiler use but do not load it into the role context; optional `authoring-svg-flat/` is a visual cross-check only and never a template materialization input -- for `mirror` only, matching immutable `svg/` source/package evidence plus `svg/inheritance.json`; immutable `svg-flat/` remains an optional visual cross-check and never replaces authored visible SVG -- optional screenshots, if available - -When the bundle includes Type B, pass `authoring_summary.json`, the cleaned SVG file list from the analysis workspace, `*_vector_asset_inventory.json` as an exact-id query surface if extraction ran, any companion `design_spec.md` / `spec_lock.md`, and the analysis notes. Do not bulk-read the inventory or extracted vectors; open individual `icons/imported/*.svg` files only when needed. -When the bundle includes Type C, pass the image file list and the visual analysis notes. -When the bundle includes Type D, pass the direct text, converted document/website outputs, traceable source list, explicit asset inventory, and analysis notes. -For Type E, pass only the finalized brief. -For a mixed reference bundle, pass the union of the applicable packages while keeping each fact's source and every unresolved conflict explicit. - -The role interprets the package according to the AI-derived internal creation strategy recorded as `replication_mode`: +**Create Layout / Create Deck branch**: switch to Template_Designer with `<template_workspace>` bound to `<authoring_workspace>`, `<design_spec_path>`, the Step 3 brief, and the Step 1 analysis bundle. **Mandatory — authored construction bundle**: as soon as the strategy resolves to `standard` or `fidelity`, and before selecting any contour, read [`native-shape-authoring.md`](../references/native-shape-authoring.md) and [`preset-shape-vocabulary.md`](../references/preset-shape-vocabulary.md) completely; never load them for `mirror`. Pass the applicable package: Type A — the brief, `analysis/manifest.json`, `native_structure.json` and `sources/source.pptx`, `validation/conversion-report.json` when present, exported resources, `*_vector_asset_inventory.json` as an exact-id query surface, `authoring_summary.json` plus the layered IR (manifest bundled for the compiler, never loaded), and for `mirror` the immutable `svg/` plus `inheritance.json`; Type B — the summary, cleaned SVG list, inventory query surface, companion specs, notes; Type C — image list and notes; Type D — direct text, converted outputs, source list, asset inventory, notes; Type E — the brief only; mixed — the union with provenance and conflicts explicit. | Mode | Final SVG authority | Structure behavior | |---|---|---| -| `standard` / `fidelity` | Newly authored SVGs from the brief and complete source evidence | Author a compact or broader useful Master/Layout/slot system; do not retain identities merely because they exist. | -| `mirror` | Reviewed compact authoring SVG plus inline native JSON and structure facts | Publish source Slides and their reachable Layout/Master chains from the current authored tree; resolve inherited context without changing ownership. Similar presentation is required, code isomorphism is not. | +| `standard` / `fidelity` | Newly authored SVGs from the brief and complete source evidence | Author a compact or broader useful Master/Layout/slot system; never retain identities merely because they exist. Use the compact canonical `<g>` from `preset_shape_svg.py` when one registered preset expresses one object (paint from the brief and spec; add only the registered structural attributes after insertion; geometry or paint changes require a new render); Template_Designer decides any `shape_boolean_svg.py` use under [`native-shape-authoring.md`](../references/native-shape-authoring.md) §6 | +| `mirror` | Reviewed compact authoring SVG plus inline native JSON and structure facts | Publish source Slides and their reachable chains from the current authored tree; complete inherited context without changing ownership; similar presentation required, code isomorphism not. Redraw/normalize visible SVG, equivalent inheritance, safe metadata, and transport without changing meaning; never synthesize, promote/demote, rename, or re-parent | -For Type A `mirror`, publish the reviewed/authored layered compact SVG into a -workspace with no existing roster, using the deterministic validator/publisher: +For Type A `mirror`, publish with `mirror_template_materialize.py "<import_workspace>" "<authoring_workspace>"` into a workspace with no existing roster; it validates and publishes but never authors visible design, writes the sidecars listed in [`svg-pipeline.md`](../scripts/docs/svg-pipeline.md#mirror_template_materializepy), and does not create the Design Spec — Template_Designer writes it from the brief and the materialized roster before Step 5. -```bash -python3 skills/ppt-master/scripts/mirror_template_materialize.py \ - "<import_workspace>" "<authoring_workspace>" -``` +**Hard rule — multi-Master package boundary**: more than one Master is valid only when `mirror` preserves a source graph or an authored template intentionally defines distinct reusable design families — never one Master per Layout or equivalent duplicates. Every Master owns at least one emitted Layout and every Layout is selected by at least one prototype. SVG authors own the semantic roster, parentage, picker names, atoms, and slots; the exporter owns OOXML cloning, Theme isolation (one Theme part per Master — two Masters never resolve to the same `ppt/theme/themeN.xml`), `p14:creationId` uniqueness, numeric registration, and relationship registration — never encode package repair in SVGs. Do not package `native_structure.json` or `source.pptx` as template inputs. -Destination `templates/` may be absent/empty or hold unique qualified -Brand/Style specs; a Layout-over-Deck stage may also hold one qualified Deck -spec without its roster. A bare spec, Layout spec, active roster, or other -payload blocks publication. Before atomic publication, the command verifies -the layered manifest, source SHA/known refs, reachable native/inheritance graph, -assignments, closure, and vector inventory. Authoring subtree hash changes are -classified as legitimate edits; the command never rehydrates an ordinary -visible lossless subtree. It emits source-ordered Slide -SVGs only, plus `icons/imported/`, referenced -`images/`, `audio/`, `video/`, or -`native-payloads/imported/` resources as applicable, and one -deduplicated `templates/native_payloads.json.gz` store when supported native -payload or repeated restoration metadata exists. A PPTX-backed mirror also -writes `templates/source_themes.json` with the exact Theme of each retained -Master. It also writes -`templates/template_execution_manifest.json` with schema -`ppt-master.template-execution-manifest.v1`, a compact tool-readable prototype -roster and grouped source-import warning summary. Each prototype points to one -`templates/template_execution/*.text-slots.json` sidecar with schema -`ppt-master.template-text-slots.v2-min`. Each slot contains only `selector`, -`role`, `current_text`, `text_segments`, and `tspan_count`; the complete -prototype remains authoritative. The manifest and sidecars are deterministic -tool diagnostics; page-context does not inject or require them, and models do -not read them during page authoring. Validators/export own attribute and -topology checks. Template SVGs and imported -vectors keep content-hash payload references plus short -`data-pptx-native-ref` attribute-record ids. Structural Master/Layout, -placeholder, layer, and editable-object fields remain inline. The command does -not create the Design Spec. Template_Designer writes `<design_spec_path>` from -the confirmed brief and the materialized roster before Step 5. A rerun targets -a workspace with no roster rather than overwriting a partially reviewed one. +**Sprite-sheet preservation**: PPTX-exported assets are often sprite sheets cropped through nested `<svg viewBox>` wrappers around `<image width="1" height="1">`; that nesting is load-bearing geometry — preserve the exact `viewBox` crop and outer placement, never flatten to one `<image>` with direct geometry. If an asset's pixel aspect differs from its on-page aspect, it is a sprite. -**Hard rule — mode-specific authorship**: `standard` and `fidelity` review all -source Master/Layout evidence, then author a compact or broader useful canonical -system without copying unused/duplicate identities. When one registered PowerPoint preset exactly -expresses one complete object, they use the compact canonical -`<g>` emitted by `preset_shape_svg.py`, following -[`native-shape-authoring.md`](../references/native-shape-authoring.md); its -paint comes from the confirmed brief and `<design_spec_path>`. After -inserting the complete helper group, add only the registered structural -attributes required by its Master/Layout or object-slot role; geometry and -paint changes require a new helper render. When actual `standard` / `fidelity` -construction needs a Boolean result over supported shape/text operands, Template_Designer -decides whether to use `shape_boolean_svg.py` under -[`native-shape-authoring.md`](../references/native-shape-authoring.md) §6; a -brief/reference suggestion does not lock the operation. `mirror` preserves the -source structure ownership, meaning, similar visible result, and supported -native facts in a new workspace while spelling them in the same compact -authoring contract used by other modes. It may redraw/normalize visible SVG, -equivalent inheritance, safe page-space metadata, and compiler transport -without changing object meaning. Mirror never performs semantic synthesis, -promotion/demotion, renaming, or re-parenting. +**Mirror authoring/publication** (A or B): author and publish one SVG per source Slide in `<authoring_workspace>/templates/` — inspect every matching `authoring-svg/` document, redraw where useful, refresh the summary, then run the materializer (never hand-copy the lossless tree or rebuild the graph); preserve reachable keys, picker names, parentage, assignment, placeholder type/index/bounds, inherited-shape visibility, ownership, and native facts; unused identities produce no file. Name files `<NNN>_<page_type>.svg` (3-digit source order; type from `pageTypeCandidates` for A, from a convention filename or content for B, else `content`). Route assets through the common contract — Type A media from `<import_workspace>/images/`, Type B relative hrefs resolved and copied once — into `images/` with `../images/<name>` references and semantic directories for audio/video/payloads, keeping stable source asset identity; copy decoration vectors once to `icons/imported/` as `<use data-icon="imported/<name>" data-pptx-asset-role="decoration"/>` (never `templates/icons/`, never inlined by hand). Write `<design_spec_path>` per template-designer §1; `replication_mode: mirror` records creation, never a 1:1 downstream sequence. -**Hard rule — multi-Master package boundary**: More than one Master is valid only when `mirror` preserves an existing source graph in the new workspace or an authored template intentionally defines distinct reusable design families. `standard` / `fidelity` must not create one Master per Layout or duplicate equivalent Masters merely for organization. Every declared Master must own at least one emitted Layout, and every declared Layout must be selected by at least one prototype SVG so the complete graph can be compiled and verified. +**Expected outputs**: `<design_spec_path>` with package-specific rules only (deck: descriptive Overview, Color Scheme, Signature Elements, factual Page Roster, conditional Typography / Assets / Overrides; layout: structure-owned Signature Elements and Page Roster only) and no restated generic constraints; the roster per template-designer; conventional `{{...}}` placeholder vocabulary with a `placeholders:` frontmatter override when a style legitimately differs (indexed TOC pattern, never one-off families); each SVG carrying the native contract — root identity, direct atomic fixed layers, direct slot `<g>` with design-zone bounds and exactly one compatible carrier (a validated compact preset `<g>` counts as one atom or one `object` carrier; composite regions use only the `object` + `proxy` downgrade; `data-pptx-role` only when specialized metadata cannot express behavior); optional assets under the common routing. -| Package concern | Requirement | -|---|---| -| Theme ownership | Every registered Slide Master receives its own Theme part. Two Masters must never resolve to the same `ppt/theme/themeN.xml`. Theme cloning is exporter-owned. Authored modes do not bundle Theme XML; a PPTX-backed mirror may carry the compiler-written `source_themes.json` sidecar. | -| Creation identity | Any generated `p14:creationId` on Slides, Layouts, or Masters is a valid unsigned 32-bit value and unique across those parts. Cloned structural parts always receive fresh values. | -| Numeric registration | Master and Layout registration IDs are valid and unique in their owning lists; Layout numeric IDs are unique across the complete package, including across different Masters. | -| Relationship graph | The presentation registers the exact Master and Slide rosters; each Master registers exactly its owned Layouts; each Layout targets exactly one declared Master; each Slide targets exactly its declared Layout. | - -SVG authors own the semantic roster, parentage, picker names, direct atoms, and slots. The exporter owns OOXML part cloning, Theme isolation, relationship registration, and package identity. Do not encode package repair workarounds in individual template SVGs. - -Do not package `analysis/native_structure.json` or `sources/source.pptx` as template inputs. In `standard` / `fidelity`, author Master/Layout direct semantic atoms and bounded slot groups deliberately from the intended reusable behavior. A validated compact canonical authored-preset `<g>` compiles to one native shape and therefore counts as one semantic atom; it may own a Master/Layout fixed layer or serve as the one direct carrier of an `object` slot. Ordinary groups are not structural atoms or single-object carriers. In `mirror`, edit the layered compact authoring SVG and use inheritance/native facts to preserve source ownership; the lossless trees remain immutable validation/non-visible-payload backing. Recursively expand fixed Master/Layout group wrappers only because the structured contract requires semantic atoms; keep comparable paint order and presentation, but do not require identical SVG transforms/styles/nodes or regroup by semantic judgment. - -`<design_spec_path> §V` records every emitted Slide. Mirror adds the [required Source Preservation Map](../references/template-designer.md) for source-Slide assignments and, when relevant, one sentence that unreferenced source identities exist but were not materialized. Do not add per-identity analysis or model-authored synthesis rationale. - -**Native-shape metadata boundary**: The authoring IR removes opaque payload -from model context while retaining stable source refs. `standard` / `fidelity` -use helper-generated compact canonical preset groups and project SVG/assets -rather than copied source payload. `mirror` publication validates known refs -and may recover only non-visible native metadata already supported by the -converter. It always keeps the current compact visible authoring tree; matching -hashes never authorize lossless visible-subtree replacement. Fixed layers are -normalized to semantic atoms; -unsupported or edited objects keep the current SVG fallback and are reported -rather than silently replaced by stale metadata. Do not reproduce the preset -syntax here; its single authority is -[`shared-standards-core.md`](../references/shared-standards-core.md), with selection and -usage guidance in the native-shape reference. - -Downstream, Strategist inspects the installed workspace and current content, then derives an internal application plan. The plan may use the full roster or a subset, repeat or reorder prototypes, and choose literal reuse, structural reuse, or visual-reference-only behavior. For exporter compatibility it records `template_reuse_scope` and, when structured, `template_adherence`; these are machine execution values, not user choices. `page_layouts` selects one complete authoring prototype per generated page, `pptx_masters` / `pptx_layouts` declare unique reusable definitions, and `page_pptx_layouts` assigns generated pages. No internal value forces a future generated deck to keep the source page count or order. - -**Apply the confirmed natural-language intent to authored output**: in `standard` / `fidelity`, reproduce reference geometry and decoration where the request calls for close preservation, and adapt compositions where it calls for a reusable redesign. Mirror authors compact SVG from every supported source visual represented by the parsed evidence, keeping a similar presentation without requiring the same code or nodes. - -**Sprite-sheet preservation (do NOT simplify away)**: PPTX-exported assets are often sprite sheets — a single tall/large image referenced from multiple slides, each cropping a different region via nested `<svg ... viewBox="...">` wrappers around `<image width="1" height="1">`. This nesting is **load-bearing geometry**, not redundant structure. When rebuilding, preserve the exact `viewBox` crop and the outer `<svg>` placement for every image; do not flatten to a single `<image>` with direct `x/y/width/height`. Verify by sampling: if any asset's pixel dimensions don't match the on-page display aspect, it is a sprite and the wrapper must stay. - -**Mirror authoring/publication contract** (type A or B): when the derived implementation writes `replication_mode: mirror`, the Template_Designer role: - -1. **Authors and publishes one output SVG per source Slide** in `<authoring_workspace>/templates/`. Inspect every matching `authoring-svg/` document, redraw/normalize where useful for compactness while keeping similar presentation and source meaning, refresh its summary, then run `mirror_template_materialize.py`. The publisher consumes the tool-only authoring manifest together with native structure facts and immutable source evidence; it validates/composes the current authored tree and never restores ordinary visible source XML. Do not hand-copy the lossless tree or independently rebuild the graph. Preserve each Slide's reachable Master/Layout keys and picker names, Layout parentage, assignment, placeholder type/index/bounds, inherited-shape visibility, ownership, and supported native facts. Code/node identity is not required. - - Type A model-facing source: `<import_workspace>/authoring-svg/authoring_summary.json` plus the editable compact SVGs; `<import_workspace>/svg/`, `svg/inheritance.json`, and `analysis/native_structure.json` provide immutable source/non-visible payload and structural backing. The publisher alone reads `<import_workspace>/authoring-svg/authoring_manifest.json`. Optional `<import_workspace>/svg-flat/` is verification-only. - - Type B model-facing source: `<svg_analysis_workspace>/authoring-svg/authoring_summary.json` plus its editable SVGs; the complete explicit source SVG contract is immutable backing - - Each source Slide SVG resolves Master + Layout + Slide context and keeps layer markers explicit. Source Master/Layout identities unused by every Slide produce no file; use `standard` / `fidelity` to re-author useful ones as complete Slide prototypes. -2. **Renames each file** using the source-order-first convention `<NNN>_<page_type>.svg`, where `<NNN>` is the source-order index zero-padded to 3 digits and `<page_type>` is typically `cover` / `toc` / `chapter` / `content` / `ending` (fall back to `content` when the type cannot be confidently classified). Examples: `001_cover.svg`, `002_toc.svg`, `003_content.svg`, ..., `050_ending.svg`. - - Type A: derive `<page_type>` from `analysis/manifest.json.pageTypeCandidates` - - Type B: derive `<page_type>` from the source filename when it follows the PPT Master convention (`01_cover.svg` → `cover`, `03a_content_two_col.svg` → `content`); otherwise infer from page content or fall back to `content` -3. **Routes bundled assets through the common workspace contract** and rewrites every `<image href="...">` consistently. Keep stable source asset identity in mirror; do not rename, merge, or replace assets by semantic judgment. - - Type A: image media come from `<import_workspace>/images/`; other resources retain their semantic source directories - - Type B: resolve relative paths in source `<image href="...">` against the source SVG location and copy each unique asset; if the source already follows PPT Master conventions (assets co-located with SVGs in the same directory), copy the whole asset set and then rewrite paths - - Both scopes: write raster, SVG, EMF, and WMF image media to `<authoring_workspace>/images/`, point SVG references at `../images/<name>`, and route audio, video, or opaque payloads to their semantic workspace directories. -4. **Copies decoration-only imported vector assets once** to `<authoring_workspace>/icons/imported/` and rewrites their placeholders to `<use data-icon="imported/<name>" data-pptx-asset-role="decoration"/>`. Semantic authoring objects stay inline. Never place a second copy under `templates/icons/`. Other explicitly adopted icon-library references keep their existing library namespace. Do not inline these assets manually in the template working SVGs; template validation, preview, and final export all resolve icons from the workspace-root `icons/` directory. -5. Writes `<design_spec_path>` per [template-designer.md](../references/template-designer.md) §1. The §V Page Roster remains a factual prototype index; explicit SVG metadata is the native Master/Layout contract. `replication_mode: mirror` records how the workspace was created and only makes literal downstream reuse technically possible; it never selects that behavior or forces a 1:1 slide sequence. - -Mirror mode may simplify SVG code but does not redesign the visual target or synthesize layer ownership. The sprite-sheet preservation rule applies because crop wrappers carry visible geometry; preserve their crop behavior and source scope faithfully. - -**Expected outputs from this step** (full spec → [template-designer.md](../references/template-designer.md)): - -1. `<design_spec_path>` — **package-specific rules only**. A deck writes a descriptive Template Overview, Color Scheme, Signature Design Elements, and factual Page Roster; Typography / Assets / Placeholder Overrides are conditional. A layout writes only structure-owned Signature Design Elements and Page Roster; its frontmatter `summary` carries concise selection context, and it omits the deck-only Template Overview plus every identity section. The Page Roster must match the actual SVG files on disk and must not prescribe which pages or sample content a future project keeps. Declare portable brief frontmatter; `register_template.py` consumes it only in library scope. **Do not** restate generic SVG constraints, layout pattern libraries, font-size ratio bands, the canonical placeholder table, or content methodology — those are sourced from `shared-standards-core.md` / `pptx-structure-interface.md` / `strategist.md` and are already in the downstream reader's context. Full scope rule and skeleton: [template-designer.md §1](../references/template-designer.md#1-must-generate-design_specmd). -2. Page roster — see [Page Roster](../references/template-designer.md#page-roster) for `standard` / `fidelity` / `mirror` mode rosters, variant naming, and TOC handling -3. Placeholder vocabulary — pages should adopt the conventional names (`{{TITLE}}`, `{{CONTENT_AREA}}`, ...) when they fit. Full reference: [Placeholder Reference](../references/template-designer.md#4-placeholder-reference-canonical-convention-overridable-per-template). When a template style legitimately needs different vocabulary (consulting → `{{KEY_MESSAGE}}`, branded cover → `{{BRAND_LOGO}}`), declare a `placeholders:` block in `<design_spec_path>` frontmatter so the registrar and quality checker treat it as the template's authoritative contract. **Avoid** one-off indexed families such as `{{CHAPTER_01_TITLE}}` — use the indexed TOC pattern instead. - - `{{...}}` placeholders are the authoring vocabulary used to generate final slide content. Each emitted SVG also carries the native structure contract: root Master/Layout key/name, direct atomic Master/Layout elements, and direct slot `<g>` elements with explicit design-zone bounds plus exactly one compatible carrier. A validated compact canonical authored-preset `<g>` counts as one semantic atom or one `object` carrier; ordinary groups do not. Composite regions use only the explicit `object` + `proxy` downgrade. Minimal structural `data-pptx-role` hints are added only when specialized metadata cannot express required behavior. Both strict and adaptive downstream set `mode: structured` and require complete `page_layouts`, `page_pptx_layouts`, `pptx_masters`, and `pptx_layouts` from planning onward. -4. Template assets (optional) — both scopes apply the same `templates/` / `images/` / root `icons/imported/` routing defined above - -**Hard rule — placeholder examples are executable defaults**: In authored -`standard` / `fidelity` templates, a carrier is not a floating review label. It -becomes the prototype Slide placeholder, while -`data-pptx-bounds` becomes the reusable Layout frame. - -| Concern | Requirement | -|---|---| -| Full editable frame | `data-pptx-bounds` describes the complete intended text, picture, chart, table, or object box. Never derive it from the sample text's glyph bounds or leave it as a one-line tight box. | -| Generic text entry | General `body` and text-carried `object` slots begin at the upper-left, use left paragraph alignment, and wrap inside the full frame. Title/subtitle alignment follows the authored composition. | -| Centered exceptions | Center alignment is reserved for semantically short focal content such as KPI values, short process nodes, hero statements, and compact takeaways. Record a template-wide exception in `<design_spec_path> §IV` when it is part of the layout grammar. | -| Review Slide binding | `template_preview_pptx.py` sizes each authored Slide carrier to the same complete frame as its registered Layout placeholder. A review deck whose Slide carrier is only the prompt text's tight box fails Step 6. | -| Review prompt legibility | For `standard` / `fidelity`, the preview exporter substitutes concise sample text only in ephemeral review SVGs so long canonical markers such as `{{CHAPTER_NUM}}` or `{{PAGE_NUM}}` do not wrap. The source SVG markers, carrier font sizes, slot metadata, and Layout frames remain unchanged. | -| Mirror boundary | `mirror` preserves source Slide carrier geometry exactly in the tool-side native record referenced by its text carrier and keeps `data-pptx-bounds` as the reusable Layout default. Do not normalize one to the other when the source intentionally overrides that frame. | +**Hard rule — placeholder examples are executable defaults**: in authored templates a carrier is the prototype Slide placeholder and `data-pptx-bounds` the reusable Layout frame — the complete intended box, never the sample text's glyph bounds; general `body` and text-carried `object` slots begin upper-left, left-aligned, wrapping inside the frame, while center alignment is reserved for short focal content (record a template-wide exception in `§IV`); `template_preview_pptx.py` sizes each review carrier to the same frame and substitutes concise sample text only in ephemeral copies; `mirror` keeps source Slide carrier geometry in the tool-side native record and `data-pptx-bounds` as the Layout default without normalizing one to the other. --- ## Step 5: Validate Template Assets -**Create Brand branch**: run the child workflow's §4 checklist and the shared project-safe validator below in both scopes. It detects `kind: brand`, validates the identity-only frontmatter/sections/colors/provenance/asset references, and does not require an SVG roster or touch a global index. Any failure blocks completion. +**Create Brand / Create Style**: run the child's §4 checklist and `svg_quality_checker.py "<template_workspace>/templates" --template-mode --canonical-authoring` in both scopes (it detects the kind and validates the roster-free contract); in `library` add `register_template.py <id> --kind brand|style --dry-run`. Then skip the rest of this step and Step 6. Style Review Focus is advisory only and never activates visual review. + +**Create Layout / Create Deck**: `<template_source>` is the active authoring root's `templates/`. `ls` it and the `images/` / `icons/` roots, then run read-only validation (Template_Designer writes canonical compact SVG directly; mirror normalizes in memory; authored-preset and native record frames stay unchanged): ```bash -python3 skills/ppt-master/scripts/svg_quality_checker.py "<template_workspace>/templates" --template-mode --canonical-authoring +python3 skills/ppt-master/scripts/svg_quality_checker.py "<template_source>" --template-mode --canonical-authoring --format <canvas_format> ``` -In `library` scope, additionally run the registrar dry-run so `brand_id` is checked against the library directory/index key: +Checker behavior in template mode: [`template-tools.md`](../scripts/docs/template-tools.md#svg_quality_checkerpy---template-mode). It validates the authoring contract; Theme ownership, package IDs, and registrations are verified by Step 6. -```bash -python3 skills/ppt-master/scripts/register_template.py <brand_id> --kind brand --dry-run -``` +**Checklist**: the spec follows the kind skeleton with template-specific norms and no generic restatement; every SVG is a complete prototype with a §V row (mirror adds one scope sentence for omitted identities); variant filenames use letter suffixes and reuse the parent placeholder set unless overridden; TOC uses the indexed form; frontmatter declares the canvas fields (and `source_*` for PPTX/SVG-backed templates) and `native_structure_mode: structured`; `viewBox` equals the declared canvas; model-facing bounds and page coordinates use at most two decimals while crop/path/transform/preset/native frames keep required precision; placeholder names follow the convention or a declared override; every referenced asset exists via `../images/` with no bitmap stranded in `templates/`; no `native_structure.json` or `source.pptx` packaged; every root declares Master/Layout keys and names with direct atomic fixed visuals in paint order; every slot is a direct `<g id>` with design-zone bounds and one compatible carrier or an explicit `object` proxy; authored bounds are complete editable boxes with upper-left body entry; review prompts stay readable without changing source markers; authored output was newly authored without distilling source topology; every extra Master is a distinct family with owned Layouts and prototypes; mirror preserves order, identity, parentage, placeholder facts, ownership, meaning, and presentation with a complete Source Preservation Map, canonical lowercase visibility attributes, complete reachable-chain preflight, and the execution manifest plus text-slot sidecars; no duplicate-Layout warning remains for authored modes; edits used the compact authoring SVG and mirror published through the materializer without lossless rehydration; extracted vectors use the `imported/<name>` decoration reference with no `templates/icons/`; fidelity keeps every sprite crop wrapper; mirror SVG count equals source Slide count with `<NNN>_<page_type>.svg` names, no standalone Master/Layout SVG, and no new `{{...}}` markers. -After Create Brand validation passes, skip the Create Layout/Create Deck-only remainder of this step and all of Step 6; continue at Step 7. - -**Create Style branch**: run the child workflow's §4 semantic checklist, then -the shared validator in both scopes. The validator detects `kind: style` and -mechanically enforces the frontmatter, section/field shape, conditional custom -and fallback values, portable ID, and one-file roster-free package boundary. -The child checklist remains authoritative for semantic scope and provenance. - -```bash -python3 skills/ppt-master/scripts/svg_quality_checker.py "<template_workspace>/templates" --template-mode --canonical-authoring -``` - -In `library` scope, additionally run the registrar dry-run so `style_id` is -checked against the library directory/index key: - -```bash -python3 skills/ppt-master/scripts/register_template.py <style_id> --kind style --dry-run -``` - -After Create Style validation passes, skip the Create Layout/Create Deck-only -remainder of this step and all of Step 6; continue at Step 7. Review Focus is -advisory content only and never activates the Generate visual-review stage. - -**Create Layout/Create Deck branch**: set `<template_source>` to the active authoring root's `templates/`. This is `<template_workspace>/templates/` normally and the isolated project-shaped staging root during a structural precedence transition. - -```bash -ls -la "<template_source>" -ls -la "<authoring_workspace>/images" "<authoring_workspace>/icons" -``` - -Run read-only SVG validation on the template directory. The Template Designer -must write canonical compact SVG directly; mirror materialization applies the -same normalization in memory before its first template write. Keep canonical -authored-preset and native record frames unchanged: - -```bash -python3 skills/ppt-master/scripts/svg_quality_checker.py "<template_source>" \ - --template-mode --canonical-authoring --format <canvas_format> -``` - -`--template-mode` makes the checker: - -- glob `*.svg` in the template directory directly (templates do not live under `svg_output/`) -- skip `spec_lock.md` drift checks (templates do not ship a spec_lock) -- enforce roster ↔ resolved Design Spec consistency as **errors** (orphan files / missing files break the template contract and, in library scope, the target kind's index) -- emit advisory **warnings** when a page lacks a conventional placeholder — these are hints, not failures. Declare a `placeholders:` block in `<design_spec_path>` frontmatter to silence them when your template intentionally uses a different vocabulary -- require every SVG root to declare one output Master and Layout; zero-slot Layouts are valid -- reject ordinary Master/Layout `<g>` elements, nested structure markers, missing slot bounds, and carrier-bound slots without exactly one compatible carrier; a validated compact canonical authored-preset `<g>` is the sole fixed-layer group exception and may be one `object` carrier -- validate cross-page Master equality plus same-key Layout atom/slot equality -- warn when distinct Layout keys have identical static framing/slot contracts. Resolve this for `standard` / `fidelity`; mirror keeps distinct source identities and records them in its Source Preservation Map - -This checker validates the authoring contract, not the compiled OOXML package. Theme ownership, package IDs, and registered part relationships are verified by `template_preview_pptx.py` in Step 6. - -**Checklist**: - -- [ ] `<design_spec_path>` follows the kind-specific package skeleton: deck = descriptive Overview / Color / Signature / Page Roster plus conditional sections; layout = structure-owned Signature / Page Roster with no Overview, application contract, or identity sections. Generic constraints (SVG rules, pattern libraries, ratio bands, canonical placeholder table) are NOT restated. The source-derived basic norms are present as template-specific layout / image / density / asset rules, not generic advice. Deck Overview identifies recurring situations, audiences/outcomes, delivery assumptions, and representative narrative/page roles; §V Page Roster factually describes every emitted prototype without required/optional/repeatable or fixed/replaceable/example-only policy -- [ ] Every SVG on disk is a complete Slide prototype with a §V roster row; when mirror omits unreferenced source identities, one §V scope sentence records that fact without per-identity analysis -- [ ] Variant filenames follow the letter-suffix convention (e.g. `03a_content_two_col.svg`); variants typically reuse the parent type's placeholder set unless the spec frontmatter declares otherwise -- [ ] If TOC exists, placeholder pattern uses the canonical indexed form -- [ ] `<design_spec_path>` frontmatter declares `canvas_format`, `canvas_width`, `canvas_height`, and `canvas_viewbox`; PPTX/SVG-backed templates also declare `source_canvas_width`, `source_canvas_height`, and `source_viewbox` -- [ ] SVG `viewBox` matches the declared canvas dimensions, not just the aspect ratio (for `ppt169`: `0 0 1280 720`; for `banner`: `0 0 1920 1080`); `width` / `height`, if written, equal it -- [ ] Model-facing placeholder bounds and transform page coordinates use at most two decimals; normalized crop/viewBox ratios, path geometry, transform scale/rotation coefficients, authored-preset frames, and tool-side native frames retain their required precision -- [ ] Placeholder names follow the canonical convention where applicable; templates with intentionally different vocabularies (e.g. `{{KEY_MESSAGE}}` instead of `{{PAGE_TITLE}}`) should declare a `placeholders:` frontmatter block to silence advisory warnings -- [ ] Asset files referenced by SVGs exist at their resolved paths. In both scopes, bitmap references resolve through `../images/`; no bitmap remains accidentally stranded in `templates/` -- [ ] `<design_spec_path>` frontmatter declares `native_structure_mode: structured`; no `analysis/native_structure.json` or `sources/source.pptx` is packaged -- [ ] Every SVG root declares Master/Layout key and picker names; Master/Layout visuals are direct semantic atoms and obey the explicit paint-order contract. Ordinary `<g>` elements remain forbidden there; a validated helper-generated compact canonical preset `<g>` is the sole group exception because it compiles to one native shape. Structural `data-pptx-role` is used only when specialized metadata cannot express required package/page-number/animation behavior -- [ ] Every slot is a direct `<g id>` with explicit design-zone bounds and exactly one compatible direct carrier, or an explicit composite `object` proxy. A validated compact canonical preset `<g>` may be the one carrier of an `object` slot; an ordinary multi-object group may not. Zero-slot Layouts remain valid -- [ ] For `standard` / `fidelity`, every placeholder bound is the complete editable box rather than the current marker text's tight bounds; general body/object carriers begin at the upper-left and only intentional short focal roles remain centered -- [ ] In review output, authored placeholder prompts remain readable; `template_preview_pptx.py` uses preview-only sample text and leaves every canonical source marker and carrier style unchanged -- [ ] `standard` / `fidelity` output SVGs and their Master/Layout/slot contracts were newly authored without preserving or distilling source topology -- [ ] Every additional authored Master represents a distinct reusable design family, not one Layout or an equivalent duplicate; every declared Master owns at least one emitted Layout and every declared Layout has at least one emitted prototype -- [ ] Mirror output preserves source slide order, the full identity and parentage of every retained Master/Layout, placeholder facts, ownership, source meaning, and similar presentation; SVG code/node identity is not required, and the Source Preservation Map lists every source slide -- [ ] Mirror materialization wrote one compact `ppt-master.template-execution-manifest.v1` roster and one linked `ppt-master.template-text-slots.v2-min` diagnostic sidecar per prototype; each slot has only `selector`, `role`, `current_text`, `text_segments`, and `tspan_count`; neither artifact is injected into page authoring, while validation/export check the complete prototype -- [ ] Mirror roots preserve source inherited-shape visibility with canonical lowercase `data-pptx-show-master-shapes` and `data-pptx-show-inherited-shapes`; same-key Layouts agree on the former, while each Slide retains its own latter value -- [ ] Mirror preflight covered every source Slide and its reachable Layout/Master chain; unreferenced source identities produced no SVG and are reported as omitted -- [ ] For `standard` / `fidelity`, no duplicate-Layout-contract warning remains; mirror may keep equivalent source Layout identities when the preservation map explains them -- [ ] All template-creation edits used the compact authoring SVG; Type A mirror used `mirror_template_materialize.py` only after Template_Designer review, validated source SHA/known refs/manifest/graph/assignment closure before atomic publication, published the current visible tree without lossless subtree rehydration, recovered only supported non-visible semantics, kept authoritative Chart/Table JSON inline, deduplicated supported opaque payload and repeated native restoration attributes into `templates/native_payloads.json.gz`, stripped IR-only source refs, and kept fixed Master/Layout visuals as direct atoms -- [ ] If any SVG references an extracted vector, it uses `data-icon="imported/<name>" data-pptx-asset-role="decoration"`; the v2 inventory and sole SVG asset under `<authoring_workspace>/icons/imported/` declare the same role; no semantic object or descendant is externalized, `templates/icons/` does not exist, and no separate illustration embedding script was added -- [ ] For `fidelity` mode: every sprite-sheet asset retains its nested `<svg viewBox=...>` crop wrapper; no image whose file aspect differs from its on-page aspect was flattened to a bare `<image>` -- [ ] For `mirror` mode: SVG count equals source Slide count, filenames follow `<NNN>_<page_type>.svg`, no standalone Master/Layout SVG exists, and **no new `{{...}}` authoring placeholders were inserted**; §V lists every emitted Slide prototype - -This step is a **hard gate**. Do not generate a review PPTX, register, install a staged structural transition, or hand the workspace to the main pipeline until validation passes. After a staged project install, rerun the checker on the final `<target_project>/templates/`; it validates the effective Layout roster when Layout and Deck coexist. A one-Master template may skip Step 6 when no review was requested; a multi-Master template must continue to Step 6 and may not register or complete before that package gate passes. +This step is a **hard gate**: no review PPTX, registration, staged install, or handoff until it passes. After a staged project install, rerun the checker on the final `<target_project>/templates/`. A one-Master template may skip Step 6 when no review was requested; a multi-Master template must pass Step 6 before registration or completion. --- ## Step 6: Template Review PPTX and Multi-Master Package Gate -**Trigger — Create Layout/Create Deck only**: Run when the user requests a PowerPoint review file **or** when the validated SVG roster declares more than one unique Master key. A multi-Master template requires this step even when no review artifact was requested. A one-Master template may skip directly to Step 7 when the user did not request a review file. Create Brand and Create Style always skip this step because they own no SVG roster or native structure. - -Export the complete SVG roster, one prototype per slide, from the workspace root: +**Trigger — Layout/Deck only**: a requested PowerPoint review file, or a validated roster declaring more than one unique Master key (required even without a request). Brand and Style always skip it. ```bash -python3 skills/ppt-master/scripts/template_preview_pptx.py "<authoring_workspace>" +python3 skills/ppt-master/scripts/template_preview_pptx.py "<authoring_workspace>" # exports/<template_id>_template_preview.pptx +python3 skills/ppt-master/scripts/template_preview_pptx.py "<authoring_workspace>" --native-charts-and-tables -o "<authoring_workspace>/exports/<template_id>_template_preview_native.pptx" # optional JSON-first check +python3 skills/ppt-master/scripts/template_preview_pptx.py "<authoring_workspace>" --force # intentional replacement after a fix ``` -`<authoring_workspace>` is the final workspace normally and the isolated staging -root during a project structural transition. The default output is -`<authoring_workspace>/exports/<template_id>_template_preview.pptx`; the command -creates `exports/` on demand. Copy a requested/required successful review -artifact into the target project's `exports/` during the same atomic install. -The script consumes `templates/*.svg` directly, compiles the declared structured Master/Layout contract, and reopens the result. For `standard` / `fidelity`, it uses ephemeral SVG copies with concise preview-only placeholder samples so long `{{...}}` markers stay readable; canonical source SVGs and placeholder semantics are not modified. It does not require a project `spec_lock.md`, does not create a persistent intermediate project, and does not infer or distill structure. - -The default review keeps visible SVG Chart/Table fallbacks. Marker presence or -template origin never activates native replacement. When JSON-first capability -must also be verified, write a second, distinctly named review explicitly: - -```bash -python3 skills/ppt-master/scripts/template_preview_pptx.py \ - "<authoring_workspace>" \ - --native-charts-and-tables \ - -o "<authoring_workspace>/exports/<template_id>_template_preview_native.pptx" -``` - -The first export refuses an existing output. After intentionally fixing the template and replacing its prior review deck, rerun with `--force`; never rely on a silent overwrite: - -```bash -python3 skills/ppt-master/scripts/template_preview_pptx.py "<authoring_workspace>" --force -``` - -**Validation**: - -- [ ] Review PPTX exists under `<authoring_workspace>/exports/` and, after a staged project transition, was copied to the final project `exports/` -- [ ] PPTX slide count equals the template SVG roster count -- [ ] Package read-back reports the expected Master and Layout counts -- [ ] The presentation registers the exact Master and Slide rosters; every Master registers exactly its owned Layouts; every Layout and Slide relationship resolves to its declared parent -- [ ] Every registered Master targets a distinct Theme part; shared Theme ownership across structured Masters is a hard failure -- [ ] Generated `p14:creationId` values are valid and unique across Slides, Layouts, and Masters; Master/Layout numeric registration IDs are valid and unique in their required scopes -- [ ] For `standard` / `fidelity`, every carrier-bound placeholder on each review Slide has exactly the same type, effective index, and full frame as its registered Layout placeholder; `template_preview_pptx.py` verifies this automatically -- [ ] For `mirror`, source Slide-local placeholder geometry remains unchanged even when it differs from the Layout default frame -- [ ] The user can open one file and review every template page in deterministic filename order -- [ ] When Microsoft PowerPoint is available for acceptance testing, the file opens without a repair prompt and every emitted Layout appears under its intended Master. When PowerPoint is unavailable, report package read-back as the verified evidence and do not claim a PowerPoint-open result - -`template_preview_pptx.py` automatically enforces the deterministic package checks above during read-back. Every applicable validation item is a hard gate for the review artifact. Fix the owning SVG/spec/asset or exporter defect before reporting the preview as verified. For a multi-Master template, any Step 6 failure blocks registration and completion; for a one-Master template, failure of an unrequested preview does not block a workspace that already passed Step 5. +Copy a requested/required review artifact into the target project's `exports/` during a staged install. **Validation**: the PPTX exists (and was copied after a staged transition); slide count equals the roster; read-back reports the expected Master/Layout counts and exact registrations; every Master targets a distinct Theme part; `p14:creationId` and registration IDs are valid and unique; for authored modes every carrier-bound placeholder matches its Layout placeholder's type, index, and frame (verified automatically); for mirror, source Slide-local geometry is unchanged; the user can review every page in filename order; when PowerPoint is available it opens without repair with every Layout under its Master — otherwise report package read-back as the evidence and claim no PowerPoint-open result. Every item is a hard gate for the artifact; a multi-Master failure blocks registration and completion, while an unrequested one-Master preview failure does not block a workspace that passed Step 5. --- ## Step 7: Register Template in Library Index (Library Scope Only) -Branch on the confirmed output scope: - -| Scope | Action | -|---|---| -| `library` | Run the registrar below after Step 5 passes and Step 6 also passes whenever it was requested or required by a multi-Master roster | -| `project` | Skip the registrar entirely. Do not edit any global template index or library README; continue to Step 8 with index status `Not registered (project workspace)` | - -Run the unified registrar with the kind flag; it derives the corresponding index entry from `templates/design_spec.md` (frontmatter when present, prose fallback otherwise) plus the actual `templates/*.svg` file list. The workspace must already use the current nested contract: - -```bash -# For brand -python3 skills/ppt-master/scripts/register_template.py <template_id> --kind brand - -# For style -python3 skills/ppt-master/scripts/register_template.py <template_id> --kind style - -# For deck -python3 skills/ppt-master/scripts/register_template.py <template_id> --kind deck - -# For layout -python3 skills/ppt-master/scripts/register_template.py <template_id> --kind layout -``` - -Outputs by kind (the JSON index is the single source of truth — READMEs describe the kind in prose but do not enumerate templates): - -| `--kind` | Index updated | -|---|---| -| `deck` | `templates/decks/decks_index.json` | -| `layout` | `templates/layouts/layouts_index.json` | -| `brand` | `templates/brands/brands_index.json` | -| `style` | `templates/styles/styles_index.json` | - -The Layout/Deck completion card's file roster is collected by globbing -`templates/*.svg` in the workspace. Brand/Style cards are spec-only. Legacy -flat Layout/Deck packages still use their root `*.svg` roster. - -The index file is the complete **registered-library discovery source** for -Default [`generate-pptx`](./generate-pptx.md#step-3-template-candidate-preparation) -Stage-1 template controls. Step 3 prepares their candidate input without -interaction; the controls read only the four kind indexes, while chat discovery -uses the same entries to list exact workspace-root paths. Neither path scans -template directories. Selecting a registered entry and submitting Stage 1 -activates installation. An exact unregistered workspace supplied by the user, -or the exact validated root handed off by this route in the current -conversation, appears as a specified candidate and is preselected when it is -the only supplied root; it remains labelled `explicit` and does not enter the -library catalog. If an explicit root exactly matches a registered canonical -root, it may be displayed as `library`. Bare names and style phrases are never -resolved implicitly or used to preselect a template. - -> **Recommended for new templates**: declare a YAML frontmatter block at the top of `<design_spec_path>`. The registrar prefers it over prose extraction: -> -> ```yaml -> # style example -> --- -> style_id: consulting_analytical -> kind: style -> summary: Answer-first, evidence-led decision-document defaults without page prototypes or brand identity. -> keywords: [consulting, decision-support, evidence, analytical] -> --- -> -> # deck example -> --- -> deck_id: my_deck -> kind: deck -> category: brand -> summary: ... -> keywords: [brand, reporting, structured] -> canvas_format: ppt169 -> canvas_width: 1280 -> canvas_height: 720 -> canvas_viewbox: "0 0 1280 720" -> source_canvas_width: 1280 -> source_canvas_height: 720 -> source_viewbox: "0 0 1280 720" -> replication_mode: standard -> # All current deck/layout templates rebuild the current structured SVG contract. -> # Downstream strict/adaptive use is confirmed by Strategist and is not stored here. -> native_structure_mode: structured -> page_count: 5 -> primary_color: "#005587" -> --- -> -> # layout example -> --- -> layout_id: my_layout -> kind: layout -> category: general -> summary: ... -> keywords: [general, layout, structured] -> canvas_format: ppt169 -> canvas_width: 1280 -> canvas_height: 720 -> canvas_viewbox: "0 0 1280 720" -> source_canvas_width: 1280 -> source_canvas_height: 720 -> source_viewbox: "0 0 1280 720" -> replication_mode: standard -> native_structure_mode: structured -> page_count: 5 -> page_types: [cover, toc, chapter, content, ending] -> --- -> ``` - -> To rebuild every entry at once (e.g. after editing many specs), run: -> -> ```bash -> python3 skills/ppt-master/scripts/register_template.py --kind style --rebuild-all -> python3 skills/ppt-master/scripts/register_template.py --kind deck --rebuild-all -> python3 skills/ppt-master/scripts/register_template.py --kind layout --rebuild-all -> ``` - -README files describe each kind in prose only — they do not list templates. -The Default Stage-1 template controls and chat discovery read the JSON index files; the -registrar does not touch READMEs. +`library`: after Step 5 (and Step 6 when requested or required), run `python3 skills/ppt-master/scripts/register_template.py <template_id> --kind brand|style|deck|layout`; it derives the entry from the spec frontmatter (preferred) or prose plus the actual `templates/*.svg` roster and updates that kind's `*_index.json` — the complete discovery source for Default Stage-1 controls and chat listing (neither scans directories). `project`: skip the registrar, edit no index or README, and report `Not registered (project workspace)`. An exact unregistered root supplied by the user or handed off by this route appears as an `explicit` candidate preselected only when it is the sole root; a root matching a registered canonical root may display as `library`; bare names are never resolved. Frontmatter examples per kind live in the child workflows; `--rebuild-all` rebuilds a kind's index after editing many specs. --- ## Step 8: Output Confirmation -Produce one scope-aware, evidence-driven completion card for either location: - ```markdown ## Template Creation Complete @@ -1012,63 +211,28 @@ Produce one scope-aware, evidence-driven completion card for either location: **Workspace Path**: `<template_workspace>/` **Template Source**: `<template_workspace>/templates/` **Design Spec**: `<installed_design_spec_path>` -**Bitmap Path**: `<template_workspace>/images/` ← omit when no bitmap was written or adopted -**Imported Vector Path**: `<template_workspace>/icons/imported/` ← omit when no imported vector was written or adopted -**Review PPTX**: `<template_workspace>/exports/<template_id>_template_preview.pptx` ← Create Layout/Create Deck only; omit for Create Brand/Create Style and when an optional one-Master review was not requested -**Primary Color**: <hex> ← Create Brand/Create Deck only; omit for Create Style/Create Layout +**Bitmap Path**: `<template_workspace>/images/` ← omit when nothing was written or adopted +**Imported Vector Path**: `<template_workspace>/icons/imported/` ← omit when nothing was written or adopted +**Review PPTX**: `<template_workspace>/exports/<template_id>_template_preview.pptx` ← Layout/Deck only; omit when an optional one-Master review was not requested +**Primary Color**: <hex> ← Brand/Deck only **Index Registration**: Done | Not registered (project workspace) ### Files Included - | File | Status | |------|--------| -| `templates/01_cover.svg` | Done | -| `templates/02_toc.svg` | Done | -| `templates/03_chapter.svg` | Done | -| `templates/04_content.svg` | Done | -| `templates/05_ending.svg` | Done | -| `exports/<template_id>_template_preview.pptx` | Verified, when requested or required for multi-Master | +| `templates/01_cover.svg` … | Done | +| `exports/<template_id>_template_preview.pptx` | Verified, when requested or required | ``` -For Create Brand, replace the SVG/review rows with -the Design Spec plus only real identity assets. For Create Style, -list only that spec. Both completion cards must explicitly -state `SVG roster: N/A` and `Native structure: N/A`; Style must also state -`Visual review trigger: N/A (advisory focus only)`. - -The exact `<template_workspace>/` root in either scope is the -current-conversation handoff to Default Generate Step 3. It appears as the -specified candidate, defaults Stage 1 to template mode, and is preselected only -when it is the sole supplied root. After Stage 1 confirms it, the application -stage resolves the root's Design Spec(s) and always ignores `exports/`. -Brand/Layout/Deck copy or consume package-owned `templates/` plus any existing -`images/` and `icons/`; Style consumes only its own spec and ignores sibling -project scaffolding. It then authors new `svg_output/` pages -under the template contract and exports a new PPTX. Neither the reference -PPTX/SVG nor the template prototypes are upgraded in place. Any older flat or -semantic-legacy package is input evidence only; create a new current workspace -through this route before it can be selected by Generate. - ---- - -## Color Scheme Quick Reference - -| Style | Primary Color | Use Cases | -|-------|---------------|-----------| -| Tech Blue | `#004098` | Certification, evaluation | -| McKinsey | `#005587` | Strategic consulting | -| Government Blue | `#003366` | Government projects | -| Business Gray | `#2C3E50` | General business | +Brand lists the spec plus real identity assets; Style lists only its spec; both state `SVG roster: N/A` and `Native structure: N/A`, and Style adds `Visual review trigger: N/A (advisory focus only)`. The exact `<template_workspace>/` root is the current-conversation handoff to Generate Step 3: it appears as the specified candidate, defaults Stage 1 to template mode, and is preselected only when it is the sole root; after Stage 1 confirms it, application resolves its spec(s), ignores `exports/`, and authors new `svg_output/` pages — neither the reference nor the prototypes are upgraded in place, and any older flat or legacy package is evidence only. --- ## Notes -1. **SVG technical constraints**: Create Layout/Create Deck load [shared-standards-core.md](../references/shared-standards-core.md) plus [pptx-structure-interface.md](../references/pptx-structure-interface.md), and load [svg-effects.md](../references/svg-effects.md) only when the authored design uses those effects. Create Brand and Create Style author no SVG and load none of these SVG modules. Do not restate the contracts in the template's `design_spec.md`. -2. **Color consistency**: Create Deck SVG files must use the same color scheme as `design_spec.md §II Color Scheme`; Create Layout owns no identity colors, Create Style owns only overrideable visual defaults, and Create Brand/Create Style own no SVG files -3. **Native-object mapping**: Treat Theme/Master/Layout/Placeholder as compiled PowerPoint objects, not template kinds. Layout owns topology and placement, Brand owns identity values/assets, Style owns portable direction/method defaults, and Deck adds descriptive recurring-application context. -4. **Placeholder convention**: `{{}}` format only; default names listed in [Placeholder Reference](../references/template-designer.md#4-placeholder-reference-canonical-convention-overridable-per-template). Override per template via `placeholders:` frontmatter when needed. -5. **Discovery requirement**: A library template appears in the Default Stage-1 template selector and chat discovery only after `register_template.py` has updated its kind index (Step 7). A project-scoped workspace intentionally stays out of the library catalog and is consumed as an exact `explicit` workspace-root candidate. Step 3 only prepares candidates; Stage 1 confirms communication plus free design/template use together, and only a non-free confirmed selection installs a workspace before Stage 2. -6. **Review output**: Generate `exports/<template_id>_template_preview.pptx` on request and always for a multi-Master template. It is derived local evidence, never a source input during template application, and library exports stay Git-ignored. Brand and Style never generate this preview; Style Review Focus cannot activate visual review. - -> **Full role specification**: [template-designer.md](../references/template-designer.md) +1. Layout/Deck load [`shared-standards-core.md`](../references/shared-standards-core.md) and [`pptx-structure-interface.md`](../references/pptx-structure-interface.md), plus [`svg-effects.md`](../references/svg-effects.md) only when the design uses those effects; Brand and Style author no SVG and load none. Never restate these contracts in a template spec. +2. Deck SVGs use the spec's §II Color Scheme; Layout owns no identity colors; Style owns only overrideable defaults. +3. Theme/Master/Layout/Placeholder are compiled PowerPoint objects, not template kinds: Layout owns topology and placement, Brand identity values and assets, Style portable direction, Deck descriptive application context. +4. Placeholders use `{{}}` with the canonical names in [template-designer.md §4](../references/template-designer.md#4-placeholder-reference-canonical-convention-overridable-per-template), overridden per template through `placeholders:` frontmatter. +5. A library template is discoverable only after Step 7; a project workspace stays out of the catalog and is consumed as an exact `explicit` root. Stage 1 confirms communication plus free design/template use together; only a non-free confirmed selection installs a workspace before Stage 2. +6. The review PPTX is derived local evidence, generated on request and always for multi-Master; Brand and Style never generate it. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/create-template/create-brand.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/create-template/create-brand.md index 11cf07f6..3f71dc7f 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/create-template/create-brand.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/create-template/create-brand.md @@ -4,78 +4,36 @@ description: Create Brand workflow for an identity-only reusable workspace witho # Create Brand Workflow -Enter this child workflow only after [`Create Template`](../create-template.md) dispatches `kind: brand`. +Enter only after [`Create Template`](../create-template.md) dispatches `kind: brand`. Create Template owns dispatch, scope, the confirmation gate, collision preflight, registration, completion, and the Generate handoff; Create Brand owns brand analysis, the identity brief, the identity-only spec, adopted assets, and brand validation. -## Responsibility Boundary +**Hard rule — child workflow, not a top-level route**: executes only inside Create Template under its single shared gate; never a competing entry or second confirmation. -| Owner | Responsibilities | -|---|---| -| Create Template | Child-workflow dispatch plus the shared `library` / `project` scope, confirmation gate, collision preflight, registration, completion, and Generate PPTX handoff contract | -| Create Brand | End-to-end brand-specific analysis, identity brief, identity-only `design_spec.md`, adopted brand assets, and brand-specific validation | +**Hard rule — identity only**: a brand owns color, typography, logo, voice, and icon style — no canvas, spacing system, page roster, SVG prototype, Master/Layout graph, placeholder contract, or preview PPTX. -**Hard rule — child workflow, not a top-level route**: Create Brand executes only inside Create Template. It uses the parent workflow's single shared confirmation/preflight/registration contract and never creates a competing entry route or second confirmation gate. - -**Hard rule — identity only**: A brand owns color, typography, logo, voice, and icon style. It owns no canvas, spacing system, page roster, SVG prototype, Master/Layout graph, placeholder contract, or preview PPTX. - -## Invocation Points - -1. Use §1–2 below for brand analysis and identity fields, then execute Create Template Steps 2–3 with those child-owned fields. -2. After Create Template Step 4 resolves and preflights `<template_workspace>` and `<design_spec_path>`, use §3 to materialize the confirmed identity. -3. Run §4, then return its evidence to Create Template Steps 5, 7, and 8. Create Brand always skips shared Step 6. +**Invocation**: §1–2 feed Create Template Steps 2–3; after Step 4 resolves and preflights `<template_workspace>` / `<design_spec_path>`, §3 materializes; §4 returns evidence to Steps 5, 7, and 8; Step 6 is always skipped. ## 1. Brand Input Analysis | Input | Read path | Facts it may support | |---|---|---| -| SVG logo | Read the SVG and inspect literal `fill` / `stroke` values | Logo asset and literal colors | +| SVG logo | Inspect literal `fill` / `stroke` | Logo asset and literal colors | | PNG/JPG logo | Inspect visually | Logo asset and approximate colors | -| Official brand site or manual | Convert/read the source | Published colors, fonts, voice, usage restrictions | -| Branded PPTX/PDF | Use the existing source converters and theme/package facts | Observed colors, typography, logo assets, and tone | -| Pasted text, Markdown, or text document | Use direct text or the parent workflow's converted text output | Explicit identity values, usage rules, voice, and restrictions | -| Verbal brief | Use the user's words directly | Any identity field the user explicitly supplies | -| Mixed reference bundle | Run every applicable row and retain per-source provenance | Combined identity evidence; unresolved conflicts go to the shared confirmation gate | -| No reference | No analysis | Empty skeleton only when the user explicitly requests it | +| Official brand site or manual | Convert/read | Published colors, fonts, voice, usage restrictions | +| Branded PPTX/PDF | Source converters and theme/package facts | Observed colors, typography, logo assets, tone | +| Pasted text, Markdown, or document | Direct text or the parent's converted output | Explicit identity values, usage rules, voice, restrictions | +| Verbal brief | The user's words | Any explicitly supplied field | +| Mixed bundle | Every applicable row with per-source provenance | Combined evidence; conflicts go to the shared gate | +| No reference | None | Empty skeleton only when explicitly requested | -Use these provenance labels in the proposal and final Color Scheme table: - -- `fact` — literal value from an official asset or manual. -- `user` — value explicitly authored by the user, whether in chat, pasted text, or a user-written brief file. -- `approx` — visual estimate or pattern observed in an existing deck/site. - -**Hard rule — no inferred brand truth**: Do not promote a visual estimate, presentation convention, or observed neutral into an official brand fact. Do not invent semantic success/warning/error colors. +Provenance labels for the proposal and the Color Scheme table: `fact` (literal value from an official asset or manual), `user` (explicitly authored by the user in any carrier), `approx` (visual estimate or observed pattern). **Hard rule — no inferred brand truth**: never promote an estimate, presentation convention, or observed neutral into an official fact, and never invent semantic success/warning/error colors. ## 2. Identity Brief Fields -Surface these through Create Template's single shared Step 2–3 gate: - -| Field | Requirement | -|---|---| -| Brand display name and use cases | Required | -| Primary color | Required; `#RRGGBB` plus provenance | -| Secondary/accent/text/background colors | Include only when confirmed or supported by evidence; every written color uses `#RRGGBB` plus provenance | -| Title/body typography | Required; retain provenance in surrounding prose when it is not official | -| Logo | Optional; identify the default presenting entity, file, usage rule, and any trademark restriction | -| Voice and tone | Required; formality, grammatical person, emoji policy, abbreviation policy | -| Icon style | Required; `linear`, `filled`, `duotone`, or a confirmed custom description | -| Adopted assets | Optional; list included and excluded candidates with reasons | - -When the user explicitly requests an empty skeleton, all identity values remain TODO comments, materialization stops after writing the file, and Create Template reports that the workspace is incomplete and unregistered. +Surface through Create Template's Step 2–3 gate: brand display name and use cases (required); primary color (required, `#RRGGBB` plus provenance); secondary/accent/text/background colors (only when confirmed or evidenced, each with provenance); title/body typography (required, provenance in prose when unofficial); logo (optional: default presenting entity, file, usage rule, trademark restriction); voice and tone (required: formality, person, emoji policy, abbreviation policy); icon style (required: `linear`, `filled`, `duotone`, or a confirmed custom description); adopted assets (optional, with included/excluded reasons). An explicitly requested empty skeleton leaves every value as a TODO comment, stops after writing the file, and is reported as incomplete and unregistered. ## 3. Materialize the Confirmed Brand -Create Template supplies an already resolved and collision-checked `<template_workspace>` and `<design_spec_path>`. Write only: - -```text -<template_workspace>/ -├── templates/ -│ └── design_spec.md # project scope: design_spec.brand.<brand_id>.md -├── images/ # optional; logo/photos/illustrations only when adopted -└── icons/ # optional; branded icon overrides only when adopted -``` - -Do not create optional directories or `exports/` solely to retain empty paths. An initialized project may already contain empty scaffolding; leave it untouched and do not report it as Brand output. Bitmap references from `<design_spec_path>` use `../images/<name>`; branded icon references use `../icons/<name>`. - -Write this personality-only schema: +Write only `templates/design_spec.md` (project: `design_spec.brand.<brand_id>.md`), plus optional `images/` (logo/photos when adopted) and `icons/` (branded icon overrides when adopted); never create optional directories or `exports/` to keep empty paths, and leave pre-existing project scaffolding untouched. References use `../images/<name>` and `../icons/<name>`. ```markdown --- @@ -95,7 +53,7 @@ primary_color: "#XXXXXX" | Brand Name | <display name> | | Use Cases | <summary> | | Tone | <one-line tone summary> | -| Sources | <official URL or bundled asset paths; include version/retrieval date when known> | +| Sources | <official URL or bundled asset paths; version/retrieval date when known> | ## II. Color Scheme | Role | HEX | Provenance | @@ -124,38 +82,13 @@ primary_color: "#XXXXXX" - Preference: linear \| filled \| duotone \| <custom> ## VII. Visual Assets -- Include this section only when real `images/` or `icons/` assets exist. +- Only when real `images/` or `icons/` assets exist. ``` -Preserve a supplied logo's extension. When multiple lockups exist, use descriptive filenames and name exactly one default presenting entity. Keep subsidiary/campaign alternates explicit; create another brand workspace when their identity differs materially. +Keep a supplied logo's extension; with several lockups use descriptive filenames and name exactly one default presenting entity; create another workspace when a subsidiary/campaign identity differs materially. ## 4. Brand Validation -Return these facts to Create Template: +Return to Create Template: the spec exists with `brand_id`, `kind: brand`, `summary`, `primary_color`; `brand_id` matches the library workspace ID; sections I–VI exist and Page Roster / Signature Design Elements do not; no `*.svg`, `native_structure_mode`, Master/Layout, placeholder, canvas, or page-count field; every color is `#RRGGBB` with the primary row matching frontmatter and provenance `fact` / `approx` / `user`; every referenced asset exists in the workspace and no empty optional directory was created. -- The Design Spec exists and contains `brand_id`, `kind: brand`, `summary`, and `primary_color`. -- `brand_id` matches the confirmed workspace ID in library scope. -- Required sections I–VI exist; Page Roster and Signature Design Elements do not exist. -- No `*.svg`, `native_structure_mode`, Master/Layout, placeholder, canvas, or page-count fields were written. -- Every color is `#RRGGBB`, the primary table row matches frontmatter, and provenance is `fact`, `approx`, or `user`. -- Every referenced asset exists under the same workspace; this workflow created no optional directory or `exports/` directory solely to leave it empty. Pre-existing initialized-project scaffolding is allowed and remains untouched. - -For both scopes, Create Template Step 5 validates the portable Brand contract without registration: - -```bash -python3 skills/ppt-master/scripts/svg_quality_checker.py "<template_workspace>/templates" --template-mode --canonical-authoring -``` - -For `library` scope, additionally validate the directory/index identity with: - -```bash -python3 skills/ppt-master/scripts/register_template.py <brand_id> --kind brand --dry-run -``` - -After that gate passes, Create Template Step 7 registers with: - -```bash -python3 skills/ppt-master/scripts/register_template.py <brand_id> --kind brand -``` - -For `project` scope, run only the shared validator, skip both registrar commands, and report `Not registered (project workspace)`. Downstream consumption always uses the explicit workspace root through Generate PPTX Step 3; a bare brand name never activates it. +Both scopes run `svg_quality_checker.py "<template_workspace>/templates" --template-mode --canonical-authoring`; library adds `register_template.py <brand_id> --kind brand --dry-run` and, after the gate, Step 7 registers with `register_template.py <brand_id> --kind brand`. Project scope skips both registrar commands and reports `Not registered (project workspace)`. Downstream consumption always uses the explicit root through Generate Step 3; a bare brand name never activates it. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/create-template/create-deck.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/create-template/create-deck.md index 25d780d4..3c349c95 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/create-template/create-deck.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/create-template/create-deck.md @@ -4,56 +4,23 @@ description: Create Deck child workflow for a recurring presentation application # Create Deck Workflow -Enter this child workflow only after [`Create Template`](../create-template.md) dispatches `kind: deck`. +Enter only after [`Create Template`](../create-template.md) dispatches `kind: deck`. Create Template owns dispatch, the source taxonomy, scope, the confirmation gate, collision preflight, the structured authoring contract, validation commands, registration, completion, and the Generate handoff; Create Deck owns recurring-application interpretation, integrated identity/structure, the complete spec, the SVG roster, and deck validation. -## Responsibility Boundary +**Hard rule — child workflow, not a top-level route**: executes only inside Create Template Steps 1–8. -| Owner | Responsibilities | -|---|---| -| Create Template | Child-workflow dispatch plus the shared source taxonomy, `library` / `project` scope, confirmation gate, collision preflight, structured authoring contract, validation commands, registration, completion, and Generate PPTX handoff | -| Create Deck | Recurring-application interpretation, integrated identity/structure, complete `design_spec.md`, SVG roster, and deck-specific validation | +**Hard rule — recurring application**: a deck owns descriptive application context (recurring presentation family, intended audiences/outcomes, delivery/reading assumptions, representative narrative/page roles) together with integrated identity and structure. The context helps later planning understand the resource; it never prescribes which prototypes or content a future project must keep, and the workspace is a reusable template, not the user's finished deck. -**Hard rule — child workflow, not a top-level route**: Create Deck executes only inside Create Template. It reuses the parent workflow's Steps 1–8 and never creates a competing entry route or second confirmation gate. - -**Hard rule — recurring application**: A deck owns descriptive application context together with integrated identity and structure. The context states the recurring presentation family, intended audiences/outcomes, delivery/reading assumptions, and representative narrative/page roles. It helps later AI planning understand the resource, but it does not prescribe which prototypes or visible content a future project must keep. It is a reusable template workspace, not the user's finished content deck. - -## Invocation Points - -1. Use §1–2 below while executing Create Template Steps 1–3. -2. After Create Template Step 4 preflights `<template_workspace>` and `<design_spec_path>`, use §3 to author or materialize the deck workspace under the shared structured contract. -3. Apply §4 in addition to Create Template Step 5, then continue through shared Steps 6–8. +**Invocation**: §1–2 during Create Template Steps 1–3; after Step 4 preflights the workspace, §3 authors or materializes under the shared structured contract; §4 adds to Step 5, then shared Steps 6–8. ## 1. Deck Input Interpretation -Use Create Template Step 1 for source ingestion and internal creation-strategy feasibility. Interpret source evidence across all three segments: +Use Create Template Step 1 for ingestion and strategy feasibility across three segments: identity (color, typography, logo, visual voice, icon style, with provenance); structure (canvas, page grammar, Master/Layout families, slot geometry, text roles, alignment/wrapping/capacity, page types, image behavior, density rhythm); application (recurring situations, audiences/outcomes, delivery assumptions, representative roles, the actual source-page vocabulary — never assigned required/optional/repeatable status or fixed/replaceable/example-only policy). `standard` / `fidelity` author a new complete system (source topology is not output topology); `mirror` preserves only validated package/contract facts in a new workspace; the AI derives the implementation from intent. Direct text, converted documents, images, and assets are first-class evidence; user-authored instructions are decisions in any carrier, vague prose stays suggested until the gate. -- Identity: color, typography, logo, visual voice, and icon style, with fact/suggestion provenance preserved in the brief. -- Structure: canvas, page grammar, Master/Layout families, slot geometry, semantic text roles, alignment/wrapping/capacity behavior, page types, image behavior, and density rhythm. -- Application: recurring situations, intended audiences/outcomes, delivery or reading assumptions, representative narrative/page roles, and the actual source-page vocabulary. Do not assign required/optional/repeatable status or fixed/replaceable/example-only policy. -- Internally, `standard` and `fidelity` author a new complete system; source topology is not output topology. `mirror` preserves only validated package/contract facts in a new workspace and never modifies the source. The AI derives this implementation from the natural-language intent; it is not a user mode selector. - -Direct conversation text, pasted requirements, converted documents/websites, images, and supplied assets are first-class evidence under Create Template Step 1. In a mixed bundle, combine the applicable identity, structure, and application evidence without erasing provenance. Exact user-authored instructions remain decisions whether they arrive in chat or a user-written brief file; vague prose remains suggested interpretation until the shared confirmation gate. - -Create Deck is selected when identity and structure must travel together, when the source is a specific organization's branded presentation system, or when reusable scenario/content semantics are requested. A complete PPTX source alone does not make the output a Deck. If only identity is stable, use Create Brand; if the reusable structure is brand-neutral and the communication application remains downstream-defined, use Create Layout. Return to Create Template dispatch before the shared confirmation marker is emitted when the evidence supports a different kind. +Select Create Deck when identity and structure must travel together, the source is one organization's branded presentation system, or reusable scenario/content semantics are requested. A complete PPTX alone does not make a Deck: identity-only → Create Brand; brand-neutral structure with downstream-defined application → Create Layout; return to dispatch before the marker when the evidence supports another kind. ## 2. Deck Brief and Schema -Add these child-owned requirements to Create Template Step 2: - -| Field | Requirement | -|---|---| -| Deck ID and display name | Required; `deck_id` is a filesystem-safe ASCII slug | -| Recurring presentation family | Required; identify the repeatable situations this Deck serves rather than listing every plausible use | -| Intended audiences and outcomes | Required; state who the recurring users/recipients are and what the presentation should enable | -| Delivery and reading assumptions | Required; state whether the family is usually presented, closely read, handed off, or used in a mixed way | -| Representative narrative/page roles | Required; describe the roles present in the source or useful to the recurring family without assigning future inclusion rules | -| Identity | Required; primary color plus supported palette, typography, logo policy, visual voice, and icon style | -| Canvas and page grammar | Required; exact canvas, page types, variants, grids, zones, density rhythm, and image behavior | -| Native structure | Required; Master families, Layout ownership, slot vocabulary, and zero-slot Layouts where intentional | -| Creation intent | Required as natural-language prose: what should remain recognizable, what should be rebuilt into a reusable system, and whether the source page set should be preserved broadly or distilled. The AI derives `replication_mode` internally. | -| Adopted assets | Optional; list included and excluded candidates with reasons | - -Write this complete schema: +Add to Create Template Step 2 (required unless noted): Deck ID (ASCII slug) and display name; recurring presentation family (repeatable situations, not every plausible use); intended audiences and outcomes; delivery and reading assumptions (presented, closely read, handed off, mixed); representative narrative/page roles (without future inclusion rules); identity (primary color plus palette, typography, logo policy, visual voice, icon style); canvas and page grammar (exact canvas, page types, variants, grids, zones, density, image behavior); native structure (Master families, Layout ownership, slot vocabulary, intentional zero-slot Layouts); creation intent as prose (what stays recognizable, what is rebuilt, whether the source page set is preserved broadly or distilled — `replication_mode` derived internally); adopted assets (optional, with included/excluded reasons). ```markdown --- @@ -83,53 +50,14 @@ page_count: <N> ## VII. Placeholder Overrides ``` -`replication_mode` is required machine provenance, not a user-facing choice. Omit Typography only when the shared default is intentionally used. Omit Assets and Placeholder Overrides when none exist. Do not restate generic SVG constraints, layout libraries, font-ratio bands, or the canonical placeholder table. - -Write Template Overview as descriptive application context. In Page Roster, -describe each prototype's observed or intended role, visual character, -reusable slots, and structural capacity. Do not add required/optional/ -repeatable status or fixed/replaceable/example-only content policy; downstream -Strategist inspects the actual template and current content and decides what to -use. +`replication_mode` is machine provenance. Omit Typography only when the shared default is intentional; omit Assets and Placeholder Overrides when none exist; restate no generic SVG constraints, layout libraries, font-ratio bands, or the canonical placeholder table. Template Overview is descriptive application context; Page Roster describes each prototype's role, visual character, reusable slots, and capacity without status or content policy — downstream Strategist decides what to use. ## 3. Author or Materialize the Deck -Follow Create Template Step 4 and the shared Template_Designer contract with `kind: deck`, `kind_dir: decks`, and `id_key: deck_id` fixed. Do not ask the user to choose the kind again. - -The output is: - -```text -<template_workspace>/ -├── templates/ # design_spec.md (project scope: design_spec.deck.<deck_id>.md) + SVG prototypes -├── images/ # optional adopted bitmaps -├── icons/ -│ └── imported/ # optional imported vectors -└── exports/ # conditional review evidence -``` - -Every SVG is a complete preview and declares one root Master and Layout under the shared structured contract. The deck's SVG paint, typography, and adopted assets must agree with its identity segment. Every additional authored Master represents a distinct reusable design family, not one Layout or an organizational duplicate. +Follow Create Template Step 4 and the Template_Designer contract with `kind: deck`, `kind_dir: decks`, `id_key: deck_id` fixed; never ask for the kind again. Output: `templates/` (spec plus prototypes), optional `images/` and `icons/imported/`, conditional `exports/`. Every SVG is a complete preview declaring one root Master and Layout; paint, typography, and adopted assets agree with the identity segment; every additional authored Master is a distinct reusable design family, never one Layout or an organizational duplicate. ## 4. Deck Validation -In addition to Create Template Steps 5–6, verify: +In addition to Create Template Steps 5–6: the spec contains `deck_id`, `kind: deck`, `summary` (naming the family/outcome, not only visual tone), `primary_color`, canvas fields, `replication_mode`, `native_structure_mode: structured`, `page_count`; `deck_id` matches the library workspace ID; Template Overview, Color Scheme, Signature Design Elements, and Page Roster exist with the Overview descriptive, every roster row factual, and conditional sections matching real choices; every identity color is `#RRGGBB` with the primary row matching frontmatter and SVG paint following the identity; every SVG satisfies the shared Master/Layout/slot contract with a bidirectionally complete roster; every referenced image/icon exists and no empty optional directory was created (pre-existing project scaffolding stays untouched). -- The Design Spec contains `deck_id`, `kind: deck`, `summary`, `primary_color`, canvas fields, `replication_mode`, `native_structure_mode: structured`, and `page_count`; `summary` names the recurring presentation family/outcome rather than only visual tone. -- `deck_id` matches the confirmed workspace ID in library scope. -- Template Overview, Color Scheme, Signature Design Elements, and Page Roster exist; Template Overview describes the recurring application context, every roster row factually describes its prototype and slots without future-use policy, and conditional sections match real choices/assets. -- Every identity color is `#RRGGBB`; the primary table row matches frontmatter, and SVG paint follows the confirmed identity. -- Every SVG in the roster satisfies the shared Master/Layout/slot contract and the roster is bidirectionally complete. -- Every referenced image/icon exists under the same workspace; this workflow created no optional directory solely to leave it empty. Pre-existing initialized-project scaffolding is allowed and remains untouched. - -For library scope, Create Template Step 5 validates the directory/index identity with: - -```bash -python3 skills/ppt-master/scripts/register_template.py <deck_id> --kind deck --dry-run -``` - -After that gate and any triggered Create Template Step 6 pass, Step 7 registers with: - -```bash -python3 skills/ppt-master/scripts/register_template.py <deck_id> --kind deck -``` - -For project scope, skip both commands. The exact workspace root becomes the next Generate PPTX Step 3 input; any separately supplied Brand, Style, or Layout workspace overrides the corresponding complete segment downstream without mutating this deck workspace. +Library scope validates with `register_template.py <deck_id> --kind deck --dry-run` and, after Step 5 and any triggered Step 6, registers with `register_template.py <deck_id> --kind deck`; project scope skips both. The exact root becomes the next Generate Step 3 input; a separately supplied Brand, Style, or Layout workspace overrides its complete segment downstream without mutating this deck. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/create-template/create-layout.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/create-template/create-layout.md index 015256c9..4f0bd3b8 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/create-template/create-layout.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/create-template/create-layout.md @@ -4,54 +4,21 @@ description: Create Layout child workflow for a brand-neutral reusable page-stru # Create Layout Workflow -Enter this child workflow only after [`Create Template`](../create-template.md) dispatches `kind: layout`. +Enter only after [`Create Template`](../create-template.md) dispatches `kind: layout`. Create Template owns dispatch, the source taxonomy, scope, the confirmation gate, collision preflight, the structured authoring contract, validation commands, registration, completion, and the Generate handoff; Create Layout owns structure-only interpretation, layout brief fields, the brand-neutral spec, the SVG roster, and layout validation. -## Responsibility Boundary +**Hard rule — child workflow, not a top-level route**: executes only inside Create Template Steps 1–8. -| Owner | Responsibilities | -|---|---| -| Create Template | Child-workflow dispatch plus the shared source taxonomy, `library` / `project` scope, confirmation gate, collision preflight, structured authoring contract, validation commands, registration, completion, and Generate PPTX handoff | -| Create Layout | Structure-only interpretation, layout-specific brief fields, brand-neutral `design_spec.md`, SVG roster, and layout-specific validation | +**Hard rule — brand-neutral structure only**: a layout owns canvas, page grammar, Master/Layout families, slot geometry, semantic text roles, alignment/wrapping/capacity behavior, page types, image behavior, density rhythm, and the prototype roster — no palette, typeface/weight identity, final type scale, logo, voice, icon identity, communication objective, audience outcome, narrative sequence, scenario copy, or example content downstream must preserve. Neutral colors, safe fonts, and provisional sizes may appear in prototypes for review; they are preview values, never identity or a locked scale. Downstream `layout` scope resolves appearance from Brand, reading mode, and project typography; `mirror` scope preserves literal source formatting. -**Hard rule — child workflow, not a top-level route**: Create Layout executes only inside Create Template. It reuses the parent workflow's Steps 1–8 and never creates a competing entry route or second confirmation gate. - -**Hard rule — brand-neutral structure only**: A layout owns canvas, page grammar, Master/Layout families, slot geometry, semantic text roles, alignment/wrapping/capacity behavior, page types, image behavior, density rhythm, and the SVG prototype roster. It owns no brand palette, typeface/weight identity, final resolved type scale, logo, voice, icon identity, communication objective, audience outcome, required narrative sequence, fixed scenario copy, or example content that downstream generation is expected to preserve. - -Neutral colors, safe fonts, and provisional sizes may appear in SVG prototypes so the structure is reviewable. They are preview values, not a locked identity segment or final project type scale, and must not be written as brand truth in `design_spec.md`. The reusable rule is the text role and its spatial behavior. Downstream `layout` scope resolves actual appearance from Brand, reading mode, and confirmed project typography; explicit `mirror` scope preserves the literal source formatting instead. - -## Invocation Points - -1. Use §1–2 below while executing Create Template Steps 1–3. -2. After Create Template Step 4 preflights `<template_workspace>` and `<design_spec_path>`, use §3 to author or materialize the layout workspace under the shared structured contract. -3. Apply §4 in addition to Create Template Step 5, then continue through shared Steps 6–8. +**Invocation**: §1–2 during Create Template Steps 1–3; after Step 4 preflights the workspace, §3 authors or materializes under the shared structured contract; §4 adds to Step 5, then shared Steps 6–8. ## 1. Layout Input Interpretation -Use Create Template Step 1 for source ingestion and internal creation-strategy feasibility. Interpret source evidence only for reusable structure: - -- Canvas dimensions, grid, zones, page taxonomy, repeated chrome, image placement, density rhythm, placeholder geometry, semantic text roles, alignment, wrapping, and capacity may become layout facts or suggestions. -- Colors, font families, branded weight choices, final absolute sizes, logos, voice, and icon style remain source context only. Do not copy them into the layout identity because a layout has no identity segment. -- A source scenario may inform the content shapes or delivery conditions the geometry can support. Do not turn that fit into an application contract. If the reusable artifact prescribes the objective, outcome, narrative sequence, boilerplate, or content policy, return to Create Template dispatch and select Create Deck. -- When the source is branded, state in plain language that Create Layout will omit the identity. The AI therefore derives an authored internal strategy. If the user wants the identity retained with the structure, return to Create Template dispatch and select Create Deck before the shared confirmation marker is emitted. -- Internally, `standard` and `fidelity` inspect the complete source inventory and author a new Master/Layout/slot system. `mirror` may be derived only when the source-Slide-reachable contract is complete, brand-neutral, and application-neutral; it preserves that reachable structure and its visual facts in a new workspace without modifying the source. Never ask the user to choose among these labels. - -Direct conversation text, pasted requirements, converted documents/websites, images, and supplied assets may define or illustrate reusable structure. In a mixed bundle, combine those channels without treating identity-only evidence as layout ownership. Exact user-authored instructions remain decisions whether they arrive in chat or a user-written brief file; vague prose remains suggested interpretation until the shared confirmation gate. +Use Create Template Step 1 for ingestion and strategy feasibility, reading evidence only for reusable structure: canvas, grid, zones, page taxonomy, repeated chrome, image placement, density rhythm, placeholder geometry, semantic text roles, alignment, wrapping, and capacity may become facts or suggestions; colors, font families, weights, absolute sizes, logos, voice, and icon style stay context only. A source scenario may inform supported content shapes and delivery conditions but never becomes an application contract — if the artifact prescribes objective, outcome, sequence, boilerplate, or content policy, return to dispatch and select Create Deck. When the source is branded, state plainly that identity will be omitted (so an authored strategy is derived); if the user wants identity retained, return to dispatch for Create Deck before the marker. `standard` / `fidelity` inspect the complete inventory and author a new system; `mirror` is derived only when the source-Slide-reachable contract is complete, brand-neutral, and application-neutral. Direct text, converted documents, images, and assets may define structure; identity-only evidence never grants ownership; user-authored instructions are decisions in any carrier, vague prose stays suggested until the gate. ## 2. Layout Brief and Schema -Add these child-owned requirements to Create Template Step 2: - -| Field | Requirement | -|---|---| -| Layout ID and display name | Required; `layout_id` is a filesystem-safe ASCII slug | -| Structural use cases | Required; describe content shapes and delivery settings the geometry can support, not communication objectives, audience outcomes, narrative sequence, or brand tone | -| Canvas | Required; exact format, dimensions, and `viewBox` | -| Page grammar | Required; page types, variants, grids, zones, semantic text roles, alignment/wrapping/capacity, density rhythm, and image behavior | -| Native structure | Required; Master families, Layout ownership, slot vocabulary, and zero-slot Layouts where intentional | -| Creation intent | Required as natural-language prose: what should remain recognizable, what should become reusable structure, and how broad the page vocabulary should be. The AI derives `replication_mode` internally from this intent and the evidence. | -| Identity stripping | Required when branded reference material exists; list the identity facts intentionally excluded | - -Write this structure-only schema: +Add to Create Template Step 2 (all required unless noted): Layout ID (ASCII slug) and display name; structural use cases (content shapes and delivery settings, not objectives, outcomes, sequence, or tone); canvas (exact format, dimensions, `viewBox`); page grammar (types, variants, grids, zones, text roles, alignment/wrapping/capacity, density, image behavior); native structure (Master families, Layout ownership, slot vocabulary, intentional zero-slot Layouts); creation intent as prose (what stays recognizable, what becomes reusable, how broad the vocabulary is — `replication_mode` is derived from it); identity stripping (required for branded references: the identity facts excluded). ```markdown --- @@ -77,52 +44,14 @@ page_types: [cover, toc, chapter, content, ending] ## VII. Placeholder Overrides ``` -`replication_mode` is required machine provenance, not a user-facing choice. Omit `Placeholder Overrides` when no override exists. Omit Template Overview, Color Scheme, Typography, Logo, Voice, and every other identity section. Do not write `primary_color`. - -`Signature Design Elements` describes only reusable structure, including text-role hierarchy and spatial behavior without locking the final font identity or type scale. `Page Roster` lists every SVG with its Master/Layout identity, picker name, intended content shape, and slot behavior. - -`category: scenario` is a discovery-fit label only. It does not authorize a -Template Overview or scenario-specific content policy. +`replication_mode` is machine provenance, never a user choice. Omit `Placeholder Overrides` without overrides; omit Template Overview, Color Scheme, Typography, Logo, Voice, and every identity section; never write `primary_color`. `Signature Design Elements` describes reusable structure including text-role hierarchy and spatial behavior without locking font identity or scale; `Page Roster` lists every SVG with Master/Layout identity, picker name, content shape, and slot behavior. `category: scenario` is a discovery label and authorizes no Overview or scenario content policy. ## 3. Author or Materialize the Layout -Follow Create Template Step 4 and the shared Template_Designer contract with `kind: layout`, `kind_dir: layouts`, and `id_key: layout_id` fixed. Do not ask the user to choose the kind again. - -The output is: - -```text -<template_workspace>/ -├── templates/ # design_spec.md (project scope: design_spec.layout.<layout_id>.md) + SVG prototypes -├── images/ # optional structural/example bitmaps -├── icons/ -│ └── imported/ # optional imported vectors -└── exports/ # conditional review evidence -``` - -Every SVG is a complete preview and declares one root Master and Layout under the shared structured contract. For authored modes, neutral preview paint must remain replaceable downstream. For mirror, first prove the source contract already satisfies the complete Layout boundary, then preserve its structure and supported visuals exactly as allowed by Create Template. Never call removal or replacement of source identity or application rules “mirror”. +Follow Create Template Step 4 and the Template_Designer contract with `kind: layout`, `kind_dir: layouts`, `id_key: layout_id` fixed; never ask for the kind again. Output: `templates/` (spec plus prototypes), optional `images/` and `icons/imported/`, conditional `exports/`. Every SVG is a complete preview declaring one root Master and Layout; authored neutral paint stays replaceable downstream; for mirror, first prove the source contract satisfies the complete Layout boundary, then preserve its structure and supported visuals exactly as Create Template allows — removing or replacing identity or application rules is never "mirror". ## 4. Layout Validation -In addition to Create Template Steps 5–6, verify: +In addition to Create Template Steps 5–6: the spec contains `layout_id`, `kind: layout`, `summary`, canvas fields, `replication_mode`, `native_structure_mode: structured`, `page_count`, `page_types`; `layout_id` matches the library workspace ID; Signature Design Elements and Page Roster exist while Template Overview, application language, and identity sections do not; no `primary_color`, palette, typeface/weight, type-scale, logo, voice, or icon-identity claim (structural text roles and capacity rules may remain); every SVG satisfies the shared Master/Layout/slot contract with a bidirectionally complete roster; neutral paint is not described as identity; `replication_mode: mirror` is rejected for any source retaining organization identity or application rules. -- The Design Spec contains `layout_id`, `kind: layout`, `summary`, canvas fields, `replication_mode`, `native_structure_mode: structured`, `page_count`, and `page_types`. -- `layout_id` matches the confirmed workspace ID in library scope. -- Signature Design Elements and Page Roster exist; Template Overview, application-contract language, and all identity sections do not. -- `primary_color`, brand palette, brand typeface/weight claims, final project type-scale claims, logo, voice, and icon-identity claims are absent; structural text roles and capacity rules may remain. -- Every SVG in the roster satisfies the shared Master/Layout/slot contract and the roster is bidirectionally complete. -- Neutral prototype paint is not described as a locked brand identity. -- `replication_mode: mirror` is rejected for any source that retains organization-specific identity or reusable application rules; use authored Layout mode or Create Deck instead. - -For library scope, Create Template Step 5 validates the directory/index identity with: - -```bash -python3 skills/ppt-master/scripts/register_template.py <layout_id> --kind layout --dry-run -``` - -After that gate and any triggered Create Template Step 6 pass, Step 7 registers with: - -```bash -python3 skills/ppt-master/scripts/register_template.py <layout_id> --kind layout -``` - -For project scope, skip both commands. The exact workspace root becomes the next Generate PPTX Step 3 input; downstream identity remains a Strategist decision unless an explicit Brand or Deck workspace is also supplied. +Library scope validates with `register_template.py <layout_id> --kind layout --dry-run` and, after Step 5 and any triggered Step 6, registers with `register_template.py <layout_id> --kind layout`; project scope skips both. The exact root becomes the next Generate Step 3 input; identity remains a Strategist decision unless an explicit Brand or Deck workspace is also supplied. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/create-template/create-style.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/create-template/create-style.md index 5c712eea..ff712a46 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/create-template/create-style.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/create-template/create-style.md @@ -4,61 +4,30 @@ description: Create Style child workflow for a reusable communication method and # Create Style Workflow -Enter this child workflow only after [`Create Template`](../create-template.md) dispatches `kind: style`. +Enter only after [`Create Template`](../create-template.md) dispatches `kind: style`. Create Template owns dispatch, scope, the confirmation gate, collision preflight, registration, completion, and the Generate handoff; Create Style owns the reusable communication method, page-role vocabulary, evidence discipline, visual-system defaults, image/icon direction, review focus, and the roster-free spec. -## Responsibility Boundary +**Hard rule — child workflow, not a top-level route**: executes only inside Create Template under its single shared gate. -| Owner | Responsibilities | -|---|---| -| Create Template | Child-workflow dispatch plus the shared `library` / `project` scope, confirmation gate, collision preflight, registration, completion, and Generate PPTX handoff contract | -| Create Style | Reusable communication method, page-role vocabulary, evidence discipline, visual-system defaults, image/icon direction, review focus, and the roster-free `design_spec.md` | +**Hard rule — method and defaults only**: a Style owns a reusable way to argue, express evidence, and coordinate non-binding design defaults — no current-project communication contract, brand identity, page geometry, canvas, SVG prototype, Master/Layout graph, placeholder contract, application contract, asset inventory, carrier eligibility, image source, or capability whitelist. -**Hard rule — child workflow, not a top-level route**: Create Style executes only inside Create Template. It uses the parent workflow's single shared confirmation/preflight/registration contract and never creates a competing entry route or second confirmation gate. +**Hard rule — no page prototypes**: Style contributes only its Design Spec — no SVGs, review PPTX, or empty `images/` / `icons/` / `exports/`; files another kind owns in a shared project workspace are left untouched. -**Hard rule — method and defaults only**: A Style owns a reusable way to argue, express evidence, and coordinate non-binding design defaults. It owns no current-project communication contract, reusable brand identity, page geometry, canvas, SVG prototype, Master/Layout graph, placeholder contract, application contract, visible asset inventory, carrier eligibility, image source, or local authoring-capability whitelist. - -**Hard rule — no page prototypes**: Style contributes only its own Design Spec. Do not create page SVGs, a review PPTX, or empty `images/`, `icons/`, or `exports/` directories. In a project workspace shared with another kind, files that kind owns are not Style output and are left untouched. - -## Invocation Points - -1. Use §1–2 below for Style analysis and brief fields, then execute Create Template Steps 2–3 with those child-owned fields. -2. After Create Template Step 4 resolves and preflights `<template_workspace>` and `<design_spec_path>`, use §3 to materialize the confirmed Style. -3. Run §4, then return its evidence to Create Template Steps 5, 7, and 8. Create Style always skips the shared structured-preview step. +**Invocation**: §1–2 feed Create Template Steps 2–3; after Step 4 resolves `<template_workspace>` / `<design_spec_path>`, §3 materializes; §4 returns evidence to Steps 5, 7, and 8; the structured-preview step is always skipped. ## 1. Style Input Interpretation -Use every supplied reference only as evidence for reusable method and design defaults: - | Evidence | May inform | Must not become | |---|---|---| -| Direct brief, text, document, or website | Argument flow, claim discipline, page-role vocabulary, data-expression rules, and review focus | The current project's audience, objective, outline, page count, or source claims | -| PPTX, PDF, image, or SVG reference | Visual-system tendencies, density, decoration, image treatment, and icon treatment | A copied page roster, canvas contract, Master/Layout graph, or fixed geometry | -| Brand or organization material | A lower-priority fallback direction when the user explicitly wants it generalized | Official identity truth, logos, proprietary palettes, brand voice, or trademarked presentation rules | -| Existing mode, visual-style, or image-rendering catalog entry | A preferred catalog seed plus a concise Style-owned overlay | A duplicated copy of the catalog file | +| Direct brief, text, document, or website | Argument flow, claim discipline, page-role vocabulary, data-expression rules, review focus | The current project's audience, objective, outline, page count, or claims | +| PPTX, PDF, image, or SVG reference | Visual-system tendencies, density, decoration, image and icon treatment | A copied roster, canvas, Master/Layout graph, or fixed geometry | +| Brand or organization material | A lower-priority fallback direction when the user wants it generalized | Official identity truth, logos, proprietary palettes, voice, trademarked rules | +| Existing mode / visual-style / image-rendering catalog entry | A preferred seed plus a concise Style-owned overlay | A duplicated catalog file | -**Mandatory — series-aware PPTX analysis**: Before inferring cross-page cadence from a composite PPTX reference, distinguish coherent finished-deck series from page/layout libraries. Infer cadence only within each coherent series; treat library pages as independent composition evidence, never as one ordered narrative run. - -Preserve source provenance in `Style Overview`. Keep exact user-authored method decisions distinct from AI-derived defaults. Reject organization-confidential examples and do not generalize proprietary frameworks into a reusable Style. - -**Reference — not a constraint**: A Style may prefer a catalog mode, visual style, image rendering, fallback palette, or fallback font stack. These values seed the normal Stage-2 solution; they are not execution locks and never bypass user confirmation. +**Mandatory — series-aware PPTX analysis**: before inferring cross-page cadence from a composite reference, distinguish coherent finished-deck series from page/layout libraries; infer cadence only within a series and treat library pages as independent composition evidence. Preserve provenance in `Style Overview`; keep user-authored decisions distinct from AI defaults; reject organization-confidential examples and never generalize proprietary frameworks. **Reference — not a constraint**: preferred catalog mode, visual style, rendering, fallback palette, or font stack seed the Stage-2 solution; they are never execution locks and never bypass confirmation. ## 2. Style Brief and Schema -Add these child-owned requirements to Create Template Step 2: - -| Field | Requirement | -|---|---| -| Style ID and display name | Required; `style_id` is a filesystem-safe portable slug (prefer ASCII for interoperability) | -| Best fit | Required; describe reusable decision, explanation, or expression situations without binding a target audience or outcome | -| Reusable intent | Required; state what the method and design defaults should consistently achieve | -| Communication method | Required; argument flow, page-message discipline, and claim/evidence treatment; a preferred mode is optional | -| Page-role vocabulary | Required; reusable semantic roles and their jobs, evidence obligations, and composition tendencies; no order or inclusion policy | -| Evidence and data expression | Required; chart, table, source, and editability guidance without numeric content quotas | -| Visual-system defaults | Required; composition, density, decoration, color behavior, and native-text character; catalog seeds and literal fallbacks are optional, while carrier and native-construction eligibility remain downstream | -| Image and icon direction | Required; rendering, centrality, recurrence, and treatment defaults without source restrictions, asset inventory, or page mapping | -| Review focus | Required; extra checks to apply only if the user explicitly activates visual review | - -Write this roster-free schema: +Add to Create Template Step 2 (all required): Style ID (filesystem-safe portable slug) and display name; best fit (reusable decision/explanation/expression situations without binding audience or outcome); reusable intent; communication method (argument flow, page-message discipline, claim/evidence treatment; preferred mode optional); page-role vocabulary (roles, jobs, evidence obligations, composition tendencies — no order or inclusion policy); evidence and data expression (chart, table, source, editability guidance without numeric quotas); visual-system defaults (composition, density, decoration, color behavior, native-text character; seeds and literal fallbacks optional; carrier and construction eligibility stay downstream); image and icon direction (rendering, centrality, recurrence, treatment defaults without source restrictions, inventory, or page mapping); review focus (checks applied only if the user explicitly activates visual review). ```markdown --- @@ -78,116 +47,51 @@ keywords: [<three-to-five discovery tags>] | Style Name | <display name> | | Best Fit | <reusable selection context> | | Reusable Intent | <stable method/design outcome> | -| Sources | <source URLs, bundled references, or user brief; include date/version when known> | +| Sources | <URLs, references, or user brief; date/version when known> | ## II. Communication Method - **Preferred Mode**: <catalog id or custom; omit when none> -- **Mode References**: <catalog ids actually used by a custom seed; omit when none> +- **Mode References**: <catalog ids used by a custom seed; omit when none> - **Mode Behavior**: <required for custom; omit for a preset> -- **Argument Flow**: <reusable reasoning progression> -- **Page Message Discipline**: <relationship among question, title, message, and proof> -- **Claim Discipline**: <treatment of facts, assumptions, implications, and recommendations> +- **Argument Flow** / **Page Message Discipline** / **Claim Discipline**: <prose> ## III. Page Role Vocabulary | Role | Communication Job | Evidence Obligation | Composition Tendency | |---|---|---|---| -| <semantic role> | <job> | <proof requirement> | <non-geometric tendency> | ## IV. Evidence & Data Expression -- **Argument Trace**: <claim-to-evidence relationship> -- **Charts**: <selection, labeling, annotation, and decoration behavior> -- **Tables**: <comparison, hierarchy, and emphasis behavior> -- **Sources**: <citation and uncertainty treatment> -- **Native Editability**: <when editable data/native shapes are preferred> +- **Argument Trace** / **Charts** / **Tables** / **Sources** / **Native Editability**: <prose> ## V. Visual System Defaults -- **Preferred Visual Style**: <catalog id or custom; omit when none> -- **Visual Style References**: <catalog ids actually used by a custom seed; omit when none> -- **Visual Style Behavior**: <required for custom; omit for a preset> -- **Composition**: <page-scale relationships without fixed geometry> -- **Density**: <information and whitespace rhythm> -- **Decoration**: <shape, rule, elevation, and ornament behavior> -- **Color Behavior**: <role and contrast behavior; no identity claim> -- **Typography Character**: <hierarchy and register; no identity claim> +- **Preferred Visual Style** / **Visual Style References** / **Visual Style Behavior**: <as for Mode> +- **Composition** / **Density** / **Decoration** / **Color Behavior** / **Typography Character**: <prose; no identity claim> -### Fallback Color Scheme +### Fallback Color Scheme (conditional) | Role | HEX | Purpose | |---|---|---| -| <role> | #RRGGBB | <fallback use> | -### Fallback Typography +### Fallback Typography (conditional) | Role | Primary | Fallback Tail | Character | |---|---|---|---| -| <role> | <family> | <ordered fallbacks> | <typographic job> | ## VI. Image & Icon Direction -- **Preferred Image Rendering**: <catalog id or custom; omit when none> -- **Image Rendering References**: <catalog ids actually used by a custom seed; omit when none> -- **Image Rendering Behavior**: <required for custom; omit for a preset> -- **Image Usage**: <semantic role and frequency tendency> -- **Image Treatment**: <crop, framing, overlay, and caption behavior> -- **Icon Treatment**: <shape/stroke/fill behavior; actual library and inventory remain Stage-2 decisions> +- **Preferred Image Rendering** / **Image Rendering References** / **Image Rendering Behavior**: <as for Mode> +- **Image Usage** / **Image Treatment** / **Icon Treatment**: <prose; library and inventory stay Stage-2 decisions> ## VII. Review Focus <!-- visual-review-trigger: explicit-user-only --> -> Apply this section only after the user explicitly activates visual review. It never triggers that stage. - -- <style-specific answer, evidence, hierarchy, legibility, or scan-path check> +> Apply only after the user explicitly activates visual review. It never triggers that stage. +- <style-specific check> ``` -`Fallback Color Scheme` and `Fallback Typography` are conditional; omit either subsection when the Style has no literal fallback values. Exact fallback colors use `#RRGGBB`. A supplied Brand or Deck identity replaces overlapping fallback colors, font families, voice, and icon identity as one identity decision; it does not erase the Style's communication method or evidence discipline. - -`Preferred Mode`, `Preferred Visual Style`, and `Preferred Image Rendering` are recommendation seeds. The current project's confirmed Stage-2 values remain authoritative. A preset value must be a real ID in its matching catalog. For `custom`, retain only real catalog references actually used as a comma-separated ID list and include the matching behavior prose. - -**Hard rule — Style never becomes a capability policy**: Style prose may tune -treatment, visual weight, density, recurrence, and coherence. It never bans a -carrier or requires carrier coverage, never selects image source, and never -narrows primitives, Office presets, independent composition, Boolean, or -necessary freeform. Explicit current-project requirements remain upstream. - -`Page Role Vocabulary` is a semantic vocabulary, not a Page Roster. Do not assign order, required/optional/repeatable status, page count, filenames, Master/Layout identities, slots, or fixed/replaceable/example-only content policy. +Omit either fallback subsection without literal values; exact colors use `#RRGGBB`. A supplied Brand or Deck identity replaces overlapping fallback colors, fonts, voice, and icon identity as one decision without erasing the method. Preferred seeds are recommendations; a preset must be a real catalog ID, and `custom` keeps only real references actually used plus behavior prose. **Hard rule — Style never becomes a capability policy**: it may tune treatment, weight, density, recurrence, and coherence but never bans or requires a carrier, selects image source, or narrows primitives, presets, composition, Boolean, or freeform. `Page Role Vocabulary` is a vocabulary, not a roster: no order, status, count, filenames, identities, slots, or content policy. ## 3. Materialize the Confirmed Style -Create Template supplies an already resolved and collision-checked `<template_workspace>` and `<design_spec_path>`. Write only: - -```text -<template_workspace>/ -└── templates/ - └── design_spec.md # project scope: design_spec.style.<style_id>.md -``` - -Do not create or adopt images, icons, SVGs, native payloads, or review exports. References remain textual provenance; they are not portable Style assets. +Write only `templates/design_spec.md` (project: `design_spec.style.<style_id>.md`); create or adopt no images, icons, SVGs, payloads, or exports — references stay textual provenance. ## 4. Style Validation -Return these facts to Create Template: +Return to Create Template: non-empty `style_id`, `kind: style`, `summary`, and three-to-five `keywords` with no other frontmatter field; `style_id` matches the library workspace ID; sections I–VII exist with preset seeds resolving to real IDs and custom seeds carrying behavior prose; no `*.svg`, asset directory, export, or payload; no `primary_color`, canvas, page-count/type, replication, structure, Master/Layout, placeholder, Page Roster, or Signature Design Elements; no current-project audience, objective, delivery context, afterlife, outline, page assignment, icon inventory, or image mapping; Brand-only and Deck-only sections absent, fallback subsections keeping their exact names; `Review Focus` carries exactly one `<!-- visual-review-trigger: explicit-user-only -->` marker and cannot activate the stage. -- The Design Spec contains non-empty `style_id`, `kind: style`, `summary`, and three-to-five `keywords`; no other frontmatter field exists. -- `style_id` matches the confirmed workspace ID in library scope. -- Required sections I–VII exist; preset seeds resolve to real catalog IDs, while custom seeds include behavior prose and only real comma-separated catalog references. -- No `*.svg`, optional asset directory, review export, or native payload was created. -- No `primary_color`, canvas, page-count, page-type, replication, native-structure, Master/Layout, placeholder, Page Roster, or Signature Design Elements field exists. -- No current-project target audience, communication objective/outcome, delivery context, artifact afterlife, content outline, page assignment, icon inventory, or image-resource mapping exists. -- Brand-only identity sections (`Brand Overview`, `Color Scheme`, `Typography`, `Logo`, `Voice & Tone`, and `Icon Style`) and Deck-only `Template Overview` are absent. Conditional fallback subsections remain explicitly named `Fallback Color Scheme` and `Fallback Typography`. -- `Review Focus` contains exactly one `<!-- visual-review-trigger: explicit-user-only -->` marker; its localized prose explains the same boundary, and the section cannot activate visual review by itself. - -For both scopes, Create Template Step 5 validates the portable Style contract without registration: - -```bash -python3 skills/ppt-master/scripts/svg_quality_checker.py "<template_workspace>/templates" --template-mode --canonical-authoring -``` - -For `library` scope, additionally validate the directory/index identity with: - -```bash -python3 skills/ppt-master/scripts/register_template.py <style_id> --kind style --dry-run -``` - -After that gate passes, Create Template Step 7 registers with: - -```bash -python3 skills/ppt-master/scripts/register_template.py <style_id> --kind style -``` - -For `project` scope, run only the shared validator, skip both registrar commands, and report `Not registered (project workspace)`. Downstream consumption always uses the explicit workspace root through Generate PPTX Step 3; a bare Style name or ordinary style description never activates it. +Both scopes run `svg_quality_checker.py "<template_workspace>/templates" --template-mode --canonical-authoring`; library adds `register_template.py <style_id> --kind style --dry-run` and, after the gate, Step 7 registers with `register_template.py <style_id> --kind style`. Project scope skips both and reports `Not registered (project workspace)`. Downstream consumption uses the explicit root through Generate Step 3; a bare Style name or style description never activates it. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/edit-native-pptx.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/edit-native-pptx.md index f149705e..e1d32612 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/edit-native-pptx.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/edit-native-pptx.md @@ -4,90 +4,62 @@ description: Edit Native PPTX route — import a finished PowerPoint deck into a # Edit Native PPTX Route -> Run when the user brings an existing `.pptx` whose design must survive — as a template to fill with new content, as a deck to partially rewrite or restructure, or as a finished deck that only needs notes, narration, timings, or transitions. This route never regenerates the deck from scratch and never runs the Generate SVG pipeline. +> Run when the user brings an existing `.pptx` whose design must survive — a template to fill, a deck to partially rewrite or restructure, or a finished deck that only needs notes, narration, timings, or transitions. Never regenerates from scratch and never runs the Generate SVG pipeline. -The source deck becomes a `pptx_to_svg.py --roundtrip` workspace. Every source slide is available as a compact editable SVG plus immutable native backing. Pages the plan leaves untouched are **referenced**: export restores their original slide XML byte-for-byte. Pages the plan edits are rebuilt only where they changed; every unchanged object on them restores its native form. Notes, narration audio, and motion are overlays on the preserved slide and never rewrite visible content. - -**Boundary against other routes**: +The source deck becomes a `pptx_to_svg.py --roundtrip` workspace: every slide is a compact editable SVG plus immutable native backing. Untouched pages are **referenced** and restored byte-for-byte; edited pages rebuild only what changed while unchanged objects restore natively; notes, narration, and motion are overlays that never rewrite visible content. | User wants | Route | |---|---| -| Fill a raw PPTX template with new content, keep its design | This route | -| Keep a finished PPTX, add speaker notes / narration / auto-advance / transitions | This route | -| Rewrite some pages of a finished PPTX, keep the rest exactly | This route | -| Drop, reorder, or repeat pages of an existing PPTX without redesign | This route | -| Regenerate every page with a new visual design (beautify, 1:1) | Generate PPTX, [`beautify-pptx`](./profiles/beautify-pptx.md) | -| Split / merge / re-outline an existing PPTX into a new deck | Generate PPTX, PPTX as source material | -| Create a reusable brand / style / layout / deck asset from the PPTX | [`create-template`](./create-template.md) | +| Fill a raw PPTX template with new content, keep its design; add notes / narration / auto-advance / transitions; rewrite some pages and keep the rest; drop, reorder, or repeat pages without redesign | This route | +| Regenerate every page with a new visual design (1:1) | Generate PPTX, [`beautify-pptx`](./profiles/beautify-pptx.md) | +| Split / merge / re-outline into a new deck | Generate PPTX, PPTX as source material | +| Create a reusable brand / style / layout / deck asset | [`create-template`](./create-template.md) | -**Hard rule — no Generate pipeline**: Do not run `pptx_template_import.py`, `project_manager.py init`, `finalize_svg.py`, or create `svg_output/` for this route. The round-trip workspace is the project; `svg_to_pptx.py --roundtrip` is the only exporter that restores source slides. +**Hard rule — no Generate pipeline**: never run `pptx_template_import.py`, `project_manager.py init`, or `finalize_svg.py`, and never create `svg_output/`; the round-trip workspace is the project and `svg_to_pptx.py --roundtrip` is the only exporter that restores source slides. --- ## 1. When to Run -| Pattern | Example | -|---|---| -| Raw PPTX called a template + new material or topic | "Use this PowerPoint template to make a deck about X" | -| Existing deck + selective reuse | "Only keep the pages that fit, in this order" | -| Existing deck + copy replacement | "Keep the design, swap in this text" | -| Existing deck + page-level rewrite | "Redo page 5 and 7, leave everything else" | -| Existing deck + page combination | "Merge the two market pages into one, drop the old chart, add the new KPI" | -| Existing deck as skeleton + a few new pages | "Keep the deck, add a summary page and a Q3 page in the same style" | -| Finished deck + delivery add-ons, visible slides stable | "Add narration and auto-play", "add fade transitions", "write speaker notes" | - -**Deterministic routing**: Do not ask a route-choice question for these shapes. Ask one discriminator only when the request is ambiguous between preserving pages (this route) and redesigning them (Generate). +Raw PPTX called a template + new material or topic; existing deck + selective reuse ("only keep the pages that fit, in this order"), copy replacement, page-level rewrite ("redo page 5 and 7"), page combination ("merge the two market pages"), or a few new pages in the same style; finished deck + delivery add-ons with visible slides stable. Never ask a route-choice question for these shapes; ask one discriminator only when preserving (this route) and redesigning (Generate) are genuinely ambiguous. --- ## 2. Inputs -🚧 **GATE**: The user has provided: +🚧 **GATE**: source PPTX (required — the native design authority); new material only when content changes (text, Markdown, documents, or URLs converted with `source_to_md.py`; a bare topic without facts is not enough — ask for material or gather it from user-approved URLs); optional delivery intent (audience, page count, must-keep / must-drop pages, notes, narration, transitions, auto-advance). -| Input | Required | Notes | -|---|---:|---| -| Source PPTX | Yes | Finished deck or template; the native design authority | -| New material | Only when content changes | Text, Markdown, documents, or URLs converted with `source_to_md.py`. A bare topic without facts is not enough: ask for material, or gather it from user-approved URLs before planning | -| Delivery intent | Optional | Audience, page count, must-keep / must-drop pages, notes, narration, transitions, auto-advance | - -**Hard rule — facts**: Every substantive claim written into a page or a note comes from the user material; the §4.3 content mapping names the source for each page, and a page without one is dropped. Placeholder wording in the template is never carried into the output as content. +**Hard rule — facts**: every substantive claim in a page or note comes from the user material; the §4.3 content mapping names the source for each page and a page without one is dropped; template placeholder wording never becomes output content. --- ## 3. Import the Round-trip Workspace -Create the workspace directly under `projects/`; it is the project. - ```bash -python3 skills/ppt-master/scripts/pptx_to_svg.py "<source.pptx>" \ - -o "projects/<slug>_<YYYYMMDD>" --inheritance-mode both --roundtrip +python3 skills/ppt-master/scripts/pptx_to_svg.py "<source.pptx>" -o "projects/<slug>_<YYYYMMDD>" --inheritance-mode both --roundtrip ``` | Path | Content | Reading rule | |---|---|---| -| `authoring-svg-flat/slide_NN.svg` | One compact editable SVG per source slide, in source order | Open only the pages you will edit or need to judge for reuse | -| `authoring-svg-flat/authoring_summary.json` | Roster plus per-page canvas, text, image, vector, placeholder, source-ref, and source-proxy counts | Read first; plan from it before opening any SVG | -| `images/`, `icons/imported/`, `audio/`, `video/`, `sounds/` | Source media and imported decorative vectors | Keep names. Export hashes materialized files; changed bytes rebuild every output page whose source Slide/Layout/Master/notes graph references that package part, and a format mismatch fails export | -| `notes/slide_NN.md` | Source speaker notes when present | Edit, delete, or add per output page (§6) | -| `native-payloads/`, `analysis/` | Immutable native backing and tool-owned contracts | Tool-owned; opening them costs context and changes nothing — do not read, edit, or quote | -| `sources/source.pptx` | Exact source package | Read only through `ppt_to_md.py "<workspace>/sources/source.pptx" -o "<workspace>/validation/source_readback.md"` when you need page text without opening every SVG (notes on unchanged pages, content mapping) | +| `authoring-svg-flat/slide_NN.svg` | One compact editable SVG per source slide, in order | Open only pages you will edit or must judge for reuse | +| `authoring-svg-flat/authoring_summary.json` | Roster plus per-page canvas, text, image, vector, placeholder, source-ref, and proxy counts | Read first; plan from it before opening any SVG | +| `images/`, `icons/imported/`, `audio/`, `video/`, `sounds/` | Source media and imported vectors | Keep names; changed bytes rebuild every output page whose source graph references that part, and a format mismatch fails export | +| `notes/slide_NN.md` | Source speaker notes | Edit, delete, or add per output page (§6) | +| `native-payloads/`, `analysis/` | Immutable native backing and tool-owned contracts | Do not read, edit, or quote | +| `sources/source.pptx` | Exact source package | Read only through `ppt_to_md.py "<workspace>/sources/source.pptx" -o "<workspace>/validation/source_readback.md"` when you need page text without opening every SVG | | `validation/`, `exports/` | Diagnostics and published decks | Tool-written | -**Hard rule — source proxies are atomic**: An `<image data-pptx-source-proxy="native-restore">` element stands for an unsupported native object (SmartArt, complex effects, media frames). Leave it unchanged to restore the original object; a Slide-local proxy may be deleted; an inherited Master/Layout proxy stays. Editing a proxy or its preview asset fails export. +**Hard rule — source proxies are atomic**: an `<image data-pptx-source-proxy="native-restore">` stands for an unsupported native object (SmartArt, complex effects, media frames). Leave it to restore the original; a Slide-local proxy may be deleted, an inherited Master/Layout proxy stays; editing a proxy or its preview asset fails export. --- ## 4. Plan the Output Deck -**Default — layout-first selection (may override when the user fixes the page mapping)**: Treat the roster as a slide library, not an outline. A source page's layout already encodes a rhetorical shape — hero statement, lead-then-detail, comparison, stepwise progression, metric row, dense explanation. Match each target message to a page whose structure expresses that same logic; drop the content or the page rather than force a fit. Use fewer pages than the source when that reads better; repeat one good layout for several messages when they share its pattern. - -**Default — source order is not the outline (may override when the user asks to preserve it)**: The target story controls output order. Source slides may move, be omitted, or be reused several times. - -**Default — skeleton first (may override when the user asks for new pages)**: The source deck is the reference material and the skeleton of the output. Most output pages keep a source page's structure; sub-content may be recombined freely across pages, and new pages are added where the story needs them rather than as a rule. +**Defaults (may override when the user fixes the mapping, asks to preserve order, or asks for new pages)**: treat the roster as a slide library, not an outline — a source page's layout already encodes a rhetorical shape (hero statement, lead-then-detail, comparison, progression, metric row, dense explanation), so match each target message to a page whose structure expresses the same logic and drop content or the page rather than force a fit; the target story controls order, so source slides may move, be omitted, or be reused; the source deck is the skeleton — most output pages keep a source structure, sub-content recombines freely, and new pages appear where the story needs them. ### 4.1 Page plan -Write `page_plan.json` at the workspace root only when the output differs from the source roster (subset, reorder, repeat, or a copied page). Without the file, export is the identity round trip and every page is referenced or edited in place. +Write `page_plan.json` at the workspace root only when the output differs from the source roster (subset, reorder, repeat, or a copied page); without it export is the identity round trip. ```json { @@ -96,117 +68,75 @@ Write `page_plan.json` at the workspace root only when the output differs from t {"source_slide": 1}, {"source_slide": 4, "svg": "chapter_market.svg"}, {"source_slide": 7}, - {"source_slide": 7, "svg": "kpi_second_half.svg"}, - {"source_slide": 12} + {"source_slide": 7, "svg": "kpi_second_half.svg"} ] } ``` -| Field | Rule | -|---|---| -| `pages` | Complete output order; non-empty | -| `source_slide` | One-based source index of the page whose native slide backs this output page | -| `svg` | Authoring filename inside `authoring-svg-flat/`; omit to use that source page's `slide_NN.svg`. To reuse one source page twice, copy its SVG to a new name (`cp slide_07.svg kpi_second_half.svg`) and list the copy — every output page needs a distinct file, and every extra file must appear in the plan | +`pages` is the complete non-empty output order; `source_slide` is the one-based source index whose native slide backs the page; `svg` is the authoring filename inside `authoring-svg-flat/`, omitted to use that page's `slide_NN.svg` — to reuse a source page twice, copy its SVG under a new name and list the copy, since every output page needs a distinct file and every extra file must appear in the plan. Only these fields are accepted. **Forbidden — plans the exporter refuses**: a same-deck slide jump whose destination is omitted or repeated; unknown, duplicated, or cross-owned `svg` filenames; `source_slide` out of range. Omitting a slide drops the audio, video, or undecodable payloads only it owns (export prints a note). With a plan, presentation-level sections and custom shows are dropped and slide ids renumbered. -Only `schema` and `pages` at the root and `source_slide` / `svg` per page are accepted; the exporter rejects any other field. - -**Forbidden — plans the exporter refuses** (fail-closed, fix the plan instead of forcing): -- A same-deck slide jump whose destination is omitted or repeated (include the target exactly once, or remove the link from the page) -- Unknown, duplicated, or cross-owned `svg` filenames; `source_slide` out of range - -Omitting a source slide deliberately drops the audio, video, or undecodable payloads only that slide owns; export prints a note listing them. - -**Combining pages**: One output page always has exactly one skeleton — its `source_slide`. To merge several source pages, pick the page whose layout carries the result as the skeleton, then copy the needed elements from the other pages' SVGs into it and delete what the merged page no longer needs. Bring an object across pages only through the adopt command below — never by pasting raw SVG, because source refs are page-local and a pasted object would be mistaken for one of the skeleton's own. The adopted object keeps its visual form by materializing effective inherited presentation attributes (including `font-family`, `fill`, `opacity`, and CSS-resolved values) and composing ancestor transforms onto the copy. It loses its native identity and is rebuilt from SVG, so the combined page counts as `rebuilt`. A source proxy (§3) cannot leave its own page; a merge that needs one keeps that page as the skeleton instead. +**Combining pages**: one output page has exactly one skeleton (`source_slide`). To merge, pick the page whose layout carries the result, then bring objects from other pages only through the adopt command — never pasted raw SVG, because source refs are page-local. The adopted object materializes its effective inherited presentation attributes and ancestor transforms, loses native identity, and makes the page `rebuilt`; a source proxy cannot leave its page, so a merge that needs one keeps that page as the skeleton. The object lands at the end of the target page for normal editing. ```bash -python3 skills/ppt-master/scripts/svg_authoring_view.py \ - "projects/<slug>_<YYYYMMDD>/authoring-svg-flat" \ - --adopt-object slide_05.svg:<element-id> --into chapter_market.svg +python3 skills/ppt-master/scripts/svg_authoring_view.py "projects/<slug>_<YYYYMMDD>/authoring-svg-flat" --adopt-object slide_05.svg:<element-id> --into chapter_market.svg ``` -The object lands at the end of the target page; then edit its position and content like any authored element. - -**New pages**: A brand-new page also needs a skeleton so it inherits the deck's Master/Layout (background, logo, page number). Copy the closest source page under a new name, list it in the plan with that page's `source_slide`, delete its Slide-local content, and author the new content on the empty canvas; inherited proxies stay. The page counts as `rebuilt`. - -> Note: with a plan present, presentation-level sections and custom shows are dropped and slide ids are renumbered; visible slides are unaffected. +**New pages** need a skeleton too: copy the closest source page under a new name, list it with that page's `source_slide`, delete its Slide-local content, and author on the empty canvas (inherited proxies stay); the page is `rebuilt`. ### 4.2 Enhancement modules | Module | Default | Carrier | |---|---|---| -| Speaker notes | Source notes travel with every page; add or rewrite only where the plan says | `notes/<svg-stem>.md` | +| Speaker notes | Source notes travel with every page; add or rewrite only where planned | `notes/<svg-stem>.md` | | Narration audio | Off unless requested; implies notes on every output page | [`generate-audio`](./stages/generate-audio.md) → `audio/<stem>.*` | | Auto-advance from narration | On when narration is requested | `svg_to_pptx.py --use-narration-timings` | | Page transitions | Preserve source; replace only on request | `svg_to_pptx.py -t <effect>` or per-slide rows in `animations.json` | -| Object animations | Preserve source; author only on explicit request | `animations.json`, see [`animations.md`](../references/animations.md) | -| Native chart / table data | Source data unless the plan edits it | Inline JSON authority on the page; export needs `--native-charts-and-tables` (§7) | +| Object animations | Preserve source; author only on explicit request | `animations.json`, [`animations.md`](../references/animations.md) | +| Native chart / table data | Source data unless the plan edits it | Inline JSON authority; export needs `--native-charts-and-tables` (§7) | ### 4.3 Confirmation -⛔ **BLOCKING**: Present one plan and wait for explicit confirmation before editing any SVG, writing notes, generating audio, or exporting: - -| Item | Show | -|---|---| -| Output roster | Ordered list: output page → source slide → referenced unchanged / edited / new copy, with a one-line reason for each edited or dropped page | -| Content mapping | Which material goes to which page; anything dropped for lack of a fitting layout | -| Enhancement modules | Each module on/off with its effect and duration where relevant | -| Known refusals | Any §4.1 fail-closed case the plan must avoid | - -Chat confirmation is sufficient; write `page_plan.json` after confirmation. +⛔ **BLOCKING**: present one plan and wait for explicit confirmation before editing any SVG, writing notes, generating audio, or exporting: the output roster (output page → source slide → referenced / edited / new copy, with a one-line reason per edited or dropped page), the content mapping (which material goes where, what is dropped for lack of a fitting layout), each enhancement module on/off with its effect and duration, and any §4.1 fail-closed case the plan must avoid. Chat confirmation suffices; write `page_plan.json` afterwards. --- ## 5. Edit Pages -Load [`shared-standards-core.md`](../references/shared-standards-core.md) before the first edit. Load [`svg-effects.md`](../references/svg-effects.md) only when authoring new visual elements, and [`native-data-interface.md`](../references/native-data-interface.md) only when changing native chart or table data. +Load [`shared-standards-core.md`](../references/shared-standards-core.md) before the first edit; [`svg-effects.md`](../references/svg-effects.md) only when authoring new visual elements; [`native-data-interface.md`](../references/native-data-interface.md) only when changing native chart or table data. -**Hard rule — edit only planned pages**: A page marked referenced is not opened for writing. Export proves it: a referenced page appears under `passthrough` / `cloned_passthrough` (no overlay) or `patched` (notes or motion overlay only) in the receipt (§7) — never under `rebuilt`. - -**Hard rule — edit in place, keep identity**: Change text, paint, position, or content inside the existing page tree. Keep every `data-pptx-*` attribute on objects you did not intend to change; an object whose source attributes survive is restored natively, an object you rewrote is converted from your SVG. Do not paste a page from `svg_output/` conventions or another deck over a round-trip page. +**Hard rule — edit only planned pages**: a referenced page is never opened for writing; export proves it by listing it under `passthrough` / `cloned_passthrough` or `patched`, never `rebuilt`. **Hard rule — edit in place, keep identity**: change text, paint, position, or content inside the existing tree and keep every `data-pptx-*` attribute on objects you did not intend to change — surviving attributes restore natively, rewritten objects convert from your SVG. Never paste a page from `svg_output/` conventions or another deck over a round-trip page. | Edit | Rule | |---|---| -| Text replacement | Fit the slot's visual capacity from its geometry and font size, not the old placeholder length. Resolve overflow in this order: rewrite shorter → split across another selected page → choose a larger source layout; shrinking type is last and never deck-wide. §5's capacity gate rejects text that leaves its frame | +| Text replacement | Fit the slot's visual capacity from its geometry and font size, not the old placeholder length; resolve overflow by rewriting shorter → splitting across another selected page → choosing a larger source layout; shrinking type is last and never deck-wide | | Cover / chapter pages | Replace title, subtitle, author, section label only | -| Dense content pages | Compress material to the slot count the page already has; move overflow to another selected page | -| Native tables | Imported tables carry `data-pptx-native-authority="json"`; edit cell text in that inline `ppt-master.semantic-table.v2` JSON and keep row/column structure unless the design calls for a different table. Export with `--native-charts-and-tables` (§7) — without it the stale preview ships | -| Native charts | Imported charts carry the same JSON authority; edit categories and series values there and leave chart type and formatting to the source. Same export flag | -| Images | Replace by pointing the existing `<image>` at a new file under `images/`; keep the frame | -| New elements | Author canonical compact SVG per shared standards; icons come from `icon_sync.py "<workspace>" <lib/name>`; AI images from `image_gen.py --manifest` when the user wants generated visuals | -| Objects from another page | Use `--adopt-object` (§4.1); it strips source identity, inlines cross-page vector assets, and keeps chart/table JSON authority. Never paste raw SVG across pages; proxies cannot move | +| Dense content pages | Compress to the slot count the page has; move overflow to another selected page | +| Native tables / charts | Imported objects carry `data-pptx-native-authority="json"`: edit cell text or categories/series values in the inline JSON, keep structure and formatting from the source, and export with `--native-charts-and-tables` — without it the stale preview ships | +| Images | Point the existing `<image>` at a new file under `images/`; keep the frame | +| New elements | Canonical compact SVG per shared standards; icons via `icon_sync.py "<workspace>" <lib/name>`; AI images via `image_gen.py --manifest` when wanted | +| Objects from another page | `--adopt-object` only (§4.1); proxies cannot move | | Source proxies | Leave or delete; never edit (§3) | -**Mandatory after editing** — refresh the summary (page-plan copies are accepted), then run the capacity gate: +**Mandatory after editing** — refresh the summary, then run the capacity gate: ```bash -python3 skills/ppt-master/scripts/svg_authoring_view.py \ - "projects/<slug>_<YYYYMMDD>/authoring-svg-flat" --refresh-summary +python3 skills/ppt-master/scripts/svg_authoring_view.py "projects/<slug>_<YYYYMMDD>/authoring-svg-flat" --refresh-summary python3 skills/ppt-master/scripts/svg_quality_checker.py "projects/<slug>_<YYYYMMDD>" --roundtrip ``` -🚧 **GATE**: The checker's `--roundtrip` mode estimates edited text against its frame and canvas. Errors block export until the text is rewritten, split, or moved to a larger layout; warnings are reviewed and either fixed or accepted with a stated reason. The exporter remains the final gate and fails closed on a page it cannot restore or convert. +🚧 **GATE**: `--roundtrip` estimates edited text against its frame and canvas; errors block export until the text is rewritten, split, or moved to a larger layout, warnings are fixed or accepted with a stated reason. The exporter remains the final gate and fails closed on a page it cannot restore or convert. --- ## 6. Notes, Narration, and Motion -Skip this section when no module in §4.2 is enabled beyond preserving source notes. +Skip when no §4.2 module beyond preserving source notes is enabled. -**Notes** — keyed by output SVG stem: +**Notes** are keyed by output SVG stem: `notes/<stem>.md` for a canonical page replaces source notes (delete the file to remove them); for a copied page it applies to that output page only, and without a file the copy inherits the source notes. **Hard rule — spoken prose only**: `svg_to_pptx.py` embeds and `notes_to_audio.py` reads each note verbatim, so a heading, bullet, `[tag]`, or duration line is spoken and shown. Write 2–5 natural sentences per content page, one or two for cover / chapter / ending, transitions as prose, one language per deck, sourced from the page's SVG text or the §3 read-back plus user material — a note never adds a claim the page or material does not carry. -| Case | Behavior | -|---|---| -| `notes/<stem>.md` exists for a canonical page | Replaces source notes; delete the file to remove source notes | -| `notes/<stem>.md` exists for a copied page | Notes for that output page only | -| No file for a copied page | Inherits the source page's notes | +**Narration audio**: run [`generate-audio`](./stages/generate-audio.md) Steps 1–4 with the workspace path after notes are complete; the source deck's own media in `audio/` is left alone; `notes_to_audio.py` resolves the roster from `page_plan.json` (copies inherit) and refuses an incomplete roster. Stop after audio; §7 integrates it. -**Hard rule — spoken prose only**: `svg_to_pptx.py` embeds each note verbatim and `notes_to_audio.py` reads it aloud verbatim, so a heading, bullet, `[tag]`, or duration line is spoken and shown. Write 2–5 natural sentences per content page, one or two for cover / chapter / ending, transitions as prose, one language per deck. Source the content from the page's SVG text or the §3 read-back plus the user material; a note never adds a claim the page or material does not carry. - -**Narration audio**: Run [`generate-audio`](./stages/generate-audio.md) Steps 1–4 with the workspace path after notes are complete (`notes_to_audio.py "<workspace>" --provider <p> --voice <v> --rate <r>`); the source deck's own media in `audio/` (imported files not named after a page) is left alone. `notes_to_audio.py` resolves the roster from `page_plan.json` (copies inherit source notes) and refuses an incomplete roster, listing the missing stems. Audio lands at `audio/<stem>.*` per output page. Stop after audio generation; §7 integrates it. - -**Motion**: Load [`animations.md`](../references/animations.md) when transitions or object animations are requested. `animations.json` rows are keyed by output SVG stem; a copied page inherits its source row unless it has its own. - -**Hard rule — rebuilt animation targets**: Rebuilding an object that a source animation targets (for example a chart whose data you edited) leaves that animation without a target, and export stops with `Edited slide removed source animation target(s)`. Give that page its own row so its motion becomes explicit — `"<stem>": {"animation": {"effect": "none"}}` drops the source build, or author the page's animation in the row — then export again. +**Motion**: load [`animations.md`](../references/animations.md) when transitions or object animations are requested; `animations.json` rows are keyed by output stem and a copied page inherits its source row unless it has its own. **Hard rule — rebuilt animation targets**: rebuilding an object a source animation targets leaves that animation without a target and export stops with `Edited slide removed source animation target(s)`; give the page its own row — `"<stem>": {"animation": {"effect": "none"}}` drops the source build, or author the page's motion — then export again. --- @@ -216,67 +146,26 @@ Skip this section when no module in §4.2 is enabled beyond preserving source no python3 skills/ppt-master/scripts/svg_to_pptx.py "projects/<slug>_<YYYYMMDD>" --roundtrip ``` -| Request | Add | -|---|---| -| Replace transitions deck-wide | `-t <effect> [--transition-duration <s>]` | -| Narration with auto-advance | `--recorded-narration audio --use-narration-timings` (round-trip export reads the workspace `animations.json` by default) | -| Per-slide motion | `--animation-config animations.json` | -| Object animation policy | `-a <preset>` (default `none`) | -| Strip all notes | `--no-notes` | -| Native chart / table data edited | `--native-charts-and-tables` | - -Export writes into `exports/` and prints the exact output path (a `_narrated` or `_native_charts_tables` suffix may apply — use the printed path in every later command) plus one receipt: +Add `-t <effect> [--transition-duration <s>]` to replace transitions deck-wide; `--recorded-narration audio --use-narration-timings` for narration with auto-advance (round-trip export reads the workspace `animations.json` by default); `--animation-config animations.json` for per-slide motion; `-a <preset>` (default `none`) for object animation policy; `--no-notes` to strip notes; `--native-charts-and-tables` when chart/table data was edited. Export writes into `exports/`, prints the exact output path (a `_narrated` or `_native_charts_tables` suffix may apply — use the printed path afterwards), and one receipt: ```text Round-trip export summary: output_pages=N passthrough=P cloned_passthrough=C patched=M rebuilt=R ``` -| Bucket | Meaning | Assert | -|---|---|---| -| `passthrough` | Identity page, original XML and relationships | Referenced pages without a plan and without any notes/motion overlay | -| `cloned_passthrough` | Planned page, original XML on a cloned part | Referenced pages with a plan and without any overlay | -| `patched` | Source shape XML is kept while shape order, notes, transitions, animation, or narration timing may change | Pages with z-order-only edits or package overlays that do not rebuild a source shape | -| `rebuilt` | Visible authoring or a referenced materialized resource changed | Exactly the pages marked edited in §4.3 plus every output page that references a changed resource — a delivery-only job must show `rebuilt=0` | +`passthrough` = identity page with original XML (referenced, no plan, no overlay); `cloned_passthrough` = planned referenced page on a cloned part; `patched` = source shape XML kept while order, notes, transitions, animation, or narration timing changed; `rebuilt` = visible authoring or a referenced materialized resource changed — exactly the pages marked edited in §4.3 plus pages referencing a changed resource, and a delivery-only job must show `rebuilt=0`. -**Validation**: - -```bash -python3 skills/ppt-master/scripts/pptx_delivery_check.py "<printed_output.pptx>" \ - > "projects/<slug>_<YYYYMMDD>/validation/<output_stem>.delivery.json" -python3 skills/ppt-master/scripts/source_to_md/ppt_to_md.py \ - "<printed_output.pptx>" -o "projects/<slug>_<YYYYMMDD>/validation/readback.md" -``` - -| Check | Expected | -|---|---| -| Delivery check | No structural errors; review advisories | -| Slide count | Equals plan length, or source count without a plan | -| Key titles and replaced text | Present in the read-back | -| Notes count | Matches planned notes | -| Receipt buckets | Match the confirmed roster | +**Validation**: `pptx_delivery_check.py "<printed_output.pptx>" > ".../validation/<output_stem>.delivery.json"` (no structural errors; review advisories) and `ppt_to_md.py "<printed_output.pptx>" -o ".../validation/readback.md"` — slide count equals the plan length (or source count), key titles and replaced text present, notes count matches, receipt buckets match the confirmed roster. ```markdown ## ✅ Edit Native PPTX Complete - -- [x] Round-trip workspace imported at `projects/<slug>_<YYYYMMDD>/` -- [x] Plan confirmed by the user; `page_plan.json` written when the roster differs from the source +- [x] Round-trip workspace imported at `projects/<slug>_<YYYYMMDD>/`; plan confirmed; `page_plan.json` written when the roster differs - [x] Only planned pages edited; `authoring_summary.json` refreshed; `svg_quality_checker.py --roundtrip` reports no errors -- [x] Notes / audio / motion prepared as confirmed -- [x] `svg_to_pptx.py --roundtrip` receipt matches the confirmed roster -- [x] Delivery JSON and read-back written under `validation/` -- [x] Final deck at the exporter's printed `exports/` path +- [x] Notes / audio / motion prepared as confirmed; `--roundtrip` receipt matches the confirmed roster +- [x] Delivery JSON and read-back written under `validation/`; final deck at the printed `exports/` path ``` --- ## 8. Current Boundary -| Capability | Status | -|---|---| -| Reference unchanged pages byte-for-byte; select / reorder / repeat / omit pages | Supported | -| Edit text, paint, images, native table cells, native chart data on selected pages | Supported; unchanged objects restore natively; chart/table data edits export only with `--native-charts-and-tables` | -| Author new elements on an edited page | Supported through canonical compact SVG | -| Preserve SmartArt, complex effects, embedded media | Supported as atomic source proxies; not editable | -| Notes, narration audio, auto-advance, transitions, object animations | Supported as overlays keyed by output page | -| Delete inherited source notes on a copied page | Not supported; give the copy its own `notes/<stem>.md` | -| Edit a source proxy, change slide size, add Master/Layout structure | Not supported; use Create Template → Generate for a new structure | +Supported: referencing unchanged pages byte-for-byte with select / reorder / repeat / omit; editing text, paint, images, native table cells, and native chart data on selected pages (chart/table edits export only with `--native-charts-and-tables`); authoring new elements as canonical compact SVG; preserving SmartArt, complex effects, and embedded media as atomic proxies; notes, narration, auto-advance, transitions, and object animations as overlays keyed by output page. Not supported: deleting inherited source notes on a copied page (give the copy its own file); editing a source proxy; changing slide size; adding Master/Layout structure (use Create Template → Generate). diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/generate-pptx.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/generate-pptx.md index 4784483f..b082a862 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/generate-pptx.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/generate-pptx.md @@ -4,287 +4,106 @@ description: Default Generate PPTX authority for source intake, planning, SVG au # Generate PPTX Route -> Load only after [`routing.md`](./routing.md) selects Default Generate or its -> Beautify profile. This file owns that runtime's Step 1–7 sequence, gates, role -> switching, and mandatory commands. Explicit Quick loads its own profile instead. +> Load only after [`routing.md`](./routing.md) selects Default Generate or its Beautify profile. This file owns that runtime's Step 1–7 sequence, gates, role switching, and mandatory commands; explicit Quick loads [`quick-generate.md`](./profiles/quick-generate.md) instead, and Beautify enters here only when it does not explicitly select Quick. -**Hard rule — runtime paths**: Resolve every linked or abbreviated package path -below from the entry-time `SKILL_DIR` anchor and expand it inside each tool -call. Never change CWD or inherit a prior shell working directory. +**Hard rule — runtime paths**: expand every linked or abbreviated package path from the entry-time `SKILL_DIR` anchor inside each tool call; never change CWD or inherit a prior shell working directory. **Default Core Pipeline**: `Initial Materials → [Fact Research] → Create Project → Template Candidate Preparation → Stage-1 Communication + Template Confirmation → [Template Installation] → Stage-2 Solution → [Image Acquisition] → Executor Live Preview → Quality Check → Post-processing → Export` **Generate-specific execution discipline**: -- The current main agent hand-writes every SVG page; never delegate page generation or run a Python, Node, or shell generator over `svg_output/`. -- Initial SVG cadence: P01 → first-page gate → remaining pages (one page gate per first-exercised `not-exercised` item) → final gate. Batches and other mid-run checker calls are forbidden. -- `preset_shape_svg.py` and `shape_boolean_svg.py` may provide only their documented stdout fragment(s) after the main agent chooses the object's role, operands, paint, and z-order; neither helper chooses layout or writes a page. -- Gate checklists are internal verification, not user-facing output. On success, continue automatically and emit at most one compact status line when useful; on failure, report only the blocking items and required recovery. +- The current main agent hand-writes every SVG page; never delegate page generation or run a generator over `svg_output/`. `preset_shape_svg.py` and `shape_boolean_svg.py` provide only their stdout fragments after the agent chooses role, operands, paint, and z-order. +- SVG cadence: P01 → first-page gate → remaining pages → final gate. No batches, no other mid-run checker calls. +- Gate checklists are internal: on success continue with at most one compact status line; on failure report only the blocking items and required recovery. -**Profile boundary**: Explicit Quick is selected before runtime authority -loading and never enters this file. Beautify enters this file only when its -request does not explicitly select Quick. - -### SVG Page-Design Boundary - -| Scope | Contract | -|---|---| -| Any route that authors or regenerates slide visuals through SVG | `svg_output/` is the complete page-design source: every visible text, image, shape, chart/table fallback, block/inline native-formula preview, and layout element that should appear on the exported slide is present in that page SVG or referenced by it. | -| Templates, `design_spec.md`, and `spec_lock.md` | Authoring/control inputs. They guide SVG creation but MUST NOT supply visible slide content that is absent from the completed SVG during export. | -| Semantic SVG markers | Minimal rendering-neutral compiler hints used only after existing Layout/Layer/Placeholder/Native metadata has been considered. Chart/table markers preserve their visible SVG fallback; block and inline formula markers carry exact LaTeX and replace only their registered ordinary SVG preview with editable Office Math during PPTX export. | -| `svg_final/` | Optional derived, self-contained SVG visual preview in the default pipeline; release export never reads it. It may be opened directly or inserted into PowerPoint as an SVG picture, but it is not a supported PPTX source and carries no manual Convert-to-Shape compatibility contract. Quick-generate skips it. | -| SVG-to-PPTX export | The only supported generated-PPTX route reads `svg_output/` and maps its content through the project converter to DrawingML/native objects. It compiles only the selected route's explicit structure contract: `flat` keeps represented content Slide-local, while `structured` may place explicitly scoped content in Master/Layout/Slide parts. It MUST NOT infer structure, upgrade `flat`, or invent new visible page content. | -| Edit Native PPTX and presentation-behavior stages | Remain outside SVG page-design closure. `edit-native-pptx` restores unchanged source slides natively; animations, transitions, speaker notes, narration, and package relationships are not required to round-trip through SVG. | - -**MUST — page-design closure**: For an SVG-authoring route, inspect the final page SVG to determine what the exported slide looks like. Do not reinterpret “SVG is the page-design language” as “SVG is the complete PPTX package description language.” +**SVG page-design boundary**: `svg_output/` is the complete page-design source — every visible element of the exported slide is in the page SVG or referenced by it; templates, `design_spec.md`, and `spec_lock.md` never supply content at export ([`shared-standards-core.md`](../references/shared-standards-core.md) §4.0). Export compiles only the selected route's explicit structure contract (`flat` Slide-local; `structured` Master/Layout/Slide parts) and never infers structure. `svg_final/` is an optional preview release export never reads. Notes, animations, narration, and Edit Native PPTX stay outside this closure. ## Cross-Cutting Authorities -| Concern | Authority | Contract | -|---|---|---| -| Main pipeline sequencing | This file | Owns Step 1–7 order, gates, role switching, and mandatory commands | -| Artifact ownership | [`artifact-ownership.md`](../references/artifact-ownership.md) | Owns fact channels, source/derived artifact boundaries, and regeneration rules | -| Failure recovery | [`failure-recovery.md`](./governance/failure-recovery.md) | Owns stop/continue policy and resume pointers | -| Confirm UI details | [`confirm_ui.md`](../scripts/docs/confirm_ui.md) | Owns the JSON schema, launcher behavior, staged-result contract, port strategy, and chat fallback details | -| Confirmed template application | [`apply-template-workspace.md`](./stages/apply-template-workspace.md) | Owns validation and installation after Stage 1 confirms library or explicit workspace roots; skip for confirmed free design | +| Concern | Authority | +|---|---| +| Step 1–7 order, gates, role switching, mandatory commands | This file | +| Fact channels, source/derived artifact boundaries, regeneration | [`artifact-ownership.md`](../references/artifact-ownership.md) | +| Stop/continue policy and resume pointers | [`failure-recovery.md`](./governance/failure-recovery.md) | +| Surface decision, in-run switch, Stage-1/Stage-2/result payload shapes | [`confirm-surface.md`](../references/confirm-surface.md); server lifecycle and template-selection sidecar in [`confirm_ui.md`](../scripts/docs/confirm_ui.md) | +| Validation and installation of confirmed template roots | [`apply-template-workspace.md`](./stages/apply-template-workspace.md); skipped for confirmed free design | ## Workflow ### Step 1: Source Content Processing -🚧 **GATE**: The user has provided a topic / desired outcome and any available initial material. +🚧 **GATE**: the user has provided a topic / desired outcome and any available initial material. -> **Topic-only**: run [`topic-research`](stages/topic-research.md) immediately, -> then use its research pair as source content; Step 2 imports that pair without -> expanding the facts JSON's webpage URLs. - -When the user provides non-Markdown content, convert immediately through the -unified dispatcher. It preserves the backend converters' existing behavior, -routes by source type, and writes the standard Markdown plus conversion profile. - -| User Provides | Action | -|---------------|--------| -| PDF / DOCX / Office document / XLSX / XLSM / PPTX / EPUB / HTML / LaTeX / RST / web URL | `python3 ${SKILL_DIR}/scripts/source_to_md.py <file_or_URL_or_dir> [<file_or_URL_or_dir> ...]` | -| CSV / TSV | Read directly as plain-text table source | -| Markdown | Read directly | - -For PPTX sources, Step 1 converts the deck to Markdown content; after Step 2 -`import-sources`, standard PPTX intake is also written to `<project>/analysis/`. -Use `source_to_md.py -t <type>` only when extension detection is ambiguous. -Default local conversion writes Markdown/profile outputs beside each source file. -Use `-o` only when a specific output file/directory is required; with multiple -inputs or directory inputs, `-o` is an output directory. Backend converter details are documented in -[`scripts/docs/conversion.md`](../scripts/docs/conversion.md). - -**Source-image orientation trigger**: Before Step 2, follow -[`conversion.md`](../scripts/docs/conversion.md) § Image Orientation Review when -the user requests correction, converted text asks for rotated viewing, or a -downloaded asset is visibly sideways. Do not launch its legacy HTML tool. - -After reading direct and converted content, assess factual sufficiency: - -| Material state | Action | +| User provides | Action | |---|---| -| Requested outcome is supported | Continue Step 2 | -| Required externally verifiable claims remain unsupported | Run [`topic-research`](stages/topic-research.md) for those gaps only | -| Closed corpus / source-only / no external enrichment | Stay within supplied material | +| PDF / DOCX / Office document / XLSX / XLSM / PPTX / EPUB / HTML / LaTeX / RST / web URL | `python3 ${SKILL_DIR}/scripts/source_to_md.py <file_or_URL_or_dir> [<file_or_URL_or_dir> ...]` | +| CSV / TSV | Read directly as a plain-text table source | +| Markdown | Read directly | +| Topic only | Run [`topic-research`](stages/topic-research.md) first and use its research pair as source; Step 2 imports the pair without expanding the facts JSON's URLs | -**Sufficiency test**: research only to avoid inventing, omitting, or leaving -unsupported a factual claim the requested outcome requires; file presence or -length is irrelevant. It records the needed facts and adopted webpage URLs in -the research pair. Step 2 fetches no adopted page; Step 5 -acquires only Strategist-selected independent AI / web / slice assets after -final confirmation. +The dispatcher writes standard Markdown plus a conversion profile beside each source; use `-t <type>` only when detection is ambiguous and `-o` only when a specific output location is required (an output directory for multiple or directory inputs). PPTX sources also receive standard intake in `<project>/analysis/` after Step 2. Backend details: [`conversion.md`](../scripts/docs/conversion.md), whose § Image Orientation Review applies when the user requests correction, converted text asks for rotated viewing, or a downloaded asset is visibly sideways (never launch its legacy HTML tool). -> **Office vector assets (EMF/WMF) from DOCX/PPTX sources**: -> Source conversion extracts embedded Office vector images (.emf/.wmf) -> alongside bitmap images when the source format exposes them. After `import-sources`, these land in `images/` -> together with `image_manifest.json` and are first-class assets in §VIII Image Resource List. -> -> **Do NOT convert EMF/WMF to PNG.** The PPT Master pipeline preserves them as external -> references (`finalize_svg.py` skips them) and `svg_to_pptx.py` embeds them as -> PPTX-native media via `image/x-emf` / `image/x-wmf` MIME — PowerPoint renders them at full vector fidelity. -> Converting via LibreOffice/Inkscape introduces CJK font substitution drift and -> rasterization loss; the original EMF/WMF is always higher fidelity than the converted PNG. -> -> Browser-based live preview cannot render EMF (will show blank) — this is expected; -> the PPTX output is the source of truth. +**Sufficiency test**: after reading direct and converted content, run [`topic-research`](stages/topic-research.md) only for gaps where the requested outcome would otherwise require inventing, omitting, or leaving unsupported an externally verifiable claim; a closed corpus stays within the supplied material, and file presence or length is irrelevant. Research records facts and adopted URLs in its pair; Step 2 fetches no adopted page, and Step 5 acquires only Strategist-selected assets after final confirmation. -**✅ Checkpoint — Confirm source content and any factual supplement/provenance pair are ready, proceed to Step 2.** +**EMF/WMF from DOCX/PPTX**: embedded Office vectors land in `images/` with `image_manifest.json` as first-class §VIII assets. Never convert them to PNG — `finalize_svg.py` preserves them as external references and `svg_to_pptx.py` embeds them as native `image/x-emf` / `image/x-wmf` media at full vector fidelity; browser preview shows them blank, which is expected. + +**✅ Checkpoint** — source content and any research pair are ready; proceed to Step 2. --- ### Step 2: Project Initialization -🚧 **GATE**: Step 1 complete; source content is ready (Markdown file, user-provided text, or requirements described in conversation are all valid). +🚧 **GATE**: Step 1 complete; source content is ready (Markdown, direct text, or requirements described in conversation). ```bash python3 ${SKILL_DIR}/scripts/project_manager.py init <project_name> +python3 ${SKILL_DIR}/scripts/project_manager.py import-sources <project_path> <source_files_or_dirs...> # skip when content is only in conversation ``` -**Hard rule — truthful canvas token**: append -`--format <registered_format>` only when an explicit user/source fact already -establishes an exact registered canvas before initialization. Otherwise omit -the flag; Stage 1 confirms the canvas and `spec_lock.md` records its viewBox. +**Hard rule — truthful canvas token**: append `--format <registered_format>` only when an explicit user/source fact already establishes an exact registered canvas ([`canvas-formats.md`](../references/canvas-formats.md)); otherwise Stage 1 confirms the canvas, starting from the project-initialization canvas unless the user/source context changes it, and `spec_lock.md` records its viewBox. -Project initialization creates `<project_path>/validation/workflow.log` and -records the initialization milestone. After the project exists, run each -project-scoped Python tool normally. The shared CLI bootstrap automatically -records its command envelope and a bounded set of material outcome lines in -that log; no wrapper command is required. Full console output is not copied. -Detached Confirm UI and live-preview processes retain their detailed output in -their existing component logs. +Initialization creates `<project_path>/validation/workflow.log`; later project-scoped Python tools record their command envelopes there automatically (prefix `PPT_MASTER_PROJECT_PATH="<project_path>"` when a helper's arguments do not identify the project; append one concise note with `python3 ${SKILL_DIR}/scripts/workflow_log.py <project_path> "<detail>"` only for a material handoff, rework reason, approved exception, or manual recovery with no owning command output). The log is cold audit evidence, never read during generation. -When a Python helper serves the active deck but neither its arguments nor its -working directory identifies the project, provide the routing signal on that -same command — still one Python process: +**Import rules**: pass the source path once when Step 1 wrote Markdown beside it, both locations when `-o` wrote it elsewhere, and only the research pair when Topic Research ran (its facts JSON is imported as a file; no URL is fetched). Inputs already under `projects/` move; every other path is copied and left untouched even with `--move` (`--copy` keeps a projects-local input in place). Direct bitmap inputs are archived under `sources/` and copied collision-safely into `images/`; SVG/EMF/WMF stay source assets unless a converter manifest supplies display metadata. For each PPTX, `import-sources` runs `pptx_intake.py <source.pptx> -o <project_path>/analysis` and writes `analysis/<stem>.identity.json`, `<stem>.slide_library.json`, and the multi-deck index `analysis/source_profile.json` (one `decks[]` entry per distinct stem; re-importing a stem replaces its entry) — source facts and recommendation candidates, not replica constraints; Beautify stays single-deck. -```bash -PPT_MASTER_PROJECT_PATH="<project_path>" python3 ${SKILL_DIR}/scripts/<helper>.py <args...> -``` - -When an important audit detail has no owning command output — for example a -material stage handoff or rework reason, a user-approved exception, or a manual -recovery choice — the active role may append one concise note: - -```bash -python3 ${SKILL_DIR}/scripts/workflow_log.py <project_path> "<material audit detail>" -``` - -Notes are selective and non-authoritative. Do not duplicate artifact contents, -routine page progress, or chain-of-thought; current artifacts and gate results -still determine stage and readiness. The transcript is cold audit evidence: -never read it during normal generation; open it only when the user explicitly -asks to review the run. - -Registered formats: [`canvas-formats.md`](../references/canvas-formats.md). - -Import source content (choose based on the situation): - -| Situation | Action | -|-----------|--------| -| Has source files (PDF/MD/etc.) | `python3 ${SKILL_DIR}/scripts/project_manager.py import-sources <project_path> <source_files_or_dirs...>` | -| User provided text directly in conversation | No import needed — content is already in conversation context; subsequent steps can reference it directly | - -When Topic Research ran, include only its research pair. `project_manager.py` -imports the facts JSON as an ordinary file and never expands its `source_url` -values, so project initialization fetches no adopted page. - -For PPTX sources, `import-sources` automatically runs the standard intake enrichment: - -```bash -python3 ${SKILL_DIR}/scripts/pptx_intake.py <project_path>/sources/<source.pptx> -o <project_path>/analysis -``` - -For each PPTX it writes `<stem>.identity.json` (canvas, theme palette/fonts, observed usage) and `<stem>.slide_library.json` (text slots, geometry, native tables, native chart caches, SmartArt nodes/connections), and merges that deck's Strategist-facing digest into the single multi-deck index `analysis/source_profile.json` (`decks[]`, one self-contained entry per source deck, with prefixed artifact pointers). In the main generation path these are source facts and recommendation candidates, not replica constraints; the beautify profile decides separately which fields become locked constraints. - -Multi-deck: several PPTX files may be imported into one main-pipeline project — each gets its own `<stem>.*` artifacts and a deck entry in `source_profile.json`. `source_profile.json` stays the single must-read index (one entry for a one-deck project, several for a combined-source project). Stems must be distinct; re-importing the same stem replaces that deck's entry. The beautify profile remains single-deck (1:1 to one chosen source deck) and reads that deck's `<stem>.*` artifacts. - -**Source ownership boundary**: Use the automatic import mode shown above. Only inputs already under the repository's `projects/` tree move into the target project's `sources/`; every other local path is copied and remains untouched, even if `--move` is supplied. Use `--copy` when a projects-local input must also remain in place. If Step 1 wrote Markdown beside the original sources, pass that source path/directory once. If Step 1 used `-o` to write Markdown elsewhere, pass both the original source path(s)/directory and the Markdown output path(s)/directory. Intermediate artifacts (e.g., `_files/`) are handled automatically. - -Direct supported bitmap inputs follow both boundaries: the original is archived under `sources/`, and a collision-safe basename is copied into `images/` for analysis and §VIII planning. SVG/EMF/WMF remain source assets unless they arrive through a converter companion manifest that supplies their display metadata. This does not classify an asset's role; Strategist still decides whether it is used. - -**✅ Checkpoint — Confirm project structure created successfully, `sources/` contains all source files, converted materials are ready. Proceed to Step 3.** `import-sources` exits 0 when any input converts; read the printed `skipped` reasons and treat those inputs as absent sources. +**✅ Checkpoint** — project created, `sources/` complete, converted materials ready. `import-sources` exits 0 when any input converts: read the printed `skipped` reasons and treat those inputs as absent. Proceed to Step 3. --- ### Step 3: Template Candidate Preparation -**Scope**: Every Default Generate run. This is internal preparation only: do not -open a page, ask a question, wait for a receipt, select a workspace, read a -template spec/prototype, or install anything. Quick resolves exact supplied -roots or free design inside its profile and skips this Step. +Internal preparation for every Default run — no page, question, receipt, selection, template read, or installation. Quick skips this Step. -Prepare the candidate boundary that Stage 1 will confirm. Registered candidates -come from exactly these discovery sources: +Registered candidates come only from `templates/{brands,styles,layouts,decks}/*_index.json`, each root derived as `templates/<kind_dir>/<id>/`; never scan kind directories or resolve a bare name, brand mention, or style phrase to a path. Preserve every exact root supplied for this run (a registered-root match stays `library`; any other root is `explicit`; provenance never changes precedence). Raw PPTX is source material, not a candidate — raw PPTX plus new content is [`edit-native-pptx`](./edit-native-pptx.md), and a reusable workspace comes from [`create-template`](./create-template.md). -- `templates/brands/brands_index.json` -- `templates/styles/styles_index.json` -- `templates/layouts/layouts_index.json` -- `templates/decks/decks_index.json` +Resolve the surface under [`confirm-surface.md`](../references/confirm-surface.md). UI branch: run `--reset-template-selection`, then write `<project_path>/confirm_ui/template_options.json` with `schema_version: 1`, `phase: "template"`, the UI `lang`, all supplied roots as absolute `explicit_workspace_roots` (empty array when none), and `default_mode` — `templates` for explicit template intent or any supplied root, otherwise `free_design`. Do not launch yet; the server reads the indexes itself. Chat/delegated branch: retain the same candidate boundary in context and create no UI artifact. Stage 1 initializes from `default_mode` but the user may switch; template mode requires at least one selection; exactly one supplied root may be preselected, several remain unselected. -Derive each library root as `templates/<kind_dir>/<id>/` from its index entry. -Never scan kind directories, infer unregistered entries, or resolve a bare name, -brand mention, or style phrase to a path. Preserve every exact root supplied for -this run. A registered-root equality match remains `library`; every other exact -root remains `explicit`. Candidate provenance never changes later validation, -installation, or precedence. - -Resolve the confirmation surface under -[`confirm_ui.md`](../scripts/docs/confirm_ui.md). In the UI branch, run -`--reset-template-selection`, then write -`<project_path>/confirm_ui/template_options.json` with schema version `1`, -`phase: "template"`, the UI language, and all supplied exact roots as absolute -`explicit_workspace_roots`; use an empty array when none were supplied. Also -write required `default_mode`: `templates` when the user explicitly asks to use -or browse templates or supplies any exact root, otherwise `free_design`. The -server reads the four indexes itself. Do not launch it yet. In chat/delegated -confirmation, retain the same candidate boundary in context and create no UI -artifact. - -Stage 1 initializes from `default_mode`, but the user can switch modes. Template -mode alone expands the candidates and must eventually select at least one -workspace. Exactly one supplied root may be preselected as an editable default; -multiple supplied roots remain unselected candidates. `free_design` selects none. - -**Raw PPTX boundary**: A raw PPTX remains valid source material, but it is not a -template workspace candidate. Raw PPTX plus new content uses -[`edit-native-pptx`](./edit-native-pptx.md). To create a reusable workspace, -run [`create-template`](./create-template.md), then return with the generated -root. Never add Master/Layout/placeholder structure directly to an existing -PPTX or SVG project. - -**✅ Checkpoint**: Candidate input is ready for the combined Stage-1 -confirmation. No template has been selected, read, validated, or -installed. Proceed to Step 4 without a user-visible stop. +**✅ Checkpoint** — candidates ready; nothing selected, read, validated, or installed. Proceed to Step 4 without a user-visible stop. --- ### Step 4: Strategist Phase (MANDATORY in the default pipeline) -🚧 **GATE**: Source preparation and Step-3 candidate preparation are -complete. No template content has entered planning context and no template has -been installed. Stage 1 has not started before this point. +🚧 **GATE**: Steps 1–3 complete; no template content in planning context; Stage 1 not started. -**Hard rule — Stage 1 is template-independent**: Author every Stage-1 -communication recommendation from the user's current request, source facts, -conversation constraints, and project-initialization state only. Candidate -paths, index summaries, template specs/prototypes/assets, and template canvas -are not recommendation evidence. Author the communication proposal before any -chat-branch catalog listing. The project initialization canvas remains the -Stage-1 starting value unless the current user/source context changes it. -Template inspection and current-project fit begin only after Stage 1 confirms -both the communication contract and template/free-design choice and any selected -workspace has been installed. +**Hard rule — Stage 1 is template-independent**: author every Stage-1 recommendation from the user's request, source facts, conversation constraints, and project-initialization state only; candidate paths, index summaries, template specs/prototypes/assets, and template canvas are not evidence. Template inspection begins only after Stage 1 confirms both the communication contract and the template/free-design choice and any selection is installed. -At Step-4 entry, load the always-required planning context directly in one -batch: the role core, every canonical content-type source file defined below, -and the compact structured analysis facts already present. Do not load any -mode, visual-style, or image-rendering detail file before Stage 1. For a multi-deck -`source_profile.json`, read its compact `decks[]` digests in that batch and open -a deck's larger identity/slide-library files only when the specific need below -arises. +Load the planning core in one batch, plus the structured facts already in `<project_path>/analysis/`: ``` Read ${SKILL_DIR}/references/strategist.md Read ${SKILL_DIR}/references/canvas-formats.md ``` -Then load only the extra role modules triggered by the current plan: - -| Deterministic trigger | Additional Strategist reference | +| Trigger | Additional Strategist reference | |---|---| -| Stage 1 is confirmed and its template choice installed a selected Brand/Style/Layout/Deck workspace into this project | `references/strategist-template.md` before Stage 2 | -| The confirmed Stage-1 `delivery_context` identifies recorded/self-running/video delivery, or input is an explicit final/literal narration script | `references/video-design.md` before the three Stage-2 whole solutions and page roster | +| Stage 1 confirmed and a Brand/Style/Layout/Deck workspace installed | `references/strategist-template.md` before Stage 2 | +| Confirmed `delivery_context` is recorded/self-running/video, or input is a final/literal narration script | `references/video-design.md` before the three Stage-2 solutions and page roster | -After Stage 1 and template handoff, load the fixed planning-capability block -below in one batch before authoring any Stage-2 whole-solution intent, image -source recommendation, or page roster: +After Stage 1 and the template handoff, load the fixed planning-capability block in one batch before authoring any Stage-2 solution, image recommendation, or roster: ``` Read ${SKILL_DIR}/references/strategist-image.md -Read ${SKILL_DIR}/references/image-layout-spec.md -Read ${SKILL_DIR}/references/image-layout-patterns.md Read ${SKILL_DIR}/references/modes/_index.md Read ${SKILL_DIR}/references/visual-styles/_index.md Read ${SKILL_DIR}/references/image-renderings/_index.md @@ -293,540 +112,203 @@ Read ${SKILL_DIR}/templates/charts/chart-vocabulary.md Read ${SKILL_DIR}/templates/tables/table-vocabulary.md ``` -This is a capability map; retain the Strategist/Executor ownership boundary. Author the three whole solution -intents before mapping any component basis. Freeze every referenced -mode/style/rendering id from the indexes, then read once only the deduplicated -union of those exact detail files and finish the three custom behaviors. A novel -custom reads no detail file. Confirmed non-`none` uses the already-loaded image -layout references and continues into resource planning; confirmed `none` writes -no image rows while retaining recommendation-only rendering candidates. Only an installed -project-local template state loads the template module, and only after Stage 1 -is confirmed; a bare template/style name does not. +This is a capability map, not a usage checklist. Author the three whole-solution intents first, freeze every mode/style/rendering id from the indexes, then read once only the deduplicated union of those detail files; a novel custom reads none. Confirmed non-`none` image sources continue into resource planning under `strategist-image.md` (the image-layout files are Executor's); confirmed `none` writes no image rows but keeps the rendering candidates. -> ⚠️ **Mandatory artifact gates**: after final confirmation, author `design_spec.md` at the confirmed `design_spec_depth` from `${SKILL_DIR}/templates/design_spec_reference.md`. After Gate 1 and any refinement approval, author `spec_lock.md` from `${SKILL_DIR}/templates/spec_lock_reference.md` plus approved Design Spec/context. Author each new artifact once without placeholders or `scaffold-*` (manual-only). Schema validity does not prove semantic fidelity. +**Fact channels** ([`artifact-ownership.md`](../references/artifact-ownership.md) §1–2): before Stage 1 read `analysis/source_profile.json`'s `decks[]` digests, opening a deck's identity/slide-library files only when raw facts are needed. Content — text, tables, chart values, SmartArt wording — comes from the content-type files in `sources/` (`<stem>.md` and archived `.txt` / `.csv` / `.json` / `.yaml`), never from the digest; `*.conversion_profile.json` and `*_files/image_manifest.json` are sidecars. A source deck's identity is reference, not constraint. If the user provided images, run `python3 ${SKILL_DIR}/scripts/analyze_images.py <project_path>/images` before the Design Spec and read `analysis/image_analysis.csv` before §VIII; the CSV is a regenerated view of `images/` — rerun after any change, never treat it as a store. Never bulk-open images: Strategist inspects one specifically ambiguous asset under [`strategist-image.md`](../references/strategist-image.md) and records the result in §VIII; Executor inspects one `Existing` / `Sourced` asset only for crop, focal placement, or text contrast. -**Artifact ownership**: fact-channel and source/derived artifact boundaries are defined in [`references/artifact-ownership.md`](../references/artifact-ownership.md). This Step uses those ownership rules; it does not redefine them. +⛔ **BLOCKING — two-stage confirmation**: the always-on user gate unless explicitly delegated. Stage 1 confirms the communication contract and exactly one template mode (`free_design` or `templates`, the latter expanding the four registered-kind selectors plus supplied roots and requiring at least one selection). Final Stage 2 confirms the complete deck solution plus production mechanics only after the Stage-1 choice is installed or free design is closed; `refine_spec: true` adds one chat gate after Design Spec Gate 1. Author each stage once; submitted values — including blanks and unusual overrides — are authoritative. Only the user confirms: the agent authors recommendations, operates the server, reads state, and applies a template, but never confirms on the user's behalf, automates submission, synthesizes a payload, or writes user result state; silence confirms nothing. Under explicit delegation the agent makes the Stage-1 decision, installs it, derives Stage 2, and presents one complete summary without fabricating UI receipts. -**`<project_path>/analysis/` is the project's intermediate-analysis folder: the canonical home for machine-extracted source/asset facts — the PPTX intake bundle (`source_profile.json` index + per-deck `<stem>.identity.json` / `<stem>.slide_library.json`) and `image_analysis.csv`. It holds facts, not design contracts — `design_spec.md` / `spec_lock.md` stay at the project root.** The MUST-read contract covers only the **compact structured data files (`.json` / `.csv`)**; other artifacts that may live under `analysis/` (e.g. a beautify `source_svg_import/` vector reference package) are NOT bulk-read — they are read selectively only when a specific workflow step calls for them. Before the Strategist confirmation stage, Strategist MUST read the auto-extracted fact files already in `analysis/` — currently `source_profile.json` (PPTX intake), when present. This file is the multi-deck index: read it once for the `decks[]` digests (canvas / chart / table / SmartArt entries per source deck), then open a specific deck's `<stem>.identity.json` / `<stem>.slide_library.json` only if you need its full raw facts. Use these entries as **factual source context** (format default + content facts); when several decks are present, synthesize across all of them. The source's **palette / typography / visual identity are a reference, not a constraint**: the main pipeline may inherit them where they fit the content and the confirmed style, or design fresh where they don't — the Strategist's judgment, never an obligation to either keep or discard. (Edit Native PPTX preserves source-native objects through its source-backed round trip; beautify defaults to the source identity but still follows the confirmed values; the main pipeline treats source identity as reference only and defaults to fresh design.) (`image_analysis.csv` lands later, at the image-analysis step below, and is the authoritative regenerated image-fact view there — re-derived from the live `images/` folder, not a durable store.) - -**Channel ownership — read each fact once from its owning channel.** In the main pipeline the **content contract is the content-type files in `sources/`** — primarily `<stem>.md`, but also any user-supplied content the import archived there: `.md` / `.markdown` / `.txt` / `.csv` / `.tsv` / `.json` / `.jsonl` / `.yaml` / `.yml` (a `metrics.json` or `data.csv` may carry core content — judge by what the file holds). Text, tables, chart data values, and SmartArt node wording come from these (`ppt_to_md` transcribes native charts as Markdown tables and SmartArt nodes as hierarchical bullets). **Do NOT read pipeline sidecars in `sources/` as content**: `*.conversion_profile.json` (conversion audit) and `*_files/image_manifest.json` (asset index) are process metadata — open them only to audit a conversion or resolve assets, never as slide content. Converted-source originals archived in `sources/` (`.pdf` / `.pptx` / `.docx` / `.xlsx` / `.html` / `.epub` / `.tex` / `.rst` / `.ipynb` / `.typ`, etc.) are read via their converted `<stem>.md`, not scanned directly in the main pipeline. The `analysis/` chart / table / diagram entries are a **structural digest** for outline decisions (which slides carried charts, tables, or SmartArt; chart types / series names; SmartArt layout and hierarchy) — not a second copy of the content values; do NOT also pull chart values or SmartArt wording from `<stem>.slide_library.json` in the main pipeline. The `<stem>.slide_library.json` full structured data is owned by beautify for native chart / table data and SmartArt relationships while keeping all wording from the Markdown. - -**Confirmation orchestration**: field meaning and recommendation logic belong to the active Strategist modules; [`confirm_ui.md`](../scripts/docs/confirm_ui.md) owns the JSON schema, server lifecycle, staged-result contract, port behavior, and equivalent chat fallback. - -⛔ **BLOCKING**: The two-stage Strategist confirmation is the always-on user -gate unless explicitly delegated. Stage 1 confirms the communication contract -and, on the same screen or in the same chat turn, exactly one template mode: -`free_design` or `templates`. Only `templates` expands the four registered-kind -selectors plus supplied exact-root candidates, and it requires at least one -selection. Final Stage 2 confirms the complete deck solution plus production -mechanics only after the Stage-1 choice is installed or its free-design handoff -is complete. An enabled `refine_spec` adds the one conditional chat gate after -Design Spec Gate 1. Author each stage once; submitted values—including blanks or -unusual overrides—are authoritative. - -**Confirmation ownership and surface**: Only the user confirms. Before any -confirmation server command, apply -`confirm_ui.md`'s surface -decision to this run's most recent explicit surface instruction and retain that -branch as the owner specifies. A natural-language request or agreement to -personally confirm in chat, or to avoid the page, selects the chat branch without -a magic keyword; skip UI launch/wait commands and UI-authored result state. -Explicit delegation is a separate higher-priority branch. With no surface -instruction, use the default UI branch. A chat-question tool alone does not -replace that default. The agent may author recommendations, operate the -server, read state, and apply a selected template, but MUST NOT confirm on the -user's behalf, automate submission, synthesize a payload, or write/replace user -result state. Delegation applies only to this run: make the Stage-1 communication -and template decision, install any selection, then derive and show the complete -Stage-2 summary without fabricating UI results. Silence confirms nothing. - -**UI branch files and completion evidence:** - -| Input file (only the active unconfirmed Strategist stage may be overwritten) | Agent writes | Completion evidence | -|---|---|---| -| `confirm_ui/template_options.json` | Candidate schema/language plus supplied exact roots; library entries remain server-owned index data | Stage-1 submission writes user-owned `template_selection.json` with `phase: template`, `status: confirmed` | -| `confirm_ui/recommendations.stage1.json` | Communication contract, `content_divergence`, and canvas only; no template-derived recommendation | The same submission writes `result.json` with `status: stage1-confirmed` | -| `confirm_ui/template_handoff.json` | Only through `--complete-template-selection`, after the Stage-1 selection and free-design closure or successful installation | `status: ready`, bound to the current selection hash; prerequisite for Stage 2 | -| `confirm_ui/recommendations.stage2.json` | `stage: stage2`; complete deck solution plus conditional AI path, generation mode, refine-spec, design-spec depth, proactive speaker notes, custom animations, and narration audio | `stage: final`, `status: confirmed` | - -If the user rejects the current recommendation before confirming it, regenerate by overwriting that same stage file and have the page refresh; do not create revision-suffixed files. This never authorizes one stage file to carry another stage's payload. - -**UI branch only** — Step 3 wrote `template_options.json` but did not launch or -wait. Create `confirm_ui/recommendations.stage1.json` without reading template -candidate content, then launch the combined Stage-1 page and post -`confirm_ui.md`'s required communication + template-choice summary/fallback: +**UI branch** — `template_options.json` (Step 3), `recommendations.stage1.json`, `template_handoff.json` (written only by `--complete-template-selection`), and `recommendations.stage2.json` are agent inputs; `template_selection.json` and `result.json` are user receipts. Only the active unconfirmed stage file may be overwritten, in place, never with a revision suffix or another stage's payload. Author Stage 1 without reading candidates, launch, post the [`confirm-surface.md`](../references/confirm-surface.md) handoff summary, then wait: ```bash python3 ${SKILL_DIR}/scripts/confirm_ui/server.py <project_path> --daemon python3 ${SKILL_DIR}/scripts/confirm_ui/server.py <project_path> --wait-only --wait-stage stage1 ``` -**Hard rule — Stage 1 is intermediate**: exit `0` from this first wait is an -instruction to continue, not a route-completion condition. Do not send a final -chat reply, go idle, or yield the task here. In the same active run, read the two -Stage-1 receipts, complete the template/free-design handoff, author fresh Stage -2, and invoke the final wait below. Only `stage: final` + `status: confirmed` -may close this confirmation flow. - -The single Stage-1 submission writes both `result.json` and -`template_selection.json`; neither replaces the other. Read each exactly once. -Require a confirmed communication result and either `free_design` with no roots -or `templates` with at least one server-resolved root. - -1. For `templates`, load and run - [`apply-template-workspace.md`](./stages/apply-template-workspace.md) against - every confirmed exact root. It validates them and installs each as its own - `templates/design_spec.<kind>.<id>.md` plus any real `images/` and `icons/`. - For `free_design`, skip installation. Then bind the completed state: +**Hard rule — Stage 1 is intermediate**: exit `0` here means continue, not finish — no final reply, no idling. Read `result.json` and `template_selection.json` exactly once (a confirmed contract plus either `free_design` with no roots or `templates` with ≥1 server-resolved root), then in the same run: +1. For `templates`, run [`apply-template-workspace.md`](./stages/apply-template-workspace.md) against every confirmed root (each installs as `templates/design_spec.<kind>.<id>.md` plus real `images/` and `icons/`); for `free_design` skip it. Then bind the state — agent-only, never hand-authored: ```bash python3 ${SKILL_DIR}/scripts/confirm_ui/server.py <project_path> --complete-template-selection ``` - - This agent-only command writes `template_handoff.json`; do not hand-author - it. The server requires this handoff before Stage 2. - -2. Only now inspect installed template state and apply - `strategist-template.md` when active. Load the fixed Stage-2 planning-capability - block above, author three whole solution intents, freeze their exact component - references from its indexes, then read only the referenced detail files and - complete the custom projections. Derive the - remaining production defaults and create - `confirm_ui/recommendations.stage2.json` without changing Stage 1; declare - `stage: "stage2"`, then wait for the final confirmation: - +2. Only now inspect installed template state (apply `strategist-template.md` when active), load the planning-capability block, author the three solutions, freeze and read their exact bases, derive the production defaults, and create `recommendations.stage2.json` (`stage: "stage2"`) without changing Stage 1. Wait: ```bash python3 ${SKILL_DIR}/scripts/confirm_ui/server.py <project_path> --wait-only ``` - -3. After the final wait returns, read the complete `result.json` exactly once - and retain that object through Design Spec authoring and its fidelity audit. - Proceed only when it carries `stage: final` and `status: confirmed`. Do not - reopen the file during normal lock authoring or downstream execution. On a - non-zero wait, this same single read determines whether the persisted result - succeeded before using the documented chat fallback. A stage-skip result - returns to the missing stage; it is not a browser failure. - -4. After final confirmation or chat fallback, always release the server: - +3. Read the complete `result.json` exactly once and retain it through Design Spec authoring; proceed only on `stage: final` + `status: confirmed`. On a non-zero wait this single read decides whether the persisted result succeeded before the chat fallback; a stage-skip result returns to the missing stage. +4. Always release the server: ```bash python3 ${SKILL_DIR}/scripts/confirm_ui/server.py <project_path> --shutdown ``` -If the user selects chat any time after the UI server launches, immediately -apply `confirm_ui.md`'s in-run switch procedure. Continue the unresolved current -stage and all remaining stages in chat; do not enter UI interruption recovery -or relaunch the server. +If the user selects chat after launch, apply `confirm-surface.md`'s in-run switch and finish every remaining stage in chat without relaunching. -**Chat branch** — present the template mode and Stage-1 communication contract -together and wait for one explicit response. Show registered candidates only -when the user chooses `templates`; supplied exact roots remain available in that -expanded choice. Initialize free design for an ordinary request and template -mode for explicit template intent or any exact root; with exactly one root it -may also be the preselected candidate, while multiple roots remain unselected. -Do not create UI receipts -or call `--complete-template-selection`. After confirmation, install/fuse any -selected roots (or close free design) and retain that completed state in context -as the Stage-2 gate. Then run final Stage 2 in chat and retain one visible -cumulative summary as the equivalent final state. Under explicit delegation, -make the same Stage-1 decision, install it, derive Stage 2, and present one -complete AI-authored summary. +**Chat branch** — present the template mode and Stage-1 contract together and wait for one explicit response (registered candidates shown only when the user chooses `templates`; free design for an ordinary request, template mode for explicit intent or any supplied root, one root preselectable). Create no UI receipts and do not call `--complete-template-selection`. After confirmation, install or fuse selected roots (or close free design), retain that state as the Stage-2 gate, run final Stage 2 in chat, and keep one visible cumulative summary as the final state. -⛔ **GATE — final state → Design Spec → conditional review → lock.** Consume every present final value once into the complete, audited `design_spec.md` under [`strategist.md`](../references/strategist.md) §6.2. Preserve each owning semantic type and all production, typography, image-source, and `image_notes` obligations; acceptance never turns a Reference/Permission into a Literal. Do not reopen `result.json`. +⛔ **GATE — final state → Design Spec → conditional review → lock**: consume every present final value once into the complete, audited `design_spec.md` under [`strategist.md`](../references/strategist.md) §6.2, preserving each field's semantic type (acceptance never turns a Reference or Permission into a Literal) and every production, typography, image-source, and `image_notes` obligation; never reopen `result.json`. -With `refine_spec: true`, run [`refine-spec`](stages/refine-spec.md) after Gate 1: review that same file in chat, accept arbitrary revisions, touch no lock, and stop until explicit approval. Revisions supersede only affected decisions. Otherwise skip the stop. +1. Read `${SKILL_DIR}/templates/design_spec_reference.md`; create the complete I–X `design_spec.md` once at the confirmed `design_spec_depth`, without placeholders or `scaffold-*`. +2. Audit it field by field against the retained confirmation — Gate 1. +3. With `refine_spec: true`, run [`refine-spec`](stages/refine-spec.md): review that file in chat, accept arbitrary revisions, touch no lock, stop until explicit approval. Otherwise skip. +4. Read `${SKILL_DIR}/templates/spec_lock_reference.md`; author `spec_lock.md` once from the approved Design Spec and context — identity and refinements, every recurring typography role, routing anchors, each placed image's source/layout suggestion/crop policy; no page-local garnish, no image palette; `strategist-template.md` §3 when active. +5. Compare lock anchors to the Design Spec and run `python3 ${SKILL_DIR}/scripts/project_manager.py validate <project_path>`. Schema validity never proves fidelity: a final-state → Design Spec mismatch, an approved Design Spec → lock mismatch, or an unapplied revision blocks. Repair from the retained confirmation (or the approved revision); resume and refine edit existing files, never scaffolds; only fresh recovery may reread persisted final evidence once. Unhonorable requirements follow [`failure-recovery.md`](governance/failure-recovery.md). -After the review closes, author `spec_lock.md` from the approved Design Spec and context. Preserve identity/refinements, every recurring typography role, reusable routing anchors, and each placed image's source/layout suggestion/crop policy; omit page-local garnish and never write a separate image palette. Apply `strategist-template.md` §3 when active. Unhonorable requirements follow [`failure-recovery.md`](governance/failure-recovery.md). +**Confirmation notes**, appended after the stage details in the user's language, each one 💡 line: the split-mode note only when the confirmed mode is `split` or the run is heavy (long page count, bulky sources, substantial research retained in this chat — an isolated `topic-research` worker's fetches do not count) — recommend or confirm stopping after Step 5 and entering the execution session with `继续生成 projects/<project_name>` ([`resume-execute`](stages/resume-execute.md)); no response or "continue" means `continuous`, and the default path prints no reminder. The spec-refinement note always: offer review of the complete Design Spec before the lock (default OFF; only explicit opt-in or `refine_spec: true` runs `refine-spec`). -**Conditional — split-mode note** (not a separate confirmation): after listing the Strategist confirmation stage details, append one short line (rendered in the user's language, prefixed with 💡) only when the confirmed mode is `split` or upstream-load signals make a fresh execution context materially useful. Judge those signals from recommended page count, source-material bulk, and research material actually retained in this chat. Raw fetches performed by a successful isolated `topic-research` worker do not count; substantial local-fallback fetches or unusually large imported research artifacts do. +**Production fields**: resolve Speaker Notes, Custom Animations, and Narration Audio as latest explicit user instruction → final Stage-2 proactive value → default `true` / `false` / `false`; enabled Narration Audio raises a non-explicitly-disabled Speaker Notes outcome and names that dependency. Persist the effective outcomes with provenance as the three rows in `design_spec.md §I`, keep the raw proactive fields as evidence only, and project neither into `spec_lock.md`. A later explicit request updates only its §I outcome and resumes the owning step without reopening Confirm UI; disabling notes while audio stays enabled asks one question (disable audio too, or keep its required notes) before writing either row. Formulas and hyperlinks are §IX content, not confirmation fields or resources: Strategist records the delimiter-free LaTeX body or the exact URI / 1-based slide target, and Executor chooses the realization (text, inline, or block math; inline or whole-object link carrier) under [`native-formula.md`](../references/native-formula.md) / [`native-hyperlinks.md`](../references/native-hyperlinks.md); no manifest or lock entry exists for either. -| Signal read | Line content | -|---|---| -| Heavy (long page count / bulky sources / heavy retained research context) | State the applicable heavy signals; recommend switching to [split mode](stages/resume-execute.md) after Step 5 — stop this chat, open a fresh window and input `继续生成 projects/<project_name>` to enter the execution session (SVG generation + export); no response or "continue" = default continuous mode. | -| Explicit `split` selection | Confirm that planning will stop after Step 5 and give the `继续生成 projects/<project_name>` handoff command. | +**Prepared final narration**: when an explicit final/literal script will become notes or audio, follow `video-design.md` §1 and §3 — segment it by scene in Stage 2, give each segment a supporting visible state in §IX, record source and verbatim policy in §X, and after Gate 2 (before Step 5 or the split handoff) write the exact segments once to `notes/total.md`, split only in Step 7.1. -For the normal/default `continuous` path, print no split-mode reminder and proceed automatically. Confirm UI still exposes the generation-mode toggle and records it in `result.json`; a chat fallback captures the same choice in its confirmation summary without adding a separate reminder. +**Output**: `design_spec.md`, `spec_lock.md`, and `notes/total.md` only on the narration branch. -**Mandatory — spec-refinement note** (not another Confirm UI stage): after confirmation details and any split-mode line, append one localized 💡 line offering review of the complete Design Spec before the lock; any part may be revised in chat until explicit approval. Default OFF; only explicit chat opt-in or `refine_spec: true` runs [`refine-spec`](stages/refine-spec.md) after Gate 1. Confirm UI records the toggle; chat fallback prints the same line. - -**Native formula content**: Formula handling is not a confirmation field or an -image-acquisition path. Strategist records exact mathematical content as a -delimiter-free LaTeX expression body in the applicable §IX page block without -classifying its implementation. Executor independently chooses ordinary text, -same-paragraph native inline math, or a standalone native block under -[`native-formula.md`](../references/native-formula.md); matrices, multiline -derivations, and other high-structure expressions remain blocks. -No formula manifest, §VIII resource row, or `spec_lock.md images` entry is -created. - -**Native hyperlink content**: Hyperlinks are not a confirmation field or a -resource-acquisition path. Strategist records the linked text/object intent and -exact absolute URI or 1-based same-deck slide target in the applicable §IX page -block. Executor chooses an inline or whole-object carrier and authors the -canonical SVG `<a href>` under -[`native-hyperlinks.md`](../references/native-hyperlinks.md). Unknown targets -return upstream; no hyperlink manifest or `spec_lock.md` entry is created. - -**Proactive production decisions**: Final Stage 2 records -`proactive_speaker_notes`, `proactive_custom_animations`, and -`proactive_narration_audio`. They control only what the agent initiates when the -user has not already given an explicit instruction. Resolve each effective -outcome as latest explicit user instruction → final Stage-2 value → workflow -default `true` / `false` / `false`. Final Stage-2 Narration Audio enabled raises a -non-explicitly-disabled Speaker Notes outcome to enabled and names that -dependency in its provenance without rewriting the raw proactive preference. -Persist the resolved effective outcomes plus provenance as the `Speaker Notes`, -`Custom Animations`, and `Narration Audio` rows in `design_spec.md §I`; keep the -raw proactive fields only as confirmation evidence and do not project either -form into `spec_lock.md`. - -**Post-confirmation override**: A later explicit request updates only affected -§I outcomes/provenance and resumes their owning step; do not reopen Confirm UI. -If it disables Speaker Notes while Narration Audio remains enabled, write -neither row and ask one question: disable audio too, or retain its required -notes. Wait, then update both. Before `generate-audio`, create and split notes -when complete per-slide files are absent. - -If the user provided images, run analysis **before outputting the design spec**. It writes `analysis/image_analysis.csv` — the authoritative regenerated image-fact view in the `analysis/` folder, which MUST be read before authoring §VIII: -```bash -python3 ${SKILL_DIR}/scripts/analyze_images.py <project_path>/images -``` - -> 🔁 **Image facts are regenerated on change, never maintained as a second store.** `images/` is the live working folder and single source of truth; `analysis/image_analysis.csv` is its regenerated view. Run `analyze_images.py` before the first inventory read, then reuse that CSV while `images/` is unchanged. Re-run after import/acquisition or any user addition, removal, or replacement; an empty folder produces a fresh header-only CSV rather than leaving stale facts. - -> ⚠️ **Image understanding**: Do not bulk-open images. Strategist starts from context, filenames, records, and `image_analysis.csv`; inspect only a specifically ambiguous asset under [`strategist-image.md`](../references/strategist-image.md), then record the result in §VIII. Under [`executor-image.md`](../references/executor-image.md), Executor may inspect one selected `Existing` / `Sourced` asset only to resolve crop, focal placement, or text contrast—never to reselect, replace, or infer provenance. - -**Output**: -- `<project_path>/design_spec.md` — complete human-readable design narrative and durable confirmed production state -- `<project_path>/spec_lock.md` — machine-readable stable execution anchors/routing, authored after conditional review approval -- `<project_path>/notes/total.md` — only when the prepared final narration branch is active; frozen verbatim production input - -For a new project, use the reference-first whole-document sequence: - -1. Read `${SKILL_DIR}/templates/design_spec_reference.md`; create complete I–X `<project_path>/design_spec.md` once from retained confirmation, analysis, and context, without placeholders/examples. -2. Audit it field by field against retained confirmation; Gate 1 must pass. -3. If enabled, run [`refine-spec`](stages/refine-spec.md) on that file until explicit approval; touch no lock. -4. Read `${SKILL_DIR}/templates/spec_lock_reference.md`; create or resynchronize the lock once from approved Design Spec and context. Never reopen `result.json` or make a new design choice. -5. Compare lock anchors/routing to the Design Spec; run `python3 ${SKILL_DIR}/scripts/project_manager.py validate <project_path>`. - -Final state → initial Design Spec mismatch, approved Design Spec/context → lock mismatch, or an unapplied revision blocks despite schema validity. `validate` does not prove fidelity. Repair from retained confirmation before refinement; during it, preserve unaffected values and apply explicit revisions. After approval, derive the lock from that Design Spec/context. Resume/refine edits existing files, never scaffolds. Fresh recovery alone may reread persisted final evidence once. - -**Prepared final narration branch**: follow `video-design.md` §1 and §3 when an -explicit final/literal script will become notes or generated audio. Segment it -by semantic scene during Stage 2; §IX gives each segment a supporting visible -state and §X records its source/verbatim policy. After Gate 2, before Step 5 or -split handoff, write the exact segments once to `notes/total.md`; split them only -in Step 7.1. This is frozen production input, not a third planning artifact. - -**✅ Internal checkpoint — Phase deliverables complete**: facts read; confirmation consumed once; final Stage-2 production fields resolved (generation mode, refine-spec, proactive choices, and conditional AI path); mathematical content recorded where applicable; every §IX page resolved its one-pass carrier mix and §VIII contains only assigned external image-resource jobs; Design Spec passed Gate 1; enabled refinement approved; lock derived from it; split handling resolved; communication and every §IX `Audience move` validated. Do not print this checklist; auto-proceed. +**✅ Internal checkpoint** — facts read; confirmation consumed once; production fields, mathematics, per-page `Relationships`, and §VIII resource jobs resolved; Gate 1 passed; refinement approved when enabled; lock derived; split handling resolved; every §IX `Audience move` present. Do not print; auto-proceed. --- ### Step 5: Image Acquisition Phase (Conditional) -🚧 **GATE**: Step 4 complete; `<project_path>/design_spec.md` and `<project_path>/spec_lock.md` both exist. If either required artifact is missing, stop before any acquisition or generation and follow [`failure-recovery.md`](governance/failure-recovery.md) §3. +🚧 **GATE**: Step 4 complete; `design_spec.md` and `spec_lock.md` exist (otherwise stop under [`failure-recovery.md`](governance/failure-recovery.md) §3). -> **Trigger**: §VIII is Step 4's committed external image-resource result, not a candidate inventory. At least one row has `Acquire Via: ai`, `web`, and/or `slice`, or one row is a pending prepared derivative declared by `Reference: Derived from <canonical bare filename>; treatment=...`. A prepared-user-only plan skips this step only when it has no derivative to materialize; `placeholder` rows alone do not trigger it. A permitted but unused image source creates no row and does not trigger acquisition. If §VIII omits a source, asset, or page role that `image_notes` explicitly requires, the Design Spec is incomplete; return to Step 4 Gate 1, repair it from the retained final state, and re-author the affected lock anchors from context. Do not reopen `result.json` during this check. - -**Failure recovery**: stop/continue behavior for AI/web/slice/image-readiness failures is defined in [`workflows/governance/failure-recovery.md`](governance/failure-recovery.md). This Step keeps the acquisition procedure. - -**Always load the common framework**: +**Trigger**: §VIII has at least one `Acquire Via: ai`, `web`, or `slice` row, or a pending derivative declared by `Reference: Derived from <canonical bare filename>; treatment=...`. Prepared-user-only plans and `placeholder` rows do not trigger it; a permitted but unused source creates no row. If §VIII omits a source, asset, or page role that `image_notes` explicitly requires, return to Step 4 Gate 1 and repair from the retained final state. ``` -Read ${SKILL_DIR}/references/image-base.md +Read ${SKILL_DIR}/references/image-base.md # always ``` -Then **lazy-load the path-specific reference** for each row that actually needs it: - -| Row kind / Acquire Via | Load reference (only if any such row exists) | Run | +| Row | Additional reference | Run | |---|---|---| -| Prepared derivative | `references/image-base.md`; add `references/image-generator.md` §4.4 only for registered layers | after its named canonical source reaches a usable terminal state, run `python3 ${SKILL_DIR}/scripts/image_treat.py ...` for the declared per-pixel treatment or the existing §4.4 preparation path | -| `ai` | `references/image-generator.md` | write `<project_path>/images/image_prompts.json`, then follow `image-generator.md §7 Path Selection` (`image_gen.py --manifest` is **Path A only**) | -| `web` | `references/image-searcher.md` | `python3 ${SKILL_DIR}/scripts/image_search.py ...` (≥2 web rows → `--batch images/image_queries.json`) | -| `slice` | `references/image-generator.md` §4.3 | derived — **after** the parent `ai` sheet row is `Generated`, run `python3 ${SKILL_DIR}/scripts/slice_images.py <project_path>/images/<sheet>.png --grid RxC --names ... --trim --alpha --bg KEY_HEX_FROM_PROMPT --strict-alpha` (see workflow step 2.5) | -| `user` / `placeholder` | (skip) | (skip) | +| Prepared derivative | `image-generator.md` §4.4 only for registered layers | after its canonical source is terminal: `python3 ${SKILL_DIR}/scripts/image_treat.py ...` for blur, desaturation/grayscale, duotone, brightness, or contrast, or the §4.4 preparation path | +| `ai` | `image-generator.md` | write `images/image_prompts.json`, render `image_prompts.md` with `image_gen.py --render-md`, then follow §7 Path Selection — `image_gen.py --manifest` is Path A only, `host-native` is Path B and skips `--manifest`, `manual` writes prompts and stops; the recorded `design_spec.md §I` path wins over `IMAGE_BACKEND` | +| `web` | `image-searcher.md` | `python3 ${SKILL_DIR}/scripts/image_search.py ...`; with ≥2 rows write `images/image_queries.json` and run `--batch` once | +| `slice` | `image-generator.md` §4.3 | after the parent sheet is `Generated`: `python3 ${SKILL_DIR}/scripts/slice_images.py <project_path>/images/<sheet>.png --grid RxC --names ... --trim --alpha --bg KEY_HEX_FROM_PROMPT --strict-alpha` | +| `user` / `placeholder` | — | skip | -A deck with only `ai` rows never loads `image-searcher.md`; a deck with only `web` rows never loads `image-generator.md`. A mixed deck loads both, processes each row through its own path, and writes both `image_prompts.json` and `image_sources.json`. +Load only the references the rows need; a mixed deck writes both `image_prompts.json` and `image_sources.json`. The positional `image_gen.py "prompt"` form is for out-of-pipeline fixups and the §4.4 reconstruction derivation only. -> ⚠️ **In-pipeline ai rows MUST use the manifest contract** — even when only 1 ai row exists. Always write `images/image_prompts.json` first and render `image_prompts.md` with `image_gen.py --render-md`. Then execute the confirmed path from `image-generator.md §7`: `image_gen.py --manifest` is **Path A only**; `host-native` is **Path B** and MUST skip `--manifest`; `manual` writes the prompts and stops for external generation. The positional form (`image_gen.py "prompt" ...`) is reserved for **out-of-pipeline one-off testing / single-image fixups**, except for the already-planned registered reconstruction-group derivation in `image-generator.md` §4.4. That narrow exception keeps every final member in the resource authority and operational sidecar; it does not authorize unrelated in-pipeline generation outside the manifest contract. +**Web selection**: when any vision-capable context exists, add `--save-candidates` with explicit `query_variants` and run [`web-image-review`](stages/web-image-review.md); only a stage-selected candidate is promoted with `--promote`, a row advances to `next_candidate_page` before its query changes, and only an exhausted pool returns it to `Pending` with new variants. Without vision, omit `--save-candidates`: best-only mode downloads a strict metadata-verified candidate (`selection_method: metadata-ranked`) or stops at `Needs-Manual`. Only after normal search is exhausted may a vision-capable owner fetch one [`topic-research`](stages/topic-research.md) `source_url` as a reviewed source package. §VIII `Reference` stays the locked intent; the provider query is authored separately. -> ⚠️ **web path — batch multiple rows**: when ≥2 rows are `Acquire Via: web`, write all queries into `images/image_queries.json` and run `image_search.py --batch` once (concurrent acquisition, status written back), instead of one CLI call per row. A single web row may use the positional single-query form. See [image-searcher.md](../references/image-searcher.md) §5. +🚧 **Exhausted-automation GATE**: `auto` tries Path A then Path B and never silently enters Offline Manual. When both are exhausted, or a confirmed `api` / `host-native` path stays unavailable after retry, ask whether to repair and retry the same path, generate the listed files manually, or cancel the affected AI images and repair the plan; only confirmed `manual` creates `Needs-Manual` rows. Web failures follow [`image-base.md`](../references/image-base.md) §3 without halting: try materially different query/provider/license strategies, then mark `Needs-Manual`, report, and continue. -> **Default — bounded multimodal web thumbnail selection**: when either the current agent or an available isolated reviewer can inspect images, add `--save-candidates` to the single or batch web command. Author explicit `query_variants` for materially different official translations, spellings, aliases, or Chinese names; the tool aggregates and deduplicates them, then saves only the first ranked page (8 previews by default), writes `candidates/<stem>/review_sheet.jpg`, marks the batch row `Needs-Selection`, and downloads no original. Run [`web-image-review`](stages/web-image-review.md): dispatch exactly one isolated reviewer for all current sheets when supported, passing only each row's locked Reference/Crop Policy plus candidate sidecar/sheet paths; otherwise the active image owner reads that stage and reviews locally. Only a stage-selected passing candidate may be used with `--promote` to download one original and write provenance (pass the same `--batch images/image_queries.json` to reconcile its row to `Sourced`). If none passes and `has_more_candidates` is true, advance that row to `next_candidate_page` before changing the query. Only after the pool is exhausted may the row receive materially different query variants and return to `Pending`. When no available context has vision, omit `--save-candidates`: best-only mode may download only a strict metadata-verified candidate, records `selection_method: metadata-ranked`, and otherwise stops at `Needs-Manual` without claiming visual confirmation. +**Workflow**: -> **Adopted-page fallback**: only after that normal search is exhausted, a vision-capable image owner may follow [`topic-research`](stages/topic-research.md) § Hand-off to fetch one relevant `source_url` as a Markdown + companion-image source package, review it, and copy only accepted files into `<project>/images/`. Never auto-expand facts URLs or promote the whole package; without vision, skip this fallback. +1. Extract §VIII rows; separate derivative rows first (reject source/output equality, a derivative parent, chains, cycles, self-reference), then group canonical rows by `Acquire Via`. Every Pending/Failed row reaches a terminal state before Executor starts. +2. Generate prompts and/or run search per [`image-base.md`](../references/image-base.md) §1. +3. Slice each generated sheet with its grid, `--names`, and the exact key HEX from its prompt; a `slice` row is `Generated` only after exit 0, a strict keying failure writes no replacement outputs and returns the sheet to preparation, and a `Needs-Manual` sheet leaves its slices `Needs-Manual` for the Step 7 gate. +4. Materialize derivatives from their terminal source under the declared treatment only (`image_treat.py` for per-pixel treatments; §4.4 for registered clean-base/layer work — supplied assets are `user / Existing`, generated ones `ai / Generated`). A standalone cutout is prepared RGBA, a flat-key slice, or host-supplied. Never bake crop/clip, rotation/mirror, opacity, frame, shadow, scrim/wash, vignette, or overlap into a bitmap, never present `image_treat.py` as background removal, and copy a web source's license record to its derivative. +5. Verify every row's terminal status under [`svg-image-embedding.md`](../references/svg-image-embedding.md) — no `Pending`, `Failed`, or `Needs-Selection`; `auto` follows its fallback chain, confirmed `api` / `host-native` retries only that path, and an unresolved Default AI row waits at the gate above. +6. `python3 ${SKILL_DIR}/scripts/analyze_images.py <project_path>/images` so the CSV reflects every placeable image. -> **Default — short provider query (may override for a complete entity name or necessary disambiguation)**: keep §VIII `Reference` as the locked subject/focal/crop intent and author a separate concrete `image_queries.json.query`. Search/review never rewrites the Design Spec or lock to fit a candidate. +**✅ Internal checkpoint** — sidecars, slice outputs, terminal statuses, refreshed CSV. Do not print. Auto-proceed to Step 6; only `generation_mode: split` prints the handoff and stops this conversation: -> **Illustration Sheet contract**: [image-generator.md](../references/image-generator.md) §4.3 owns grouping, prompting, and slicing for illustration, illustrated-icon, and lettering elements. Keep every sheet unplaced and place/project only successful transparent `slice` rows. - -> ⚠️ **Honor the Design Spec's confirmed image source before running any generation command**: the `ai` generation path (Path A = `image_gen.py` API / Path B = host-native tool / Offline Manual) is **not** auto-only — the production value recorded in `design_spec.md §I` wins. `host-native` forces Path B even when `IMAGE_BACKEND` is configured; `api` forces Path A; `manual` forces offline. Never reopen `result.json` here, and never run `image_gen.py --manifest` when the recorded value is `host-native` or `manual`. Full selection rule: [image-generator.md](../references/image-generator.md) §7 Path Selection. - -> 🚧 **Default exhausted-automation GATE**: `auto` tries Path A then Path B but does not silently enter Offline Manual. When both are unavailable/exhausted—or a confirmed `api` / `host-native` path remains unavailable after its retry—apply `image-generator.md` §7's single recovery decision: ask whether to repair and retry the same path, generate the listed files manually, or cancel the affected AI images and repair the plan. Only confirmed `manual` may create `Needs-Manual` rows. Quick instead applies its own non-interactive no-AI replan after automated exhaustion. - -Workflow: - -1. Extract all resource rows from the design spec. First separate rows whose `Reference` starts `Derived from <canonical bare filename>; treatment=` so they cannot re-enter ordinary ai/web/slice acquisition; reject source/output equality, a derivative parent, chains, cycles, or self-reference; then group canonical rows by `Acquire Via`. Every Pending/Failed canonical acquisition row and Pending derivative must reach a terminal state before Executor starts. -2. Generate prompts (ai rows) and/or run search (web rows) per [image-base.md](../references/image-base.md) §3 dispatch table -2.5. **Slice any illustration, illustrated-icon, or lettering sheets (only if `slice` rows exist).** For each generated `ai` **sheet** row, run `slice_images.py` with the matching grid/`--names`, `--trim --alpha`, the exact key HEX named in its prompt as `--bg`, and `--strict-alpha`. Mark each `slice` row `Generated` only after exit 0; a strict keying failure writes no replacement outputs and returns the affected sheet to image preparation. A sheet still in `Needs-Manual` cannot be sliced — leave its `slice` rows `Needs-Manual` and surface them at the Step 7 readiness gate. Contract: [image-generator.md](../references/image-generator.md) §4.3. -2.6. **Materialize planned prepared derivatives.** After each named canonical source reaches a usable terminal state, preserve it and write the separately named derivative only from its declared treatment. Use `image_treat.py` for per-pixel blur, desaturation/grayscale, duotone, brightness, or contrast; that row inherits the canonical `Acquire Via` and terminal class. Use `image-generator.md` §4.4 only for registered clean-base/layer work; a supplied final asset is `user / Existing`, while generated/reconstructed output remains `ai / Generated`. A standalone cutout must be prepared RGBA, a flat-key slice, or supplied by the active host; otherwise follow its owning source's terminal rule, including the Default AI recovery decision before `Needs-Manual`. Do not present `image_treat.py` as photo background removal. Do not bake crop/clip, rotation/mirror, opacity, frame, shadow, scrim/wash, vignette, or overlap into a bitmap. Any derivative of a web source copies that source's license/attribution record to the new filename. A parent without a usable status leaves the child in the same unresolved or manual state. -3. Verify every processed acquisition/derivative row reaches its source-class terminal status under [`svg-image-embedding.md`](../references/svg-image-embedding.md); no `Pending`, `Failed`, or web `Needs-Selection` remains. On `auto`, follow the owning automated fallback chain. For confirmed `api` or `host-native`, retry only that path. Any unresolved Default AI row stops at the recovery decision above; do not mark it `Needs-Manual` or switch provider before the user's choice. -4. Re-derive image facts after canonical acquisition, slicing, and prepared derivatives are final — `python3 ${SKILL_DIR}/scripts/analyze_images.py <project_path>/images` — so `analysis/image_analysis.csv` reflects every image the Executor may place. Image facts are regenerated on use, never a stale store (see Step 4's image-facts note). - -**✅ Internal checkpoint — acquisition complete**: verify conditional AI/web sidecars, all required slice outputs, terminal status for every resource row, and a refreshed `image_analysis.csv`. Do not print this checklist. On success, auto-proceed under the compact status rule above. - -**Default — auto-proceed to Step 6.** Only when `design_spec.md §I` records `generation_mode: split`, output the planning-session handoff below and stop this conversation: - - ```markdown - ## ✅ Planning Session Complete - - [x] Spec: `design_spec.md`, `spec_lock.md` - - [x] Resources: `sources/`, `images/`, `templates/` - - [ ] **Next**: open a fresh chat window and input `继续生成 projects/<project_name>` to enter the execution session via the [`resume-execute`](stages/resume-execute.md) stage. - ``` - -> On web acquisition failure, follow [image-base.md](../references/image-base.md) §6 without halting. Continue through materially different query/provider/license/URL strategies; after exhaustion, mark `Needs-Manual`, report, and continue. AI rows use the separate Default recovery gate above. +```markdown +## ✅ Planning Session Complete +- [x] Spec: `design_spec.md`, `spec_lock.md` +- [x] Resources: `sources/`, `images/`, `templates/` +- [ ] **Next**: open a fresh chat window and input `继续生成 projects/<project_name>` to enter the execution session via the [`resume-execute`](stages/resume-execute.md) stage. +``` --- ### Step 6: Executor Phase -🚧 **GATE**: Step 4 (and Step 5 if triggered) complete; all prerequisite deliverables are ready. - -Read the Executor role core before applying its context policy: +🚧 **GATE**: Step 4 (and Step 5 if triggered) complete. ``` -Read ${SKILL_DIR}/references/executor-base.md # REQUIRED: flat/shared execution core -``` - -**Planning context**: follow [`executor-base.md`](../references/executor-base.md) §2.1. Reuse the complete Design Spec and lock in an unchanged, uncompacted context. Fresh/resumed/restarted, compacted/summary-only, or externally/unknown changed execution reads both once and reloads triggered inputs. For a local question, consult the retained lock first, then only the owning Design Spec fragment; do not poll files merely to prove validity. - -**Scheduled lock re-read (Default Generate only)**: when another page follows, re-read `spec_lock.md` once after P05/P10/P15/… per [`executor-base.md`](../references/executor-base.md) §2.1. - -**Exact page roster**: render `design_spec.md §IX` one-for-one, in order. Any add/drop/merge/split/reorder requires Spec repair first; a continuous run may repair within the confirmed range per [`executor-base.md`](../references/executor-base.md) §2.1. - -**Page content**: §IX is preferred wording and semantic authority. Use it when it works; adapt it when presentation benefits while preserving intent, facts, and explicit literal requirements. Read sources only to verify requested evidence; return incomplete blocks to Step 4 instead of enriching them during execution. - -**Prepared final narration**: when §X records a literal script, read the frozen -`notes/total.md` once before P01 and design each visible state/semantic group -around its exact segment; never edit or pad it. - -**Artifact ownership**: `svg_output/` is the author source, `svg_final/` is derived, and image facts come from the regenerated `analysis/image_analysis.csv`; see [`references/artifact-ownership.md`](../references/artifact-ownership.md). - -Read the exact execution references named by this deck's retained -`spec_lock.md`; do not reopen the planning indexes. Load the remaining fixed -construction block plus the resolved mode/style detail files as one batch: -``` -Read ${SKILL_DIR}/references/shared-standards-core.md # REQUIRED: SVG compatibility + shared aesthetic/leading baseline -Read ${SKILL_DIR}/references/svg-effects.md # REQUIRED: effects/construction vocabulary (§6.1 Visual Job Router as recall) -Read ${SKILL_DIR}/references/native-shape-authoring.md # REQUIRED: native-shape selection and Boolean construction -Read ${SKILL_DIR}/references/preset-shape-vocabulary.md # REQUIRED: complete 187-name authoring vocabulary -Read ${SKILL_DIR}/references/executor-structure.md # REQUIRED: qualitative relationship and topology grammar -Read ${SKILL_DIR}/references/topology-assembly.md # REQUIRED: topology assembly and relative-registration material -Read ${SKILL_DIR}/references/semantic-svg.md # REQUIRED: semantic metadata boundary +Read ${SKILL_DIR}/references/executor-base.md # REQUIRED core: execution rules, device menu, everyday effects, module triggers +Read ${SKILL_DIR}/references/shared-standards-core.md # REQUIRED core: SVG contract + shared aesthetic/leading baseline +Read ${SKILL_DIR}/references/semantic-svg.md # REQUIRED core: semantic metadata boundary +Read ${SKILL_DIR}/references/preset-shape-vocabulary.md # REQUIRED core: complete 187-name preset vocabulary Read ${SKILL_DIR}/references/modes/<resolved-id>.md # one preset id, or each `mode_references` id Read ${SKILL_DIR}/references/visual-styles/<resolved-id>.md # one preset id, or each `visual_style_references` id +# Triggered modules — evaluate every trigger over the §IX roster before P01 and read the triggered ones now, in this batch; +# a page reaching a capability the sweep did not foresee reads its module then (executor-base routing table): +# executor-structure.md + topology-assembly.md first `Structure = yes` page +# native-shape-authoring.md first contour beyond rect / roundRect / circle / ellipse / line, or a Boolean / freeform +# svg-effects.md first visual job beyond the everyday block ``` -Keep the core's shared visual-quality defaults active during page authoring, with `svg-effects.md` §6.1's Visual Job Router as recall; they are not passive compatibility reading. Explicit user/template requirements and the locked style override compatible aesthetic defaults, never technical Required / Forbidden boundaries. +Read the core as one batch with the exact detail files named by the retained `spec_lock.md`, then every module the roster sweep triggers, in the same batch (each page's module line records what it uses; a capability the sweep did not foresee loads at that page); never reopen the planning indexes, infer adjacent bases, glob a catalog, or blend unselected identities (an unreferenced custom follows its behavior alone). Conditional modules load on [`executor-base.md`](../references/executor-base.md)'s routing table, never by analogy; `video-design.md` is read before the first SVG when §I records recorded/self-running/video delivery or §X a literal script. `executor-structured.md` owns template specs and prototypes; `executor-visualization.md` resolves a selected reference to one SVG plus its family branch. Read each reference once per valid context. -> Read only the role core, always-on construction references, exact locked detail files, and conditionally triggered modules below. The selection indexes remain planning-only. A preset reads its one locked file. For `custom`, read only the exact bases named by optional `mode_references` / `visual_style_references`: apply one under the corresponding behavior, or synthesize several by their stated contributions. If absent, read no preset file and follow the behavior directly. Do not infer adjacent bases, glob a catalog, or blend unselected identities. +**Context validity**: reuse the retained Design Spec and lock for every page while the context is unchanged and uncompacted; do not reread or poll them. A fresh, resumed, restarted, compacted, or externally changed context rereads `design_spec.md`, then `spec_lock.md`, once, plus triggered references and the latest completed SVG when mid-deck ([`failure-recovery.md`](governance/failure-recovery.md)); on local uncertainty consult the retained lock, then only the owning Design Spec fragment — sources supply facts only, and the Design Spec wins a conflict. A bounded same-context repair that preserves roster/order/identity/communication needs only the affected fragment readback plus `project_manager.py validate`. **Five-page lock re-read**: after P05, P10, P15, … when another page follows, read `spec_lock.md` in full once before the next page — a pure re-anchor of palette, typography, icon style, and `page_rhythm` under long context, with no checker run, no output, no pause, and no repair loop; an external change found here follows the recovery branch. **Hard rule — exact page roster**: `design_spec.md §IX` is the ordered queue — one final slide per entry, same id and order; never add, drop, merge, split, or reorder while drawing. A continuous run may first repair the affected §IX blocks and `page_rhythm` rows and rerun `validate` while the count stays inside the Stage-1 confirmed range; leaving that range reconfirms Stage 1. §IX is preferred wording and semantic authority, adapted only under `executor-base.md` §2.1's content-vs-expression contract, with sources read only for verification. **Missing `spec_lock.md` or `design_spec.md`** → stop and report the missing gate artifact; recover through [`failure-recovery.md`](governance/failure-recovery.md) §3; a missing field in an existing lock → its §2. When §X records a literal script, read the frozen `notes/total.md` once before P01 and design each visible state around its segment. Trust the latest `analysis/image_analysis.csv` (rerun `analyze_images.py` if `images/` changed; an empty folder means no inventory). `page-context` is a diagnostic only ([`artifact-ownership.md`](../references/artifact-ownership.md) §1). -| Deterministic trigger | Additional references | -|---|---| -| `pptx_structure.mode: structured` | `executor-structured.md` + `pptx-structure-interface.md` | -| Selected §VII / `page_visualizations` Chart/Table `family/key`, or a legacy `page_charts` row resolving to a live Chart/Table SVG | `executor-visualization.md` + the selected Chart/Table branch | -| Actual value-driven geometry, including mini/inset charts and sparklines | `executor-chart.md` | -| Actual row × column fact grid | `executor-table.md` | -| Used preset pattern fill, or independent Chart/Table with §IX `<object-key>=yes` | `native-data-interface.md` before that object | -| §IX or current page content contains mathematical notation that may require native math | `native-formula.md` before choosing ordinary text, inline native math, or block native math | -| §IX or current page content requires an external or same-deck click hyperlink | `native-hyperlinks.md` before authoring its inline or whole-object SVG anchor | -| `spec_lock.md images` / §VIII has an image row, or the template has bundled images | `executor-image.md` + `image-layout-spec.md` + `image-layout-patterns.md` + `svg-image-embedding.md` | -| At least one placed image is `Status: Sourced` or its filename has an `image_sources.json` record | `executor-web-image.md` after the image branch | -| §I records recorded/self-running/video delivery, or §X records a final/literal narration script | `video-design.md` before the first SVG; retain it through notes/motion handling | -| All SVG pages and SVG quality gates are complete, and the effective Speaker Notes outcome in `design_spec.md §I` is enabled | `executor-notes.md` before generating speaker notes | +**Design Parameter Confirmation (Mandatory)**: before the first SVG, output one confirmation listing the compact communication objective, canvas dimensions, body font size, color scheme (primary/secondary/accent HEX), font plan, the per-role calibration table from `python3 ${SKILL_DIR}/scripts/text_measure.py calibrate <project_path> --outline` (every lock role: family, size, CJK and Latin ≈ chars per 100 px, and the longest planned §IX line per role in px — the checker's own estimator with wrapping headroom, written to `validation/text_calibration.json`), and the live-preview URL from the launcher below. If the preview failed to launch, say so here rather than proceeding silently. -No branch is loaded by analogy. For each page, after §IX content/communication -but before geometry, apply [`executor-base.md`](../references/executor-base.md)'s -mandatory Structure decision with the already-loaded -`executor-structure.md`. `no` stays on the shared base; `yes` applies that -grammar without another load gate. -Create no catalog/lock/artifact. Chart/Table selection neither replaces this -decision nor locks geometry/native readiness. +**Live Preview Auto-Startup (Mandatory)**: before the first SVG, start the editor and keep it running through Step 7: -**Design Parameter Confirmation (Mandatory)**: before the first SVG, output key design parameters from the spec (canvas dimensions, color scheme, font plan, body font size). See executor-base.md §2. - -**Live Preview Auto-Startup (Mandatory)**: before the first SVG, automatically start the browser editor in live mode and keep it running continuously through Executor + Step 7 export: ```bash python3 ${SKILL_DIR}/scripts/svg_editor/server.py <project_path> --live --daemon ``` -- Start when Executor begins; `svg_output/` may be empty. Default: first free port from `6060`; `--port N`: strict bind. Read the actual URL from output or `<project_path>/live_preview/lock.json`. -- Before the first SVG, report that URL or the launch failure; never claim an unavailable preview. -- Run it as a long-running side process/session; do not wait for it to exit before generating SVG pages. Do not wait for user confirmation after startup. -- **Service must keep running** until one of: (a) the user clicks **Exit preview** in the browser, or (b) the user explicitly asks in chat to stop it. Generation continues even if the user closes the editor. -- **Do NOT read or apply submitted annotations during generation.** Users may annotate at any time, but Executor proceeds without touching them. The window to apply annotations opens only after Step 7 completes — see [`workflows/stages/live-preview.md`](stages/live-preview.md). -- The editor also supports **staged direct edits** (text content + SVG element attributes previewed immediately, then written to `svg_output/` only when the user clicks **Apply changes**; `Ctrl+Z` / Undo drops staged edits) alongside annotation; re-export stays chat-driven. Full scope and editor details: see [`workflows/stages/live-preview.md`](stages/live-preview.md) Notes. -**Conditional reference reads**: `executor-structured.md` owns template specs -and prototypes. `executor-visualization.md` resolves a selected canonical or -legacy value; read only its returned SVG plus applicable family branches. Read -each full reference once per valid context and reread only after change/context -invalidation. Flat routes skip template reads; never substitute summaries, -sidecars, or guessed family paths. +Default first free port from `6060` (`--port N` binds strictly); read the URL from output or `<project_path>/live_preview/lock.json` and report it — or the launch failure — before the first SVG. It is a side process: never wait for it or for user confirmation, and keep it running until the user clicks **Exit preview** or asks in chat. Do not read or apply submitted annotations during generation; that window opens after Step 7 ([`live-preview.md`](stages/live-preview.md), which also describes staged direct edits). -> Image facts: trust the latest `analysis/image_analysis.csv` from the Step 4 inventory read or the Step 5 post-acquisition refresh. If `images/` changed since, re-run `python3 ${SKILL_DIR}/scripts/analyze_images.py <project_path>/images` before layout; if the folder is empty, use no image inventory and ignore a stale CSV. +> ⚠️ **Main-agent only**: SVG generation stays in the current main agent — page design depends on full upstream context. Cadence: P01 → first-page gate → remaining pages → final gate, in one context, no batches or other mid-run checker calls; reload under Context validity above after context invalidation. -**Page-context**: use the read-only projector only for the diagnostic/telemetry triggers in Executor §2.1, never as a routine pre-page load. +**Visual Construction Phase**: generate pages sequentially into `<project_path>/svg_output/`. Each SVG carries the slide's complete visible design (a JSON-first Chart/Table is the sole exception: inline JSON authoritative, visible subtree an approximate preview). Native shapes follow [`native-shape-authoring.md`](../references/native-shape-authoring.md), loaded at the first contour beyond basic primitives while the preset vocabulary is read before page one: independent atoms first, Merge Shapes only when contour semantics require it, freeform last. `mirror|layout` pages start from the complete `page_layouts` SVG and preserve inherited visuals, root identity, atoms, and slots (strict keeps the contract; `layout` may reflow carrier text inside unchanged slot bounds; adaptive uses a Strategist-declared Layout; a required atom or slot change returns upstream, and Executor never edits `spec_lock.md`); `style`, free-design, and brand-only pages are flat per `executor-base.md` and [`semantic-svg.md`](../references/semantic-svg.md). -> ⚠️ **Main-agent only**: SVG generation MUST stay in the current main agent — page design depends on full upstream context. Do NOT delegate to sub-agents. -> ⚠️ **Generation rhythm**: P01 → first-page gate → remaining pages (one page gate per first-exercised `not-exercised` item) → final gate. After context invalidation, reload under §2.1 before continuing. +**Motion-ready image composition**: only when an explicit user motion instruction, an enabled Custom Animations outcome in §I, or an existing `animations.json` activates custom motion, evaluate §IX `Motion suggestion` rows and author any in-slide image states or cross-slide continuity now under [`executor-image.md`](../references/executor-image.md), each revealable or continuing Slide-local unit in a descriptive direct-root `<g id>`. Effects, pairing, order, and timing stay in the custom stage after the final gate; a suggestion alone activates nothing; deterministic Morph needs the continuing object as a direct-root group on both pages. -**Visual Construction Phase**: generate SVG pages sequentially, one at a time, in one continuous pass → `<project_path>/svg_output/` +**First-page gate (Mandatory)** — after the first SVG, before page 2: -Each completed SVG MUST contain the slide's complete visible design; export never reaches back to templates or planning artifacts for omitted visible objects. A Chart/Table marked `data-pptx-native-authority="json"` is the sole object-local exception: its inline JSON is authoritative and its visible subtree is an approximate derived preview. Notes, animation, narration, transitions, and direct native-PPTX workflows remain separate. Native shapes are Executor-local capabilities: follow [`native-shape-authoring.md`](../references/native-shape-authoring.md), read the full preset vocabulary before page one, prefer independent native atoms, use Merge Shapes only when contour semantics require it, and use freeform last. Diagram relationships follow the same Shape-first gate; never infer a preset from contour similarity. - -**Motion-ready image composition**: Only when an explicit user motion -instruction, the effective Custom Animations outcome in `design_spec.md §I` is -enabled, or an existing `animations.json` activates custom motion, evaluate §IX `Motion suggestion` -rows. If the adopted motion depends on distinct in-slide image states or -cross-slide image continuity, author those visible states now under -[`executor-image.md`](../references/executor-image.md). Give each independently -revealable or continuing ordinary Slide-local unit a descriptive direct-root -`<g id>`; structured atoms/slots retain their declared boundaries and are -targetable only when that contract permits. Do not defer required visible -content or reshape structure for the later stage. This is SVG preparation, not -early animation authoring: effects, pairing, order, and timing remain in the -conditional custom stage after the final SVG quality gate and any enabled -speaker-note pass. A Motion suggestion alone does not activate preparation or -custom animation. A page-transition-only request requires no extra visible -layer; deterministic Morph still needs the continuing object as a direct-root -group on both pages. - -`template_reuse_scope: mirror|layout` pages MUST start from the complete `page_layouts` SVG and preserve inherited visuals, root Master/Layout identity, atoms, and slots. Strict keeps that contract; `layout` may apply authorized carrier text/tspan reflow within unchanged slot bounds. Adaptive uses a Strategist-declared Layout. If construction requires fixed-atom or slot topology/bounds changes, return upstream for plan/lock repair and validation; Executor never edits `spec_lock.md`. `mirror` changes only permitted text while preserving ordinary text/tspan topology/attributes. A JSON-first Chart/Table preserves marker id/kind/authority, metadata schema/bounds, and structure; its preview children may regenerate from the same JSON. `style` follows the flat rule below. - -`template_reuse_scope: style`, Style-only, free-design, and brand-only pages use -`pptx_structure.mode: flat`. Style supplies no prototype mappings; beside -Layout/Deck it changes only Direction/method and follows that structure plan. -Draw the complete flat page as ordinary Slide-local SVG. Omit -`pptx_masters` / `pptx_layouts` / `page_pptx_layouts`, root Master/Layout -identity, layers, and placeholders; group logical content with top-level -`<g id>`. Export creates one project Master plus Blank Layout, applies locked -theme defaults, removes stock placeholders/Layouts, retains standard -date/footer/slide-number hooks, and never promotes/deduplicates page content. - -Do not duplicate specialized identity with `data-pptx-role`. Add it only to structural page-frame objects whose package, page-number, or animation behavior is not already expressed by `data-pptx-layer`, `data-pptx-placeholder`, or `data-pptx-replace-with`; such an element needs a stable unique `id`. Do not add generic content roles to ordinary titles, body text, cards, KPIs, diagrams, charts, icons, or images. Full contract: [`references/semantic-svg.md`](../references/semantic-svg.md). - -**First-page gate (Mandatory)** — after the **first** SVG page, before drawing page 2: ```bash python3 ${SKILL_DIR}/scripts/svg_quality_checker.py <project_path> \ --canonical-authoring --stage first-page --json ``` -Run the command unfiltered (no `tail`/`head`/`grep`). Review the complete P01 issue set from that one run before editing. Select any advisory warnings worth addressing, fix all blocking errors and selected warnings in one consolidated edit pass, then perform one verification rerun. If verification still fails, treat its complete output as the next batch and repeat the same review → consolidated edit → single verification cycle; never check between individual fixes. If the terminal output itself is truncated, read only the relevant issue arrays from `validation/svg_quality_first_page_report.json`; do not launch another checker run for discovery. -**Mandatory — read P01 as a method sample, then emit the classification before editing**: the gate validates how the remaining pages will be authored, not only this page. - -| Signal | Reading | -|---|---| -| Two or more issues share a category and direction | Method-level bias — resolve it to the authoritative rule before P02; a correction fitted to the observed offset only patches this sample. For text extents that rule is the shared estimator, exposed as `python3 ${SKILL_DIR}/scripts/text_measure.py measure|wrap|box` — calibrate each role once; measure only lines near a limit (`--stdin` batches) | -| One isolated issue tied to this page's structure | Page-local — fix and continue | -| A recurring element appears for the first time (page furniture, caption format, section numbering, accent discipline) | It will be copied to every later page — confirm its semantics now | - -Emit one line before the consolidated edit: +Run unfiltered, review the complete P01 issue set, fix every blocking error plus selected warnings in one consolidated pass, verify once; a still-failing verification is the next batch. If terminal output is truncated, read only the issue arrays from `validation/svg_quality_first_page_report.json`. The gate validates the method, not just the page — emit one line before editing: ``` gate-signal: method=<rule resolved, or none> | page-local=<count> | not-exercised=<list> ``` -`not-exercised` names what P01 could not test — a cover typically omits multi-line text, columns, charts, image captions, and data objects. Carry every resolved rule forward as arithmetic. +| Signal | Reading | +|---|---| +| Two or more issues share a category and direction | Method-level bias — resolve to the authoritative rule before P02 (for text extents: correct the per-role calibration table — rerun `python3 ${SKILL_DIR}/scripts/text_measure.py calibrate <project_path> --outline` or add the missing `--role` — then every later page estimates by that arithmetic and measures nothing); a correction fitted to the observed offset patches only this sample | +| One isolated issue tied to this page's structure | Page-local — fix and continue | +| A recurring element appears for the first time (furniture, caption format, section numbering, accent discipline) | It will be copied to every later page — confirm its semantics now | -**Mandatory — first-exercise gate**: the first page exercising a listed item runs `python3 ${SKILL_DIR}/scripts/svg_quality_checker.py <project_path> --canonical-authoring --stage page --page <svg>` once (items first exercised together share it), fixes blocking items, then continues. Every other page runs without checker calls. +`not-exercised` names what P01 could not test (a cover typically omits multi-line text, columns, charts, captions, data objects); carry each resolved rule forward as arithmetic. Every later page runs without checker calls; a listed item first exercised later is held to the carried-forward rule and caught by the final gate. + +**Quality Check Gate (Mandatory)** — only after every planned SVG exists, before annotations and speaker notes: -**Quality Check Gate (Mandatory)** — only after every planned SVG exists, BEFORE annotation handling and speaker notes: ```bash python3 ${SKILL_DIR}/scripts/svg_quality_checker.py <project_path> \ --canonical-authoring --stage final --json ``` -- **MUST**: Before this gate, every §IX `Native-ready` entry `<object-key>=yes` already has one matching draw-time marker group and JSON metadata child; `=no` and incidental microvisuals remain ordinary SVG. A legacy bare `yes|no` is readable only when that page has exactly one eligible object; it never derives from §VII. -- **Authority gate**: JSON-first Chart/Table validates inline schema/bounds; its preview has no freshness authority. SVG-first native-ready markers require a current `data-pptx-fallback-sha256`, stamped after SVG/JSON synchronization. Missing/stale baselines block canonical/native export, not fallback export. -- Run the command unfiltered (no `tail`/`head`/`grep`). One invocation already scans every page and reports the complete issue set. -- On failure, review all `blocking` errors and all advisory warnings from that run before editing. Choose which warnings merit work, fix every blocking error and the selected warnings in one consolidated edit pass, then perform one verification rerun. If it still fails, its complete output begins the next batch cycle; never run the checker between individual fixes or use repeated invocations to discover one next issue at a time. If terminal output is truncated, extract only `categories.blocking.issues` and, when needed, `categories.introduced.issues` from the report written by that same run. -- Every `warning` is advisory and non-blocking: do not return the page for mandatory modification, do not auto-normalize user-authored compatible syntax, and do not require an acknowledgement/disposition line. Recommendation warnings identify the generated-SVG default; fidelity/quality warnings may be reported when material, but the existing input may ship unchanged. If a condition must be corrected before release, the checker must classify it as an `error`, not a `warning`. -- The same rule applies to structured-template warnings (empty/framing-only Layout, bare Master, duplicate layout keys): they may guide an optional template cleanup, but warnings alone never fail the quality gate. Flat `style`, free-design, and brand-only routes still rely on their existing hard errors for invalid structure metadata or incomplete required locks. -- Run against `svg_output/` (not after `finalize_svg.py` — finalize rewrites SVG and masks violations). -- The JSON report is written to `validation/svg_quality_report.json`. `inherited` prototype diagnostics and `source-import` compatibility losses are informational provenance; only changed/new warnings remain `introduced`, and all release-blocking failures remain `blocking`. -- **Hard rule — token-safe report handling**: On a successful checker run, use the exit status and terminal summary as gate evidence. Do not open, `cat`, or otherwise load the complete JSON report into model context. Read it only for failure investigation, an explicit audit request, or a field absent from stdout; extract only the required field(s). -**Logic Construction Phase (conditional)**: after the SVG quality gate passes, -when the effective Speaker Notes outcome in `design_spec.md §I` is enabled, load -[`executor-notes.md`](../references/executor-notes.md). When the prepared final -narration branch already created `notes/total.md`, validate its exact segments -against every information-bearing final SVG group and repair the visual page or -upstream plan on mismatch; never rewrite the script. Otherwise ground each -page's narration in its final SVG and generate complete speaker notes → -`<project_path>/notes/total.md`. When the outcome is `disabled`, do not load the -notes branch and do not require or create `notes/total.md`. +- Before the gate, every §IX `Native-ready` `<object-key>=yes` has its draw-time marker group and JSON child; `=no` and incidental microvisuals stay ordinary SVG (a legacy bare `yes|no` is readable only when the page has exactly one eligible object). JSON-first Chart/Table validates inline schema/bounds; SVG-first markers need a current `data-pptx-fallback-sha256`, stamped after synchronization — missing or stale baselines block canonical/native export, not fallback export. +- Run unfiltered against `svg_output/` (never after `finalize_svg.py`, which masks violations); one run reports every page. On failure review all `blocking` errors and advisory warnings, fix every error plus the selected warnings in one consolidated pass, verify once; never check between individual fixes. If output is truncated, extract only `categories.blocking.issues` (and `categories.introduced.issues` when needed) from that run's `validation/svg_quality_report.json`, where `inherited` and `source-import` are provenance and `introduced` holds changed/new warnings. +- Every `warning` is advisory — no mandatory modification, no auto-normalizing user syntax, no disposition line; structured-template warnings (empty/framing-only Layout, bare Master, duplicate layout keys) guide optional cleanup only. A condition that must be corrected before release is an `error`. +- **Hard rule — token-safe report handling**: on success use the exit status and terminal summary; never `cat` the complete JSON into context. Read it only for failure investigation, an explicit audit, or a field absent from stdout. -**✅ Internal checkpoint — execution complete**: verify live preview timing, -the P01 method gate, uninterrupted remaining-page generation, consolidated -repair of any complete failure set, exact §IX roster coverage, one-frame prose -wrapping, a final checker result of 0 errors, and `notes/total.md` only when -speaker notes are enabled. Do not print this checklist. Run the applicable -conditional gates below, then proceed to Step 7 under the compact status rule -above. +**Mandatory — final carrier-receipt review**: compare the checker's `[CARRIERS]` summary (detail under `files[].info.carrier_receipt`) with the retained page jobs, resource roles, and running geometry signatures. Counts and diversity are not quotas; when the facts contradict an active decision — an adopted preset absent, a directional / step / flowchart relationship drawn as a hand path or polygon where `executor-base.md` §3.0 names a preset, a primary image reduced to a minor frame, unrelated jobs collapsing to one neutral construction — read only the affected rows, repair those pages in one pass, and rerun the final checker. **Absence needs a reason**: when the receipt shows a deck-wide zero — `Presets: (none)`, or `inline emphasis 0`, `gradients 0`, or `filters 0` on the `Effects:` line — or fewer pages carrying a preset or connector than pages whose §IX `Relationships` line names `order` / `link` / `parent` / `membership` — or the `Presets:` line names no carrier-and-field contour — answer one line per absent family or per such page: what carries that job instead, and why it serves the reader better — for presets, one line per job the family serves, not for arrows alone: carrier and field (snipped or one-sided rounded rectangles, plaque, bevel, polygons, pie / arc / donut, frames, corners, folded corner, trapezoid, parallelogram, and `native-shape-authoring.md` §7 modelled forms), direction and sequence (arrows, chevrons, flow nodes), grouping and ownership (brackets, braces, frames, plaques), emphasis and annotation (callouts, badges, banners, stars). The style, speed, restraint, "text was enough", or "it is editable anyway" are not answers; a family or page without one is repaired where the page job calls for it, then the checker reruns. Choosing not to use a device is valid — only an unstated reason is not. -> **Chart pages?** If this deck contains data charts, run the [`verify-charts`](stages/verify-charts.md) quality-gate stage before Step 7 to calibrate coordinates. Skip if no chart pages. +**Logic Construction Phase (conditional)**: when the effective Speaker Notes outcome in §I is enabled, load [`executor-notes.md`](../references/executor-notes.md): validate a frozen `notes/total.md` against every information-bearing final SVG group (repair the page or the plan, never the script), or otherwise ground each page's narration in its final SVG and write `notes/total.md`. When disabled, load nothing and create no notes. -> **Visual self-check (opt-in)?** If the user explicitly asked for a per-page visual re-pass on the SVGs ("跑一下视觉自检 / 视觉回看", "visual review", "check pages visually", etc.), run the [`visual-review`](stages/visual-review.md) quality-gate stage before Step 7. Do NOT run it by default and do NOT recommend it based on inferred model capability or deck size — trigger is user request only. +**✅ Internal checkpoint** — preview launched in time, P01 method gate, uninterrupted remaining pages, consolidated repair, exact §IX coverage, one-frame prose, final checker 0 errors, `notes/total.md` only when enabled. Do not print. Then run the applicable conditional gates and proceed to Step 7. -> **Motion execution (conditional)?** Visible-layer preparation belongs to the -> main SVG pass above. An existing `<project_path>/animations.json` always runs -> [`customize-animations`](stages/customize-animations.md) to validate and -> resolve preserve/adjust/replace/suppress intent before export. Without a sidecar, run -> the custom stage only for an explicit per-slide/per-object motion request or -> when the effective Custom Animations outcome in `design_spec.md §I` is -> enabled; §IX `Motion suggestion` rows inform that active pass but never -> trigger it alone. A deck-wide request loads -> [`animations.md`](../references/animations.md) and resolves Step 7.3 flags -> without activating the custom stage. Otherwise keep the exporter defaults -> (`fade` page transition, per-element animation `none`) and load no motion -> reference. Strategist owns the communication purpose; Executor owns exact -> native effects, options, order, timing, and whether a non-literal suggestion -> should simplify to `none`. Never add motion for coverage or variation. -> Sound is not a Strategist resource: do not select or sync it during Steps -> 3–6 and never write a sound id/path into `design_spec.md` or `spec_lock.md`. -> Any optional cue is selected only after the visual motion solution is final, -> under [`animations.md`](../references/animations.md) §2.2. +> **Chart pages?** Run [`verify-charts`](stages/verify-charts.md) before Step 7 to calibrate coordinates; skip without chart pages. +> +> **Visual self-check (opt-in)?** Run [`visual-review`](stages/visual-review.md) before Step 7 only when the user explicitly asked for a per-page visual re-pass ("跑一下视觉自检 / 视觉回看", "visual review", "check pages visually"); never by default, on inferred model capability, or on deck size. +> +> **Motion execution (conditional)?** An existing `animations.json` always runs [`customize-animations`](stages/customize-animations.md) before export. Without a sidecar, run it only for an explicit per-slide/per-object request or an enabled Custom Animations outcome in §I (§IX suggestions inform it, never trigger it); a deck-wide request loads [`animations.md`](../references/animations.md) and resolves Step 7.3 flags instead; otherwise keep `fade` / `none` and load nothing. Executor owns effects, options, order, timing, and simplification to `none`; never add motion for coverage. Sound is never a Strategist resource: no id or path in `design_spec.md` / `spec_lock.md`, and any cue is selected only after the motion solution is final under `animations.md` §2.2. --- ### Step 7: Post-processing & Export -🚧 **GATE**: Step 6 is complete; `svg_output/` contains every final page, all -required conditional quality gates passed, and the final SVG quality report has -0 errors. When the effective Speaker Notes outcome in `design_spec.md §I` is -enabled, -`notes/total.md` also exists and covers every page; when it is disabled, notes -artifacts are not gate requirements. +🚧 **GATE**: Step 6 complete — every final page in `svg_output/`, all conditional gates passed, final report 0 errors, and `notes/total.md` covering every page when Speaker Notes is enabled. -🚧 **Image readiness GATE**: When any required resource row is `Needs-Manual`, every expected file and derived slice output MUST exist under `<project_path>/images/` before the first active Step 7 sub-step. If any file is absent, pause and list the exact filenames; do not run `finalize_svg.py`, `svg_to_pptx.py`, or any other export path, and never ship the dashed placeholder. After the files arrive, rerun `analyze_images.py`, replace each dashed placeholder in `svg_output/`, reconcile every `no-crop` container to the measured native ratio, then rerun the final SVG quality check so the gate covers the changed sources. +🚧 **Image readiness GATE**: when any required row is `Needs-Manual`, every expected file and slice output must exist under `images/` before the first Step 7 command. If any is absent, pause and list the exact filenames; never run `finalize_svg.py` or `svg_to_pptx.py`, never ship the dashed placeholder. When the files arrive, rerun `analyze_images.py`, replace each placeholder, reconcile every `no-crop` container to the measured native ratio, and rerun the final checker (which then closes each terminal §VIII row through `spec_lock.md images`, the exact file, and a real `<image href>`, and validates Sourced provenance, visible credits, and per-placement pixel scale under `meet` / `slice` / `none`). -After the separate readiness gate above has supplied every required manual file, the final SVG quality check closes each usable terminal §VIII row through `spec_lock.md images`, the exact locked file, and a real `<image href>`; it rejects unplanned/wrong-path references and also validates Sourced provenance/license records, image-specific visible credits, and effective per-placement pixel scale under `meet` / `slice` / `none`. +**Hard rule — strict serial commands**: one command at a time, each in its own invocation; enter the next sub-step only after the current one exits successfully and its success criterion holds. On failure, repair the owning source artifact and resume from the failed sub-step ([`failure-recovery.md`](./governance/failure-recovery.md)); never restart planning unless its source changed. -**Failure recovery**: On a command failure, repair the owning source artifact and resume from that failed sub-step per [`failure-recovery.md`](./governance/failure-recovery.md). Do not restart planning unless its owning source changed. - -**Hard rule — strict serial commands**: Run the following commands one at a time. Do not combine them in one code block or shell invocation. Enter the next sub-step only after the current command exits successfully and its success criterion is true. - -#### Step 7.1 — Split Speaker Notes - -Run this sub-step only when the effective Speaker Notes outcome in -`design_spec.md §I` is enabled: +#### Step 7.1 — Split Speaker Notes (only when enabled) ```bash python3 ${SKILL_DIR}/scripts/total_md_split.py <project_path> ``` -**Success criterion**: When enabled, per-slide Markdown files exist under -`<project_path>/notes/` and cover every published slide. When disabled, skip the -command and proceed directly to Step 7.2. +**Success criterion**: per-slide Markdown files under `notes/` cover every published slide. When disabled, skip to 7.2. #### Step 7.2 — Build the Self-Contained SVG Preview @@ -834,65 +316,24 @@ command and proceed directly to Step 7.2. python3 ${SKILL_DIR}/scripts/finalize_svg.py <project_path> ``` -**Success criterion**: `<project_path>/svg_final/` contains one self-contained preview SVG for every published slide. This optional derived preview does not replace `svg_output/` as the native-export source, and its absence never blocks Step 7.3. +**Success criterion**: `svg_final/` holds one self-contained preview per slide. Its absence never blocks 7.3. #### Step 7.3 — Export the Native PPTX -Choose exactly one notes mode: - | Effective decision | Command | |---|---| | Speaker Notes `enabled` | `python3 ${SKILL_DIR}/scripts/svg_to_pptx.py <project_path>` | | Speaker Notes `disabled` | `python3 ${SKILL_DIR}/scripts/svg_to_pptx.py <project_path> --no-notes` | -Append `--native-charts-and-tables` only for an explicit editable PowerPoint -Chart/Table delivery decision. Templates, markers, semantic tables, and imported -charts never activate it. Without the flag, Chart/Table uses its SVG fallback; -formula native behavior remains intrinsic. +Append `--native-charts-and-tables` only for an explicit editable Chart/Table delivery decision (markers, templates, semantic tables, and imported charts never activate it; formulas are always native). Motion: with a preserved or produced `animations.json`, keep the base command — the exporter reads the sidecar; append the resolved [`animations.md`](../references/animations.md) flags for a deck-wide setting — explicit flags override the corresponding sidecar default/slide fields while group overrides remain; an explicit Custom Animations disable keeps the sidecar and appends `-a none`, an explicit all-motion disable uses `--no-animations`, and final Stage-2 `false` does neither. Sound: after the motion solution is final, run the optional pass in `animations.md` §2.2 — no cue creates no `sounds/`; a selected cue is synced with `sound_sync.py` (never read from `templates/sounds/` directly) and referenced from the validated sidecar. For a narrated MP4, [`generate-audio`](stages/generate-audio.md) owns the delivery choice; do not add `--conversion-trace` to every base export; an explicit `--conversion-trace <path>` writes to that destination instead of the default. -For deck-wide motion settings, append the resolved flags from -[`animations.md`](../references/animations.md). When the conditional custom -stage preserves or produces `<project_path>/animations.json`, keep the base command above: -the exporter reads the sidecar automatically. Explicit motion flags override -the corresponding sidecar default/slide fields, while group overrides remain -unless `-a none` hard-disables object motion. Exception: explicit Custom -Animations disable keeps the sidecar and appends `-a none`; final Stage-2 `false` -does neither. Only explicit all-motion disable uses `--no-animations`. -Otherwise do not mix deck-wide flags with a sidecar. With no motion input or -sidecar, preserve `fade` / `none`. - -After the transition/object-motion solution above is final, perform the -optional sound pass in [`animations.md`](../references/animations.md) §2.2. -If no concrete cue is selected, do not create `<project_path>/sounds/` or copy -anything from the global library. If a cue is selected, run `sound_sync.py` -for only its namespaced id(s), reference the resulting project-relative `.wav` -path from the sidecar, and validate the sidecar before export. A -transition-sound-only choice may create a sparse `animations.json` here without -activating object choreography; the exporter never reads -`templates/sounds/` directly. - -When downstream delivery is a narrated MP4 and the resolved final motion has -sound cues, `generate-audio` owns the final sound-delivery choice. Its default -automated branch uses a final narrated export with `--conversion-trace`, native -PowerPoint raw-video export, and the verified post-export sound mix. An -explicit real-time slideshow capture instead records PowerPoint playback with -system audio and skips both conversion-trace-only work and sound mixing. Do not -enable conversion trace on every base export only for a possible downstream -branch. - -**Success criterion**: The command exits successfully and produces: - -- `exports/<project_name>_<timestamp>.pptx` -- `validation/<project_name>_<timestamp>.report.json` with `passed` or `passed-with-warnings` package/resource postflight status -- `validation/<project_name>_<timestamp>.trace.json` when bare `--conversion-trace` is enabled; an explicit `--conversion-trace <path>` uses that destination instead - -Before creating the PPTX, the exporter independently requires the current matching `final` quality report; a missing, unreadable, unsupported, non-final, blocking, stale, or unverifiable report exits nonzero. The compact `[POSTFLIGHT]` receipt prints `status`, `quality_gate`, Slide count, warning-category counts, and PPTX/report paths. Disclose material warnings. Do not open or `cat` the complete report on routine success; use targeted field extraction only for failure investigation, an explicit audit request, or information absent from the receipt. A failed report or missing PPTX is not success. Retain its report path for later Generate narration (`deck_motion` handoff). This postflight proves the PPTX package, including native sound relationships; it is not acceptance evidence for a later MP4 audio track. `generate-audio` owns that triggered delivery check. +**Success criterion**: the command exits 0 and produces `exports/<project_name>_<timestamp>.pptx`, `validation/<project_name>_<timestamp>.report.json` with `passed` or `passed-with-warnings`, and `validation/<project_name>_<timestamp>.trace.json` when `--conversion-trace` was enabled. The exporter itself requires the current matching `final` quality report and exits nonzero on a missing, unreadable, unsupported, non-final, blocking, stale, or unverifiable one. Read the compact `[POSTFLIGHT]` receipt (`status`, `quality_gate`, slide count, warning counts, paths), disclose material warnings, and never `cat` the full report on success. Retain the report path for a later `deck_motion` handoff; postflight proves the package, not a later MP4 audio track. ## ✅ Generate PPTX Complete - [x] Image readiness gate passed -- [x] The final carrier receipt was compared with the retained page decisions, and any factual contradiction was repaired without treating counts as quotas -- [x] Notes split completed when enabled; disabled exports used `--no-notes` -- [x] `svg_final/` preview completed +- [x] Carrier receipt compared with the retained page decisions; contradictions repaired without treating counts as quotas +- [x] Notes split when enabled; disabled exports used `--no-notes` +- [x] `svg_final/` preview built - [x] Native PPTX published and postflight report written -- [ ] **Next**: Report the exported PPTX path; when the effective Narration Audio outcome in `design_spec.md §I` is enabled, run [`generate-audio`](stages/generate-audio.md), otherwise run a supporting post-export stage only when its explicit trigger is present +- [ ] **Next**: report the exported PPTX path; when the effective Narration Audio outcome in `design_spec.md §I` is enabled, run [`generate-audio`](stages/generate-audio.md); otherwise run a supporting post-export stage only on its explicit trigger diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/governance/failure-recovery.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/governance/failure-recovery.md index af7e9639..d15b044c 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/governance/failure-recovery.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/governance/failure-recovery.md @@ -4,9 +4,9 @@ description: Cross-route stop/continue governance with a concrete recovery matri # Failure Recovery Governance -Global stop/continue rules for all three top-level routes, plus concrete failure handling for Generate PPTX. Section 2 applies across routes; Sections 1 and 3 apply only to Generate PPTX. Owning route and stage documents may add narrower handling, but must not weaken the global rules or duplicate this matrix. +Global stop/continue rules for all three routes plus concrete Generate PPTX handling. §2 applies across routes; §1 and §3 apply only to Generate PPTX. Owning route and stage documents may add narrower handling but never weaken these rules or duplicate the matrix. -**Hard rule**: A failed required artifact blocks the next gate. A failed convenience surface falls back to the canonical channel and does not block the active route. +**Hard rule**: a failed required artifact blocks the next gate. A failed convenience surface falls back to the canonical channel and does not block the route. --- @@ -14,34 +14,33 @@ Global stop/continue rules for all three top-level routes, plus concrete failure | Failure point | Blocking | Automatic recovery | User intervention | Resume entry | |---|---:|---|---|---| -| Confirm UI launch failure | No | Re-check `confirm_ui/result.json` once, then use chat fallback | No | [`generate-pptx`](../generate-pptx.md) Step 4 chat confirmation | -| Confirm UI wait timeout | No, if no final result yet | Re-check `result.json` once; keep server cleanup mandatory | Only if user still wants the page | Step 4 same stage or chat fallback | -| User explicitly switches from Confirm UI to chat during any stage | Yes until the unresolved current stage is confirmed | Follow [`confirm_ui.md`](../../scripts/docs/confirm_ui.md)'s in-run switch, retain persisted confirmed stages, then continue the current and remaining stages in chat; never relaunch UI | Confirm in chat unless explicitly delegated | Step 4 current chat stage | -| Confirm UI Stage 1 completed then unexpectedly interrupted while UI remains selected | Yes until final Stage 2 is written/confirmed | Read existing Stage 1 `result.json`, derive a fresh `recommendations.stage2.json` without changing Stage 1, then `--wait-only` for final confirmation | Usually no | Step 4 final Stage 2 write/wait | -| Missing final confirmation | Yes | None | User must confirm or change the values | Step 4 final confirmation | -| Final confirmed value or a later explicit user override is missing, changed, substituted, or weakened in `design_spec.md` | Yes | Repair from the retained final-confirmation object plus any newer explicit instruction; only a fresh recovery turn with no retained state reads persisted final evidence once | Only when the effective value genuinely cannot be honored | Step 4 Gate 1 — confirmation fidelity | -| `spec_lock.md` changes confirmed identity or omits a required execution anchor/routing decision | Yes | Re-author the affected lock rows from the completed Design Spec and current context; do not enumerate page-local literals | No unless the Design Spec itself is incomplete | Step 4 Gate 2 — lock context fidelity | -| Execution exposes a missing Strategist-owned role/plan detail | Yes for the affected page | Repair affected Design Spec/lock fragments under [`executor-base.md`](../../references/executor-base.md) §2.1 | Only if confirmed intent changes | Step 4 Gate 1/2 → Step 6 current page | -| Execution context is fresh, resumed, restarted, compacted/summary-only, external, or unknown | Yes until rebuilt | Read complete Design Spec, then lock, once; reload triggered inputs and latest completed SVG when mid-deck | No | Step 6 current page | -| `apply-template-workspace` rejects a legacy or incomplete template contract | Yes | Stop template consumption; create a new current workspace through Create Template from the original PPTX/reference, then return with its exact workspace root | Only when required source evidence or template choices are unavailable | Create Template → Generate PPTX Step 4 Stage 1 (`apply-template-workspace`) | -| Native formula marker validation or LaTeX compilation failure | Yes for the affected page | Repair the marker metadata or source LaTeX and rerun the SVG checker; there is no formula-image fallback | Clarify the intended equation only when the source is ambiguous | Active SVG authoring step | -| AI image generation failure | Default blocks at the recovery decision; Quick does not | Default `auto`: try A → B, then ask once to repair/retry, generate manually, or cancel/replan affected AI images; explicit `api` / `host-native`: retry only that path, then ask the same question. Quick removes the exhausted AI/dependent-slice jobs, replans them with native editable text/SVG or already prepared non-AI assets, and continues | Default chooses one outcome; manual files are still required before export | Default: Step 5 decision → same path, Step 4 affected-plan repair, or Step 7 image readiness gate; Quick: current resource plan | -| Web image search/download failure | No | Adjust query/source per image-searcher rules, then mark `Needs-Manual` if unresolved | Only if the resource is required and no acceptable substitute exists | Step 5 | -| Slice sheet missing | Yes for derived slice rows | Wait for parent sheet; run `slice_images.py`; rerun image analysis | Yes when sheet was manual/offline | Step 5 slice handling / Step 7 image readiness gate | -| Strict-alpha slice failure | Yes for every named output | Return the parent to image preparation; correct an evidenced key/tolerance mismatch, then enlarge cells or split incompatible shape families and regenerate when content reaches an edge. A generated parent never substitutes for its missing slices | Only after the selected automated recovery is exhausted | Quick §2 resource closure / Default Step 5 slice handling | -| Residual `Pending` or `Failed` image row before Executor | Yes | Re-run the owning path; Default AI follows its three-outcome decision and reaches `Needs-Manual` only after manual confirmation; Quick automated AI follows its declared no-AI replan | Only when the owning rule requires a new choice or manual file | Step 5 terminal-state check | +| Confirm UI launch failure | No | Re-check `confirm_ui/result.json` once, then chat fallback | No | [`generate-pptx`](../generate-pptx.md) Step 4 chat confirmation | +| Confirm UI wait timeout | No, if no final result yet | Re-check `result.json` once; server cleanup stays mandatory | Only if the user still wants the page | Step 4 same stage or chat fallback | +| User switches from Confirm UI to chat mid-stage | Yes until the current stage is confirmed | Follow the in-run switch in [`confirm-surface.md`](../../references/confirm-surface.md): keep persisted confirmed stages, continue the current and remaining stages in chat, never relaunch UI | Confirm in chat unless delegated | Step 4 current chat stage | +| Stage 1 completed, then interrupted while UI remains selected | Yes until final Stage 2 is confirmed | Read Stage 1 `result.json`, derive a fresh `recommendations.stage2.json` without changing Stage 1, then `--wait-only` | Usually no | Step 4 final Stage 2 write/wait | +| Missing final confirmation | Yes | None | User confirms or changes the values | Step 4 final confirmation | +| Final confirmed value or later explicit override missing, changed, or weakened in `design_spec.md` | Yes | Repair from the retained final-confirmation object plus any newer explicit instruction; only a fresh recovery turn with no retained state reads persisted evidence once | Only when the value genuinely cannot be honored | Step 4 Gate 1 | +| `spec_lock.md` changes confirmed identity or omits a required anchor/routing decision | Yes | Re-author the affected rows from the completed Design Spec and context; do not enumerate page-local literals | No unless the Design Spec is incomplete | Step 4 Gate 2 | +| Execution exposes a missing Strategist-owned role/plan detail | Yes for the page | Repair the Design Spec/lock fragments under [`executor-base.md`](../../references/executor-base.md) §2.1 | Only if confirmed intent changes | Step 4 Gate 1/2 → Step 6 current page | +| Execution context is fresh, resumed, compacted, external, or unknown | Yes until rebuilt | Read the complete Design Spec, then lock, once; reload triggered inputs and the latest completed SVG when mid-deck | No | Step 6 current page | +| `apply-template-workspace` rejects a legacy or incomplete template | Yes | Stop template consumption; create a new workspace through Create Template from the original PPTX/reference and return with its exact root | Only when source evidence or template choices are unavailable | Create Template → Step 4 Stage 1 | +| Native formula marker validation or LaTeX compilation failure | Yes for the page | Repair the marker or LaTeX and rerun the checker; no formula-image fallback | Clarify the equation only when the source is ambiguous | Active SVG authoring step | +| AI image generation failure | Default blocks at the recovery decision; Quick does not | Default `auto`: try A → B, then ask once to repair/retry, generate manually, or cancel/replan; explicit `api` / `host-native`: retry that path, then ask. Quick removes exhausted AI/dependent-slice jobs, replans with native text/SVG or prepared non-AI assets, and continues | Default chooses one outcome; manual files still required before export | Default: Step 5 decision, Step 4 plan repair, or Step 7 image readiness gate; Quick: current resource plan | +| Web image search/download failure | No | Adjust query/source per image-searcher rules, then `Needs-Manual` if unresolved | Only if required with no substitute | Step 5 | +| Slice sheet missing | Yes for derived slice rows | Wait for the parent sheet; run `slice_images.py`; rerun image analysis | Yes when the sheet was manual/offline | Step 5 slice handling / Step 7 image readiness gate | +| Strict-alpha slice failure | Yes for every named output | Return the parent to preparation; correct an evidenced key/tolerance mismatch, then enlarge cells or split incompatible shape families and regenerate; a parent never substitutes for its slices | Only after automated recovery is exhausted | Quick §2 resource closure / Default Step 5 | +| Residual `Pending` or `Failed` image row before Executor | Yes | Re-run the owning path; Default AI follows its three-outcome decision and reaches `Needs-Manual` only after manual confirmation; Quick follows its no-AI replan | Only when the owning rule requires a new choice or file | Step 5 terminal-state check | | User replaces/adds images after analysis | No | Re-run `analyze_images.py` before reading image facts | No | Step 4/5/6 image-fact read | -| Live preview fails to start | No | Continue generation; report that preview is unavailable | Only if user requires browser preview | Step 6 or `live-preview` Step 1 | -| Live preview closed by user | No | Continue generation | No | Restart through `live-preview` only if requested | -| Browser annotations submitted during generation | No | Defer application until after Step 7 | User asks to apply annotations | `live-preview` Step 2 | -| `svg_quality_checker.py` error | Yes | Review the complete issue set from one unfiltered run; fix all errors and selected warnings in one consolidated edit pass, then perform one verification rerun. If it still fails, use that complete result as the next batch; never check between individual fixes | No unless required asset is missing | Step 6 Visual Construction | -| `svg_quality_checker.py` warning | No | Continue without mandatory modification or acknowledgement; preserve compatible user syntax, and report material fidelity/quality advice when useful | No | Step 6 advisory warning handling | -| Missing `notes/total.md` while the effective Speaker Notes outcome is enabled | Yes | Generate speaker notes before Step 7 | No | Step 6 Logic Construction | -| Step 7 image readiness missing manual files | Yes | None for manual assets; list required filenames and prompts | Yes | Step 7 image readiness gate | -| `total_md_split.py` failure while speaker notes are enabled | Yes | Fix notes format/path, rerun only Step 7.1 | Usually no | Step 7.1 | -| `finalize_svg.py` failure | Yes | Fix SVG/assets, rerun Step 7.2 | Only if source asset is missing | Step 7.2 | -| `svg_to_pptx.py` failure | Yes | If no current matching passing final SVG quality report exists, obtain the complete blocking issue set from the final checker as needed, fix it, rerun the checker against the updated `svg_output/`, and proceed to Step 7.3 only after it reports `passed`; otherwise fix the conversion issue and rerun Step 7.3 | Only if a required artifact is missing | Step 6 final quality gate or Step 7.3 | -| Export succeeds but user wants direct browser edits re-exported | No | Rerun Step 7.2 and Step 7.3 after applied edits | No | Post-export live-preview handling | +| Live preview fails to start / closed by user | No | Continue generation; report unavailability | Only if the user requires browser preview | Step 6, or `live-preview` Step 1 on request | +| Browser annotations submitted during generation | No | Defer application until after Step 7 | User asks to apply | `live-preview` Step 2 | +| `svg_quality_checker.py` error | Yes | Review the complete issue set from one unfiltered run; fix all errors and selected warnings in one consolidated pass, then one verification rerun; a remaining failure is the next batch — never check between individual fixes | No unless a required asset is missing | Step 6 Visual Construction | +| `svg_quality_checker.py` warning | No | Continue without mandatory modification; preserve compatible user syntax, report material advice when useful | No | Step 6 advisory handling | +| Missing `notes/total.md` while Speaker Notes is enabled | Yes | Generate notes before Step 7 | No | Step 6 Logic Construction | +| Step 7 image readiness missing manual files | Yes | None; list required filenames and prompts | Yes | Step 7 image readiness gate | +| `total_md_split.py` failure | Yes | Fix notes format/path, rerun Step 7.1 | Usually no | Step 7.1 | +| `finalize_svg.py` failure | Yes | Fix SVG/assets, rerun Step 7.2 | Only if a source asset is missing | Step 7.2 | +| `svg_to_pptx.py` failure | Yes | Without a current passing final report: get the complete blocking set from the final checker, fix, rerun the checker, proceed only after `passed`; otherwise fix the conversion issue and rerun Step 7.3 | Only if a required artifact is missing | Step 6 final quality gate or Step 7.3 | +| Export succeeds but the user wants browser edits re-exported | No | Rerun Step 7.2 and 7.3 after the edits | No | Post-export live-preview handling | --- @@ -49,50 +48,41 @@ Global stop/continue rules for all three top-level routes, plus concrete failure | Condition | Action | |---|---| -| Required gate artifact missing | Stop at that gate and name the missing artifact. | -| Optional stage not explicitly requested | Do not run it as recovery. | -| Convenience UI/server failure | Fall back to chat or continue without the surface. | -| Derived artifact stale | Regenerate it from its owning source. | -| Required manual artifact missing | Pause and name the exact required artifacts; resume only after they exist. | -| Validation or export failure | Fix the owning source artifact, then rerun the failed operation and affected downstream operations only. | -| Confirmed execution choice cannot be honored | Keep the confirmed requirement visible. Retry the confirmed provider, mode, voice, effect, or path only as its owning workflow allows; if it remains unavailable, stop, request a new decision, or use the owning workflow's declared recovery. Quick's AI-generation exception is an explicit no-AI replan that preserves the communication job; it never substitutes another image source. | +| Required gate artifact missing | Stop at that gate and name it | +| Optional stage not explicitly requested | Do not run it as recovery | +| Convenience UI/server failure | Fall back to chat or continue without the surface | +| Derived artifact stale | Regenerate from its owning source | +| Required manual artifact missing | Pause and name the exact artifacts; resume only after they exist | +| Validation or export failure | Fix the owning source artifact, then rerun only the failed and affected downstream operations | +| Confirmed execution choice cannot be honored | Keep the confirmed requirement visible; retry the confirmed provider, mode, voice, effect, or path only as its owning workflow allows; if still unavailable, stop, request a new decision, or use the owning workflow's declared recovery. Quick's AI-generation exception is an explicit no-AI replan that preserves the communication job and never substitutes another image source | -**Missing values**: For a field in an existing artifact, follow only the exact requiredness, inference procedure, or fixed default declared by its owning schema or workflow; an active omission with no such rule stops at the owning boundary. Empty values, inactive conditional fields, whole artifacts, derived artifacts, and file-format attributes keep their own declared semantics—do not extend a fallback by analogy. Owning rules label their fallbacks with two terms used across this repository: a **declared-inference / declared-procedure fallback** states its missing condition and a bounded procedure that needs no new user decision; a **fixed compatibility default** states the exact fallback value, applied with one warning. +**Missing values**: for a field in an existing artifact, follow only the requiredness, inference procedure, or fixed default declared by its owning schema or workflow; an active omission with no such rule stops at the owning boundary. Do not extend a fallback by analogy to empty values, inactive conditional fields, whole or derived artifacts, or file-format attributes. Two fallback terms are used across the repository: a **declared-inference / declared-procedure fallback** states its missing condition and a bounded procedure needing no new user decision; a **fixed compatibility default** states the exact value, applied with one warning. -**Forbidden — silent downgrade**: Do not skip a required gate because a downstream command might tolerate the missing file, and do not change a confirmed execution value merely to keep the route moving. Fix, pause, request a new decision, or apply an explicit profile-owned recovery at the owning boundary; Quick's documented AI-to-no-AI replan is the narrow exception. +**Forbidden — silent downgrade**: never skip a required gate because a downstream command might tolerate the missing file, and never change a confirmed execution value to keep the route moving. Fix, pause, request a new decision, or apply an explicit profile-owned recovery at the owning boundary. -**Proactive production resolution**: Keep final Stage-2 raw fields as evidence. -Resolve durable outcomes as explicit instruction → final Stage 2 → workflow defaults -`enabled` / `disabled` / `disabled`. Audio raises Notes only when Notes is not -explicitly disabled; an explicit notes-off/audio-on conflict stops at -Generate's one-question dependency gate. Keep raw values unchanged and record -outcomes/provenance only in Design Spec §I, never the lock. +**Proactive production resolution**: keep final Stage-2 raw fields as evidence; resolve durable outcomes as explicit instruction → final Stage 2 → workflow defaults `enabled` / `disabled` / `disabled`. Audio raises Notes only when Notes is not explicitly disabled; an explicit notes-off/audio-on conflict stops at Generate's one-question dependency gate. Record outcomes/provenance only in Design Spec §I, never the lock. --- ## 3. Generate PPTX Resume Pointers -Here, **final confirmation evidence** means either the explicit final confirmation in the current chat or `<project>/confirm_ui/result.json` with `status: confirmed` and `stage: final`. Planning artifacts alone do not prove that the user confirmed their values. After that gate, a newer explicit user instruction may update only its effective production outcome and provenance in the durable Design Spec; resume from the owning step without reopening Confirm UI. - -The UI wait resume entries below apply only while UI remains the selected -surface. A newer explicit chat-surface instruction follows `confirm_ui.md`'s -in-run switch and resumes the unresolved stage in chat without relaunching UI. +**Final confirmation evidence** means the explicit final confirmation in the current chat or `<project>/confirm_ui/result.json` with `status: confirmed` and `stage: final`; planning artifacts alone prove nothing. After that gate, a newer explicit instruction updates only its effective production outcome and provenance in the Design Spec; resume from the owning step without reopening Confirm UI. UI wait entries apply only while UI remains the selected surface; a newer chat-surface instruction follows the in-run switch and resumes in chat. | Last good state | Resume from | |---|---| -| Stage 1 confirmation exists, final Stage 2 is missing or unconfirmed, and UI remains selected | Derive a fresh `recommendations.stage2.json` from confirmed Stage 1 and current inputs without changing Stage 1, then run `confirm_ui/server.py <project> --wait-only` for final confirmation. | -| Final confirmation evidence exists; `design_spec.md` is missing, with or without a surviving `spec_lock.md` | Return to Generate Step 4 and [`strategist.md`](../../references/strategist.md) §6.2; read final evidence once into the fresh context, read [`design_spec_reference.md`](../../templates/design_spec_reference.md), author the complete `design_spec.md` from scratch using that state plus source analysis, and pass Gate 1. Then read [`spec_lock_reference.md`](../../templates/spec_lock_reference.md) and re-author the complete `spec_lock.md` from the audited Design Spec plus current context, replacing any orphan lock. Never reconstruct the Design Spec from an orphan lock or retain orphan-lock choices as authority. | -| Final confirmation evidence exists; `design_spec.md` exists and `spec_lock.md` missing | Return to Generate Step 4; in this fresh recovery context read final evidence once to audit the existing Design Spec, then read [`spec_lock_reference.md`](../../templates/spec_lock_reference.md) and author the complete lock from the audited Design Spec plus current context. | -| Final confirmation evidence and both planning artifacts exist, but Gate 1 fails | In a fresh recovery context read final evidence once, repair `design_spec.md`, then re-author every affected lock row. Do not reopen recommendations or infer a replacement from the current lock. | -| Gate 1 passes but Gate 2 fails | Keep the Design Spec unchanged and re-author only the mismatched lock anchors/routing rows from it plus current context. | -| No final confirmation evidence is available | If `confirm_ui/result.json` proves Stage 1 confirmation, resume at final Stage 2; otherwise restart Step 4 at Stage 1. Do not infer confirmed choices from partial planning artifacts. | -| `design_spec.md` and `spec_lock.md` complete, split mode selected | [`resume-execute`](../stages/resume-execute.md) | -| Images acquired but SVGs not started | [`generate-pptx`](../generate-pptx.md) Step 6 | -| SVGs complete and checker passed; effective Speaker Notes outcome enabled and notes missing | Step 6 Logic Construction | -| SVGs complete; effective Speaker Notes outcome disabled | Run any applicable conditional motion handling, then Step 7.2 and export with `--no-notes` | -| SVGs and enabled notes complete | Step 7.1 | -| Step 7.1 complete, export not complete | Step 7.2 | -| Step 7.2 complete, PPTX not complete | Step 7.3 | +| Stage 1 confirmed, final Stage 2 missing or unconfirmed, UI selected | Derive a fresh `recommendations.stage2.json` from confirmed Stage 1 and current inputs, then `confirm_ui/server.py <project> --wait-only` | +| Final evidence exists; `design_spec.md` missing (with or without a surviving lock) | Step 4 and [`strategist.md`](../../references/strategist.md) §6.2: read final evidence once, read [`design_spec_reference.md`](../../templates/design_spec_reference.md), author the complete Design Spec from scratch, pass Gate 1; then read [`spec_lock_reference.md`](../../templates/spec_lock_reference.md) and re-author the complete lock, replacing any orphan. Never reconstruct the Design Spec from an orphan lock | +| Final evidence exists; Design Spec exists, lock missing | Step 4: read final evidence once to audit the Design Spec, then author the complete lock from it plus context | +| Both planning artifacts exist but Gate 1 fails | Read final evidence once, repair `design_spec.md`, re-author every affected lock row; do not reopen recommendations or infer from the lock | +| Gate 1 passes, Gate 2 fails | Keep the Design Spec; re-author only the mismatched lock rows | +| No final evidence | If `result.json` proves Stage 1, resume at final Stage 2; otherwise restart Step 4 at Stage 1. Never infer confirmed choices from partial artifacts | +| Both planning artifacts complete, split mode selected | [`resume-execute`](../stages/resume-execute.md) | +| Images acquired, SVGs not started | [`generate-pptx`](../generate-pptx.md) Step 6 | +| SVGs complete and checker passed; Speaker Notes enabled, notes missing | Step 6 Logic Construction | +| SVGs complete; Speaker Notes disabled | Conditional motion handling, then Step 7.2 and export with `--no-notes` | +| SVGs and notes complete | Step 7.1 | +| Step 7.1 complete | Step 7.2 | +| Step 7.2 complete, PPTX missing | Step 7.3 | | Browser annotations saved after export | [`live-preview`](../stages/live-preview.md) Step 2 | -**Default - resume at the owning failed step**: Do not restart the planning session or regenerate prior artifacts unless the owning source has changed. +**Default — resume at the owning failed step**: do not restart planning or regenerate prior artifacts unless the owning source changed. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/profiles/beautify-pptx.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/profiles/beautify-pptx.md index f1c60304..5306a8a9 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/profiles/beautify-pptx.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/profiles/beautify-pptx.md @@ -4,172 +4,75 @@ description: Generate profile for 1:1, content-faithful re-layout of an existing # Beautify PPTX (Re-layout) Profile -> Generate profile, not a top-level route. [`edit-native-pptx.md`](../edit-native-pptx.md) keeps a deck's native design and edits selected pages; this profile keeps a deck's content and redoes its layout. +> Generate profile, not a top-level route. [`edit-native-pptx.md`](../edit-native-pptx.md) keeps a deck's native design and edits selected pages; this profile keeps a deck's content and redoes its layout: text verbatim, source palette/fonts as the preselected recommendation (only explicit user requirements or final confirmation override them), layout, hierarchy, whitespace, and visual treatment rebuilt into a new native deck through the SVG pipeline — not a patch over the original. -Re-lays-out an existing `.pptx`: text is preserved **verbatim** and source -palette / fonts are the preselected recommendation. Only explicit user -requirements or final confirmation may override them; never deviate silently. -It rebuilds layout, hierarchy, whitespace, and effective visual treatment into -a new native deck through the SVG pipeline — not a patch over the original. +**Trigger**: the user supplies a `.pptx` and asks to beautify / re-layout / 重新排版 / 美化 while keeping the content — explicit intent plus a provided file, never inferred. -**Trigger**: the user supplies a `.pptx` and asks to beautify / re-layout / 重新排版 / 美化 while keeping the content. Explicit intent + a provided file only; never auto-infer. - -**Hard rule — select one runtime before continuing**: when the same request -also meets [`quick-generate.md`](./quick-generate.md)'s explicit trigger, load -that runtime and do not load `generate-pptx.md`. Otherwise load -[`generate-pptx.md`](../generate-pptx.md) and do not load Quick. The 1:1 -Beautify constraints in this file apply in either runtime. +**Hard rule — select one runtime before continuing**: when the request also meets [`quick-generate.md`](./quick-generate.md)'s explicit trigger, load that runtime and not `generate-pptx.md`; otherwise load [`generate-pptx.md`](../generate-pptx.md) and not Quick. The 1:1 constraints below apply in either runtime. --- ## 1. When to Run -| Pattern | Example | -|---|---| -| Existing `.pptx` + beautify intent | "把这份 PPT 美化一下" / "make this deck look better" | -| Existing `.pptx` + re-layout intent | "重新排版这份 PPT,内容别动" / "re-layout this, keep the wording" | -| Existing `.pptx` + paste-back intent | "重排后我要把元素贴回原来的模板" | +Existing `.pptx` + beautify intent ("把这份 PPT 美化一下" / "make this deck look better"), re-layout intent ("重新排版这份 PPT,内容别动"), or paste-back intent ("重排后我要把元素贴回原来的模板"). -**Hard rule — content is frozen**: every text string from the source is preserved exactly (no add / remove / reword / reorder). Beautification freedom lives only in layout, hierarchy, spacing, and visual rhythm. +**Hard rule — content is frozen**: every source text string is preserved exactly (no add / remove / reword / reorder); freedom lives only in layout, hierarchy, spacing, and rhythm. -**Hard rule — not a patch, not a fill**: this regenerates a native deck through the selected Default or Quick SVG → PPTX runtime. It does **not** edit the source file in place, and it is **not** [`edit-native-pptx`](../edit-native-pptx.md) (which restores unchanged source slides and edits only planned pages). It also does not parse an arbitrary third-party template for text-only substitution (the rejected #53 direction) — it builds every page from scratch. +**Hard rule — not a patch, not a fill**: this regenerates a native deck through the selected runtime; it never edits the source in place, is not Edit Native PPTX, and never parses a third-party template for text-only substitution (the rejected #53 direction). It is the inverse of a `replication_mode: mirror` template ([`executor-structured.md`](../../references/executor-structured.md) §1.1), which keeps layout and edits text. When the authoritative input is a raster page roster whose visible layout must be preserved, activate the Quick-only [`image-to-pptx.md`](./image-to-pptx.md) instead; the two fidelity profiles never compose. -**Distinct from mirror templates**: `replication_mode: mirror` ([`executor-structured.md`](../../references/executor-structured.md) §1.1) keeps layout + visuals verbatim and edits text. Beautify is the inverse — content verbatim, layout redone, source identity recommended unless the user overrides it. - -**Distinct from page-image reconstruction**: when the authoritative input is -an ordered raster page roster and the user wants its visible layout preserved, -activate the Codex-supported, Quick-only -[`image-to-pptx.md`](./image-to-pptx.md) instead. -Beautify requires a semantic source PPTX and deliberately redesigns layout; the -two fidelity profiles never compose. - -**When this profile is wrong — re-architecture belongs to ordinary Generate**: this profile preserves the source's page count and page order 1:1. It is for "keep this deck, just lay it out better". When the user instead wants the original page breakdown reconsidered — merge / split / reorder pages, re-outline the structure, build a *better deck* from the same content rather than a prettier version of the same pages — do not activate this profile. This includes re-pagination for fit: "keep every word but split a crowded page so it reads better" changes page count. Convert the deck with [`ppt_to_md`](../../scripts/source_to_md/ppt_to_md.py) and use ordinary Quick when Quick was explicit, otherwise the Default main pipeline. The deciding question: is the source's page split information to preserve, or just the previous author's structure to improve? Preserve → activate this profile; improve → ordinary Generate in the selected runtime. +**When this profile is wrong**: it preserves page count and order 1:1 — "keep this deck, lay it out better". Merging, splitting, reordering, re-outlining, or re-paginating for fit ("keep every word but split a crowded page") changes the page breakdown: convert with [`ppt_to_md`](../../scripts/source_to_md/ppt_to_md.py) and use ordinary Quick or Default instead. The deciding question: is the source's page split information to preserve, or the previous author's structure to improve? --- ## 2. Inputs -🚧 **GATE**: the user has provided: - -| Input | Required | Notes | -|---|---:|---| -| Source PPTX | Yes | The deck to re-lay-out | -| Beautify scope | Optional | Density / emphasis preference — never content rewrites, and never page drops (v1 is strict 1:1) | +🚧 **GATE**: the source PPTX (required) and an optional beautify scope — density / emphasis preference, never content rewrites or page drops. --- ## 3. Create the Project Workspace -Match the canvas to the source so 1:1 pages and paste-back align. Determine the source aspect first — before the project exists, run `beautify_identity.py <source.pptx>` to **stdout** and read `canvas.aspect` (the formal standard intake bundle is written in Step 4, after `init`) — then select the source-faithful canvas, passing `--format` only for an exact registered match: - -| Source aspect | Canvas | -|---|---| -| ≈1.778 (16:9) | `ppt169` | -| ≈1.333 (4:3) | `ppt43` | -| other | the exact source `width_px`x`height_px`; omit `--format` | +Match the canvas to the source so 1:1 pages and paste-back align: before the project exists, run `beautify_identity.py <source.pptx>` to stdout, read `canvas.aspect`, and pick `ppt169` (≈1.778), `ppt43` (≈1.333), or the exact source `width_px`x`height_px` without `--format`. ```bash -# Default runtime: -python3 ${SKILL_DIR}/scripts/project_manager.py init <project_name> [--format <format>] - -# Quick runtime instead: -python3 ${SKILL_DIR}/scripts/project_manager.py init <project_name> [--format <format>] --quick-generate - -# Both runtimes then import once: +python3 ${SKILL_DIR}/scripts/project_manager.py init <project_name> [--format <format>] # Default +python3 ${SKILL_DIR}/scripts/project_manager.py init <project_name> [--format <format>] --quick-generate # Quick — run exactly one init python3 ${SKILL_DIR}/scripts/project_manager.py import-sources <project_path> <source.pptx> ``` -Run exactly one `init` command: the Quick form only when Quick was selected. - --- ## 4. Extract Identity and Data; Assemble Inventory -Use the standard PPTX intake bundle from Step 3. `project_manager.py import-sources` already writes it under `analysis/` for PPTX-family inputs. If the bundle is missing because the project predates this workflow, generate it once: +`import-sources` already wrote the standard PPTX intake bundle under `analysis/` (for an older project, `pptx_intake.py <project_path>/sources/<source.pptx> -o <project_path>/analysis` once) and ran `ppt_to_md`, so the **frozen content contract** is `sources/<stem>.md` (one source slide per block, in order) and extracted pictures are in `images/` with per-slide binding in `images/image_manifest.json` (`occurrences[].slide_index`); never re-run `ppt_to_md`. -```bash -python3 ${SKILL_DIR}/scripts/pptx_intake.py <project_path>/sources/<source.pptx> -o <project_path>/analysis -``` +**Visual identity** — read `analysis/<stem>.identity.json`: `theme.palette.background` / `text` / `primary` / `accent1..6` and `theme.fonts.title` / `body` (`latin` / `ea` / `cs`, with `scripts` mapping `Hans` / `Hant` / `Jpan` / `Hang` supplemental faces — use the matching script when `ea` is empty) are what the deck declares; `theme.sizes.title` / `body` (pt) are the master placeholder defaults, `body` being the coarse level-1 value that commonly over-reads, with `theme.sizes.body_levels` as the full ramp for reference; `observed.colors` / `observed.fonts` / `observed.sizes_pt` are frequency-ranked samples of run-level overrides (not a complete style resolution — they miss `schemeClr` and inheritance and count chart/gradient fills); `layout_sizes_pt` is a reference fact only; `canvas.aspect` drove Step 3. A hand-edited deck can diverge from `theme`; Step 5 resolves which to use. -**Content + images — already produced by Step 3.** `import-sources` ran `ppt_to_md` on the deck, so the **frozen content contract** is `sources/<stem>.md` (one source slide per block, in order). If the source deck contains pictures, they are already propagated to `images/` with per-slide binding in `images/image_manifest.json` (`occurrences[].slide_index`). Do **not** re-run `ppt_to_md` — it would duplicate the conversion and write images to `analysis/<stem>_files/` instead of `images/`. +**Hard rule — regenerate visuals, do not carry them over**: charts / tables / images are rebuilt from their data in the effective style, never spliced byte-for-byte; data values are frozen, only rendering is the deck's own; pictures are reused but re-laid-out. A user who wants an original element verbatim copies it across themselves. -**Visual identity (theme + observed sample + canvas)**: read `<project_path>/analysis/<stem>.identity.json` (intake prefixes per-deck artifacts by source-file stem). - -| Field | Use | -|---|---| -| `theme.palette.background` / `text` / `primary` / `accent1..6` | the deck's *declared* colors | -| `theme.fonts.title` / `body` (`latin` / `ea` / `cs`; `scripts` maps `Hans` / `Hant` / `Jpan` / `Hang` supplemental faces) | the deck's *declared* fonts; use the matching script when `ea` is empty | -| `theme.sizes.title` / `body` (pt) | the deck's *declared* placeholder sizes (master `txStyles`) — the size a run inherits when it sets no explicit `sz`; `body` is the **level-1** default (coarsest, commonly over-reads) | -| `theme.sizes.body_levels` (pt list) | the full master `bodyStyle` ramp (lvl1..lvl9, e.g. `[32, 28, 24, 20, …]`) — **reference context** so you can read a deeper level than the over-reading level-1, not an auto-seed | -| `observed.colors` / `observed.fonts` (`latin` / `ea`, frequency-ranked) | a usage **sample / frequency hint** — run-level fonts + explicit `srgbClr` fills across slides | -| `observed.sizes_pt` (pt, frequency-ranked) | a usage **sample** of run-level explicit point sizes — the **size the deck actually renders at** when it overrides the placeholder default; the source for the Step 5 `body_size` recommendation | -| `layout_sizes_pt` (pt, frequency-ranked) | **reference fact only**, NOT an auto-seed — the level-1 sizes that the in-use slide layouts' body placeholders declare. Usually empty (decks rely on runs / master) and ambiguous when present; use it as a hint when judging the body size, never as the authoritative seed | -| `canvas.aspect` | drives the Step 3 format choice | - -> Note: `theme` is what the deck declares; `observed` is a frequency sample of run-level overrides (not a complete style resolution — it misses `schemeClr` and master/layout inheritance, and counts chart/gradient fills). A hand-edited deck can diverge from `theme` — Step 5 resolves which to use. - -**Hard rule — regenerate visuals, do not carry them over**: charts / tables / images are rebuilt from their data in the effective style, never spliced in byte-for-byte. This keeps the deck style-consistent and natively editable. **Data values are frozen** (categories / series / cell text / numbers unchanged); only their rendering is the deck's own. Pictures (`ppt_to_md`-extracted files) are reused but re-laid-out — position / crop / size follow the new layout, not the source slot. A user who wants an original element verbatim copies it across themselves. - -**Optional source-SVG visual reference**: when the source deck has complex vector decoration, distinctive page chrome, or a visual language that cannot be captured by `<stem>.identity.json` colors/fonts alone, create a read-only SVG reference package under `analysis/`. This is for understanding style only; it is not a carry-over asset path. +**Optional source-SVG visual reference**: when the deck has complex vector decoration or a visual language colors/fonts cannot capture, build a read-only reference package for understanding style, not a carry-over path: ```bash python3 ${SKILL_DIR}/scripts/pptx_to_svg.py <project_path>/sources/<source.pptx> -o <project_path>/analysis/source_svg_import -python3 ${SKILL_DIR}/scripts/extract_svg_assets.py <project_path>/analysis/source_svg_import/svg-flat \ - --icons-dir <project_path>/analysis/source_svg_import/icons \ - --icon-namespace imported \ - --inplace --id-prefix source_flat --min-decoration-bytes 3000 --clean-stale +python3 ${SKILL_DIR}/scripts/extract_svg_assets.py <project_path>/analysis/source_svg_import/svg-flat --icons-dir <project_path>/analysis/source_svg_import/icons --icon-namespace imported --inplace --id-prefix source_flat --min-decoration-bytes 3000 --clean-stale ``` -Use the cleaned `analysis/source_svg_import/svg-flat/slide_*.svg` files plus `analysis/source_svg_import/svg-flat_vector_asset_inventory.json` in Step 5/Strategist. Extraction is required for inspection when complex vectors exist: it creates a candidate pool the AI can index, compare, and judge for possible reuse without reading every heavy vector body. Read an individual `analysis/source_svg_import/icons/imported/*.svg` only when the cleaned page and inventory indicate that candidate may be promoted or materially affects the style decision. These candidates are analysis artifacts first, not automatic output assets. +Use the cleaned `svg-flat/slide_*.svg` pages and `svg-flat_vector_asset_inventory.json` in Step 5; open an individual `icons/imported/*.svg` only when a candidate may be promoted or materially affects the style decision. By default do not copy candidates into `icons/`, list them as output assets, or preserve decorations byte-for-byte. **Optional reuse gate**: a non-text brand/logo/motif/decorative candidate may be promoted to `<project_path>/icons/imported/` and referenced with `<use data-icon="imported/<name>"/>` — Default lists it in Step 5 and waits for confirmation, Quick decides directly and stops only when frozen facts lack a lossless path; never promote text-bearing groups, charts/tables, page layouts, or dense composites. -Default: do **not** copy these candidates into the project `icons/`, do **not** list them as reusable output assets, and do **not** preserve original vector decorations byte-for-byte in the beautified deck. The Executor still regenerates fresh native shapes from the confirmed plan. - -**Optional reuse gate**: retain source slide, filename, use, and dependencies -for a non-text brand/logo/motif/decorative candidate. Default lists it in Step 5 -and waits; only confirmed candidates are promoted. Quick's current main agent -decides directly and stops only when frozen facts lack a lossless preservation -path. Promote to `<project_path>/icons/imported/` and reference with -`<use data-icon="imported/<name>"/>`; Quick never runs `finalize_svg.py`. Never -promote text-bearing groups, charts/tables, page layouts, or dense composites. - -**Assemble the inventory** — the deterministic join into one per-slide ledger, `analysis/beautify_inventory.json`, the contract Step 5 resolves and Step 7 verifies against: +**Assemble the inventory** — the deterministic per-slide ledger Step 5 resolves and Step 7 verifies against: ```bash -python3 ${SKILL_DIR}/scripts/beautify_inventory.py <project_path>/analysis/<stem>.slide_library.json \ - --images <project_path>/images/image_manifest.json -o <project_path>/analysis/beautify_inventory.json +python3 ${SKILL_DIR}/scripts/beautify_inventory.py <project_path>/analysis/<stem>.slide_library.json --images <project_path>/images/image_manifest.json -o <project_path>/analysis/beautify_inventory.json ``` -If `images/image_manifest.json` does not exist because the source deck has no extracted pictures, omit `--images`. The script joins per slide: `text_blocks` (slot text + geometry), `tables` (cell grid), `charts` (categories + series values), `diagrams` (SmartArt nodes + hierarchy/connections + source layout), and `images` (bound via `image_manifest` `occurrences[].slide_index`, with geometry / `usage_count`). The **frozen source values are inlined**, so the inventory is a self-contained contract, not a pointer back to `slide_library.json`. It emits `ignored` and `needs_confirmation` as **empty arrays** — fill them with judgment before Step 5: +Omit `--images` when no pictures were extracted. It joins `text_blocks`, `tables`, `charts`, `diagrams` (SmartArt nodes + hierarchy + source layout), and `images` (bound through `image_manifest` `occurrences[].slide_index`, with geometry and `usage_count`) per slide with frozen values inlined, and emits empty `ignored` and `needs_confirmation` arrays to fill with judgment: `ignored` — hidden slides/shapes, master-only text, image crop/opacity/rotation/mask; `needs_confirmation` — unreadable SmartArt, combo / dual-axis / waterfall charts, merged-cell or multi-header tables, density outliers (overcrowded or near-empty). SmartArt keeps its wording and relationships and is redrawn as ordinary editable shapes, never regenerated natively. -| Field | Fill with | -|---|---| -| `ignored` | hidden slides / shapes, master-only text, image crop / opacity / rotation / mask (not captured upstream) | -| `needs_confirmation` | unreadable SmartArt data; combo / dual-axis / waterfall charts; merged-cell or multi-header tables; density-outlier pages — **either** overcrowded **or** near-empty / title-only | - -**Mandatory — bounded inventory reads**: the complete inventory is the Step 7 -validation ledger, not the default authoring prompt. Read its compact roster, -then the current page; add geometry only for structural ambiguity: - -```bash -python3 ${SKILL_DIR}/scripts/beautify_inventory.py \ - <project_path>/analysis/beautify_inventory.json --summary -python3 ${SKILL_DIR}/scripts/beautify_inventory.py \ - <project_path>/analysis/beautify_inventory.json --page <N> -python3 ${SKILL_DIR}/scripts/beautify_inventory.py \ - <project_path>/analysis/beautify_inventory.json --page <N> --with-geometry -``` - -During authoring, do not bulk-read either complete file. - -**SmartArt output boundary**: Preserve its extracted wording and semantic relationships, then redraw it through SVG as ordinary editable PowerPoint shapes. Do not attempt to regenerate a native SmartArt object or reuse persisted-drawing text as a second content source. +**Mandatory — bounded inventory reads**: the complete inventory is the validation ledger, not the authoring prompt. Read `beautify_inventory.py <inventory> --summary`, then `--page <N>`, adding `--with-geometry` only for structural ambiguity; never bulk-read either complete file during authoring. ```markdown ## ✅ Extraction Complete - -- [x] `sources/<stem>.md` (from Step 3) holds every source slide's text, in order; extracted pictures, if any, are in `images/` + `images/image_manifest.json` -- [x] `analysis/<stem>.identity.json` has theme + observed identity + canvas aspect -- [x] `analysis/<stem>.slide_library.json` holds chart + table data and SmartArt semantic structure for regeneration -- [x] `analysis/source_profile.json` (multi-deck index) summarizes the source facts in its `decks[]` entry +- [x] `sources/<stem>.md` holds every slide's text in order; pictures in `images/` + `image_manifest.json` +- [x] `analysis/<stem>.identity.json`, `<stem>.slide_library.json`, `source_profile.json` present - [x] `analysis/beautify_inventory.json` ledgers per-slide text / images / data + ignored + needs-confirmation - [ ] **Next**: Step 5 — resolve Beautify decisions in the selected runtime ``` @@ -180,184 +83,75 @@ During authoring, do not bulk-read either complete file. ### Quick branch -When Quick was selected, do not run the Default confirmation flow below. Apply -the same inventory interpretation, source-identity judgment, and body-size -method documented in this section, but make the decisions directly in the -active context. Explicit user requirements remain authoritative; otherwise use -the source identity as the default. Resolve `ignored` and `needs_confirmation` -without creating a confirmation payload, Design Spec, lock, or substitute -plan. If a flagged complex object cannot be regenerated without losing frozen -facts, stop as a hard prerequisite instead of simplifying it. - -**Mandatory — close the transient Quick state before authoring**: before -entering §6 and [`quick-generate.md`](./quick-generate.md) §3, resolve every -row below in the active context: - -| Transient state | Required closure | -|---|---| -| Roster and message | Exact source-order roster and one core message per page | -| Identity and type | Source identity, palette, fonts, body size, and type-role anchors | -| Page geometry | Per-page density, body frame, primary zone, and composition direction | -| Meaning and rhythm | Frozen relationships, reading path, neighbor/section rhythm, and ending | -| Resources and capabilities | Required local resources are usable; triggered notes, motion, audio, image, icon, formula, Chart/Table, and verification outcomes are decided | - -Keep it transient: create no page/resource plan, Design Spec, lock, -confirmation payload, or substitute artifact. Then continue to §6 Quick. +Do not run the Default confirmation flow. Apply the same inventory interpretation, identity judgment, and body-size method directly in active context: explicit user requirements are authoritative, otherwise the source identity is the default; resolve `ignored` and `needs_confirmation` without a payload, Design Spec, lock, or substitute plan; if a flagged complex object cannot be regenerated without losing frozen facts, stop as a hard prerequisite instead of simplifying. **Mandatory — close the transient state before §6**: exact source-order roster and one core message per page; identity, palette, fonts, body size, and type-role anchors; per-page density, body frame, primary zone, and composition direction; frozen relationships, reading path, neighbor/section rhythm, and ending; usable local resources and decided notes / motion / audio / image / icon / formula / Chart-Table / verification outcomes. Keep it transient, then continue to §6 Quick. ### Default branch — Recommend & Confirm -⛔ **BLOCKING**: the scope is not hard-coded — same spirit as the Strategist confirmation stage. Recommend each item below from what the deck actually contains (the Step 4 inventory), present the plan, and **wait for the user to confirm or adjust** before writing any spec. Use Generate Step 4's selected surface for the full visual confirmation; keep the structural-scope decisions in chat. Values confirmed through either channel are honored identically. - -This step has two halves: -- **Visual re-confirm via the selected confirmation surface** — the **full** Step 4 field set (below), seeded from the source so every targeted-confirmation field (canvas, mode, visual style, palette, icons, typography incl. body baseline, image strategy, generation mode) is **pre-filled with the inherited / source-derived default and left editable**. Beautify *recommends* keeping the source's identity, but never removes the user's place to override any field — you may choose not to change a value, but you must not deny the place to change it. This is also where the deck's text size is confirmed: `<stem>.identity.json` now carries size hints — `observed.sizes_pt` (the point sizes the deck actually renders at) and `theme.sizes` (the declared placeholder defaults) — so the `body_size` recommendation **follows the source's own font size** rather than a blind canvas default; the user still confirms or overrides it here. -- **Structural scope** — the inventory-driven list decisions below (ignored, reuse, needs-confirmation, verification level) stay in **chat**; they have no confirm-UI widget. +⛔ **BLOCKING**: recommend each item from what the deck actually contains, present the plan, and wait for the user to confirm or adjust before writing any spec. The **visual re-confirm** goes through Generate Step 4's selected surface with the full field set seeded from the source — every field pre-filled with the inherited default and left editable (recommend keeping identity, never remove the place to override). The **structural scope** stays in chat: | Plan item | Recommend from | Default lean | |---|---|---| -| Identity source | `<stem>.identity.json` `theme` vs `observed` | present **both as color / typography candidates in the selected confirmation surface** so the user picks the one that looks right (theme first when the deck is theme-driven; observed first when slides override heavily) — recommend a default ordering and say why | -| Preserve scope | inventory `text_blocks` / `images` / `charts` / `tables` / `diagrams` | all text verbatim; data values and SmartArt relationships frozen; pictures reused | -| Ignored | inventory `ignored` | name them so the user sees what drops (hidden / master-only text / image crop / rotation) | -| Needs confirmation | inventory `needs_confirmation` | flag complex charts + overcrowded pages explicitly; ask how to handle | -| Verification level | deck size / risk | recommend the Step 7 per-page checks; user sets strictness | +| Identity source | `theme` vs `observed` | Present both as color / typography candidates; theme first when the deck is theme-driven, observed first when slides override heavily; say why | +| Preserve scope | inventory `text_blocks` / `images` / `charts` / `tables` / `diagrams` | All text verbatim; data values and SmartArt relationships frozen; pictures reused | +| Ignored | inventory `ignored` | Name them so the user sees what drops | +| Needs confirmation | inventory `needs_confirmation` | Flag complex charts and overcrowded pages; ask how to handle | +| Verification level | deck size / risk | Recommend the Step 7 per-page checks; user sets strictness | -**Hard rule — content is frozen, not the scope decisions**: text strings and chart/table/table-cell data values are non-negotiable (verbatim). *Which* identity to inherit, what to ignore, and how to treat flagged items are recommend-then-confirm, never silently decided. +**Hard rule — content is frozen, not the scope decisions**: text and chart/table/cell values are non-negotiable; which identity to inherit, what to ignore, and how to treat flagged items are recommend-then-confirm, never silently decided. **Name the v1 ceiling honestly**: an overcrowded page improves within the page as-is (no information-overload relief — flag it for manual split); paste-back keeps confirmed palette + font declarations but guarantees neither coordinate alignment nor font availability; combo / dual-axis / waterfall charts and merged-cell tables are best-effort from captured data and flagged. -**Recommend honestly — name the v1 ceiling**: - -| Item | What v1 delivers | -|---|---| -| Overcrowded source page | layout / hierarchy / whitespace improve **within the page as-is** — v1 does **not** relieve information overload (that needs re-pagination / rewrite, deferred). Flag such pages; the user may accept or note them for manual split | -| Paste-back into the original | regenerated elements retain confirmed palette + font declarations; v1 does **not** guarantee coordinate alignment or font availability in the original deck | -| Complex charts / merged-cell tables | best-effort from the captured data; combo / dual-axis / waterfall lose the un-captured plots — flagged for the user | - -**Visual re-confirm — full confirmation seeded from the source**: - -Apply [`generate-pptx`](../generate-pptx.md) Step 4's surface decision first. In -the default UI branch, use -`<project_path>/confirm_ui/recommendations.stage1.json` and -`recommendations.stage2.json` at the same two handoffs and launch the same -confirm server. In the chat branch, present the same two stages and fields without launching the server or requiring -`result.json`. The active, unconfirmed UI stage may be overwritten for a -requested regeneration; normal progression leaves confirmed earlier stages -intact. Do **not** hide fields: seed **every** targeted-confirmation field with -the inherited / source-derived default so the user sees the recommendation and -keeps the place to change it. Schema → -[`scripts/docs/confirm_ui.md`](../../scripts/docs/confirm_ui.md). - -Rows are abbreviated; follow Confirm UI's four-locale contract and omit `english` for English sources. +**Visual re-confirm**: apply Step 4's surface decision; in the UI branch use `confirm_ui/recommendations.stage1.json` / `.stage2.json` at the same two handoffs and the same server, in the chat branch present the same stages without a server or `result.json`. Rows abbreviated; follow the four-locale contract ([`confirm-surface.md`](../../references/confirm-surface.md)) and omit `english` for English sources: ```json { "primary_language": "<source main language>", - "recommend": { - "canvas": "<step3-canvas-id>", - "mode": "custom", - "visual_style": "custom", - "image_strategy": "custom", - "icons": "<sensible default icon library>", - "image_usage": ["provided"] - }, - "page_count": { "value": "<source-slide-count>" }, - "audience": { "value": "<carry over from the deck's apparent audience, or state a concrete provisional audience>" }, - "communication_intent": { "value": "<open prose inferred from the deck; preserve multiple purposes and their relationship>" }, - "audience_outcome": { "value": "<what the audience should know, understand, decide, or do>" }, - "core_message": { "value": "<the deck-wide claim / ask / action already present in the source>" }, - "delivery_context": { "value": "<primary presenter-led / reader-led / hybrid / recorded; hybrid names its lead and secondary use; occasion if inferable>" }, - "artifact_afterlife": { "value": "<review / approval / archive / hand-off / reuse / none planned>" }, - "content_divergence": { "value": "keep source wording and page structure verbatim", "locked": true }, - "design_directions": { "selected": 0, "candidates": [ - { - "id": "source-replica", "name_en": "Source replica (recommended)", - "mode": "custom", "mode_behavior_zh": "briefing 基底;逐页结构、顺序与文字 1:1 逐字不变。", - "visual_style": "custom", "visual_style_behavior_zh": "复刻源 PPT 视觉身份与版式。", "icons": "…", - "color": { "palette": { "background": "#...", "secondary_bg": "#...", "primary": "#...", "accent": "#...", "secondary_accent": "#...", "body_text": "#..." } }, - "typography": { "heading": { "primary": "…" }, "body": { "primary": "…" }, "body_size": <dominant observed.sizes_pt × 4/3, as px> }, - "image_strategy": { "rendering": "custom", "behavior_zh": "…" } - }, - { - "id": "alternative-a", - "mode": "custom", "mode_behavior_zh": "briefing 基底;逐页结构与文字 1:1 逐字不变。", - "visual_style": "custom", "visual_style_behavior_zh": "…", "icons": "…", - "color": { "palette": { "background": "#...", "secondary_bg": "#...", "primary": "#...", "accent": "#...", "secondary_accent": "#...", "body_text": "#..." } }, - "typography": { "heading": { "primary": "…" }, "body": { "primary": "…" }, "body_size": <canvas-appropriate baseline> }, - "image_strategy": { "rendering": "custom", "behavior_zh": "…" } - }, - { - "id": "alternative-b", - "mode": "custom", "mode_behavior_zh": "briefing 基底;逐页结构与文字 1:1 逐字不变。", - "visual_style": "custom", "visual_style_behavior_zh": "…", "icons": "…", - "color": { "palette": { "background": "#...", "secondary_bg": "#...", "primary": "#...", "accent": "#...", "secondary_accent": "#...", "body_text": "#..." } }, - "typography": { "heading": { "primary": "…" }, "body": { "primary": "…" }, "body_size": <canvas-appropriate baseline> }, - "image_strategy": { "rendering": "custom", "behavior_zh": "…" } - } - ] } + "recommend": {"canvas": "<step3-canvas-id>", "mode": "custom", "visual_style": "custom", "image_strategy": "custom", "icons": "<sensible default icon library>", "image_usage": ["provided"]}, + "page_count": {"value": "<source-slide-count>"}, + "audience": {"value": "<deck's apparent audience, or a concrete provisional one>"}, + "communication_intent": {"value": "<open prose inferred from the deck>"}, + "audience_outcome": {"value": "<know / understand / decide / do>"}, + "core_message": {"value": "<the deck-wide claim already present>"}, + "delivery_context": {"value": "<presenter-led / reader-led / hybrid / recorded; occasion if inferable>"}, + "artifact_afterlife": {"value": "<review / approval / archive / hand-off / reuse / none planned>"}, + "content_divergence": {"value": "keep source wording and page structure verbatim", "locked": true}, + "design_directions": {"selected": 0, "candidates": [ + {"id": "source-replica", "name_en": "Source replica (recommended)", "mode": "custom", "mode_behavior_zh": "briefing 基底;逐页结构、顺序与文字 1:1 逐字不变。", "visual_style": "custom", "visual_style_behavior_zh": "复刻源 PPT 视觉身份与版式。", "icons": "…", + "color": {"palette": {"background": "#...", "secondary_bg": "#...", "primary": "#...", "accent": "#...", "secondary_accent": "#...", "body_text": "#..."}}, + "typography": {"heading": {"primary": "…"}, "body": {"primary": "…"}, "body_size": "<dominant observed.sizes_pt × 4/3, as px>"}, + "image_strategy": {"rendering": "custom", "behavior_zh": "…"}}, + {"id": "alternative-a", "...": "same shape; body_size = canvas-appropriate baseline"}, + {"id": "alternative-b", "...": "same shape"} + ]} } ``` -- **Recommend keep, allow override**: pre-fill the open communication contract from the source's apparent audience and purpose, preserving composite purposes in prose; also pre-fill canvas / mode / visual style / icons / image strategy with the source-faithful default (canvas = Step 3 format, mode = `briefing`, image_usage = `provided`). The purpose examples are hints, never a `primary_job` selector. Beautify's only true non-choices are frozen text and strict 1:1 page count (changing either means routing to the main pipeline). Seed `content_divergence` to verbatim preservation with `locked: true`; the Confirm UI renders it read-only and the server restores the locked value on every staged submit. A request to reshape wording or page structure routes to the main pipeline instead of weakening this profile. -- **Our recommendation is the pre-selected default = the source replica**: for color and typography, author **several candidates** like the from-scratch flow. The pre-selected default (`selected: 0`, the first card) is what beautify recommends — the candidate that **best replicates the source deck's style** (the truest reading of `theme` / `observed`). Replicate-by-default. -- **Judge the other alternatives exactly as the from-scratch flow does — fonts as much as colors**: don't invent a beautify-specific rule. Author each non-replica candidate with the **same content-driven judgment the Strategist uses when generating from scratch** (color §e, typography §g), applied to the material this project provides — the source document's content and subject, the company's own theme colors, and any brand signal. Pick the palette **and** the font pairing by what fits *this* deck's content; fonts are chosen by content fit, not just defaulted to a safe face. Reach **≥3 meaningful candidates total**; reasonable font repetition is non-blocking, so never manufacture a different pairing just to satisfy a quota. `primary` always follows the source deck's main language; include `english` only when that language is not English. -- **`body_size` is the load-bearing field, and the replica follows the source's own size**: seed the replica candidate's `body_size` from the source's actual body size — take the dominant `observed.sizes_pt` value (the most frequent run-level size, the **body proxy**) and **convert it to px (`× 4/3`)** before seeding, since the system is px-only and the source measures in pt: a source 20pt body becomes `26.67`px, so the replica renders at the source's true size (seeding the bare `20` as px would shrink it ~25% — the pt-as-px trap). Whichever source value you land on below (observed mode, or `theme.sizes.body`) gets the same `× 4/3` conversion. The confirm page writes that px to `result.json` (`body_size`); the chat branch retains the same px in its visible final summary. Neither path performs another conversion or adds `body_size_pt` provenance (pt never enters the contract). The "most frequent = body" read is a proxy, not a guarantee — `observed.sizes_pt` counts every explicit run size (titles, captions, footnotes, chart/label text included, no placeholder-type resolution), so a deck dense with small labels can let a caption size outrank true body; cross-check the proxy against the page's actual body blocks and the sanity range below before trusting it, and prefer the size the body paragraphs visibly render at over the raw mode when the two disagree. Fall back to `theme.sizes.body` (the declared placeholder size) when `observed.sizes_pt` is empty, and to a PPT consumption-mode baseline (`text` 20 / `balanced` 24 / `presentation` 32 px — one fixed value per mode) only when neither is present. Note `theme.sizes.body` is the master `bodyStyle` **level-1 declared default** — a coarse value that commonly **over-reads** the real body density (decks often render body at a deeper outline level or override it smaller), so when you land on this fallback treat it as an upper-ish guess and run it through the sanity check below, never as a precise body size. `theme.sizes.body_levels` and `layout_sizes_pt` are **reference context, not extra fallback tiers**: consult them to judge a saner body value when the deck is theme-driven (`observed` empty) — e.g. a deeper `body_levels` entry or a `layout_sizes_pt` hint may read truer than level-1 — but do not auto-seed from them; the seed chain stays `observed → theme.sizes.body → consumption-mode baseline`, and a theme-driven deck whose body size genuinely can't be pinned cleanly is exactly the case the sanity check is for. The canvas hint stays a **sanity range**, not the seed: if the source's own size lands far outside it (a dense source doc reads tiny on a projection canvas), surface that to the user rather than silently snapping — the replica recommendation is the source's size, the user confirms or overrides. Non-replica alternatives may use the consumption-mode baseline. This is what prevents the deck from exporting at an unintentionally small size while still honoring the source. +- **Recommend keep, allow override**: pre-fill the communication contract from the source's apparent audience and purpose (composite purposes in prose; examples are hints, never a `primary_job` selector) and canvas / mode / visual style / icons / image strategy with the source-faithful default (mode `briefing`, `image_usage` `provided`). The only true non-choices are frozen text and strict 1:1 page count; `content_divergence` is seeded verbatim with `locked: true` (the UI renders it read-only and restores it on every submit). A request to reshape wording or structure routes to the main pipeline. +- **The pre-selected default is the source replica** (`selected: 0`): the candidate that best replicates the source's `theme` / `observed` style. Author the other candidates with the same content-driven judgment the Strategist uses from scratch (color §e, typography §g) — palette and font pairing chosen for this deck's content, ≥3 meaningful candidates, no manufactured pairings to fill a quota; `primary` follows the source language, `english` only when that language is not English. +- **`body_size` is load-bearing and the replica follows the source's own size**: seed it from the dominant `observed.sizes_pt` value converted to px (`× 4/3` — a 20pt body becomes `26.67`; seeding bare `20` shrinks it ~25%, the pt-as-px trap); the confirm page writes that px to `result.json` and the chat branch retains it, with no second conversion and no `body_size_pt`. The most-frequent-size proxy counts titles, captions, and chart labels too, so cross-check it against the page's actual body blocks and prefer the size body paragraphs visibly render at. Seed chain: `observed` → `theme.sizes.body` (a level-1 default that over-reads; treat as an upper-ish guess) → the consumption-mode baseline (`text` 20 / `balanced` 24 / `presentation` 32 px); `body_levels` and `layout_sizes_pt` are reference context for judging a saner value, never auto-seeds. The canvas hint is a sanity range, not the seed — when the source size lands far outside it, surface that to the user rather than snapping. Alternatives may use the consumption-mode baseline. -Run Generate Step 4's confirmation orchestration unchanged, including its -pre-launch surface decision and the UI branch's pre-wait Stage-1 chat handoff. +Run Step 4's confirmation orchestration unchanged. In the UI branch read `confirm_ui/result.json` exactly once after the final wait and run `--shutdown` before Step 6; in the chat branch retain the visible final summary. Then enter Step 4 as Strategist with the plan pre-resolved under the two invariants — the content-faithful clause ([`strategist.md`](../../references/strategist.md) §d Layer 1) and page count = source slide count — writing the confirmed state completely into `design_spec.md` (mode, canvas, visual style, color + typography incl. `body_size`; skip both recommendation flows). §VII holds only `Page | Family | Template | Usage` rows for selected `chart` / `table` references projected into `spec_lock.md page_visualizations`; qualitative relationships stay in §IX; §VIII holds source pictures for re-layout. -In the UI branch, after the final wait returns, read -`<project_path>/confirm_ui/result.json` exactly once. In the chat or delegated -branch, retain the visible final summary instead and require no UI result. After -any launched UI path, run `--shutdown` before Step 6; do not assume `5050`. - -On confirmation, enter [`generate-pptx`](../generate-pptx.md) Step 4 as Strategist with the plan pre-resolved. The two beautify invariants always hold: the content-faithful clause ([`strategist.md`](../../references/strategist.md) §d Layer 1) and page count = source slide count (strict 1:1). Write the retained final confirmation state completely into `design_spec.md` — `mode` (recommended `briefing`), canvas, `visual_style`, color (e) + typography (g) incl. `body_size` (the reviewed values; skip both recommendation flows) — honoring whatever the user kept or overrode. Do not reopen UI evidence afterward. §VII contains only `Page | Family | Template | Usage` rows for selected `chart` or `table` catalog references; project their family-qualified keys into `spec_lock.md` `page_visualizations`. Qualitative relationships and unmatched Chart/Table plans stay in §IX; Default/Quick makes the mandatory per-page Structure decision before geometry. §VIII contains source pictures for re-layout. - -**Hard rule — §IX is verbatim and 1:1**: each source slide becomes exactly one page, in source order, its text transcribed word-for-word from `sources/<stem>.md`. Do not merge, split, drop, or rewrite. Complete and audit `design_spec.md` first, then author `spec_lock.md` from that Design Spec plus the source/page/template context per `strategist.md` §6 before handing off to the Executor. +**Hard rule — §IX is verbatim and 1:1**: each source slide becomes exactly one page, in order, its text transcribed word-for-word from `sources/<stem>.md`. Complete and audit `design_spec.md`, then author `spec_lock.md` per `strategist.md` §6 before handing off. --- ## 6. Author + Export -**Quick**: follow [`quick-generate.md`](./quick-generate.md) §3–4. The -Beautify inventory is the exact page roster and frozen-content contract; keep -its source order, hand-author every page, run the lockless Quick final checker, -and export with `--quick-generate`. Do not run Confirm UI, write a Design Spec -or lock, run the Default first-page gate, or call `finalize_svg.py`. +**Quick**: follow [`quick-generate.md`](./quick-generate.md) §3–4 with the inventory as the exact roster and frozen-content contract; keep source order, hand-author every page, run the lockless final checker, export with `--quick-generate`; no Confirm UI, Design Spec, lock, first-page gate, or `finalize_svg.py`. **Long-deck review cadence (may adapt)**: after about five pages or at a section boundary, reread only the inventory summary/current-page views and cross-page anchors — no checker, no gate — and send one `authored/total` status per batch. -**Quick — lightweight long-deck review cadence (may adapt for a short deck or -semantic boundary)**: after about five pages or at a section -boundary, reread only the inventory summary/current-page views and cross-page -anchors. Do not run a checker; this is neither a gate nor an approval stop. Send -one `authored/total` status after each batch. - -**Default**: run the standard pipeline as follows. - -Run the standard pipeline ([`generate-pptx`](../generate-pptx.md) Steps 6–7). The Executor re-lays-out each page — hierarchy, spacing, alignment, page rhythm — using the semantic anchors in `spec_lock.md` plus current page/source/template context; valid page-local colors, gradients, effects, and export-safe display faces need not be added to the lock. It regenerates charts / tables as native SVG from the extracted data and re-lays-out the source pictures. - -Follow [`generate-pptx`](../generate-pptx.md) Step 7 for the canonical serial -post-processing commands, gates, success criteria, and export artifacts. +**Default**: run [`generate-pptx`](../generate-pptx.md) Steps 6–7. The Executor re-lays-out each page from the lock's semantic anchors plus page/source/template context (page-local colors, gradients, effects, and export-safe faces need no lock rows), regenerates charts/tables as native SVG from the extracted data, and re-lays-out the source pictures. Step 7 owns the serial post-processing commands, gates, and artifacts. --- ## 7. Validate Output -```bash -python3 ${SKILL_DIR}/scripts/source_to_md/ppt_to_md.py <project_path>/exports/<output.pptx> -``` - -| Check | Expected | -|---|---| -| Text fidelity | every source text string appears in the output, unaltered | -| Data fidelity | chart categories / series / table cells match the source exactly | -| Page count | output slide count equals the source slide count | -| Regenerated visuals | charts / tables are native SVG re-themed to the effective palette | -| Identity | text / shapes use effective colors + fonts, seeded from `<stem>.identity.json` | -| Paste-back | copied elements retain effective palette + font declarations; alignment and font availability are not guaranteed | +`python3 ${SKILL_DIR}/scripts/source_to_md/ppt_to_md.py <project_path>/exports/<output.pptx>` — every source text string appears unaltered; chart categories / series / table cells match exactly; slide count equals the source; charts/tables are native SVG in the effective palette; text and shapes use the effective colors and fonts; paste-back elements retain palette and font declarations (alignment and font availability not guaranteed). ```markdown ## ✅ Beautify Complete - -- [x] Content + data values verbatim (read-back Markdown matches the source) +- [x] Content + data values verbatim (read-back matches the source) - [x] 1:1 page count preserved - [x] Effective colors + fonts applied consistently -- [x] Charts / tables regenerated as native SVG in the effective style +- [x] Charts / tables regenerated as native SVG - [x] Native PPTX exported to `exports/` ``` @@ -365,14 +159,4 @@ python3 ${SKILL_DIR}/scripts/source_to_md/ppt_to_md.py <project_path>/exports/<o ## Current Boundary -| Capability | Status | -|---|---| -| Re-layout with verbatim text | Supported | -| Source palette / fonts as preselected recommendation, with user-approved overrides | Supported | -| Strict 1:1 page mapping | Supported | -| Regenerate charts / tables as native SVG from extracted data | Supported | -| Re-lay-out source pictures | Supported | -| Re-pagination (split dense / merge sparse) | Not in v1 | -| Carry source charts / tables / images over byte-for-byte | Out of scope — user copies originals manually if wanted | -| Silent visual-style / identity deviation | Out of scope | -| Batch / multi-deck beautification | Not in v1 | +Supported: re-layout with verbatim text; source palette/fonts as the preselected recommendation with user-approved overrides; strict 1:1 pages; charts/tables regenerated from extracted data; re-laid-out source pictures. Not in v1: re-pagination; batch / multi-deck beautification. Out of scope: carrying charts / tables / images over byte-for-byte (the user copies originals manually); silent visual-style or identity deviation. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/profiles/image-to-pptx.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/profiles/image-to-pptx.md index 30588ceb..f19da0b9 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/profiles/image-to-pptx.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/profiles/image-to-pptx.md @@ -4,41 +4,15 @@ description: Quick-only Generate profile for reconstructing one or more source i # Image to PPTX Profile -> Quick-only Generate profile, not a top-level route. Normalize one or more -> supplied images into the represented page roster, then rebuild each page as -> native text, identity-faithful source graphics, and independently placeable -> image layers. +> Quick-only Generate profile, not a top-level route. Normalize supplied images into the represented page roster, then rebuild each page as native text, identity-faithful source graphics, and independently placeable image layers. The visible result is the reference truth, but the output is not a screenshot skin: image content becomes the smallest useful background / foreground / subject stack, visible text is restored natively, and source graphics stay visually exact. No redesign, no Strategist, no confirmation. -Reconstructs approved mockups, rendered slide images, contact sheets, or -flattened page visuals into a new PPTX. It does not redesign the deck and does -not run Strategist or confirmation. The visible result is the reference truth, -but the output is not a screenshot skin: image content is rebuilt into the -smallest useful background / foreground / subject stack, visible text is -restored as native text, and source graphics remain visually exact. +**Trigger**: the user supplies raster visuals (approved mockups, rendered slides, contact sheets, flattened pages) and explicitly asks to restore the represented pages as a PPTX. Photos, illustrations, or moodboards used as resources for a new story do not activate it. -**Trigger**: the user supplies one or more raster visuals and explicitly asks -to restore the represented pages as a PPTX. Ordinary photos, illustrations, and -moodboards used only as resources for a new story do not activate this profile. +**Support boundary — Codex required**: documented and validated for Codex only, because it depends on Codex's native reference-image generation/editing and direct inspection of every derived layer. Other hosts may happen to work; the repository makes no compatibility claim and defines no alternate host or generic image-backend fallback. -**Support boundary — Codex required**: this profile is currently documented -and validated for Codex because it depends on Codex's native reference-image -generation/editing capability and direct inspection of every derived layer. -Other hosts are not adapted or supported by this workflow; they may happen to -work, but the repository makes no compatibility claim and defines no alternate -host or generic image-backend fallback for this profile. +**Hard rule — Quick only**: always load [`quick-generate.md`](./quick-generate.md), never `generate-pptx.md`, without the user saying "Quick"; skip Strategist, Confirm UI, template selection, Design Spec, lock, and the Default first-page gate. The main agent decides the reconstruction, prepares all resources, hand-authors SVG, runs the lockless final checker, and exports. -**Hard rule — Quick only**: this profile always loads -[`quick-generate.md`](./quick-generate.md) and never -[`generate-pptx.md`](../generate-pptx.md). The user does not need to say -"Quick" separately. Skip Strategist, Confirm UI, template selection, -`design_spec.md`, `spec_lock.md`, and the Default first-page gate. The current -main agent decides the reconstruction directly, prepares all resources, hand- -authors SVG pages, runs the lockless final checker, and exports. - -**Hard rule — source surface, not template application**: stay in Quick free -design and do not install or apply a Brand/Style/Layout/Deck workspace for this -profile. A template would compete with the canonical page geometry and visual -identity. A reusable-system request routes to Create Template instead. +**Hard rule — source surface, not template application**: stay in Quick free design; never install or apply a Brand/Style/Layout/Deck workspace — it would compete with the canonical page geometry. A reusable-system request routes to Create Template. --- @@ -46,52 +20,35 @@ identity. A reusable-system request routes to Create Template instead. | Request shape | Behavior | |---|---| -| One or more image files represent pages that must become a final editable PPTX | Activate this profile and Quick Generate | -| One file contains several clearly separated slide frames | Split it into the ordered page roster first, then reconstruct each frame | -| Images are ordinary content assets or inspiration for a new deck | Use ordinary Generate | -| Images should define a reusable Brand/Style/Layout/Deck workspace | Use [`create-template.md`](../create-template.md) | -| A semantic source PPTX exists and only its layout should improve | Use [`beautify-pptx.md`](./beautify-pptx.md) | +| Image files represent pages that must become a final editable PPTX | This profile + Quick | +| One file contains several clearly separated slide frames | Split into the ordered roster first, then reconstruct each frame | +| Images are ordinary content assets or inspiration for a new deck | Ordinary Generate | +| Images should define a reusable workspace | [`create-template.md`](../create-template.md) | +| A semantic source PPTX exists and only its layout should improve | [`beautify-pptx.md`](./beautify-pptx.md) | -**Hard rule — mutually exclusive fidelity profiles**: Image to PPTX and -Beautify never compose. Beautify preserves semantic PPTX content while -redesigning layout; Image to PPTX preserves a rendered page surface while -rebuilding its object and image-layer boundaries. +**Hard rule — mutually exclusive fidelity profiles**: Image to PPTX and Beautify never compose — Beautify preserves semantic PPTX content while redesigning layout; this profile preserves a rendered surface while rebuilding object and image-layer boundaries. -**Hard rule — flat final deck**: output stays `pptx_structure.mode: flat`. Page -pixels do not prove Master/Layout identity, placeholders, theme ancestry, -hidden objects, notes, animations, chart data sources, or authoring history. -Do not infer them. A reusable-system request routes to Create Template instead. +**Hard rule — flat final deck**: output stays `pptx_structure.mode: flat`. Pixels do not prove Master/Layout identity, placeholders, theme ancestry, hidden objects, notes, animations, chart data sources, or authoring history; never infer them. --- ## 2. Normalize Source Images into Pages -🚧 **GATE**: an ordered canonical page-image roster exists before image-layer -decisions or SVG authoring. +🚧 **GATE**: an ordered canonical page-image roster exists before any layer decision or SVG authoring. | Source form | Normalization | |---|---| -| One file containing one complete page | Keep it as one canonical page image | -| Several files containing one page each | Preserve the explicit or filename-natural order | -| One or more regular contact sheets | Split row-major with `slice_images.py --grid`, without alpha removal | -| A file containing several non-grid page frames | Record each visibly bounded page bbox and crop it into a separate lossless canonical page image | -| Boundaries or order are genuinely ambiguous | Mark the roster blocked instead of silently merging, dropping, or reordering pages | +| One file, one complete page | One canonical page image | +| Several files, one page each | Preserve explicit or filename-natural order | +| Regular contact sheets | Split row-major with `slice_images.py --grid`, without alpha removal | +| Several non-grid page frames in one file | Record each visibly bounded bbox and crop it into a separate lossless page image | +| Ambiguous boundaries or order | Mark the roster blocked; never silently merge, drop, or reorder | -Archive original files under `sources/`; keep normalized page images under -`images/source-pages/` or another project-local source-page folder. Never -overwrite an original file. +Archive originals under `sources/`; keep normalized pages under `images/source-pages/` or another project-local folder; never overwrite an original. -**Hard rule — one normalized frame, one slide**: frame count, not input-file -count, owns slide count. Every normalized page frame maps to one output slide -in the same order. Preserve the frame's aspect ratio. Mixed aspect ratios are -blocked until the current agent resolves one explicit whole-deck treatment. +**Hard rule — one normalized frame, one slide**: frame count, not input-file count, owns slide count; every frame maps to one slide in order with its aspect ratio preserved; mixed aspect ratios block until one explicit whole-deck treatment is resolved. -**Mandatory — inspect every canonical page**: ordinary image-resource -inspection limits do not apply to this page roster. Inspect each normalized -page once to identify text, source graphics, scene-image regions, overlap, -region-level source sufficiency, boundary completeness, occlusion, and the -minimum useful layer stack. Reopen only the current page or a specifically -unresolved region afterward. +**Mandatory — inspect every canonical page** once (ordinary image-resource inspection limits do not apply) for text, source graphics, scene regions, overlap, region-level source sufficiency, boundary completeness, occlusion, and the minimum useful layer stack; reopen only the current page or an unresolved region afterward. --- @@ -101,237 +58,70 @@ Classify visible regions by what they are, not by how easy they are to crop. | Content family | Default realization | Non-negotiable boundary | |---|---|---| -| Editable text | `native_text` | Restore exact visible wording, line grouping, alignment, emphasis, and approximate font metrics; do not bake ordinary slide text into generated images | -| Source graphic | `source_graphic` | Logos, icons, badges, vector-like ornaments, and decorative marks preserve visible identity. Use an exact vector, deterministic redraw, sufficient source pixels, or Codex reference reconstruction according to the quality ladder below; never substitute a merely similar graphic | -| Data graphic | `native_chart`, `native_table`, or exact `source_graphic` | Preserve every visible value, label, relationship, and geometry. Rebuild natively only when the source is legible enough to verify; otherwise use an exact crop/vector or mark `manual_required`. Never ask a generative model to recreate chart/table/data content | -| Simple exact geometry | `native_shape` | Use a native shape only when fill, stroke, geometry, and layering can be matched faithfully; otherwise prepare an identity-faithful source-graphic asset | -| Scene image | `image_layer` | Photos, people, characters, products, environmental backgrounds, textures, and complex illustrations may be reference-edited or regenerated as registered layers | -| Unreadable or unsafe region | `manual_required` | Block rather than invent wording, identity, values, or a visually different replacement | +| Editable text | `native_text` | Exact visible wording, line grouping, alignment, emphasis, approximate metrics; never bake slide text into generated images | +| Source graphic | `source_graphic` | Logos, icons, badges, ornaments preserve identity via exact vector, deterministic redraw, sufficient source pixels, or Codex reference reconstruction; never a merely similar graphic | +| Data graphic | `native_chart`, `native_table`, or exact `source_graphic` | Every value, label, relationship, and geometry preserved; native only when legible enough to verify, otherwise exact crop/vector or `manual_required`; never generatively recreated | +| Simple exact geometry | `native_shape` | Only when fill, stroke, geometry, and layering match faithfully | +| Scene image | `image_layer` | Photos, people, characters, products, environments, textures, complex illustrations may be reference-edited or regenerated as registered layers | +| Unreadable or unsafe region | `manual_required` | Block rather than invent wording, identity, values, or a different replacement | -**Hard rule — separate layer need from realization**: source clarity never -decides whether a required editable, movable, or overlapping object becomes a -separate layer; it decides only how that layer is prepared. +**Hard rule — separate layer need from realization**: source clarity never decides whether a required editable, movable, or overlapping object becomes a separate layer, only how that layer is prepared. **Mandatory — assess source sufficiency per region** at final display size without a page-wide score: complete, cleanly separable, and sufficient → a source-derived crop or RGBA layer at the recorded geometry; contaminated, occluded, incomplete, or low-resolution with verifiable identity and geometry → reference-edit or reconstruct the layer and exposed background from that evidence; unverifiable identity, wording, values, or geometry → `manual_required`. -**Mandatory — assess source sufficiency per region**: judge each region at final -display size without a page-wide score or threshold. Inspect detail, -contamination/occlusion, and whether identity, geometry, lettering, or data -remain verifiable. - -| Source evidence for a required independent image layer | Realization | -|---|---| -| Complete, cleanly separable, and sufficient at final display size | Prepare a source-derived crop or RGBA layer at the recorded geometry | -| Contaminated, occluded, incomplete, or too low-resolution; identity and geometry remain verifiable | Reference-edit or reconstruct the layer and exposed background from that evidence | -| Required identity, wording, values, or geometry cannot be verified | Mark `manual_required`; do not invent authoritative content | - -**Graphic identity is authoritative; source pixel bytes are not**: use an exact -known vector when available. Deterministically redraw a simple, fully legible -graphic as SVG/native geometry. Reuse source pixels only when they are complete -and sufficient at final display size. When a complex logo, icon, badge, -ornament, or wordmark is visibly identifiable but too low-resolution, use its -source crop as the Codex reference and reconstruct a higher-resolution asset -that preserves the same silhouette, proportions, colors, lettering, bbox, and -z-order. Never merely interpolate low-resolution pixels, redesign the brand, -replace it with a similar library icon, or invent unreadable identity. If those -properties cannot be verified, mark the graphic `manual_required`. - -**Visible-surface authority**: preserve every legible string, number, label, -relative position, crop, z-order, color relationship, and emphasis visible in -the source. Do not improve the layout, rewrite copy, correct claims through -research, reveal invented semantics, or silently replace branded graphics. +**Graphic identity is authoritative; source pixel bytes are not**: use an exact known vector when available; deterministically redraw a simple, fully legible graphic; reuse source pixels only when complete and sufficient at final size; when a complex logo, icon, badge, ornament, or wordmark is identifiable but too low-resolution, use its crop as the Codex reference and reconstruct a higher-resolution asset with the same silhouette, proportions, colors, lettering, bbox, and z-order — never mere interpolation, a brand redesign, a similar library icon, or invented identity. **Visible-surface authority**: preserve every legible string, number, label, relative position, crop, z-order, color relationship, and emphasis; never improve the layout, rewrite copy, correct claims through research, reveal invented semantics, or replace branded graphics. --- ## 4. Build the Minimum Useful Layer Stack -For each page, decide the smallest stack that makes the intended objects -independent. Do not split a page merely to maximize layer count. +Decide per page the smallest stack that makes the intended objects independent; never split merely to maximize layer count. Typical bottom-to-top order: `base` (clean full-canvas background with every planned removable subject, foreground object, and editable text removed, hidden pixels reconstructed where necessary) → `midground-*` → `subject-*` (independently movable cutouts) → `foreground-*` (effects, foliage, particles, framing that cross the subject or native objects) → `source-graphic-*` (exact or reconstructed marks plus exact/native data graphics at their z-order) → `native-text-*` and exact native shapes. -Typical bottom-to-top order: +**Registered-group rule**: every base/midground/subject/foreground layer in a group stays registered to the same canonical page or scene bbox; source-derived members keep recorded geometry, every Codex-derived member starts from that canonical source with canvas, position, scale, pose, lighting, and style preserved; never trim registered full-canvas layers. When scene layers need reference editing, use [`image-generator.md`](../../references/image-generator.md) §4.4's registered reconstruction group: one clean base with all separately realized subjects, graphics, and text removed and only the exposed background reconstructed; at least one independent subject/foreground output from the same canonical source whenever the page holds scene content that must be independently editable (base plus that output are the minimum two layers); every additional layer derived independently from the canonical source, never from the base or another generated layer; original pose, scale, and coordinates on RGBA transparency; further layers only for genuine independent movement, overlap, or animation. -1. `base` — clean full-canvas background with all planned removable subjects, - foreground objects, and editable text removed; hidden background pixels are - reconstructed where necessary. -2. `midground-*` — optional scene layers that must sit between the base and - primary subject. -3. `subject-*` — people, characters, products, props, or other independently - movable cutouts. -4. `foreground-*` — effects, foliage, particles, framing objects, or other - scene elements that cross the subject or native slide objects. -5. `source-graphic-*` — exact or identity-faithfully reconstructed logos, - icons, badges, and ornamental marks, plus exact/native data graphics at - their visible z-order. -6. `native-text-*` and exact native shapes. +**Batch non-overlapping objects**: when several subjects, props, effects, or graphic reconstructions have pairwise-disjoint padded bboxes (including shadows and effects) and share one isolation treatment, ask Codex for one `layer-plate` holding all of them with clear separation — either a full-canvas registered plate followed by one nested-SVG picture crop per recorded bbox, or a regular isolated-cell sheet sliced with `slice_images.py --grid ... --names ... --trim --alpha` and placed at the recorded bboxes. Without transparency, use one exact flat key color for the whole plate (`slice_images.py` as a `1x1` sheet with `--alpha` and without `--trim` for a registered plate) and remove it once; never a separate green-background image per object. Overlapping objects or different z-orders use separate plates. -**Registered-group rule**: every base/midground/subject/foreground layer in a -group stays registered to the same canonical page or scene bbox. A -source-derived member retains recorded geometry; every Codex-derived member -starts from that canonical source. Preserve canvas, position, scale, -pose, lighting, and style. Do not trim registered full-canvas layers; -transparent pixels retain alignment. - -When one or more scene layers require reference editing or reconstruction, use -[`image-generator.md`](../../references/image-generator.md) §4.4's registered -reconstruction group as the primitive: - -- create one clean base by removing **all** scene subjects/foreground objects, - source/data graphics, and editable text planned for separate realization, - then reconstruct only the newly exposed background; -- create at least one independent subject/foreground output from the same - canonical source whenever the page contains scene content that must be - independently editable; the base plus that output are the minimum two - independently prepared image layers, while §3 decides whether each layer - retains sufficient source pixels or requires reference reconstruction; -- derive every additional layer independently from the canonical source, never - from the base or another generated layer; -- preserve the original pose, scale, and coordinates on RGBA transparency; -- repeat only for additional layers that genuinely need independent movement, - overlap, or animation. - -**Batch non-overlapping objects**: one object does not imply one generation. -When several subjects, props, effects, or source-graphic reconstructions have -pairwise-disjoint padded bboxes—including visible shadows and effects—and can -share one isolation treatment, ask Codex for one `layer-plate` containing all -of them with clear separation. Use either: - -- a full-canvas registered plate that keeps the source positions, then create - one nested-SVG picture crop per recorded bbox; or -- a regular isolated-cell sheet when source coordinates are unnecessary, then - use `slice_images.py --grid ... --names ... --trim --alpha` and place the - resulting assets at their recorded source bboxes. - -Both paths yield independent PPT picture objects from one generated output. -If transparency is unavailable, use one exact flat key color for the whole -plate and remove it once; never regenerate a separate green-background image -for each object. Objects that overlap one another or require different z-order -must use separate plates/layers. - -The reference-image CLI does not inherit source dimensions automatically. Pass -an explicit matching aspect ratio/size, then verify that every member of one -registration group has the same final pixel canvas. In SVG, place the base and -all full-canvas layers at identical `x`, `y`, `width`, and `height` with -`no-crop` behavior. - -**Reconstruct for final resolution**: apply the §3 source-sufficiency decision -per region. Retaining complete source pixels is valid only when they remain -sharp enough at final display size; a clear source may still require reference -reconstruction when separation needs hidden or uncontaminated pixels. When -detail is insufficient, use Codex reference reconstruction; interpolation alone -does not recover detail. - -**Reference-edit, not reinterpretation**: reconstruction prompts name the -canonical source page/region and ask to preserve the visible composition and -style. They may inpaint hidden scene pixels or complete an occluded subject, -but must not redesign the scene, change a character/person, introduce text, -substitute or alter a logo, or invent extra decorative graphics. - -When Codex cannot return transparency, generate the isolated layer or shared -plate on one exact flat key color and use `slice_images.py` as a `1x1` sheet -with `--alpha` and **without** `--trim`, preserving full-canvas registration. -Several plate members share this single keyed output. +The reference-image CLI does not inherit source dimensions: pass an explicit matching aspect ratio/size and verify every member of a registration group shares the same final pixel canvas; in SVG place the base and all full-canvas layers at identical `x`, `y`, `width`, `height` with `no-crop` behavior. **Reconstruct for final resolution**: retained source pixels must stay sharp at final size; interpolation recovers no detail. **Reference-edit, not reinterpretation**: prompts name the canonical source page/region and preserve the visible composition and style; they may inpaint hidden pixels or complete an occluded subject but never redesign the scene, change a person, introduce text, alter a logo, or add decoration. --- ## 5. Source Evidence without a Quick Plan -Before deciding layers, write source evidence to: - -```text -<project_path>/analysis/reconstruction_inventory.json -``` - -The inventory records what is visibly present, not a resumable implementation -plan. Keep it limited to: - -- original file and normalized page path; -- page order, source-frame bbox, SHA-256, and pixel dimensions; -- visible regions with stable ids, source bboxes, observed family - (`text`, `graphic`, `image`, or `unknown`), verbatim text when applicable, - and confidence; -- observed source sufficiency, boundary completeness, occlusion/contamination, - and identity/data verifiability at final placement; -- overlap/z-order observations and unresolved evidence. - -Do **not** put final layer choices, generation prompts, output filenames, or SVG -bindings into this inventory. The current main agent keeps those decisions in -active context and writes only required operational image manifests/evidence. -Context loss restarts the Quick run; the inventory is not a resume artifact. - -Low-confidence visible text, an uncertain page boundary, or an unidentified -branded/data graphic is unresolved evidence and blocks successful delivery. +Before deciding layers, write `<project_path>/analysis/reconstruction_inventory.json` recording only what is visibly present: original file and normalized page path; page order, source-frame bbox, SHA-256, pixel dimensions; visible regions with stable ids, bboxes, observed family (`text` / `graphic` / `image` / `unknown`), verbatim text where applicable, and confidence; observed sufficiency, boundary completeness, occlusion/contamination, and identity/data verifiability; overlap/z-order observations and unresolved evidence. No final layer choices, prompts, output filenames, or SVG bindings — those stay in active context plus required operational image evidence; context loss restarts the run. Low-confidence text, an uncertain boundary, or an unidentified branded/data graphic is unresolved evidence and blocks delivery. --- ## 6. Image Preparation -When any `image_layer` or low-resolution `source_graphic` requires reference -editing or generation, load -[`image-base.md`](../../references/image-base.md) and -[`image-generator.md`](../../references/image-generator.md). The current Codex -main agent resolves the layer stack directly, uses Codex's native -reference-image capability, and finishes every required layer before SVG -authoring. Do not adapt `image_gen.py`, its generic manifest, or provider -backends for this profile. - -- Use `text_policy: none` for scene reconstruction layers. Use `embedded` only - when an exact visible wordmark/letterform is integral to a reconstructed - source graphic; ordinary slide text always remains native. -- Exhaust the available Codex image path automatically; block before export if a - required layer remains `Needs-Manual`. -- Preserve each prepared image layer's source page/region, source hash, - realization method, operation, output path/hash, registration group, and - z-order in the applicable operational evidence; include prompt and - backend/model when the layer was reference-edited or reconstructed. -- Re-run `analyze_images.py` after assets change. -- A generated candidate is not usable until its expected file exists, it has - been inspected once, and its registration group or plate has been checked - against the canonical page. -- Inspect the recomposed page once after all generated layers, plate crops, - source graphics, native shapes, and native text are in place. This narrow - readback is mandatory fidelity validation, not resource reselection. +When any `image_layer` or low-resolution `source_graphic` needs reference editing, load [`image-base.md`](../../references/image-base.md) and [`image-generator.md`](../../references/image-generator.md); the Codex main agent resolves the stack directly with Codex's native reference-image capability and finishes every layer before SVG authoring — never adapt `image_gen.py`, its manifest, or provider backends for this profile. Use `text_policy: none` for scene layers and `embedded` only when an exact wordmark/letterform is integral to a reconstructed graphic. Exhaust the Codex image path automatically and block before export if a layer stays `Needs-Manual`. Record each layer's source page/region, source hash, realization method, operation, output path/hash, registration group, and z-order (plus prompt and backend/model when reconstructed) in the operational evidence; re-run `analyze_images.py` after assets change. A candidate is usable only when its file exists, it has been inspected once, and its group or plate has been checked against the canonical page. Inspect the recomposed page once after all layers, crops, graphics, shapes, and text are in place — mandatory fidelity validation, not resource reselection. --- ## 7. SVG Authoring and Release Gate -Follow Quick Generate after source normalization and resource preparation. -Hand-author pages serially from the prepared base, registered scene layers, -identity-faithful source graphics, native shapes, and native text. Give independently -movable layers stable direct-root group ids so later animation can target them. +Follow Quick after normalization and preparation: hand-author pages serially from the base, registered layers, source graphics, native shapes, and native text, giving independently movable layers stable direct-root group ids for later animation. -**Forbidden — screenshot skin**: do not use the complete source page as the -sole full-slide picture and add token editable text above it. The source page -is a comparison reference, not a hidden backing layer in the delivered slide. - -Verify each page against its canonical image: +**Forbidden — screenshot skin**: never use the complete source page as the sole full-slide picture with token editable text above it; the source page is comparison evidence, not a hidden backing layer. | Final check | Required evidence | |---|---| -| Page roster | Every normalized frame becomes one slide in the same order and canvas treatment | -| Native text | Every legible string/number is present verbatim and remains editable | -| Source graphics | Logos, icons, and decorative graphics preserve the original identity and geometry at adequate final resolution; no similar substitute or unverified redesign appears | -| Data graphics | Every chart/table/data value and relationship is native-and-verified or retained from an exact source asset; none is generatively recreated | -| Layer registration | Base, subject, foreground, and other generated layers share the expected canvas/placement and show no jumps, seams, halos, or independent-crop drift | -| Visible image fidelity | The recomposed scene preserves the source's visible subject identity, pose, crop, lighting, color relationships, and z-order | -| Honest reconstruction | AI-recovered hidden pixels are identified as reconstruction, not claimed as original source detail | -| Independent objects | Every layer requested for editing or animation is a distinct SVG/PPT picture object; non-overlapping members may originate from one shared generated plate | -| Reference exclusion | Canonical full-page source images remain comparison evidence and are not referenced or packaged as delivered slide media | -| Package quality | Quick's lockless final SVG checker and PPTX postflight pass | +| Page roster | Every normalized frame is one slide in order with the same canvas treatment | +| Native text | Every legible string/number present verbatim and editable | +| Source graphics | Identity and geometry preserved at adequate resolution; no substitute or unverified redesign | +| Data graphics | Every value and relationship native-and-verified or from an exact source asset; none generatively recreated | +| Layer registration | Generated layers share canvas/placement with no jumps, seams, halos, or crop drift | +| Visible fidelity | Subject identity, pose, crop, lighting, color relationships, and z-order preserved | +| Honest reconstruction | AI-recovered hidden pixels identified as reconstruction | +| Independent objects | Every layer requested for editing or animation is a distinct picture object (shared plates allowed for disjoint members) | +| Reference exclusion | Canonical full-page source images are not referenced or packaged as slide media | +| Package quality | Quick's lockless final checker and PPTX postflight pass | -If a generated layer drifts, retry from the canonical reference with a narrower -edit instruction. Do not compensate by changing native text/graphics or by -flattening the full page. If the Codex image path is exhausted, -mark the affected layer `Needs-Manual` and block successful export. +If a layer drifts, retry from the canonical reference with a narrower edit; never compensate by changing native text/graphics or flattening the page. If the Codex path is exhausted, mark the layer `Needs-Manual` and block export. ```markdown ## ✅ Image to PPTX Complete - -- [x] Source files were normalized into the complete ordered page roster -- [x] Visible text is native and verbatim -- [x] Source graphics preserve identity and are sharp enough at final size -- [x] Required background / foreground / subject layers are independent and registered -- [x] Shared plates were split/cropped into the required independent objects -- [x] Recombined pages match the supplied visual references -- [x] Canonical full-page source images are absent from delivered slide media +- [x] Source files normalized into the complete ordered roster +- [x] Visible text native and verbatim; source graphics identity-faithful and sharp +- [x] Required background / foreground / subject layers independent and registered; shared plates split into independent objects +- [x] Recombined pages match the references; canonical source images absent from slide media - [x] Quick's SVG quality gate and PPTX postflight pass - [ ] **Next**: Report the PPTX and identify native, exact-source, and AI-reconstructed objects ``` diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/profiles/quick-generate.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/profiles/quick-generate.md index 499aaae1..11bc363d 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/profiles/quick-generate.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/profiles/quick-generate.md @@ -4,18 +4,11 @@ description: One-pass Generate profile for agent-decided preparation, direct SVG # Quick Generate Profile -> Generate-PPTX profile, not a top-level route. The current main agent completes -> one uninterrupted run without a separate Strategist/confirmation handoff or a -> resumable design record. This removes interaction and traceability, not the -> facts, resources, or authoring capabilities needed to build the final deck. +> Generate-PPTX profile, not a top-level route: the current main agent completes one uninterrupted run without a Strategist/confirmation handoff or a resumable design record. It removes interaction and traceability, not the facts, resources, or authoring capabilities the deck needs. -**Trigger**: the user explicitly requests quick/fast generation, asks to skip -strategy/confirmation, or directs the agent to proceed to SVG and export. -Page count alone never activates or blocks this profile. +**Trigger**: the user explicitly requests quick/fast generation, asks to skip strategy/confirmation, or directs the agent to proceed to SVG and export. Page count alone never activates or blocks it. -**Hard rule — Quick paths**: Apply the entry-time `SKILL_DIR` anchor to every -linked or abbreviated package path below. Expand it inside each tool call; -never change CWD or inherit a prior shell working directory. +**Hard rule — Quick paths**: expand every linked or abbreviated package path from the entry-time `SKILL_DIR` anchor inside each tool call; never change CWD or inherit a prior working directory. --- @@ -23,264 +16,70 @@ never change CWD or inherit a prior shell working directory. | Concern | Quick Generate contract | |---|---| -| Authority | Follow every explicit user requirement as stated; decide every unspecified choice directly without asking | -| Interaction | The current main agent decides content, design, resources, and implementation without Strategist, Confirm UI, or approval stops | -| Execution memory | Keep routine page, visual, and resource decisions only in the current active context; losing that context restarts Quick instead of reconstructing a plan from project files | -| Inputs | Any supported Generate input; convert/import sources and run bounded factual research when the input requires them | -| Templates | Directly validate and install at most one exact workspace root per kind supplied for this run; before P01, inspect the complete installed template SVG roster and freeze one natural-language application paragraph in active context; when none are supplied, use free design without catalog selection or Confirm UI | -| Resources | Prepare every project-local image, icon, and required provenance/manifest artifact before its SVG; author native formula markers and hyperlink anchors directly in the affected SVG; sound waits for §4 | -| Planning artifacts | Do not author a root project `design_spec.md`, `spec_lock.md`, confirmation payloads, or any substitute planning artifact; installed `templates/design_spec.<kind>.<id>.md` files remain template input | -| Traceability | Operational resource manifests, checker reports, postflight, and bounded Python command/outcome audit entries may remain, but they do not record the AI's design reasoning or form a resumable generation history | -| Delivery | Hand-author the resolved SVG roster, run one lockless final checker, skip `finalize_svg.py`, and export the final native PPTX through `--quick-generate` | +| Authority | Follow every explicit user requirement; decide every unspecified choice directly without asking | +| Interaction | The main agent decides content, design, resources, and implementation without Strategist, Confirm UI, or approval stops; pause only for user interruption or an unresolved hard prerequisite | +| Execution memory | Routine page, visual, and resource decisions live only in the active context; losing it restarts Quick rather than reconstructing a plan from files | +| Inputs | Any supported Generate input; convert/import sources and run bounded research when needed | +| Templates | Validate and install at most one exact workspace root per kind supplied for this run; before P01 inspect the complete installed SVG roster and freeze one Template Application paragraph in context; with no root, free design without catalog selection | +| Resources | Prepare every project-local image, icon, and provenance/manifest artifact before its SVG; author formula markers and hyperlink anchors directly in the SVG; sound waits for §4 | +| Planning artifacts | No root `design_spec.md`, `spec_lock.md`, confirmation payload, or substitute plan; installed `templates/design_spec.<kind>.<id>.md` files stay template input | +| Traceability | Resource manifests, checker reports, postflight, and the bounded command audit may remain; none records design reasoning or forms a resumable history | +| Delivery | Hand-author the roster, run one lockless final checker, skip `finalize_svg.py`, export with `--quick-generate` | -**Artifact ownership**: follow -[`artifact-ownership.md`](../../references/artifact-ownership.md) for source, -fact, author, derived, and regeneration boundaries. Quick changes the planning -handoff, not those artifact roles. +Artifact roles follow [`artifact-ownership.md`](../../references/artifact-ownership.md); Quick changes the planning handoff, not those roles. -**Hard rule — speed removes interaction and durable planning, not capability**: -all ordinary source, research, visual-carrier, resource-preparation, analysis, -authoring, and export capabilities remain available when they serve the deck. -This is capability availability, not a requirement to use every carrier. +**Hard rule — speed removes interaction and durable planning, not capability**: every ordinary source, research, carrier, resource, analysis, authoring, and export capability stays available when it serves the deck — availability, not a requirement to use every carrier. Explicit user facts, wording, choices, exclusions, and permission boundaries still win. -Explicit user facts, wording, choices, exclusions, and permission boundaries -still win. For every unspecified routine choice, decide directly and continue; -do not ask the user to approve a strategy or implementation detail. +**Default — optional production behavior (may override when useful)**: Speaker Notes, Custom Animations, and narration start off; enable any of them when the request or deck benefits, with their normal inputs and flags and without asking. Quick never creates or reads a root Design Spec or lock to do so. -After entry, continue through selected work, the final checker, and export. -Pause only for user interruption or an unresolved hard prerequisite. - -**Default — optional production behavior (may override when useful)**: Speaker -notes, Custom Animations, and narration start off for ordinary Quick work. The -current agent may enable any ordinary capability when the request or deck -benefits; use its normal inputs, flags, and prerequisites without asking for -approval. Quick video delivery follows the mandatory Custom Animations rule -below. Quick never creates or reads a root project Design Spec or lock to enable -an optional or mandatory capability. - -**Mandatory — discover motion before deciding whether to load it**: apply this -gate once during §2's pre-P01 planning. Do not load the full reference when -the defaults fit. +**Mandatory — discover motion before deciding whether to load it** (once, during §2's pre-P01 planning; keep the defaults when no row supplies a concrete communication job; when several apply, use the earliest load point — a before-authoring signal beats before-export): | Signal | Action | |---|---| -| Adjacent beats may share one mental map | Evaluate visible states; repetition alone does not require Morph. If continuity clarifies orientation, enable Custom Animations, load [`animations.md`](../../references/animations.md) before SVG, and author compatible Morph endpoints | -| Page- or object-specific reveal, renewed emphasis, meaningful movement, or same-page removal clarifies the message | Load [`animations.md`](../../references/animations.md) before SVG authoring; preserve the required units/states, then run [`customize-animations`](../stages/customize-animations.md) after the final checker | -| One deck-wide entrance policy supplies all required staged reveal | Load [`animations.md`](../../references/animations.md) before export and use an exporter flag such as `-a auto`; do not run the custom stage | -| A directional/section boundary benefits from a non-default transition | Load [`animations.md`](../../references/animations.md) before export and select from its §3 playbook | -| No earlier signal applies | Keep `fade` transitions and object animation `none`; do not load the motion reference | +| Adjacent beats may share one mental map | Evaluate visible states (repetition alone needs no Morph); if continuity clarifies orientation, enable Custom Animations, load [`animations.md`](../../references/animations.md) before SVG, and author compatible Morph endpoints | +| A page- or object-specific reveal, emphasis, movement, or removal clarifies the message | Load `animations.md` before authoring, preserve the required units/states, run [`customize-animations`](../stages/customize-animations.md) after the final checker | +| One deck-wide entrance policy supplies all staged reveal | Load `animations.md` before export and use an exporter flag such as `-a auto`; no custom stage | +| A directional/section boundary benefits from a non-default transition | Load `animations.md` before export and choose from its §3 playbook | +| No signal | Keep `fade` transitions and object animation `none`; load nothing | -This gate activates capability discovery, not motion coverage. Keep the -defaults when no row supplies a concrete communication job. When several -signals apply, perform every required action and use the earliest required load -point; a before-authoring signal always overrides a before-export-only timing. - -**Hard rule — Quick video Custom Animations**: when -[`video-design.md`](../../references/video-design.md) is active because the -effective Quick delivery purpose is recorded, self-running, or video-directed, -enable Custom Animations, load [`animations.md`](../../references/animations.md) -before SVG authoring, preserve the required semantic motion units, and run -[`customize-animations`](../stages/customize-animations.md) after the final -checker. Use the discovery table above to choose the choreography, not whether -Custom Animations exists. Individual pages or groups may remain static, so this -is not an animation-coverage quota. A Quick video run without a validated -`animations.json` fails this requirement unless the user explicitly requests -static or page-transition-only playback. Narration-governed motion also -activates cue synchronization. +**Hard rule — Quick video Custom Animations**: when [`video-design.md`](../../references/video-design.md) is active (recorded, self-running, or video-directed delivery), enable Custom Animations, load `animations.md` before SVG authoring, preserve the semantic motion units, and run `customize-animations` after the final checker — the table above chooses the choreography, not whether Custom Animations exists, and pages may stay static. A Quick video run without a validated `animations.json` fails unless the user explicitly asked for static or transition-only playback. Narration-governed motion also activates cue synchronization. --- ## 2. Source and Resource Preparation -Prepare source facts before initialization: - | Input | Action | |---|---| -| Topic or requirements without supporting facts | Run [`topic-research`](../stages/topic-research.md) immediately and retain its Markdown supplement plus fact-provenance JSON; adopted webpage URLs remain inside that pair and are not import inputs | -| One or more PNG / JPEG / WebP files representing page frames under Image to PPTX | Do not call `source_to_md.py`; normalize single-page files and multi-frame contact sheets into the canonical ordered frame roster through that profile, then import the originals below | -| PDF / DOCX / Office document / XLSX / XLSM / PPTX / EPUB / HTML / LaTeX / RST / web URL | Run `python3 ${SKILL_DIR}/scripts/source_to_md.py <file_or_URL_or_dir> [<file_or_URL_or_dir> ...]` | -| CSV / TSV | Read directly as a plain-text table source | -| Markdown or direct conversation text | Read directly | +| Topic or requirements without supporting facts | Run [`topic-research`](../stages/topic-research.md) and retain its Markdown supplement plus facts JSON; adopted URLs stay inside the pair and are never import inputs | +| PNG / JPEG / WebP page frames under Image to PPTX | Do not call `source_to_md.py`; normalize single pages and contact sheets into the ordered frame roster through that profile, then import the originals | +| PDF / DOCX / Office / XLSX / XLSM / PPTX / EPUB / HTML / LaTeX / RST / web URL | `python3 ${SKILL_DIR}/scripts/source_to_md.py <file_or_URL_or_dir> [...]` (`-t <type>` only when detection is ambiguous; `-o` only for a required output path) | +| CSV / TSV | Read directly as a plain-text table | +| Markdown or conversation text | Read directly | -The conversion dispatcher writes standard Markdown plus its conversion profile -beside each local source by default. Use `-t <type>` only when detection is -ambiguous and `-o` only for a required output path; with several or directory -inputs, `-o` names an output directory. A PPTX is converted to Markdown here and -receives its project analysis during the import step below. +Apply [`conversion.md`](../../scripts/docs/conversion.md) § Image Orientation Review before import when correction is requested, converted text asks for rotated viewing, or an asset is visibly sideways (skip the legacy HTML tool). After reading every source, research only the gaps where the requested outcome would otherwise require inventing, omitting, or leaving unsupported an externally verifiable claim; an Image to PPTX surface is a closed corpus whose unreadable regions become `manual_required`, and a closed/source-only brief stays within its material. When delivery is recorded, self-running, or video-directed — or a final/literal script will become notes/audio — read `video-design.md` now and retain it through roster, SVG, notes, and motion decisions. -**Source-image orientation trigger**: Before import and initialization, follow -[`conversion.md`](../../scripts/docs/conversion.md) § Image Orientation Review -when correction is requested, converted text asks for rotated viewing, or a -downloaded asset is visibly sideways. Skip the legacy HTML tool. +**Template branch** (resolve exactly one before initialization; Image to PPTX always takes free design and installs nothing): -After reading every direct and converted source, assess factual sufficiency: - -| Material state | Action | -|---|---| -| Image to PPTX page surface | Treat as a closed visible corpus; unreadable/occluded regions become `manual_required`, never external research | -| The requested outcome is supported | Continue | -| A required externally verifiable claim remains unsupported | Run [`topic-research`](../stages/topic-research.md) for those gaps only | -| Closed corpus / source-only / no external enrichment | Stay within the supplied material | - -**Sufficiency test**: research only when the requested outcome would otherwise -require inventing, omitting, or leaving unsupported an externally verifiable -claim. File presence or length does not establish sufficiency. Research records -the needed facts and adopted webpage URLs in its research pair. Project -initialization fetches none of those pages; independent AI / web / slice -acquisition remains part of the resource preparation below. - -**Conditional video-delivery context**: when the intended use is recorded, -self-running, or video-directed—or an explicit final/literal narration script -will become notes/audio—read -[`video-design.md`](../../references/video-design.md) now and retain it through -roster, SVG, notes, and motion decisions. This changes neither the Quick profile -nor its artifacts. - -Before initialization, resolve exactly one template branch: - -When [`image-to-pptx.md`](./image-to-pptx.md) is active, its canonical page -surface owns the design: select **Free design** directly and do not inspect, -install, or apply a supplied template workspace. The branches below apply to -ordinary Quick and other compatible profiles. - -- **Direct template application**: one or more exact current workspace roots - were supplied in the request, or Create Template returned an exact validated - root in the current conversation. Accept at most one root per declared kind. - Before initialization, load - [`apply-template-workspace`](../stages/apply-template-workspace.md), normalize - each supplied root, read only the matching spec frontmatter needed to resolve - its kind/canvas, and run that stage's read-only schema/structured preflight. - Do not scan the library, fuzzy-match a name, or open a selector. Explicit user - canvas wins; otherwise use the selected structure owner (Layout before Deck) - canvas when present. Pass that choice to `init --format` only when it exactly - matches a registered canvas; otherwise retain its viewBox for authoring. -- **Free design**: no exact root was supplied. Continue immediately with the - requested canvas when one exists. If no canvas is specified, decide the - viewBox during SVG authoring instead of assigning an initialization default. - A bare template name, brand mention, style phrase, or vague request to choose - a template is ordinary brief input, not a workspace reference. - -Neither branch creates anything under `confirm_ui/` or executes -`confirm_ui/server.py`. Initialize the minimal workspace with: +- **Direct template application** — exact workspace roots were supplied, or Create Template returned one in this conversation: at most one root per kind; load [`apply-template-workspace`](../stages/apply-template-workspace.md), normalize each root, read only the frontmatter needed for kind/canvas, and run its read-only preflight. Never scan the library, fuzzy-match a name, or open a selector. Explicit user canvas wins; otherwise the structure owner's canvas (Layout before Deck), passed to `init --format` only when it exactly matches a registered canvas. +- **Free design** — no exact root: continue with the requested canvas, or decide the viewBox during authoring. A bare template name, brand mention, style phrase, or vague request to pick a template is brief input, not a workspace reference. ```bash python3 ${SKILL_DIR}/scripts/project_manager.py init <project_name> --quick-generate -``` - -**Hard rule — truthful canvas token**: append -`--format <registered_format>` only when the branch above resolved an exact -registered canvas. Otherwise omit it; the first SVG root viewBox becomes the -canvas authority. Never encode custom dimensions as a format token. - -It creates `svg_output/` plus the cold -`validation/workflow.log` command/outcome audit log, and no root README. After -this command, run project-scoped Python tools directly; their shared CLI -bootstrap records command envelopes, material tagged outcomes, bounded status -samples, and omission counts. A concise manual entry is allowed only for a -material stage handoff, rework reason, user-approved exception, or manual -recovery choice that has no owning command output; do not record routine page -progress, artifact contents, or private reasoning. -Never read the log during ordinary Quick execution; open it only for an -explicit user-requested run review. Add -capability inputs only when triggered; later tools create `exports/` and the -default-path `backup/`. - -With file-based sources, import the original inputs, converted outputs, and any -research pair together: - -```bash python3 ${SKILL_DIR}/scripts/project_manager.py import-sources \ <project_path> <source_files_or_dirs...> [<converted_outputs...>] \ [projects/<research_slug>.md projects/<research_slug>.facts.json] ``` -**✅ Checkpoint — every named input landed**: `import-sources` exits 0 as long -as one input produced a usable artifact, so a partially failed batch still -succeeds. Read the printed `skipped` reasons before continuing. An entry skipped -because equivalent content already exists is benign; `path not found`, a failed -conversion, or no usable Markdown means that source is absent. Re-import or -supply a converted equivalent for each absent source, or state why the deck -proceeds without it. +**Hard rule — truthful canvas token**: `--format <registered_format>` only for an exactly resolved registered canvas; otherwise the first SVG's viewBox is the canvas authority, and custom dimensions are never encoded as a token. Neither branch touches `confirm_ui/`. `init` creates `svg_output/` and the cold `validation/workflow.log` (auto-recorded by later tools; one manual note only for a material handoff, rework reason, approved exception, or manual recovery; never read during a run and never a resume source). Use a new path or one whose `svg_output/` is empty; Quick ignores any existing Design Spec or lock and never scaffolds one. -The facts JSON is the sole URL authority, not a download queue. -`project_manager.py` imports it as an ordinary file and never expands its -`source_url` values. If normal web-image search is exhausted, follow -[`topic-research`](../stages/topic-research.md) § Hand-off to fetch one relevant -webpage package, review it, and copy only accepted images into the runtime pool. +**✅ Checkpoint — every named input landed**: `import-sources` exits 0 when one input succeeds; read the printed `skipped` reasons — "equivalent content exists" is benign, `path not found`, failed conversion, or no usable Markdown means the source is absent: re-import, supply a converted equivalent, or state why the deck proceeds without it. Pass a source once when Markdown sits beside it, both locations when `-o` wrote elsewhere; `projects/`-local inputs move (`--copy` keeps them), external paths are copied. Bitmaps are archived under `sources/` and copied into `images/`; EMF/WMF stay vector references (never PNG; blank in browser preview is expected); each PPTX yields `analysis/<stem>.identity.json`, `<stem>.slide_library.json`, and the `source_profile.json` index — source facts, not replica constraints. The facts JSON is the sole URL authority: only after web-image search is exhausted may a webpage package be fetched under [`topic-research`](../stages/topic-research.md) § Hand-off and its accepted images copied in. Under Image to PPTX, the normalized frame roster is canonical input and the agent writes `analysis/reconstruction_inventory.json` before deciding layers. -Only inputs already under the repository's `projects/` tree move into the -target project; every external path is copied and remains untouched. Use -`--copy` when a projects-local input must also remain in place. When conversion -wrote Markdown beside the original source, pass that source path or directory -once; when `-o` wrote it elsewhere, pass both locations. Direct supported bitmap -inputs are archived under `sources/` and copied collision-safely into `images/`. -When [`image-to-pptx.md`](./image-to-pptx.md) is active, its -normalized frame roster is canonical page-surface input and the current main -agent writes the source-evidence-only `analysis/reconstruction_inventory.json` -before deciding the layer stack in active context. +**Installed templates**: run `apply-template-workspace` against the preflighted roots only; the request is the selection authority, with no receipt or handoff, and every later read uses the installed state. Before P01 read each installed spec once and, for Layout/Deck, every SVG prototype; apply Brand identity, Style direction, the structure owner's prototype geometry, and Deck context under the stage's §5 segment precedence — an owner's instruction on how a value dominates, recedes, or stays rare binds as strongly as the value, and a Style tendency never demotes a Brand's dominant color. Freeze one **Template Application** paragraph in context: explicit user instructions first, otherwise the fit of the content to the complete roster, defaulting to reference-led use (redesign after full-roster study; other readings such as augment-only or replacement-only are examples, not a menu). It names which prototypes may be used, skipped, repeated, reordered, or adapted, what stays fixed, and any exception by exact SVG basename; when a detail is later uncertain, reread the installed SVG. -For each imported PPTX, `import-sources` automatically writes -`analysis/<stem>.identity.json`, `analysis/<stem>.slide_library.json`, and the -multi-deck `analysis/source_profile.json` index. Read that index as source facts -and open a per-deck artifact only when the current task needs its additional -detail; these facts are recommendations, not replica constraints. Distinct PPTX -stems may coexist, and re-importing one stem replaces only that deck's entry. - -Conversion companion manifests may place extracted SVG/EMF/WMF assets into the -project resource flow. Preserve EMF/WMF as vector references and never convert -them to PNG; browser preview may be blank while native PPTX export remains the -source of truth. Standalone SVG/EMF/WMF inputs remain source assets unless such -a manifest supplies their display metadata. - -Never scaffold a Design Spec or lock. Use a new path, or verify that an existing -path's `svg_output/` is empty; Quick ignores any existing `design_spec.md` or -`spec_lock.md`. - -The audit log is an operational tool record only. It does not capture direct -SVG authoring, active-context design choices, or private reasoning and cannot be -used to resume or reconstruct a Quick run. - -For the direct-template branch, continue with -[`apply-template-workspace`](../stages/apply-template-workspace.md) after -initialization against only the preflighted roots. The user's request is the -selection authority; there is no template confirmation receipt or handoff. The -stage installs each workspace as its own spec file under `<project_path>/templates/` plus -the project-local asset pools. All later reads use that installed state, never -the original roots. - -Before writing P01, read every installed -`templates/design_spec.<kind>.<id>.md` once and, for Layout/Deck, inspect every -SVG prototype in the installed roster. Apply Brand identity, Style -direction/method, the selected structure owner's prototype geometry, and Deck -application context directly in the active context under the existing segment precedence -([`apply-template-workspace`](../stages/apply-template-workspace.md) §5). A -segment owner's instruction about how a value should dominate, recede, or stay -rare binds as strongly as the value itself; a Style composition or whitespace -tendency never demotes a Brand's declared dominant color to an incidental -accent. - -Resolve one concise **Template Application** paragraph before P01 and freeze it -for this run. Explicit user instructions win. Otherwise decide from the current -content and the complete installed roster; when no stronger fit exists, default -to reference-led use of the template's design and structural system. Common -readings are: reference-led may redesign after full-roster study; augment-only -freezes existing non-slot objects, permits slot edits, and only adds; replacement-only -changes information carriers while preserving the rest. These are examples, -not enum values or a menu. The paragraph states which prototypes may be used, skipped, repeated, -reordered, or adapted and what stays fixed versus replaceable. Any exceptional -rule names the exact SVG basename instead of a semantic label such as “cover”. -Keep the paragraph only in active context; do not create a substitute planning -artifact. If a detail becomes uncertain later, re-read the exact installed SVG -instead of relying on memory or reopening the source PPTX. If no template was -installed, make the same design choices freely. - -Before resolving the one-pass design, read this fixed planning-capability batch -in one pass: +Read the planning-capability batch in one pass — a capability map, not a usage checklist: ``` Read ${SKILL_DIR}/references/canvas-formats.md -Read ${SKILL_DIR}/references/image-layout-spec.md -Read ${SKILL_DIR}/references/image-layout-patterns.md Read ${SKILL_DIR}/references/modes/_index.md Read ${SKILL_DIR}/references/visual-styles/_index.md Read ${SKILL_DIR}/references/image-renderings/_index.md @@ -289,559 +88,139 @@ Read ${SKILL_DIR}/templates/charts/chart-vocabulary.md Read ${SKILL_DIR}/templates/tables/table-vocabulary.md ``` -This batch is the complete capability map for planning, not a usage checklist: -zero use of any capability remains valid. Resolve one recommended whole -solution directly; do not materialize Default's three candidates. Without an -installed template, choose the strongest overall fit from the project brief and -loaded decision authorities. With one, choose the viable solution that most -fully expresses the resolved template context and frozen Template Application, -varying only dimensions they leave open. Freeze its exact mode/style/rendering -ids, then read only those selected detail files or custom bases. A novel custom -reads none. Never open unselected detail siblings to compare candidates, glob a -catalog, or let them influence the decision. Decide -whether AI images are useful as a separate source judgment; even when the -answer is no, retain the chosen rendering direction for visual coherence. Keep -the chosen mode, style, rendering, and exact bases in active context only. +Resolve one whole solution directly (never Default's three candidates): the strongest fit to the brief, or with a template the solution that most fully expresses the installed context and frozen Template Application. Freeze its mode/style/rendering ids, read only those detail files or exact custom bases (a novel custom reads none; never open unselected siblings), decide AI-image usefulness as a separate source judgment while keeping the rendering direction for coherence, and keep everything in active context only — no strategy summary, checkpoint, or persisted plan. -**One-pass decision boundary**: resolve only what is needed to author this deck -in the current context. Do not print a strategy summary, create a planning -checkpoint, or persist a page/resource plan. +**Pre-P01 resolution** (apply the §1 motion gate here; freeze the roster after the rhythm check): -Before P01, apply the §1 gate while co-resolving these choices; freeze -the roster after the whole-roster check: +- Narrative beats, mental-map arcs, candidate visible states and their deltas, and enabled notes segments; adopt continuity only when it clarifies, and never alter profile-fixed count/order/content to manufacture endpoints. +- Effective Speaker Notes, Custom Animations, and Narration Audio: narration requires notes; later recording alone forces neither audio nor object animation; recorded/self-running/video delivery follows `video-design.md` and enables Custom Animations before authoring; direct narrated video also decides before audio whether narration governs group timing. +- The exact slide roster with one compact core message per page. +- Canvas, visual direction, wording, viewing distance, and reading mode (`presentation` for distance-first projected or recorded viewing, `balanced` for mixed, `text` for close content-heavy reading). Take the initial body anchor and sanity band from [`canvas-formats.md`](../../references/canvas-formats.md) § Typography Scale Start, then resolve one typography plan for the delivery target of [`shared-standards-core.md`](../../references/shared-standards-core.md) §4.1 — never the authoring host's fonts — with stable anchors for title, body, annotation, and every recurring role. When content does not fit, restructure, shorten, or split within the invariants; if none is permitted, surface the fit rather than shrinking a recurring role. +- The semantic color roles the roster needs (background/surface, primary/secondary text, dominant/accent, status), each with a concrete anchor: honor user, template/brand, fidelity, and resolved-style semantics before deriving the missing roles; decide which dominate, support, or stay rare; keep meaning-bearing text legible; pair any newly authored color-coded distinction with a label, symbol, line, or geometry cue. +- A body-content frame and a density judgment per page (`anchor`, `dense`, `breathing`) rather than one uniform fill. +- For each page, its semantic units and their source-stated relationship (`order` / `link` / `parent` / `membership` / `contrast` / `overlap`, or none), entry, and outcome — the input to §3's Structure decision; zones, geometry, and carriers are §3 authoring decisions. +- The deck-level shape language under [`visual-styles/_index.md`](../../references/visual-styles/_index.md) §2, and, when it earns a continuity job, one transient motif system with an invariant and a reuse mode (fixed chrome, adaptive variation, or both); restraint governs weight and recurrence, never the omission of an evidenced identity or communication motif. +- Resource decisions for immediate preparation: manifests may carry filenames, page relationship, status, and generation/crop/focal cues (plus subject/quiet zones, boundary, seam, and share when composition depends on them); no general roster or icon-to-page assignment; each formula's LaTeX and each hyperlink's exact target kept in context, with no manifest. An explicit user implementation path wins; otherwise the registered default. -- the narrative beats, mental-map arcs, candidate visible states, their semantic deltas, and enabled notes segments. Adopt continuity only when it clarifies the message. Profile-fixed count/order/content, including 1:1/fidelity, permits only existing-neighbor evaluation; never alter those invariants to manufacture endpoints; -- the effective Speaker Notes, Custom Animations, and Narration Audio outcomes; narration requires notes, later recording alone forces neither audio nor object animation, while a Quick recorded/self-running/video delivery purpose follows [`video-design.md`](../../references/video-design.md) and enables Custom Animations before SVG authoring; direct narrated video additionally enables notes/narration/video and decides before audio whether narration governs group timing; -- the resulting exact slide roster and one compact core message for every page, used to choose its composition and hierarchy; -- the canvas, visual direction, wording, intended viewing distance, and effective reading mode: choose `presentation` for distance-first projected or recorded viewing, `balanced` for mixed viewing, or `text` for close content-heavy reading. Take the initial body anchor and sanity band from [`canvas-formats.md`](../../references/canvas-formats.md) § "Typography Scale Start" for the resolved canvas—PPT remains reading-mode-driven, while registered/custom non-PPT canvases use their canvas-derived start—then resolve one concrete typography plan for the delivery target defined by [`shared-standards-core.md`](../../references/shared-standards-core.md) §4.1, never from the authoring host's font inventory, with stable size anchors for title, body, annotation, and every other recurring role the roster uses. When content does not fit, preserve its core message and apply only fitting actions the source/profile invariants permit—restructure, shorten, or split; if none is permitted, surface the unresolved fit instead of shrinking a recurring role. Explicit user, template, fidelity-profile, or resolved-style requirements may call for a deliberate exception; -- the semantic color roles actually needed by the roster, each with a concrete active-context color anchor, including background/surface, primary/secondary text, dominant/accent, and status roles as applicable. Honor explicit user, installed template/brand, fidelity-profile source-identity, and resolved-style color semantics before deriving only the missing roles that the active profile permits; decide which roles dominate, support, or remain rare, and preserve sufficient contrast for meaning-bearing text. Pair newly authored color-coded states, categories, or relationships with a label, symbol, line, or geometry cue; when fidelity forbids adding one, preserve the source encoding; -- an ordinary body-content frame and a density judgment for every page, adapted to the canvas and any user / template / style geometry; use `anchor`, `dense`, `breathing`, or an equivalent active-context distinction instead of one uniform fill level; -- for each page not bound to literal supplied geometry, a primary visual zone and one compact page-scale geometry job tied to its core message—what geometry must organize, without naming a preset or encoding form; keep it only in the transient roster for §3's authoring-time move; -- for each page, preserve its semantic units, source-stated qualitative relationships, intended entry, and outcome so §3 can make the sole Structure decision before geometry; -- the resolved visual direction's deck-level shape language under - [`visual-styles/_index.md`](../../references/visual-styles/_index.md) §2, - retained for page-fit native geometry without selecting an exact preset here; -- when useful, an additional transient deck-level visual motif system with an identity or - communication job, a recognizable invariant, and a reuse mode: fixed chrome, - adaptive variation, or both; treat restraint as control of visual weight, - recurrence, and reuse, not as a reason by itself to omit an evidenced source, - identity, or communication motif; omit the system when no motif earns a - continuity job or when reuse would add false meaning, compete with the page - message, or reduce clarity; -- the resource decisions needed for immediate preparation. Required operational - image manifests may carry filenames, page relationship, status, and - generation/crop/focal cues. When page use depends on stable composition, also - retain subject/quiet zones, boundary or direction, intended overlap/seam, and - approximate share only when needed. Do not create a general resource roster - or icon-to-page assignment. Keep each selected formula's source LaTeX in active - context for direct marker authoring; retain each selected hyperlink's exact - absolute URI or 1-based same-deck target; create no formula/link manifest; -- the implementation path for each resource. An explicit user path wins; - otherwise choose the registered automatic/default path without another - interaction. +**Mandatory — whole-roster rhythm check**: compare neighbors and section arcs — chapter entries visibly reset, same-density, same-resource, or same-relationship runs are intentional page-job arcs, a repeated motif carries a continuity job, each section follows a mode-fitting progression (including framework → explanation/evidence → judgment/action when it serves), and the final arc resolves the objective before a genuine ending lowers load. Same section, equal density, one style, and precedent establish no arc. Repair the transient roster in place; preserve intentional continuity, legitimately all-`dense` material, and 1:1 order; add no filler — a `breathing` page marks a real pause. No artifact or second pass. -**Prepared final narration**: when the user explicitly marks a script as -final/literal and intends it for notes or generated audio, segment it by semantic -scene while resolving the roster and preserve every spoken word. Before writing -P01, write the ordered segments once to `notes/total.md` with -`# Slide <number>` headings and `---` separators. Keep that file as exact -production input for page design; it is not a planning checkpoint. Do not split -it until the SVG roster exists. Draft narration instead remains source material -and uses the ordinary post-SVG notes branch when notes are enabled. +**Prepared final narration**: an explicit final/literal script for notes or audio is segmented by scene while resolving the roster, every word preserved, and written once before P01 to `notes/total.md` (`# Slide <number>` headings, `---` separators) as production input, split only after the roster exists. Draft narration stays source material for the ordinary notes branch. -**Mandatory — image treatment / subject layers**: Before preparation choose per -image: `none`; native SVG crop/transform/depth; or prepared -blur/tone/cutout/registered layers. `none` is valid. A subject crossing native -content requires a clean full-canvas base plus registered RGBA cutout -(`#A2-03`; [`image-generator.md`](../../references/image-generator.md) §4.4); -a floating cutout may use `#A2-01`. Finish assets before SVG per -[`image-base.md`](../../references/image-base.md) §2–3. +**Default — resource need per page (may stay implicit when a page's need is obvious)**: before resources, decide which pages need a prepared image, lettering, or illustrated-icon resource — the jobs only a prepared file can serve; SVG/emoji icons keep their curated-pool boundary. The page's carrier mix itself — background, text, native geometry, imagery, icons, visualizations and their weights — is §3's authoring decision, not a preparation decision. The resolved style controls treatment and recurrence but never eligibility, source, or the native vocabulary, and a compact icon cue does not discharge a scene, subject, or visual-weight job a photo or illustration family would serve. -**Prepared derivative**: create it with `image_treat.py` (blur, -desaturation/grayscale, duotone, brightness, contrast) under a name separate -from its source. The canonical file stays intact: a derivative never overwrites -its source, never becomes another derivative's parent, and never has its output -equal its input. Derive only after that source is itself final. - -**Mandatory — whole-roster rhythm check**: During the same active-context -resolution, compare neighbors and section arcs to judge whether chapter entries -visibly reset, extended same-density runs are intentional, extended repetitions -of one carrier or composition move form an intentional page-job arc, repeated -dominant geometry carries a continuity job, each section follows a mode-fitting -progression—including framework → explanation/evidence → judgment/action when -it serves the objective—and the final arc resolves the communication objective -before a genuine ending lowers information load. Same section, equal weight or -density, one style, and prior-page precedent do not establish a page-job arc. -Repair the transient roster, density, and composition choices in place. This is -judgment, not quota; preserve intentional continuity, legitimately all-`dense` -material, and 1:1/literal order. Add no filler page: a `breathing` page marks a -meaningful pause—chapter transition, standalone emphasis, or SCQA bridge—and -must stand alone. Create no artifact, checkpoint, lock, or second -authoring/review pass. - -**Default — page carrier resolution (may stay implicit when a page's mix is obvious)**: During -the same transient-roster resolution and before resource preparation or -coordinates, decide each page's mix of background, editable text and -optional lettering, native geometry and lines, photos/scenes, -illustrations/icons, and applicable visualizations. Decide their primary, -structural, and supporting jobs together. Only selected image, -lettering, or illustrated-icon jobs with plausible page roles create image -resources; ordinary SVG/emoji icons retain their curated-pool boundary. -Omitting any carrier is valid after this review; Quick speed, resolved style, -or easier syntax never skips it. - -**Reference — carriers compose, not compete**: Use any suitable subset from the resolved mix; outside explicit requirements, no carrier is mandatory or mutually exclusive. The resolved style controls treatment, visual weight, and recurrence; it never decides carrier eligibility, image source, or the complete native construction vocabulary. A compact icon cue does not discharge a scene, subject, or visual-weight job that a photo or illustration family would serve. - -**Hard rule**: Credentials do not decide image need or the initial carrier plan. Do not inspect backend configuration or probe a provider before planning. Web acquisition retains zero-config providers; actual AI generation capability is resolved only during resource preparation, where the declared Quick no-AI replan below owns automated exhaustion. - -**Default — visual grounding before a zero-image deck (may override when the full-roster carrier review finds no useful image job)**: Honor an explicit no-image requirement. When the audience must recognize, experience, compare, or choose an externally verifiable subject, place, product, or setting, plan supplied/extracted or web images. Prepare AI imagery proactively where invented or deliberately stylized expression materially improves a planned visual job; this may be a complete image or transparent elements composed with other page carriers. This is a semantic decision, not an image-count quota. - -**Mandatory — materialize a selected composable illustration family**: When -the carrier resolution selects one, resolve the family before SVG authoring. -Elements may repeat unchanged as title/corner chrome or vary as dominant -anchors, supporting figures, and accents on any suitable page. Batch compatible -elements through Illustration Sheets, split only for geometry/detail/quality -conflicts, and keep final page composition in SVG under -[`image-generator.md`](../../references/image-generator.md) §4.3. - -**Mandatory — materialize selected AI illustrated-icon jobs**: When the carrier -resolution selects them and the user has not forbidden AI, prepare useful cues -as transparent slices under `images/`. Leave grouping, count, and coexistence -with SVG icons to the page and deck fit under -[`image-generator.md`](../../references/image-generator.md) §4.3; apply no -coverage quota and never treat the slices as SVG inventory. - -**Reference — decorative-lettering candidates**: when the user has not -forbidden AI, any display string in the frozen roster is a candidate. Two -questions expose candidates: is -that wording stable, and could an artistic treatment plausibly communicate -better than native type? Passing both exposes a possible AI visual job; it does -not select lettering or add AI by itself. Page role, string length, line count, -kind of noun, and resolved style never pre-filter candidates — -a cover hook, chapter word, place or product name, dish or exhibit name, year, -hero number, pull quote, or recurring motif word all qualify when both answers -are yes. Read any such list as examples, never as the set of allowed cases; a -two-character mark, an eight-character phrase, and a two-line lockup are equally -valid, and a phrase is never trimmed toward one or two characters to feel more -"wordmark-like". Set over photography or a busy field is often exactly where -native type reads pasted-on. Compare every candidate inside the complete page -and deck carrier mix, then select any coherent set whose treatment wins that -fit; selecting none remains valid and needs no skip explanation or coverage -quota. For every selected mark, keep a native title wherever the page needs a -searchable, selectable, or outline-visible heading, with the lettering as its -display layer. Prepare the selected set without a separate request: preserve -the exact approved strings, use one ordinary AI -item for a single mark or group compatible marks through Illustration Sheets -and transparent slices. Let the intended character and treatment guide grouping. -Give the model the marks' role, placement/background relationship, relative -visual weight, and energy; apply `image-generator.md` §5.3's -controlled-default/high-expression boundary. Split when geometry, quality, or -the intended treatment benefits, and keep ordinary -title/chrome copy native. A prepared wordmark -and an editable title are not mutually exclusive: -one page may carry the wordmark as its display layer while its subtitle, chrome, -and body stay native text, so a wish to keep that wording editable is answered -by the native layer rather than by dropping the lettering. AI permission is not -coverage: never invent or alter copy, or create lettering merely to justify AI -usage. Actual generation capability is resolved during resource preparation, -after selection rather than during candidate discovery. - -| Communication job | Available carrier | +| Communication job | Prepared resource or information model | |---|---| | Real subject, place, product, evidence, atmosphere, or scene benefits from visual grounding | Supplied/extracted, web, AI, or sliced image | -| Reusable title/corner decoration, a dominant illustrated anchor, supporting figure, or accent strengthens one or more page compositions | A coherent AI illustration family prepared as transparent `slice` assets and combined freely with other carriers | -| A compact semantic cue clarifies a category, process, KPI, state, or navigation item | Prepared project-local SVG/emoji icon, an illustrated-icon `slice`, or a coherent combination | -| A real company, product, service, or social brand must appear as itself | Prepare the exact brand mark from `simple-icons` or supplied project assets as needed; it is not a user-facing library choice | -| Editable geometry can express a relationship, flow, emphasis, callout, symbol, or diagram | Page-fit contours from the full native vocabulary, then their simplest exact authoring forms; independent composition when possible, required Boolean next, necessary freeform last | +| Reusable title/corner decoration, a dominant illustrated anchor, supporting figure, or accent strengthens compositions | A coherent AI illustration family as transparent `slice` assets, combined freely with other carriers | +| A compact semantic cue clarifies a category, process, KPI, state, or navigation item | Prepared project-local SVG/emoji icon, an illustrated-icon `slice`, or both | +| A real company, product, service, or social brand must appear as itself | The exact mark from `simple-icons` or supplied assets; not a user-facing library choice | | Values, categories, time, weights, or duration determine mark geometry | Value-driven chart | -| Sequence, hierarchy, role, region, or relationship determines page-local topology | Qualitative structure | -| Rows, columns, cells, headers, merges, and alignment form the information model | Cell-grid table | -| Mathematical notation is clearer as typeset math than ordinary text | PowerPoint-native inline or block math | -| Any stable display string in the deck — cover hook, chapter word, place or product name, dish or exhibit name, year, hero number, pull quote, motif word — reads better with a material, dimensional, hand-rendered, or otherwise illustrative treatment than as ordinary text | Apply the proactive rule above; place prepared lettering assets as images and keep ordinary editable title/chrome in separate text frames | -| Typography, spacing, and simple geometry already carry the message | Use no additional visual carrier | +| Sequence, hierarchy, role, region, or relationship determines topology | Qualitative structure | +| Rows, columns, cells, headers, merges, alignment form the model | Cell-grid table | +| A stable display string reads better with a material, dimensional, hand-rendered, or illustrative treatment | Decorative lettering per the rule below, as an image beside a native title | -This carrier menu does not satisfy or replace the per-page Structure decision in §3. +This menu never satisfies the per-page Structure decision in §3. -**Mandatory — per-image source decision, never inherited from the resolved style**: During that same carrier resolution, outside Image to PPTX whose closed page surface owns its reconstruction assets, decide each selected page image's source separately — supplied/extracted, web, AI, or slice. Prefer a supplied/extracted asset that already carries authority; use web when an externally verifiable subject must appear as itself; use AI when invented or deliberately stylized expression matters more than documentary identity. Mixed sources across one deck are normal. +**Hard rule — credentials never decide image need**: plan carriers without inspecting backend configuration or probing a provider; web search keeps zero-config providers, and AI capability is resolved during preparation, where the no-AI replan owns exhaustion. -Resolving one visual style, `Illus.` propensity, or generated-image rendering resolves how imagery **looks**; it resolves the source for no page. A named place, building, product, artwork, person, or other externally verifiable subject stays a web/supplied candidate no matter how illustrative the deck looks. When such a subject is deliberately not shown as itself, state that choice and its reason in the final report rather than leaving it implicit. +**Default — visual grounding before a zero-image deck (may override when the full-roster review finds no image job)**: honor an explicit no-image requirement; otherwise, when the audience must recognize, experience, compare, or choose an externally verifiable subject, plan supplied/extracted or web images, and prepare AI imagery — a complete image or transparent elements — where invented or stylized expression materially improves a visual job. A semantic decision, not a quota. -**Reference — Chart/Table vocabularies**: the already-loaded Chart and Table -expression vocabularies list what exists for a page's information model; their descriptions do not rank -candidates or replace judgment from the actual information, and they are -neither usage quotas nor whitelists. Do not select a catalog reference for -qualitative shape composition. Choose at most one primary Chart/Table -`family/key` for a page, validate it with `visualization_recall.py validate`, -and keep its short purpose only in active context. Retain `no-template-match` -when none fits. The reference remains flexible: it does not lock final type, -geometry, style, or native output. -Describe an embedded child Chart/Table and every qualitative relationship in -the page's active decision rather than selecting another primary reference. -Actual information models determine the loaded execution branches. Give every independent -Chart/Table a page-local semantic `kebab-case` object key; keep its -`<object-key>=yes|no` native-ready decision and any promoted chart-verification -status in active context. Qualitative relationships create no catalog key or -reusable Master/Layout/placeholder contract. +**Mandatory — illustration families and illustrated icons**: when the resource-need review selects a composable family, resolve it before authoring — elements may repeat as title/corner chrome or vary as anchors, figures, and accents on any page — batching compatible elements through Illustration Sheets under [`image-generator.md`](../../references/image-generator.md) §4.3 and splitting only for geometry, detail, or quality conflicts. When it selects illustrated-icon cues and AI is not forbidden, prepare them as transparent slices under `images/`; grouping, count, and coexistence with SVG icons follow page fit, with no quota and never as SVG inventory. -Prepare only the resource paths needed by the decided pages: +**Reference — decorative-lettering candidates**: when AI is not forbidden, any display string in the frozen roster is a candidate on two questions — is the wording stable, and could an artistic treatment communicate better than native type? Page role, length, line count, kind of noun, and resolved style never pre-filter: a cover hook, chapter word, place or product name, dish or exhibit name, year, hero number, pull quote, or motif word all qualify, a two-character mark and a two-line lockup equally, and a phrase is never trimmed to feel more "wordmark-like"; type over photography or a busy field is often exactly where native text reads pasted-on. Compare candidates inside the whole page and deck mix and select any coherent set whose treatment wins; selecting none is valid without explanation. For each selected mark keep a native title wherever the page needs a searchable, selectable, or outline-visible heading — the lettering is the display layer, the editable wish is answered by the native layer. Prepare the set without a separate request: exact approved strings, one ordinary AI item or grouped Illustration Sheets with transparent slices, grouped by character and treatment, with role, placement/background relationship, weight, and energy given to the model under `image-generator.md` §5.3's controlled-default/high-expression boundary; chrome and body stay native. Never invent or alter copy or create lettering to justify AI. -| Resource | Required preparation | +**Mandatory — per-image source decision**: outside Image to PPTX, decide each page image's source separately — supplied/extracted when it carries authority, web when an externally verifiable subject must appear as itself, AI when invented or stylized expression matters more than documentary identity; mixed sources are normal. A visual style, `Illus.` propensity, or rendering resolves how imagery looks, never its source: a named place, building, product, artwork, or person stays a web/supplied candidate however illustrative the deck, and a subject deliberately not shown as itself is stated with its reason in the final report. + +**Mandatory — image treatment and subject layers**: choose per image: `none`; a native SVG treatment (crop viewport, opacity, frame, scrim, shadow); or a prepared derivative. A subject that crosses native content requires a clean full-canvas base plus a registered RGBA cutout (`#A2-03`). A prepared derivative never overwrites its source, never becomes another derivative's parent, never has its output equal its input, and is derived only after that source is itself final. Where fidelity forbids adding a label, symbol, line, or geometry cue to a new color encoding, preserve the source encoding instead. + +**Reference — Chart/Table vocabularies**: the loaded vocabularies list what exists; they rank nothing and are neither quota nor whitelist. Choose at most one primary `family/key` per page (never for qualitative composition), validate it with `visualization_recall.py validate`, keep its purpose in context — the reference stays flexible and locks neither final type, geometry, style, nor native output — and retain `no-template-match` when none fits; describe embedded children and qualitative relationships in the page decision. Give every independent Chart/Table a page-local `kebab-case` key with its `<object-key>=yes|no` native-ready decision and any promoted chart-verification status in context; qualitative relationships create no key or reusable structure. + +**Resource preparation** (only what the decided pages need): + +| Resource | Preparation | |---|---| -| Supplied/extracted image | Copy the selected file into `images/`; preserve its factual/provenance context and use the measured file rather than an invented substitute | -| Image-to-PPTX reconstruction asset | In Codex, preserve identity graphics through an exact vector, deterministic redraw, sufficient source asset, or reference-based high-resolution reconstruction; keep data graphics native-and-verified or exact. For scene imagery, build the minimum registered clean-base/midground/subject/foreground group; batch padded-bbox-disjoint objects into one shared plate, then split them with grid slicing or independent nested-SVG bbox crops | -| Bundled/custom/brand SVG icon | Follow the [icon library contract](../../templates/icons/README.md), use one primary generic library per pool (`icon_sync.py` rejects mixed batches), sync the project pool without assigning icons to pages, and prepare `simple-icons` marks for brands the content names | -| Formula | Create no resource file. Retain the exact source LaTeX, then choose ordinary text, an inline native marker, or a block native marker under §3; the registered SVG preview is discarded by native export | -| AI image | Follow `image-base.md` + `image-generator.md`; apply only the chosen rendering preset or exact custom bases, never blend unselected catalog identities, and keep `image_prompts.json` plus its human-readable sidecar | -| Web image | Follow `image-base.md` + `image-searcher.md`; keep query/status data and `image_sources.json`, including any required on-slide attribution | -| Composable illustration / illustrated-icon / lettering slice | Generate or obtain the parent sheet, run `slice_images.py --trim --alpha --bg KEY_HEX_FROM_PROMPT --strict-alpha`, and place only outputs from a successful strict cut. Slices remain under `images/` and may serve several pages; each lettering sheet still names every exact stable string assigned to it | -| Registered reconstruction group | Follow `image-generator.md` §4.4; keep full-canvas members registered with `crop=no-crop`, and materialize every required shared-plate member as an independent picture object | -| Visualization | Keep Chart values, Table cell topology, and chosen treatment in active context; load the applicable Chart/Table authority in §3 and write native replacement metadata for every supported chart and pure text grid, which are native-ready by default | +| Supplied/extracted image | Copy the selected file into `images/`; keep its provenance; use the measured file | +| Image-to-PPTX reconstruction asset | In Codex, preserve identity graphics through an exact vector, deterministic redraw, sufficient source asset, or reference-based high-resolution reconstruction; keep data graphics native-and-verified or exact; build the minimum registered clean-base/midground/subject/foreground group for scene imagery, batching padded-bbox-disjoint objects into one shared plate split by grid slicing or nested-SVG crops | +| Bundled/custom/brand SVG icon | [Icon library contract](../../templates/icons/README.md): one primary generic library per pool (`icon_sync.py` rejects mixed batches), synced without page assignment; `simple-icons` for named brands | +| Formula | No resource file; keep the LaTeX and choose text, inline marker, or block marker in §3 | +| AI image | `image-base.md` + `image-generator.md`; only the chosen rendering preset or exact custom bases; `image_prompts.json` plus its readable sidecar | +| Web image | `image-base.md` + `image-searcher.md`; query/status data and `image_sources.json` with any required on-slide attribution | +| Illustration / illustrated-icon / lettering slice | Obtain the parent sheet, run `slice_images.py --trim --alpha --bg KEY_HEX_FROM_PROMPT --strict-alpha`, place only outputs of a successful strict cut; slices stay under `images/` and may serve several pages; a lettering sheet names every exact string | +| Registered reconstruction group | `image-generator.md` §4.4: full-canvas members `crop=no-crop`, every shared-plate member an independent picture | +| Visualization | Keep values, cell topology, and treatment in context; load the Chart/Table authority in §3 and write native replacement metadata for every supported chart and pure text grid (native-ready by default) | -**Hard rule — planned slice closure**: Every placeable-element sheet carries `slice_grid` plus comma-separated `slice_names` in `image_prompts.json`. Deterministically enumerate those basenames and require every `images/<name>.png` after an exit-0 `slice_images.py --strict-alpha` run before SVG authoring; a `Generated` parent sheet never satisfies its named outputs. A nonzero slice run returns the parent to image preparation: correct only an evidenced key/tolerance mismatch, then enlarge cells or split incompatible shape families and regenerate when content reaches a cell edge. Repeating the same failing grid is not recovery. An explicitly selected manual path retains the marker, sets the affected item to `Needs-Manual` with `last_error`, and blocks Quick SVG/export until every named output is supplied and validated. Exhausted automated AI generation or dependent slicing instead follows the no-AI replan below; never retain an unresolved AI/slice row merely to continue. +**Hard rule — planned slice closure**: every sheet carries `slice_grid` and `slice_names` in `image_prompts.json`; every `images/<name>.png` must exist after an exit-0 `--strict-alpha` run before authoring — a `Generated` parent never satisfies its outputs. A nonzero slice run returns the parent to preparation: correct only an evidenced key/tolerance mismatch, otherwise enlarge cells or split incompatible families and regenerate; repeating the same failing grid is not recovery. An explicit manual path sets the item `Needs-Manual` with `last_error` and blocks SVG/export until every output is supplied and validated; exhausted automation follows the no-AI replan instead. -**Validation**: Before §3, verify every required file-backed resource has a usable terminal state and every `slice_names` basename resolves to its real PNG output. Any missing name resumes the owning acquisition/slicing step; it cannot be deferred to the final SVG checker. +**Quick exhausted-automation no-AI replan** ([`image-generator.md`](../../references/image-generator.md) §7): when an automated AI path or its dependent slicing is exhausted, ask no path question and enter no manual fallback — remove the affected AI jobs and stale manifest entries, carry their communication content with native text/SVG or prepared non-AI assets, and continue; retaining AI imagery means repairing capability and starting a new Quick run. -**Quick exhausted-automation no-AI replan**: Follow [`image-generator.md`](../../references/image-generator.md) §7 when an automated AI path or its required dependent slicing is exhausted: ask no path question, enter no manual fallback, remove the affected AI jobs and stale manifest entries, preserve their communication content with native editable text/SVG or already prepared non-AI assets, and continue the same run. An explicitly selected `manual` path remains subject to the file-readiness gate. To retain AI imagery after automated failure, repair the generation capability and start a new Quick run. - -**Image inspection boundary**: acquisition-time suitability review follows the -owning AI/web/slice reference. Once resources reach terminal status, SVG -authoring follows `executor-image.md`'s narrow placement inspection: inspect only -one specifically ambiguous `Existing`/`Sourced` asset and never routinely reopen -`Generated` outputs. Image to PPTX is the narrow fidelity exception: inspect -every normalized page once for its inventory, inspect every generated -reconstruction layer or shared plate once, and inspect the final recomposition -against the canonical frame. Reopen only the current page or one unresolved -region after that required comparison. - -After image resources change, run `analyze_images.py` so -`analysis/image_analysis.csv` reflects the files that SVG authoring will use. -Operational manifests and provenance are resource truth, not a hidden design -strategy. - -Every required file-backed resource must reach a usable terminal state before -its page. Web `Needs-Selection` blocks until one thumbnail is promoted or the -bounded ranked pages and materially different query variants are exhausted; -only then may a vision-capable owner fetch one adopted-page source package, -review its companion images, and promote only accepted files; never auto-expand -facts URLs or use those packages as the initial pool. -`Needs-Manual` blocks even when an unverified file exists. With no visual -capability, only the strict metadata-ranked web path may reach `Sourced`, and -its provenance must say `selection_method: metadata-ranked` rather than imply -visual confirmation. After selection or manual supply/replacement, validate -evidence and reconcile to `Existing`, `Generated`, or `Sourced`; never bypass -status by preview/file presence or substitute unrelated material. Native -formula markers are authored page content, not file-backed resources or -terminal-status rows. +**Validation before §3**: every file-backed resource is terminal — `Existing`, `Generated`, or `Sourced` under [`svg-image-embedding.md`](../../references/svg-image-embedding.md) — and every `slice_names` basename resolves to its PNG; a missing name resumes its owning step and is never deferred to the checker. Web `Needs-Selection` blocks until a thumbnail is promoted or the bounded ranked pages and materially different variants are exhausted, after which a vision-capable owner may fetch one adopted-page package; `Needs-Manual` blocks even with an unverified file; without vision only the strict metadata-ranked path reaches `Sourced`, and its provenance says so. Never bypass status by preview or presence, never substitute unrelated material. Acquisition-time review follows the owning reference; authoring inspects only one ambiguous `Existing`/`Sourced` asset under `executor-image.md` and never reopens `Generated` outputs (Image to PPTX inspects every normalized page and generated layer once, then the final recomposition). After resources change, run `analyze_images.py`; manifests and provenance are resource truth, not a design strategy. --- ## 3. Direct SVG Authoring -Read fixed references together, never file by file: -[`shared-standards-core.md`](../../references/shared-standards-core.md), -[`executor-base.md`](../../references/executor-base.md), -[`svg-effects.md`](../../references/svg-effects.md), -[`native-shape-authoring.md`](../../references/native-shape-authoring.md), -[`preset-shape-vocabulary.md`](../../references/preset-shape-vocabulary.md), -[`semantic-svg.md`](../../references/semantic-svg.md), -[`executor-structure.md`](../../references/executor-structure.md), -and [`topology-assembly.md`](../../references/topology-assembly.md). -Installed Layout/Deck structure loads -[`pptx-structure-interface.md`](../../references/pptx-structure-interface.md). -Keep one-pass-selected mode/style files and realize that direction. Exact -`*_references` define the catalog material -actually used by a custom: apply one basis under its behavior, synthesize several -by their stated contributions, or follow the behavior directly when none exist. +Read the execution core together, never file by file: [`shared-standards-core.md`](../../references/shared-standards-core.md), [`executor-base.md`](../../references/executor-base.md), [`semantic-svg.md`](../../references/semantic-svg.md), and [`preset-shape-vocabulary.md`](../../references/preset-shape-vocabulary.md) (complete, before P01); then evaluate `executor-base.md`'s routing triggers once over the frozen roster before P01 and read every triggered module in the same batch — [`executor-structure.md`](../../references/executor-structure.md) + [`topology-assembly.md`](../../references/topology-assembly.md) for any `Structure = yes` page, [`native-shape-authoring.md`](../../references/native-shape-authoring.md) for any contour beyond basic primitives, [`svg-effects.md`](../../references/svg-effects.md) for any visual job beyond the everyday block — each recorded in the module line of the pages that use it; a page that reaches a capability the sweep did not foresee reads its module at that moment, before its first SVG line; installed Layout/Deck structure adds [`pptx-structure-interface.md`](../../references/pptx-structure-interface.md). Keep the selected mode/style files: a custom applies one basis under its behavior, synthesizes several by their contributions, or follows the behavior alone. When any image exists, read the complete `Any image` row of `executor-base.md`'s routing table — [`executor-image.md`](../../references/executor-image.md), [`image-layout-spec.md`](../../references/image-layout-spec.md), [`image-layout-patterns.md`](../../references/image-layout-patterns.md), and [`svg-image-embedding.md`](../../references/svg-image-embedding.md) — once before the first affected page (plus [`executor-web-image.md`](../../references/executor-web-image.md) for a `Sourced` image); reread anything only after a known file change or context invalidation. -`executor-base.md` binds Quick authoring exactly as it binds Default, except -its items marked `Default only` — the persisted-plan handoff in §2 / §2.1, the -`Generation rhythm` and first-page gate, §6, and §7 — which Quick's transient -§2 anchors, single final checker, and export steps below own instead. Reuse the -already-loaded image-layout authorities. When any image -exists, read once before the first affected page and reuse throughout the valid -execution context: [`executor-image.md`](../../references/executor-image.md) -and [`svg-image-embedding.md`](../../references/svg-image-embedding.md); add -[`executor-web-image.md`](../../references/executor-web-image.md) for a placed -`Status: Sourced` image or filename recorded in `image_sources.json`. -Reread only after a known file change or context invalidation. +`executor-base.md` binds Quick exactly as it binds Default except its `Default only` items — the persisted-plan handoff in §2 / §2.1 and the export hand-off in §6 — which Quick's transient §2 anchors, single final checker, and export below own; the Default gate cadence lives in `generate-pptx.md` Step 6 and does not apply. Conditional authorities load on its routing table (Chart/Table branches, native data, formula, hyperlink); Chart/Table reference and final information model are independent signals, and selection never makes an object native-ready. Explicit user/template requirements and the resolved style override compatible aesthetic defaults, never technical boundaries, carrier eligibility, or native capability discovery. -`executor-structure.md` is loaded once before all SVG authoring so every -`Structure=yes` result can resolve its qualitative topology. -`topology-assembly.md` supplies assembly and relative-registration material for -that resolved topology; `native-shape-authoring.md` owns the two-step assembly -gate, contour selection, and compound page geometry for both Structure results. -Reuse all three throughout the valid execution context; before P01, read the -complete preset vocabulary once, then reread only after a known file change or -context invalidation. +**Mandatory — per-image-page composition**: for every page with images, after content and communication move but before geometry, apply `executor-image.md`'s image-integration decision once, keeping role, direction source, parent contour, slot/rhythm system, image/shape action, and continuity in context only; a deliberate plain or equal-grid result is valid when it communicates better. Image to PPTX replaces this and the page-geometry decision for its canonical frame: preserve source geometry, restore text natively, keep source-graphic identity through the prepared asset, and use the registered layer/plate stack; run the ordinary decisions only for additional non-source content. -**Mandatory — per-image-page composition decision**: For every page with one -or more images, after its content and communication move are -determined but before choosing geometry, apply -[`executor-image.md`](../../references/executor-image.md)'s active image-integration -decision once. Keep its role, direction source, parent -contour, slot/rhythm system, image/shape action, and any continuity only in -active context; create no artifact, spec, lock, manifest, or extra pass. A -deliberate plain or equal-grid result remains valid when it communicates the -relationship better. +**Mandatory — native formulas and hyperlinks**: no resource or manifest for either. Keep the exact LaTeX and choose ordinary text, same-paragraph inline math, or a standalone block with its SVG preview under [`native-formula.md`](../../references/native-formula.md); keep each link's exact target, choose an inline or whole-object carrier, and author canonical `<a href>` under [`native-hyperlinks.md`](../../references/native-hyperlinks.md), never guessing a destination. -**Mandatory — native formulas**: Quick creates no formula resource or manifest; -retain exact LaTeX in active context, then choose ordinary text, same-paragraph -native inline math, or a standalone native block and author its matching SVG -preview under [`native-formula.md`](../../references/native-formula.md). +**Mandatory — per-page Structure decision and geometry move**: after the page's content and communication move, before any geometry, decide whether geometry must carry `order`, `link`, `parent`, `membership`, `contrast`, or `overlap` (`executor-base.md` §2.1) — `no` stays on the base path, `yes` loads and applies the Shape Composition Grammar and topology assembly. Then, when the page's geometry reaches beyond basic primitives, load and apply [`native-shape-authoring.md`](../../references/native-shape-authoring.md) §2.1 to the transient geometry job, content, deck shape language, resolved style, and full vocabulary before coordinates (`describe --compact` only when objective facts could change a serious candidate). Both decisions stay in context, and the capability menu, visualization recall, and template geometry never stand in for them. Quick runs [`verify-charts.md`](../stages/verify-charts.md) after the roster and before the final checker whenever data-driven chart geometry exists. -**Mandatory — native hyperlinks**: Quick creates no hyperlink resource or -manifest. For every selected link, retain the exact target, choose an inline or -whole-object carrier, and author canonical SVG `<a href>` under -[`native-hyperlinks.md`](../../references/native-hyperlinks.md). Never guess an -unknown destination. +**Per-page anchors**: apply the core-message, typography-role, color, body-frame, density, and composition anchors from §2 while authoring; when `notes/total.md` was frozen, keep each page's segment in view so its visible state and direct-root groups support the spoken words without copying the script into body text. -Image to PPTX replaces the open image-composition and page-geometry decisions -for its canonical page frame: preserve the source geometry, restore text -natively, preserve source-graphic identity through the prepared exact or -reconstructed asset, and use the active-context registered layer/plate stack -for scene imagery. Run either ordinary decision only for additional non-source -content whose placement or geometry is not already fixed by that surface. +**Canvas**: the §2 canvas — explicit user choice, otherwise the Layout/Deck owner's, otherwise `ppt169` `viewBox="0 0 1280 720"`; another registered format takes its exact viewBox from `canvas-formats.md`. Template canvas is a default, not a gate. The first SVG fixes the export canvas; every page matches it exactly. Filenames use one zero-padded width for the roster (`01_cover.svg` … `12_end.svg`, or three digits); never leave pages from another run in `svg_output/` — the exporter publishes everything it finds. -**Mandatory — per-page Structure decision**: after the current page's content -and communication move are determined, but before choosing any geometry or -shape, decide whether geometry must carry qualitative `order`, `link`, `parent`, -`membership`, `contrast`, or `overlap`. Keep the yes/no result and, when yes, -the relationship meaning and reading path in active context only; create no -artifact, spec, lock, manifest, or extra pass. +**PPTX structure**: speed never flattens template structure. Free design and Brand/Style-only author flat Slide-local SVG with one root `data-pptx-page-role` (`cover` / `toc` / `section` / `content` / `ending`) and no Master/Layout/layer/placeholder metadata. When Layout or Deck owns structure, every page is a complete structured Slide SVG that preserves or deliberately adapts the prototype's root identity, fixed layers, and slots with current content on top — all-or-none across the roster, every reused Layout repeating an identical fixed-layer/slot contract, a new Layout allowed under the selected Master when the application paragraph calls for adaptation, ownership never inferred from repeated geometry, and `data-pptx-page-role` omitted. A Style never strips structure; only an explicit instruction to use the workspace as visual language permits flat output. -- `no` → use Quick's shared base authoring path in this section. -- `yes` → apply the already-loaded Shape Composition Grammar before drawing. +**Typography**: name a concrete target-installed/approved family under `shared-standards-core.md` §4.1, never a lock or the host's fonts. Before P01 run `python3 ${SKILL_DIR}/scripts/text_measure.py calibrate <project_path> --role <name>:<family>:<size>` for every recurring role (one command, repeatable `--role`) and keep its table — CJK and Latin ≈ chars per 100 px per role, the checker's own estimator with wrapping headroom — in context; every later page sizes zones from that per-font arithmetic — write the sentence first, fit the zone to it, and never trim wording to satisfy an estimate; calibrate again only for a role or size never calibrated, and `wrap` only a genuinely long paragraph. -This decision is mandatory on every page and cannot be satisfied by the -capability menu, visualization recall, template geometry, or a later check. +**Generation pacing**: hand-write the roster in order — P01 calibrates visual identity and cover expression, the first ordinary content page calibrates content geometry and carrier integration, neither becomes a reusable template — with no first-page checker or confirmation stop. A resolved motif follows its reuse mode (exact repetition for deliberate chrome, adaptive variation of scale, crop, density, position, or interaction otherwise). After every page exists, run the one final checker below; use other stages only when their capability is needed. -**Mandatory — independent per-page geometry move**: after the Structure result -and any applicable topology resolve, apply -[`native-shape-authoring.md`](../../references/native-shape-authoring.md) §2.1 -to the transient geometry job, actual content, retained deck shape language, -resolved style, and complete loaded native vocabulary before writing -coordinates. Select through direct semantic comparison; use `describe --compact` only when objective geometry -facts could change a serious candidate decision. This move owns the exact-fit -geometry gate, independent relationship / carrier fit, -contour-family / exact-result choice, reader effect for a generic or undrawn -result, running actual-geometry signature, and materialization boundary. A -primitive remains valid when it wins this comparison; there is no preset quota. -Apply the move to both `no` and `yes`; keep the current decision in active -context and never change the Structure result. - -| Deterministic trigger | Additional authority | -|---|---| -| A selected primary Chart/Table `family/key` | [`executor-visualization.md`](../../references/executor-visualization.md), then the matching Chart/Table authority | -| Any actual value-driven geometry, including mini/inset charts and sparklines | [`executor-chart.md`](../../references/executor-chart.md) | -| Any actual row × column fact grid | [`executor-table.md`](../../references/executor-table.md) | -| Any mathematical notation that may require native math | [`native-formula.md`](../../references/native-formula.md) before choosing ordinary text, inline native math, or block native math | -| Any external or same-deck click hyperlink | [`native-hyperlinks.md`](../../references/native-hyperlinks.md) before authoring its inline or whole-object SVG anchor | -| A used preset pattern fill, or one independent Chart/Table object resolved as `<object-key>=yes` in active context | [`native-data-interface.md`](../../references/native-data-interface.md) before drawing that object | -| Any data-driven chart geometry | [`verify-charts.md`](../stages/verify-charts.md) after the complete roster and before the one final checker | - -Chart/Table reference and final information model are independent loading -signals; load every applicable authority. Selection never makes an object -native-ready or replaces the per-page Structure decision. - -Keep the core's shared visual-quality / leading defaults active while authoring, with `svg-effects.md` §6.1's Visual Job Router as recall. Explicit user/template requirements and the resolved style override compatible aesthetic defaults, never technical Required / Forbidden boundaries, carrier eligibility, or native capability discovery. Treat selected style composition examples as generative vocabulary rather than a finite layout menu. - -**Per-page execution anchors**: apply the transient core-message, typography-role, semantic-color, body-frame, density, and composition anchors resolved in §2 while authoring; they guide the current run without creating a persisted planning artifact. - -When `notes/total.md` was frozen from a final script, retain its corresponding -segment while authoring each page. The visible state and real direct-root -semantic groups must support that spoken segment without duplicating the full -script as body copy or changing its wording. - -Use one zero-padded filename width sized for the resolved roster, such as -`01_cover.svg` through `12_end.svg` or `001_cover.svg` through `120_end.svg`. -Never reuse pages from another run: the exporter publishes every SVG discovered -under `svg_output/`. - -**Canvas**: use the canvas resolved in §2: explicit user choice, otherwise the -selected Layout/Deck structure-owner canvas, otherwise `ppt169` with -`viewBox="0 0 1280 720"`. For another registered format, load -[`canvas-formats.md`](../../references/canvas-formats.md) and use its exact -viewBox. Template canvas is a default, not a compatibility gate; an explicit -user canvas may adapt the installed visual system. The first SVG establishes -the export canvas; every remaining page must match it exactly. - -**PPTX structure**: runtime speed does not flatten template structure. Free -design and Brand/Style-only use author flat, Slide-local SVG and omit -Master/Layout/layer/placeholder metadata. When Layout or Deck owns structure, -author every page as a complete structured Slide SVG: preserve or deliberately -adapt the selected prototype's root Master/Layout identity, fixed layers, and -semantic slots, then place current Slide content on top. A Style contribution -never strips that structure. Only an explicit instruction to use the workspace -as visual language while discarding its structure permits flat output. - -Structured Quick pages use the same all-or-none SVG contract as Default: once -any page declares PPTX structure metadata, every page root declares non-empty -Master/Layout keys and picker names, and every reused Layout repeats an -identical fixed-layer/slot contract. The current agent may author a new complete -Layout under the selected Master when the frozen application paragraph calls -for adaptation; it never infers ownership from repeated Slide-local geometry. -The lockless final checker and exporter derive `structured` solely from that -complete SVG roster. Include all visible content and resource references in each -SVG. Flat pages set one root `data-pptx-page-role` from `cover`, `toc`, -`section`, `content`, or `ending`; structured pages omit it. - -**Typography**: name a concrete target-installed/approved PowerPoint family -under [`shared-standards-core.md`](../../references/shared-standards-core.md) -§4.1; do not depend on a lock or generated font asset. Before P01, measure one -representative line per recurring text role with -`python3 ${SKILL_DIR}/scripts/text_measure.py measure` and keep "≈ N chars per -W px" in active context; the final checker's module check adds DrawingML -wrapping headroom, so characters × font size underestimates by roughly 15%. -Those per-role constants cover most lines; measure only lines that approach a limit, many at once through `--stdin`, and `wrap` only a genuinely long paragraph. - -**Generation pacing**: the current main agent hand-writes the SVG roster in -order. Use P01 to calibrate visual identity and cover-specific expression; use -the first page that exercises ordinary content relationships to calibrate -content geometry and carrier integration. Neither becomes a reusable topology -template. Continue directly without a first-page checker or confirmation stop. -When a motif was -resolved, follow its reuse mode: exact repetition is valid for deliberate -title/corner chrome, while adaptive motifs may vary scale, crop, density, -position, or content interaction. Keep this choice only in active context; -create no planning artifact or approval stop. After every page -exists, run the one final checker below. Apply other supporting tools and -stages only when their capability is actually needed. - -**Hard rule — direct page authoring stays with the current main agent**: write -every page SVG directly in the active context. Do not delegate page generation -to another agent, and do not run a Python, Node, shell, or other generator that -writes slide files into `svg_output/`. Documented fragment-only helpers remain -allowed after the current main agent chooses the object's role, operands, -paint, and z-order and integrates the fragment itself. This boundary does not -restrict resource preparation, inspection, checker, verification, -post-processing, or export tools; a run fails this profile only when a delegated -agent or generator authors a page SVG on the main agent's behalf. - -This is not a resume protocol. If the active context is lost before delivery, -start a clean Quick run rather than inferring an unfinished plan from the files -already present. +**Hard rule — direct page authoring stays with the main agent**: write every page SVG in the active context; never delegate page generation or run a generator that writes slide files (fragment-only helpers remain allowed after the agent chooses role, operands, paint, and z-order). Resource, inspection, checker, verification, and export tools are unrestricted. This is not a resume protocol: if the context is lost before delivery, start a clean Quick run. --- ## 4. Export -After every page and required referenced resource exists, run the Quick branch -of [`verify-charts`](../stages/verify-charts.md) when any data-driven chart was -authored. Complete all coordinate repairs first, then use the one lockless -final check to prove the pages were authored in canonical compact form: +After every page and referenced resource exists, run the Quick branch of [`verify-charts`](../stages/verify-charts.md) when any data-driven chart was authored and complete its repairs, then prove canonical compact authoring with the one lockless final check; fix every blocking error and rerun the same command: ```bash python3 ${SKILL_DIR}/scripts/svg_quality_checker.py <project_path> \ --quick-generate --canonical-authoring --stage final --json ``` -Fix every blocking error and rerun the same command. +**Mandatory — final carrier-receipt review**: compare the `[CARRIERS]` summary with the retained page jobs, deck shape language, motif, resource roles, and geometry signatures. Counts are not quotas; when the facts contradict an active decision — an adopted preset absent, a directional / step / flowchart relationship drawn as a hand path or polygon where `executor-base.md` §3.0 names a preset, a primary image reduced to a minor frame — read only the affected `files[].info.carrier_receipt` rows, repair those pages in one pass, and rerun the checker. **Absence needs a reason**: when the receipt shows a deck-wide zero — `Presets: (none)`, or `inline emphasis 0`, `gradients 0`, or `filters 0` on the `Effects:` line — or fewer pages carrying a preset or connector than pages whose transient relationship statement names `order` / `link` / `parent` / `membership` — or the `Presets:` line names no carrier-and-field contour — answer one line per absent family or per such page: what carries that job instead, and why it serves the reader better — for presets, one line per job the family serves, not for arrows alone: carrier and field (snipped or one-sided rounded rectangles, plaque, bevel, polygons, pie / arc / donut, frames, corners, folded corner, trapezoid, parallelogram, and `native-shape-authoring.md` §7 modelled forms), direction and sequence (arrows, chevrons, flow nodes), grouping and ownership (brackets, braces, frames, plaques), emphasis and annotation (callouts, badges, banners, stars). The style, speed, restraint, "text was enough", or "it is editable anyway" are not answers; a family or page without one is repaired where the page job calls for it, then the checker reruns. Choosing not to use a device is valid — only an unstated reason is not. -**Mandatory — final carrier-receipt review**: Review the factual -`[CARRIERS]` summary against the retained page jobs, deck shape language, any -adopted motif, resource roles, and running geometry signatures before export. -Counts and diversity are not quotas; zero preset use alone neither proves fit -nor establishes a defect. When the summary contradicts an active decision, read -only the affected `files[].info.carrier_receipt` rows from the current report, -repair those pages in one consolidated pass, and rerun the same final checker. - -Then export: - -When Speaker Notes is enabled, load -[`executor-notes.md`](../../references/executor-notes.md) after the passing final -check. Validate an already frozen final script or direct-video pre-SVG narration -without regenerating it; otherwise generate `notes/total.md` from the final SVG -roster. Then run: +**Notes** (when enabled): load [`executor-notes.md`](../../references/executor-notes.md) after the passing check, validate a frozen script or pre-SVG narration without regenerating it or otherwise generate `notes/total.md` from the final roster, then split: ```bash python3 ${SKILL_DIR}/scripts/total_md_split.py <project_path> ``` -**Success criterion**: per-slide Markdown files exist under -`<project_path>/notes/` and cover every published slide. The command exits -non-zero when a slide has no notes or a write fails; repair `notes/total.md` and -rerun before animations or export, and never let leftover files from an earlier -run satisfy this criterion. +**Success criterion**: per-slide files under `notes/` cover every published slide; the command exits non-zero on a missing slide or failed write — repair and rerun, and never let leftover files satisfy it. -Run [`customize-animations`](../stages/customize-animations.md) after that notes -pass when the active-context outcome or an existing sidecar triggers it. Resolve -deck-wide-only motion through the selected exporter flags instead. - -After visual motion is final, sync a selected cue per -[`animations.md`](../../references/animations.md) §2.2; otherwise create no -`sounds/`. Sidecars never use `templates/sounds/`. This configures the native -PPTX only; `generate-audio` completes direct narrated MP4 delivery with either -the verified native-export mix or an explicitly selected real-time PowerPoint -slideshow capture. Those sound branches are mutually exclusive. - -For Quick recorded/self-running/video delivery, complete the mandatory Custom -Animations stage and validate `animations.json` before the base export unless -the user explicitly requested static or page-transition-only playback. Direct -narrated video derives cue timing only when narration governs groups; otherwise -it exports the canonical custom timing without an object-sync claim. Do not -replace this requirement with deck-wide `-a auto` or page transitions. - -Choose exactly one notes mode for the base export: +**Motion and sound**: run [`customize-animations`](../stages/customize-animations.md) after the notes pass when the §1 outcome or an existing sidecar triggers it; deck-wide-only motion uses exporter flags. Quick video delivery completes the Custom Animations stage and validates `animations.json` before export unless the user asked for static or transition-only playback; direct narrated video derives cue timing only when narration governs groups. After motion is final, sync a selected cue per [`animations.md`](../../references/animations.md) §2.2 (no cue → no `sounds/`; never `templates/sounds/`); `generate-audio` completes narrated MP4 delivery through the verified native mix or an explicit slideshow capture, never both. ```bash -# Speaker Notes enabled -python3 ${SKILL_DIR}/scripts/svg_to_pptx.py <project_path> \ - --quick-generate --with-notes - -# Speaker Notes disabled -python3 ${SKILL_DIR}/scripts/svg_to_pptx.py <project_path> \ - --quick-generate --no-notes +python3 ${SKILL_DIR}/scripts/svg_to_pptx.py <project_path> --quick-generate --with-notes # Speaker Notes enabled +python3 ${SKILL_DIR}/scripts/svg_to_pptx.py <project_path> --quick-generate --no-notes # Speaker Notes disabled ``` -`--quick-generate` reads `svg_output/` as the page source and resolves the -project-local assets referenced by those SVGs. It infers one consistent canvas, -then infers one all-page structure mode: no structure metadata produces a clean -flat package, while complete explicit Master/Layout/slot metadata produces a -structured package. It does not read or require `spec_lock.md` and does not -force-disable ordinary export options. Notes, Custom Animations, and narration remain off unless -selected by the agent or required by the Quick video rule above. Append -`--native-charts-and-tables` only when the effective delivery decision -explicitly requires native Chart/Table objects; marker presence, imported -origin, and semantic tables never activate replacement implicitly. Do not run -`finalize_svg.py`. After the validated base export, run -[`generate-audio`](../stages/generate-audio.md) when Narration Audio is enabled; -it owns page audio/SRT, narrated PPTX, the optional raw native MP4, and the -final mixed or captured MP4. When a selected manual capture has not yet been -returned, it owns the capture-ready narrated PPTX handoff instead. - -The exporter requires a passing `final` report whose SVG fingerprint matches -the current `svg_output/`; missing, blocking, non-final, or stale reports stop -before PPTX creation. The default output path retains ordinary backup and -postflight behavior. An explicit `-o <path>.pptx` keeps the ordinary no-backup -behavior. On failure, repair the owning SVG, resource, or optional capability -input, rerun the final checker, then export again; do not create a Design Spec -or lock. +`--quick-generate` reads `svg_output/`, resolves project-local assets, infers one canvas and one all-page structure mode (no metadata → flat; complete Master/Layout/slot metadata → structured), and needs no lock. Notes, Custom Animations, and narration stay off unless the agent enabled them or the video rule requires them; append `--native-charts-and-tables` only for an explicit native Chart/Table delivery decision. Never run `finalize_svg.py`. The exporter requires a passing `final` report whose fingerprint matches the current `svg_output/`; the default output path keeps backup and postflight, an explicit `-o <path>.pptx` skips backup. On failure repair the owning SVG, resource, or capability input, rerun the checker, and export again — never create a Design Spec or lock. When Narration Audio is enabled, run [`generate-audio`](../stages/generate-audio.md) after the validated export (page audio/SRT, narrated PPTX, optional raw MP4, final mixed or captured MP4, or the capture-ready handoff). ```markdown ## ✅ Quick Generate Complete -- [x] All required source/resource preparation is complete -- [x] The fixed planning-capability batch was read before the roster, and every selected detail source was read -- [x] The complete 187-name native preset vocabulary was read before P01; each page chose from that full capability surface, with objective candidate details inspected only when needed -- [x] Every page considered suitable carrier combinations without a coverage quota or single-carrier assumption -- [x] The proactive decorative-lettering capability scan ran before carrier selection; every selected lettering job entered an AI item or lettering sheet/slice job, and zero selected jobs remained valid -- [x] The deck shape language remained active independently of any optional motif; every page not bound to literal supplied geometry carried its geometry job into authoring, resolved each drawn contour from its exact family and job, retained the reader effect for any generic or undrawn result, and compared its actual geometry signature before the next page; repetition served the same page job / relationship or continuity motif -- [x] Image need was decided independently of credentials; any zero-image deck followed a complete roster review in which no image job improved communication or the selected non-image carriers fully carried it -- [x] Every `slice_names` output exists after an exit-0 strict-alpha run, and no page whose chosen composition depends on a slice was authored or exported without it -- [x] Every image-bearing page made its one pre-geometry composition decision -- [x] Every image decided its own source from that page's subject and job — not inherited from the resolved visual style — and every externally verifiable subject deliberately not shown as itself was stated with its reason -- [x] Every exhausted automated AI job was replanned under the declared no-AI rule, with its filename, attempted path, concrete error, and replacement carrier retained for final disclosure; N/A when no such replan occurred -- [x] Every selected formula uses the checker-valid ordinary/inline/block form with a matching visible SVG preview and no formula image resource -- [x] Every selected hyperlink uses a checker-valid inline/whole-object anchor and an exact external or same-deck target -- [x] Resolved SVG pages and their project-local references exist -- [x] The frozen Template Application paragraph was applied; every installed Layout/Deck SVG was read, and any page-specific exception names an exact SVG basename -- [x] Quick structure matches the installed template capability: free/Brand/Style-only pages are flat, while a Layout/Deck structure owner remains explicit and all-page consistent unless the user explicitly requested visual-only use -- [x] Every role declared by an installed template spec is locatable in the finished pages, or its non-use is deliberate — checked per installed spec, not from memory -- [x] Every triggered capability-specific preparation and pre-checker verification completed -- [x] The current final report's carrier receipt was compared with the retained page jobs and any factual contradiction was repaired before export, without treating counts as quotas -- [x] The lockless final SVG quality report passes and matches the current SVGs +- [x] Source/resource preparation complete; the planning-capability batch and every selected detail source were read before the roster +- [x] The complete preset vocabulary was read before P01; each page resolved its Structure decision, geometry move, and carrier mix without a quota and compared its geometry signature before the next page +- [x] Image need was decided independently of credentials; every image decided its own source, every `slice_names` output exists after an exit-0 strict-alpha run, and every exhausted AI job was replanned under the no-AI rule with its disclosure retained +- [x] Every selected formula and hyperlink uses its checker-valid native form +- [x] The frozen Template Application paragraph was applied, every installed Layout/Deck SVG was read, and structure matches the installed capability (flat vs explicit all-page structured) +- [x] The carrier receipt was compared with the retained page jobs and contradictions repaired; the lockless final report passes and matches the current SVGs - [x] Enabled notes were validated/generated and split; enabled custom motion ran through its owning stage -- [x] One native PPTX exists under `exports/` or the explicit output path -- [x] No Strategist, confirmation, root project Design Spec, or lock artifact was created -- [ ] **Next**: Report the base PPTX and any enabled narrated PPTX, raw/mixed/captured MP4, or capture-ready PPTX handoff, plus the resolved mode, visual style, and the image sources actually used. For every no-AI replan, report the affected AI job, attempted path, concrete error, replacement carrier, and that retaining AI imagery requires repairing generation capability and starting a new Quick run +- [x] One native PPTX exists under `exports/` or the explicit output path; no Strategist, confirmation, root Design Spec, or lock artifact was created +- [ ] **Next**: report the base PPTX and any narrated PPTX, MP4, or capture-ready handoff, plus the resolved mode, visual style, and image sources actually used; for every no-AI replan, report the affected job, attempted path, concrete error, replacement carrier, and that retaining AI imagery requires repairing generation capability and a new Quick run ``` diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/routing.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/routing.md index 0dac0909..5964dff7 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/routing.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/routing.md @@ -6,9 +6,7 @@ description: Deterministic selection among PPT Master's three top-level artifact Route selection authority for PPT Master. Select exactly one top-level route, then activate only the child workflows, profiles, and stages owned by that route. -**Hard rule**: If this file conflicts with a route summary elsewhere in the -Skill package or in a repository-level user-facing document, this file wins for -route selection. After selection, the active runtime authority owns execution. +**Hard rule**: when this file conflicts with a route summary elsewhere in the Skill package or a repository-level document, this file wins for route selection. After selection, the active runtime authority owns execution. --- @@ -17,12 +15,12 @@ route selection. After selection, the active runtime authority owns execution. | Rule | Behavior | |---|---| | One artifact lifecycle | Every request enters Generate PPTX, Create Template, or Edit Native PPTX | -| Supporting documents are not top-level routes | Create Template child workflows, generation profiles, stages, and governance documents refine the selected route; never offer them as competing top-level routes | -| Missing prerequisite | State the missing prerequisite and stop that route; do not invent an alternative | +| Supporting documents are not routes | Create Template child workflows, generation profiles, stages, and governance documents refine the selected route; never offer them as competing routes | +| Missing prerequisite | State it and stop that route; do not invent an alternative | | Ambiguous existing-deck request | Ask one discriminator question only when needed: regenerate the visible design (Generate), or preserve the native deck and edit it (Edit Native PPTX)? | | Explicit user override | Honor explicit route instructions only when the route preconditions are satisfied | -**Forbidden — route-choice menus**: Do not present multiple implementation paths when the request already matches one row in §2. Ordinary design choices remain at the selected route's existing confirmation gate. +**Forbidden — route-choice menus**: do not present multiple implementation paths when the request already matches one row in §2; ordinary design choices remain at the selected route's confirmation gate. --- @@ -30,9 +28,9 @@ route selection. After selection, the active runtime authority owns execution. | Route | Request shape | Authority | Preconditions | Mutation model | Output contract | |---|---|---|---|---|---| -| Generate PPTX | Create, reconstruct, or visually regenerate a presentation/video from sources or a topic; templates remain optional | Image to PPTX: [`image-to-pptx`](./profiles/image-to-pptx.md), always Quick; Beautify: [`beautify-pptx`](./profiles/beautify-pptx.md), Default or Quick; ordinary [`generate-pptx`](./generate-pptx.md) / [`quick-generate`](./profiles/quick-generate.md) | Facts exist or research can gather them; Image to PPTX also requires Codex and an ordered page-frame roster | Author SVG pages and export a new PPTX | Default: spec/lock/SVG/PPTX; Quick: optional source/resource artifacts, no spec/lock, SVG/PPTX; either may derive narrated PPTX/MP4 | -| Create Template | Create a reusable brand/style/layout/deck template from one or more PPTX/SVG files, images/PDFs, direct or file-based text, documents/websites, brand assets, or a mixed reference bundle | [`create-template`](./create-template.md) | A reusable-template request exists; reference material is optional, and project scope additionally requires an initialized target project | Author a new portable workspace; never modify any reference file in place | Workspace with required `templates/`, optional `images/` / `icons/`, and optional review `exports/` | -| Edit Native PPTX | Keep an existing PPTX's native design: fill it with new content, edit or restructure selected pages, or add notes, narration, timings, or transitions with visible slides untouched | [`edit-native-pptx`](./edit-native-pptx.md) | Source PPTX exists; new material only when content changes | `pptx_to_svg.py --roundtrip` workspace: unchanged pages restore byte-for-byte, edited pages rebuild only edited objects, notes/motion overlay | New PPTX in workspace `exports/` | +| Generate PPTX | Create, reconstruct, or visually regenerate a presentation/video from sources or a topic; templates optional | Image to PPTX: [`image-to-pptx`](./profiles/image-to-pptx.md), always Quick; Beautify: [`beautify-pptx`](./profiles/beautify-pptx.md), Default or Quick; ordinary [`generate-pptx`](./generate-pptx.md) / [`quick-generate`](./profiles/quick-generate.md) | Facts exist or research can gather them; Image to PPTX also requires Codex and an ordered page-frame roster | Author SVG pages and export a new PPTX | Default: spec/lock/SVG/PPTX; Quick: optional source/resource artifacts, no spec/lock, SVG/PPTX; either may derive narrated PPTX/MP4 | +| Create Template | Create a reusable brand/style/layout/deck template from PPTX/SVG files, images/PDFs, direct or file-based text, documents/websites, brand assets, or a mixed bundle | [`create-template`](./create-template.md) | A reusable-template request; reference material optional; project scope also requires an initialized target project | Author a new portable workspace; never modify a reference file in place | Workspace with required `templates/`, optional `images/` / `icons/`, optional review `exports/` | +| Edit Native PPTX | Keep an existing PPTX's native design: fill with new content, edit or restructure selected pages, or add notes, narration, timings, or transitions with visible slides untouched | [`edit-native-pptx`](./edit-native-pptx.md) | Source PPTX exists; new material only when content changes | `pptx_to_svg.py --roundtrip` workspace: unchanged pages restore byte-for-byte, edited pages rebuild only edited objects, notes/motion overlay | New PPTX in workspace `exports/` | --- @@ -40,69 +38,42 @@ route selection. After selection, the active runtime authority owns execution. | Request condition | Generate-route behavior | |---|---| -| One or more raster files represent page frames that must be reconstructed into a layered editable PPTX | Activate the Codex-supported [`image-to-pptx`](./profiles/image-to-pptx.md); normalize the represented frame roster and activate `quick-generate` directly without requiring a separate Quick request | -| Existing PPTX must preserve wording, page count, and page order 1:1 | Activate [`beautify-pptx`](./profiles/beautify-pptx.md); it selects `quick-generate` when that profile's explicit trigger also matches, otherwise `generate-pptx` | -| The effective delivery purpose is recorded, self-running, or video-directed | Inside the already selected Default or explicit Quick runtime, load [`video-design`](../references/video-design.md) before whole-solution/page planning. This is a conditional design reference, not a profile or fifth route; notes, animation, audio, and optional native MP4 remain owned by their existing stages | -| Explicit quick/fast, skip-strategy, or direct SVG-to-PPTX intent without an active fidelity profile | Load [`quick-generate`](./profiles/quick-generate.md) directly without loading `generate-pptx.md`: prepare sources/resources as needed, let the current agent decide without interaction, directly apply at most one exact workspace root per kind supplied for this run, otherwise use free design, omit Strategist/Confirm UI/spec/lock, hand-author SVG, run the lockless final checker, and export the final PPTX | -| Topic only, or supplied sources leave planning-critical factual gaps | Run [`topic-research`](./stages/topic-research.md) inside the selected Generate profile's source preparation: immediately for topic-only input, or after conversion and reading for source-backed input; research only the identified gaps | -| Existing PPTX must be split, merged, or re-outlined into newly designed pages | Treat the PPTX as source content through the selected Generate authority's source intake; continue Default unless explicit Quick intent selected that runtime | -| Existing PPTX pages are dropped, reordered, or repeated without redesign | Not Generate: route to Edit Native PPTX, whose `page_plan.json` owns selection, order, and repetition | -| Default Generate reaches planning | Step 3 prepares template candidates without interaction. Stage 1 then confirms the communication contract and free-design/template choice together; only a confirmed non-free choice runs [`apply-template-workspace`](./stages/apply-template-workspace.md) before Stage 2 | -| Explicit current brand/style/layout/deck workspace root outside Image to PPTX | Default Generate preserves the exact path as a Stage-1 template candidate; Quick Generate validates and installs it directly without Steps 3–4 or Confirm UI. Classify it as `library` only when its normalized root exactly matches a registered index entry; otherwise retain `explicit`. Consume the workspace root, never only its inner `templates/` directory | +| Raster files represent page frames to reconstruct into a layered editable PPTX | Activate the Codex-supported [`image-to-pptx`](./profiles/image-to-pptx.md); normalize the frame roster and activate `quick-generate` directly | +| Existing PPTX must preserve wording, page count, and order 1:1 | Activate [`beautify-pptx`](./profiles/beautify-pptx.md); Quick when that profile's explicit trigger also matches, otherwise `generate-pptx` | +| Effective delivery purpose is recorded, self-running, or video-directed | Inside the selected runtime, load [`video-design`](../references/video-design.md) before whole-solution/page planning; a design reference, not a profile — notes, animation, audio, and native MP4 stay with their stages | +| Explicit quick/fast, skip-strategy, or direct SVG-to-PPTX intent without an active fidelity profile | Load [`quick-generate`](./profiles/quick-generate.md) directly without `generate-pptx.md`: prepare sources/resources as needed, decide without interaction, apply at most one exact workspace root per kind supplied for this run (otherwise free design), omit Strategist/Confirm UI/spec/lock, hand-author SVG, run the lockless final checker, export | +| Topic only, or sources leave planning-critical factual gaps | Run [`topic-research`](./stages/topic-research.md) inside the selected profile's source preparation — immediately for topic-only input, after conversion and reading for source-backed input; research only the identified gaps | +| Existing PPTX must be split, merged, or re-outlined into newly designed pages | Treat the PPTX as source content through the selected Generate authority's intake; Default unless explicit Quick intent | +| Existing PPTX pages dropped, reordered, or repeated without redesign | Not Generate: Edit Native PPTX, whose `page_plan.json` owns selection, order, and repetition | +| Default Generate reaches planning | Step 3 prepares template candidates without interaction; Stage 1 confirms the communication contract and free-design/template choice together; only a confirmed non-free choice runs [`apply-template-workspace`](./stages/apply-template-workspace.md) before Stage 2 | +| Explicit current brand/style/layout/deck workspace root outside Image to PPTX | Default preserves the exact path as a Stage-1 candidate; Quick validates and installs it directly without Steps 3–4 or Confirm UI. Classify as `library` only when the normalized root exactly matches a registered index entry, otherwise `explicit`. Consume the workspace root, never only its inner `templates/` | | Split-mode project resumes in a fresh chat | Run [`resume-execute`](./stages/resume-execute.md) inside the active Generate route | -| Existing generated project needs a deck-wide `colors.*` or universal `typography.font_family` substitution | Stay in Generate; load [`update_spec.py`](../scripts/docs/update_spec.md), honor its supported-key boundary, then rerun the final quality gate and Step 7 export | +| Generated project needs a deck-wide `colors.*` or universal `typography.font_family` substitution | Stay in Generate; load [`update_spec.py`](../scripts/docs/update_spec.md), honor its supported-key boundary, then rerun the final quality gate and Step 7 export | | User explicitly requests spec refinement | Run [`refine-spec`](./stages/refine-spec.md) after Design Spec Gate 1 and before lock Gate 2 | | Data charts exist | Run [`verify-charts`](./stages/verify-charts.md) before export | | User explicitly requests visual review | Run [`visual-review`](./stages/visual-review.md) before post-processing | -| User requests preview, selection, or annotation application outside Image to PPTX | Use the default Generate pipeline and run [`live-preview`](./stages/live-preview.md) at the stage defined there; explicit Quick + preview intent falls back to default rather than dropping preview. Image to PPTX remains Quick-only and uses its mandatory canonical-frame recomposition comparison instead of this interactive stage | -| User requests page transitions, auto-advance, or deck-wide animation settings without page-specific motion planning or an existing `animations.json` | Load [`animations`](../references/animations.md) and apply its export-level contract | -| `<project_path>/animations.json` already exists, the user explicitly requests per-slide/object-level animation control, or the effective Custom Animations outcome in `design_spec.md §I` is enabled | Run [`customize-animations`](./stages/customize-animations.md) after the final SVG quality gate and any enabled speaker-note pass, before Generate Step 7. A §IX `Motion suggestion` informs an active pass but never triggers it alone | -| Generate PPTX receives an explicit narration request or has effective Narration Audio enabled in `design_spec.md §I`; Edit Native PPTX has narration confirmed in its plan | Run [`generate-audio`](./stages/generate-audio.md) after the owning route's notes readiness; audio implies notes on every output page | +| User requests preview, selection, or annotation application outside Image to PPTX | Default pipeline plus [`live-preview`](./stages/live-preview.md) at its defined stage; explicit Quick + preview intent falls back to Default rather than dropping preview. Image to PPTX stays Quick-only with its canonical-frame recomposition comparison | +| Page transitions, auto-advance, or deck-wide animation settings without page-specific motion planning or an existing `animations.json` | Load [`animations`](../references/animations.md) and apply its export-level contract | +| `<project_path>/animations.json` exists, the user explicitly requests per-slide/object-level animation control, or the effective Custom Animations outcome in `design_spec.md §I` is enabled | Run [`customize-animations`](./stages/customize-animations.md) after the final SVG quality gate and any speaker-note pass, before Step 7. A §IX `Motion suggestion` informs an active pass but never triggers it | +| Explicit narration request or effective Narration Audio enabled in `design_spec.md §I`; Edit Native PPTX narration confirmed in its plan | Run [`generate-audio`](./stages/generate-audio.md) after the owning route's notes readiness; audio implies notes on every output page | -**Hard rule — fidelity profiles, not fifth routes**: Image to PPTX and Beautify -change different source/page invariants and are mutually exclusive. Image to -PPTX always activates Quick; Beautify uses Quick only on explicit Quick intent -and otherwise uses Default. Neither defines a separate artifact lifecycle or -loads both runtimes. +**Hard rule — fidelity profiles, not fifth routes**: Image to PPTX and Beautify change different source/page invariants and are mutually exclusive. Image to PPTX always activates Quick; Beautify uses Quick only on explicit Quick intent. Neither defines a separate lifecycle or loads both runtimes. -**Hard rule — direct-generation profile, not a fifth route**: `quick-generate` -stays inside Generate PPTX but owns an explicit SVG → PPTX short circuit. Page -count alone never activates or blocks it. Conversion, bounded research, and -project-local resources remain available. Package capabilities may be requested -or agent-selected. Quick may consume exact Brand/Style/Layout/Deck workspaces, -with at most one contribution per kind. All four kinds may combine; Layout takes -structural precedence over Deck. A multi-kind project root contributes all of -its specs atomically. Brand/Style-only and free-design Quick pages remain flat; -when Layout or Deck owns structure, Quick authors the complete explicit -Master/Layout/slot metadata and its lockless checker/exporter infers structured -output from that all-page SVG contract. Runtime choice controls interaction and -durable planning, not whether an installed structural template survives. Once selected, Quick -is the complete runtime procedure and never loads `generate-pptx.md`; Default -never loads `quick-generate.md`. Image to PPTX is the narrow profile-owned -Quick activation; Beautify may select either runtime, but never both. +**Hard rule — direct-generation profile, not a fifth route**: `quick-generate` stays inside Generate PPTX and owns an explicit SVG → PPTX short circuit; page count alone never activates or blocks it. Conversion, bounded research, project-local resources, and package capabilities remain available. Quick may consume exact Brand/Style/Layout/Deck workspaces, at most one contribution per kind; all four may combine, Layout takes structural precedence over Deck, and a multi-kind root contributes all its specs atomically. Brand/Style-only and free-design Quick pages stay flat; when Layout or Deck owns structure, Quick authors the complete explicit Master/Layout/slot metadata and its lockless checker/exporter infers structured output from the all-page SVG contract. Once selected, Quick is the complete runtime and never loads `generate-pptx.md`; Default never loads `quick-generate.md`. --- ## 4. Template and Master/Layout Boundary -**Hard rule — no direct structure grafting**: An existing PPTX or SVG is never upgraded in place by adding Master/Layout/placeholder structure. If reusable native structure is required: - -1. Run [`create-template`](./create-template.md) to produce a separate validated workspace. -2. Pass that workspace root to Default as a Stage-1 template candidate, or supply its exact root directly to explicit Quick Generate. -3. Author new structured SVG pages whose Master/Layout contract exists from their first generated draft. -4. Export a new PPTX from those pages. - -When a PPTX already contains native Master/Layout parts, `create-template` mirror may read and preserve those existing package facts in the new workspace. It does not infer missing historical intent. An incomplete or legacy SVG package may guide `standard` / `fidelity` visually, but it is not mutated into a structured template and cannot claim source-topology recovery. - -**Hard rule — no automatic structure upgrade**: Free-design, brand-only, and style-only generation remains `pptx_structure.mode: flat`. Repeated Slide-local objects never trigger `structured`, Master/Layout promotion, placeholder inference, or deduplication. The minimal Master plus Blank Layout emitted by flat export is package scaffolding, not an inferred reusable design master. +**Hard rule — no direct structure grafting or automatic upgrade**: an existing PPTX or SVG is never upgraded in place by adding Master/Layout/placeholder structure — run [`create-template`](./create-template.md) for a separate validated workspace, then pass its root to Default Stage 1 or explicit Quick and author new structured pages. Free-design, brand-only, and style-only generation stays `pptx_structure.mode: flat`; repeated Slide-local objects never trigger `structured`. | Input | Route behavior | |---|---| -| One or more images containing page frames + explicit final-deck reconstruction intent | Generate PPTX with the Codex-supported, Quick-only [`image-to-pptx`](./profiles/image-to-pptx.md); normalize page frames first and do not infer reusable native structure from pixels | +| Images containing page frames + explicit final-deck reconstruction intent | Generate PPTX with Quick-only [`image-to-pptx`](./profiles/image-to-pptx.md); normalize frames first, never infer reusable native structure from pixels | | Raw PPTX called a template + new content | Edit Native PPTX unless the user explicitly asks for a reusable template workspace | | Any supported reference bundle or direct-text brief + reusable template request | Create Template | -| Current template workspace root + content | Default: [`generate-pptx`](./generate-pptx.md) Stage-1 template choice; explicit Quick: direct validated workspace application | -| Semantic-legacy or incomplete structured package | Create a new workspace through Create Template; do not migrate in place | +| Current template workspace root + content | Default: [`generate-pptx`](./generate-pptx.md) Stage-1 template choice; explicit Quick: direct validated application | +| Semantic-legacy or incomplete structured package | New workspace through Create Template; never migrate in place | | Request to add a master directly to an existing PPTX/SVG | Unsupported; explain the Create Template → Generate PPTX lifecycle | --- @@ -111,31 +82,20 @@ When a PPTX already contains native Master/Layout parts, `create-template` mirro | Selected kind | Behavior | |---|---| -| `brand` | Dispatch to [`create-brand`](./create-template/create-brand.md); write identity only and no SVG roster | -| `style` | Dispatch to [`create-style`](./create-template/create-style.md); write reusable communication method and design direction only, with no SVG roster or native structure | -| `layout` | Dispatch to [`create-layout`](./create-template/create-layout.md); author brand-neutral, application-neutral structure and an SVG roster | -| `deck` | Dispatch to [`create-deck`](./create-template/create-deck.md); author descriptive recurring-application context with integrated identity, structure, and an SVG roster | +| `brand` | [`create-brand`](./create-template/create-brand.md): identity only, no SVG roster | +| `style` | [`create-style`](./create-template/create-style.md): reusable communication method and design direction only, no roster or native structure | +| `layout` | [`create-layout`](./create-template/create-layout.md): brand-neutral, application-neutral structure plus an SVG roster | +| `deck` | [`create-deck`](./create-template/create-deck.md): descriptive recurring-application context with integrated identity, structure, and an SVG roster | -Create Template remains the fixed route name and owns the shared contract. These four documents are mutually exclusive child workflows, not additional top-level routes. +Create Template remains the fixed route name and owns the shared contract; these four are mutually exclusive child workflows. -**Hard rule — classify reusable rules, not source completeness**: A complete -PPTX does not automatically select Deck. Use Brand when only identity is -stable; use Style when reusable communication method and design direction -should travel without identity truth, page prototypes, or native -structure; use Layout when structure is brand-neutral and the communication -application stays downstream-defined; use Deck when structure carries identity -or reusable scenario/content semantics. +**Hard rule — classify reusable rules, not source completeness**: a complete PPTX does not automatically select Deck. Brand when only identity is stable; Style when communication method and design direction should travel without identity truth, prototypes, or native structure; Layout when structure is brand-neutral and the application stays downstream-defined; Deck when structure carries identity or reusable scenario/content semantics. --- ## 6. Native and Shared Post-Processing Boundary -| Artifact state | Narration route | -|---|---| -| Main-generated project with notes and exported deck | Shared [`generate-audio`](./stages/generate-audio.md) stage | -| Arbitrary finished PPTX that must preserve visible slides | Edit Native PPTX; its narration module invokes the same shared audio-stage rules against the round-trip workspace | - -Object animation for generated SVG projects uses the animation stage. Edit Native PPTX preserves source motion by default and writes requested motion as an overlay per [`animations.md`](../references/animations.md). +A main-generated project with notes and an exported deck narrates through the shared [`generate-audio`](./stages/generate-audio.md) stage; an arbitrary finished PPTX whose visible slides must be preserved goes to Edit Native PPTX, whose narration module invokes the same stage rules against the round-trip workspace. Object animation for generated SVG projects uses the animation stage; Edit Native PPTX preserves source motion by default and writes requested motion as an overlay per [`animations.md`](../references/animations.md). --- @@ -143,31 +103,13 @@ Object animation for generated SVG projects uses the animation stage. Edit Nativ | User input | Behavior | |---|---| -| Default Generate | Step 3 prepares candidates only; Stage 1 confirms one communication contract plus either free design or template use in the same interaction | -| Explicit current workspace root exposing at least one `templates/` Design Spec | Preserve it as a Stage-1 candidate and initialize template mode; preselect that specific candidate only when it is the sole supplied root. An exact registered-root match may be displayed as `library` | -| No exact workspace root and no explicit template intent | Initialize Stage 1 to free design; the user may switch to template mode and select an indexed workspace | -| Explicit template intent or any exact workspace root | Initialize Stage 1 to template mode; exactly one root may be preselected, while multiple roots remain unselected candidates | -| Bare template/brand name or style label without an explicit template-use request | Do not resolve it to a local path or preselect a template; treat it as a style brief. An explicit request to use templates still initializes template mode, but leaves the specific candidate for the user to choose | -| “What templates exist?” in chat | List indexed workspace paths; Stage 1 still requires an explicit free-design/template choice | +| Default Generate | Step 3 prepares candidates only; Stage 1 confirms one communication contract plus free design or template use in one interaction | +| Explicit current workspace root exposing at least one `templates/` Design Spec | Preserve it as a Stage-1 candidate and initialize template mode; preselect it only when it is the sole supplied root; an exact registered-root match may display as `library` | +| No exact root and no explicit template intent | Initialize Stage 1 to free design; the user may switch to template mode and pick an indexed workspace | +| Explicit template intent or any exact root | Initialize Stage 1 to template mode; exactly one root may be preselected, others remain unselected candidates | +| Bare template/brand name or style label without an explicit template-use request | Never resolve to a local path or preselect; treat as a style brief. An explicit request to use templates initializes template mode but leaves the candidate to the user | +| "What templates exist?" in chat | List indexed workspace paths; Stage 1 still requires an explicit free-design/template choice | -The default UI and chat discovery read only these indexes. Never scan the -corresponding directories to construct or supplement the catalog: +Discovery reads only [`brands_index.json`](../templates/brands/brands_index.json), [`styles_index.json`](../templates/styles/styles_index.json), [`layouts_index.json`](../templates/layouts/layouts_index.json), and [`decks_index.json`](../templates/decks/decks_index.json); never scan kind directories to construct or supplement the catalog. -| Kind | Discovery index | -|---|---| -| Brand | [`brands_index.json`](../templates/brands/brands_index.json) | -| Style | [`styles_index.json`](../templates/styles/styles_index.json) | -| Layout | [`layouts_index.json`](../templates/layouts/layouts_index.json) | -| Deck | [`decks_index.json`](../templates/decks/decks_index.json) | - -**Hard rule — one Stage-1 confirmation, delayed template reading**: Author the -communication recommendation without reading candidate workspaces. Stage 1 -confirms that contract and the template/free-design choice together. Only then -validate/install selected roots and complete the handoff. Stage 2 waits for that -handoff, reads only the installed project-local state, and decides how to apply -it; it never reselects a template. - -**Forbidden — fuzzy resolution**: Never resolve a bare name to a local template -directory on the user's behalf. A library choice comes from an index-derived -root; an unregistered workspace requires an explicit root, including the exact -validated workspace handed off by Create Template in the current conversation. +**Hard rule — index-derived roots only**: never resolve a bare name to a local template directory on the user's behalf; a library choice comes from an index-derived root, and an unregistered workspace requires an explicit root (including one handed off by Create Template in the current conversation). Stage-1 ordering and delayed template reading are owned by [`generate-pptx`](./generate-pptx.md) Steps 3–4. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/stages/apply-template-workspace.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/stages/apply-template-workspace.md index c2276ce7..a3998189 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/stages/apply-template-workspace.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/stages/apply-template-workspace.md @@ -4,47 +4,31 @@ description: Generate-PPTX runbook for validating and installing selected Brand, # Apply Template Workspace Stage -> Run from [`generate-pptx.md`](../generate-pptx.md) Step 4 only after Stage 1 confirms at least one exact template workspace. [`quick-generate`](../profiles/quick-generate.md) enters only for exact roots or a current Create Template handoff. Never load for free design, bare names, or style descriptions. This stage applies the completed Stage-1 selection; it never chooses a workspace or changes the communication contract. +> Run from [`generate-pptx.md`](../generate-pptx.md) Step 4 only after Stage 1 confirms at least one exact template workspace; [`quick-generate`](../profiles/quick-generate.md) enters only for exact roots or a current Create Template handoff. Never load for free design, bare names, or style descriptions. This stage applies the completed selection; it never chooses a workspace or changes the communication contract. ## 1. Gate and Normalize Inputs -🚧 **GATE**: Either Default Stage 1 confirmed a non-free template selection, or -Quick received exact roots directly from the -user/current Create Template handoff. In Quick, that explicit input is the complete selection authority: do -not launch Confirm UI or create `template_options.json`, -`template_selection.json`, or `template_handoff.json`. Every selected input must -resolve to one of these current contracts: +🚧 **GATE**: Default Stage 1 confirmed a non-free selection, or Quick received exact roots directly from the user/current Create Template handoff — in Quick that input is the complete selection authority (no Confirm UI, no `template_options.json` / `template_selection.json` / `template_handoff.json`). Every selected input resolves to one current contract: | Input shape | Spec and SVG source | Asset source | |---|---|---| | Current workspace root | `<root>/templates/design_spec.md`, or one `design_spec.<kind>.<id>.md` per kind, plus `<root>/templates/` | Existing `<root>/images/` and `<root>/icons/` | -| Current Create Template handoff | Its exact validated library or project workspace root | Existing portable sibling `images/` and `icons/`; already installed only when the root is the target project | +| Current Create Template handoff | Its exact validated library or project workspace root | Portable sibling `images/` and `icons/`; already installed only when the root is the target project | -Spec naming and kind declaration follow [`templates/README.md`](../../templates/README.md); a root exposing several kind-qualified specs contributes all of them. Do not accept only another project's inner `templates/` directory because that omits sibling assets. - -**Selection-source classification**: +Spec naming and kind declaration follow [`templates/README.md`](../../templates/README.md); a root exposing several kind-qualified specs contributes all of them. Never accept only another project's inner `templates/` directory — that omits sibling assets. | Source label | Resolution rule | |---|---| | `library` | The normalized root exactly equals `templates/<kind_dir>/<id>/` derived from an entry in that kind's `*_index.json` | -| `explicit` | The user or Create Template supplied an exact workspace root that is not registered at that canonical index-derived root | +| `explicit` | The user or Create Template supplied an exact root not registered at that canonical index-derived root | -Read library choices only from `brands_index.json`, `styles_index.json`, -`layouts_index.json`, and `decks_index.json`. Never scan kind directories or -promote an unregistered directory into the UI catalog. An explicit root remains -valid without index membership; exact equality with a registered root may be -reported as `library`. The label changes discovery provenance only, never schema -validation, segment precedence, or installation behavior. +Read library choices only from the four `*_index.json` files; never scan kind directories or promote an unregistered directory into the catalog. The label changes discovery provenance only, never validation, precedence, or installation. -**Selection cardinality**: Select at most one root per kind; all four kinds may -coexist. A multi-kind explicit root contributes all its specs atomically and -may combine only with non-overlapping kinds. Default permits one explicit root -beside registered choices; Quick applies the same kind constraint. Reject -duplicate kinds before validation. +**Selection cardinality**: at most one root per kind; all four kinds may coexist. A multi-kind explicit root contributes all its specs atomically and combines only with non-overlapping kinds; reject duplicate kinds before validation. -**Hard rule — raw source boundary**: A raw PPTX is not a template workspace. Raw PPTX plus new content uses [`edit-native-pptx`](../edit-native-pptx.md). When the user wants reusable SVG/template generation, run [`create-template`](../create-template.md) first; its validated workspace-root handoff becomes a Stage-1 candidate and is preselected only when it is the sole supplied root. Never add Master/Layout/placeholder structure directly to an existing PPTX or SVG project. +**Hard rule — raw source boundary**: a raw PPTX is not a template workspace. Raw PPTX plus new content uses [`edit-native-pptx`](../edit-native-pptx.md); a reusable template request runs [`create-template`](../create-template.md) first, whose validated root becomes a Stage-1 candidate preselected only when it is the sole supplied root. Never add Master/Layout/placeholder structure directly to an existing PPTX or SVG project. -**Current-contract gate**: Reject flat-root, semantic-legacy, or incomplete structured packages, including old baseline/distillation metadata, incomplete Master identity, or legacy direct atomic placeholders. Create a new current workspace through Create Template; use the original PPTX when native topology must be preserved. +**Current-contract gate**: reject flat-root, semantic-legacy, or incomplete structured packages (old baseline/distillation metadata, incomplete Master identity, legacy direct atomic placeholders); create a new workspace through Create Template, from the original PPTX when native topology must be preserved. ## 2. Read the Matching Schema @@ -53,187 +37,72 @@ Read [`templates/README.md`](../../templates/README.md), then only the README fo | Kind | Schema | Owned segment | |---|---|---| | `brand` | [`templates/brands/README.md`](../../templates/brands/README.md) | Identity: color, typography, logo, voice/tone, icon style | -| `style` | [`templates/styles/README.md`](../../templates/styles/README.md) | Direction/method: reusable communication method, visual language, composition, and information-expression defaults | +| `style` | [`templates/styles/README.md`](../../templates/styles/README.md) | Direction/method: communication method, visual language, composition, information-expression defaults | | `layout` | [`templates/layouts/README.md`](../../templates/layouts/README.md) | Structure: canvas, page structure, semantic text roles, page types, SVG roster | | `deck` | [`templates/decks/README.md`](../../templates/decks/README.md) | Application plus integrated identity and structure | -A Layout created with `mirror` remains eligible only when its source contract is brand-neutral and application-neutral. Keep a branded or application-bearing source as a Deck, or re-author it as Layout through `standard` / `fidelity`; do not remove those semantics through mirror. - -Before mapping any current workspace, run its shared package validator from the -workspace root. This is the same schema authority used during creation and -registration: Brand/Style are roster-free, the active structure validates its -roster, and a shadowed Deck still validates its declared contract: +A Layout created with `mirror` stays eligible only when its source is brand-neutral and application-neutral; keep a branded or application-bearing source as a Deck or re-author it through `standard` / `fidelity`. Before mapping any workspace, run the shared package validator from its root — Brand/Style are roster-free, the active structure validates its roster, a shadowed Deck still validates its contract; any error blocks installation: ```bash python3 skills/ppt-master/scripts/svg_quality_checker.py "<workspace_root>/templates" --template-mode --canonical-authoring ``` -Any error blocks installation. - ## 3. Structured Preflight -Before copying a Deck or Layout workspace, inspect every SVG root and slot. Brand and Style workspaces are roster-free and skip this structured preflight: - -- Every page declares root Master/Layout keys and PowerPoint picker names. -- Master/Layout visuals are direct atoms, not generic layer `<g>` wrappers. -- Every non-composite slot is a top-level `<g>` with positive bounds and exactly one compatible carrier. -- A composite region uses an explicit `object` proxy; a zero-slot Layout is valid. -- The complete SVG contract is current. Reject a legacy semantic contract instead of repairing it in the target project. +Before copying a Deck or Layout workspace (Brand and Style skip this), inspect every SVG root and slot: every page declares root Master/Layout keys and picker names; Master/Layout visuals are direct atoms, not layer `<g>` wrappers; every non-composite slot is a top-level `<g>` with positive bounds and exactly one compatible carrier; a composite region uses an explicit `object` proxy; zero-slot Layouts are valid; the contract is current — reject a legacy contract instead of repairing it in the target project. ## 4. Install Each Distinct Root Once -Validate each normalized root once. Resolve the effective structural owner as -Layout when selected, otherwise Deck; install only its SVG/non-bitmap -structural payload, but install every selected spec. A library root contributes -one bare `templates/design_spec.md`; install it -as `design_spec.<kind>.<id>.md`, where `<id>` comes from the matching -frontmatter id field. A current project root may contribute several qualified -specs; preserve each validated qualified filename. Never merge spec bodies, -and never copy one multi-kind root's shared SVG or asset pool once per kind. - -| Installed file | Meaning | -|---|---| -| `templates/design_spec.<kind>.<id>.md` | A template contribution installed into or authored in this project | -| `templates/design_spec.md` | Library source shape only; never valid beside qualified project specs | - -For every copied spec, prepend exactly one provenance line under its H1, then -leave the rest of the document untouched. An in-place root is not rewritten: +Validate each normalized root once. The effective structural owner is Layout when selected, otherwise Deck; install only its SVG/non-bitmap structural payload, but install every selected spec. A library root's bare `templates/design_spec.md` installs as `design_spec.<kind>.<id>.md` (`<id>` from its frontmatter); a project root's qualified specs keep their validated filenames. Never merge spec bodies, and never copy one multi-kind root's shared SVG or asset pool once per kind. `templates/design_spec.md` is never valid beside qualified project specs. Prepend exactly one provenance line under each copied spec's H1 and leave the rest untouched (an in-place root is not rewritten): ```markdown > **Installed from**: `skills/ppt-master/templates/brands/mckinsey/` (library) ``` -**Root mapping**: - -- Copy every selected spec from the root to its resolved qualified destination. -- If the root contributes the effective structural owner, copy its declared - SVG roster and other non-bitmap structural files once, including mirror - `source_themes.json` when present. Do not copy a Deck roster when Layout is - selected; its structure is shadowed by design. Preserve inline - `<metadata type="application/json">` and - `data-pptx-native-authority="json"` exactly; semantic Chart/Table JSON never - moves into a sidecar during installation. -- Copy the root's real package-owned `images/` and `icons/` files once. A - Style-only root has none; reject a Style-only library package carrying asset - or review payloads. -- Ignore `exports/`; it contains review artifacts, not portable inputs. - -After that root-level copy, kinds have these downstream effects: +**Root mapping**: copy every selected spec to its qualified destination; if the root is the structural owner, copy its declared SVG roster and other non-bitmap structural files once (including mirror `source_themes.json`), never a Deck roster shadowed by a selected Layout, preserving inline `<metadata type="application/json">` and `data-pptx-native-authority="json"` exactly; copy the root's package-owned `images/` and `icons/` once (a Style-only root has none — reject a Style-only library package carrying asset or review payloads); ignore `exports/`. | Kind | Consumption behavior | |---|---| -| `brand` | Identity is constrained; structure remains free unless the selected set also includes Layout or Deck. | -| `style` | Expose direction/method without identity, prototypes, or structure. Style-only and Style + Brand stay flat; Style + Layout/Deck follows that structure owner. Style never activates visual review. | -| `layout` | Expose reusable structure and take precedence over Deck; Default plans against its prototypes, while Quick reads the complete roster and authors its Master/Layout/slot contract directly. | -| `deck` | Expose descriptive application context and identity. It also supplies structure and the actual prototype roster only when no Layout is selected. | +| `brand` | Identity constrained; structure free unless Layout or Deck is also selected | +| `style` | Direction/method without identity, prototypes, or structure; Style-only and Style + Brand stay flat, Style + Layout/Deck follows that owner; Style never activates visual review | +| `layout` | Reusable structure, precedence over Deck; Default plans against its prototypes, Quick reads the roster and authors its Master/Layout/slot contract directly | +| `deck` | Descriptive application context and identity; structure and prototype roster only when no Layout is selected | -**Atomic install preflight**: +**Atomic install preflight**: resolve every source and destination path; enumerate the union mapping across all roots and across `templates/`, `images/`, `icons/`, mapping each source file at most once; resolve Layout-over-Deck precedence before building the map so the shadowed roster never enters it; reject every destination collision and duplicate kind before writing; write the accepted mapping once — never recursive copy as an implicit conflict policy. An input equal to the target project is consumed in place; if a selected Layout supersedes its in-place Deck roster, stage the mapping and replace the roster atomically. -1. Resolve every source and destination path. -2. Enumerate the union mapping across all distinct roots and across - `templates/`, `images/`, and `icons/`; map a source file at most once. -3. Reject every destination collision and every duplicate-kind selection - before writing. Resolve Layout-over-Deck structural precedence before - constructing the destination map, so the shadowed Deck roster never enters - that map. -4. Write the accepted mapping once; never use recursive copy as an implicit conflict policy. - -Consume an input equal to the target project in place, mapping only other -roots. If a selected Layout supersedes its in-place Deck roster, stage the -accepted mapping and replace that roster atomically. Never mix rosters or write -piecemeal. Ignore `exports/`; empty optional roots remain absent. - -**Hard rule — project-local consumer boundary**: After installation, -Default template-aware Strategist work in final Stage 2, Quick's current -agent before direct authoring, and every later role read only -`<project_path>/templates/` and the project-local `images/` / `icons/` pools. The original library or external root -is installation input, not a later prompt source. If source and target are the -same project root, that in-place root already satisfies this boundary. - -Template SVGs are complete Slide authoring prototypes, not export-time overlays. They already resolve Master + Layout context, so `page_layouts` selects one directly. Standalone Master/Layout definition SVGs are invalid; an unselected authored Slide prototype may still back a reusable Layout definition. -Default records `page_layouts` and the durable structure lock. Quick has no such -planning artifact: it freezes the natural-language application paragraph in -active context and writes the selected Master/Layout/slot contract directly -into the complete output SVG pages. Quick stays flat only without a Layout/Deck -structure owner or under an explicit visual-only instruction. - -For a template-owned Chart/Table carrying -`data-pptx-native-authority="json"`, the installed inline JSON remains the -object's data/native authority. A generated page may retain its existing compact -preview or regenerate an approximate preview from updated JSON, but it must not -derive replacement JSON from that preview. Keep the authority marker and JSON -inside the generated SVG so default fallback and explicit native export remain -two renderings of one object contract. +**Hard rule — project-local consumer boundary**: after installation, Default final Stage 2, Quick's agent before authoring, and every later role read only `<project_path>/templates/` and the project-local `images/` / `icons/` pools; the library or external root is installation input only. +Template SVGs are complete Slide authoring prototypes (Master + Layout context already resolved), so `page_layouts` selects one directly; standalone Master/Layout definition SVGs are invalid, and an unselected authored prototype may still back a reusable Layout definition. Default records `page_layouts` and the structure lock; Quick freezes the natural-language application paragraph in active context and writes the Master/Layout/slot contract directly into the output SVGs, staying flat only without a structure owner or under an explicit visual-only instruction. For a template-owned Chart/Table carrying `data-pptx-native-authority="json"`, the installed inline JSON remains the object's authority: a page may keep or regenerate the preview from that JSON but never derives replacement JSON from the preview. ## 5. Segment Precedence Is Resolved While Reading -Installation copies specs; it never merges them. The consuming role — Default -final Stage 2 through [`strategist-template.md`](../../references/strategist-template.md), -or Quick's current agent before authoring — reads **every** installed -`design_spec.<kind>.<id>.md` and resolves the segments below in context. Asset -collisions are still rejected at install time (§4); segment conflicts are a -reading decision, not a write-time one. - -Never reinterpret, predict, or revise the confirmed Stage-1 communication -contract here. Default obtains any additional material conflict decision -through the active chat channel after Stage 1; this does not reopen template -selection. Quick follows explicit conflict instructions; an unresolved material -compatibility conflict is a hard prerequisite handled in chat, never by -launching Confirm UI or by using path order. +Installation copies specs; it never merges them. The consuming role — Default final Stage 2 through [`strategist-template.md`](../../references/strategist-template.md), or Quick's agent before authoring — reads every installed `design_spec.<kind>.<id>.md` and resolves the segments in context; asset collisions are rejected at install time (§4), segment conflicts are a reading decision. Never reinterpret the confirmed Stage-1 contract here: Default obtains any additional material conflict decision through chat after Stage 1 without reopening selection; Quick follows explicit conflict instructions, and an unresolved material conflict is a hard prerequisite handled in chat, never by Confirm UI or path order. ### 5.1 Different Kinds -Resolve four whole template segments. This table names the starting owner; -current user instructions and the consuming plan still govern project use: - | Segment | Starting owner | |---|---| -| Identity | Brand, otherwise Deck, otherwise unresolved until the consuming plan (Default final Stage 2 or Quick active context). Style color/type/icon/image values are direction candidates, never identity truth. | -| Structure | Layout when present, otherwise Deck, otherwise unresolved/free design until the consuming plan. Style owns no canvas, prototype, Master/Layout, slot, or page mapping. | -| Reusable application context | Deck only when present. Preserve it for the consuming comparison; it never becomes the current project's application contract. | -| Direction / method | Style when present, otherwise unresolved until the consuming plan. Actual Deck prototypes and Signature facts may inform compatibility, but Deck does not own the Style-only method segment. | +| Identity | Brand, otherwise Deck, otherwise unresolved until the consuming plan; Style color/type/icon/image values are direction candidates, never identity truth | +| Structure | Layout when present, otherwise Deck, otherwise free design until the consuming plan; Style owns no canvas, prototype, Master/Layout, slot, or page mapping | +| Reusable application context | Deck only; preserved for comparison, never the current project's application contract | +| Direction / method | Style when present, otherwise unresolved; Deck prototypes and Signature facts inform compatibility but do not own this segment | -Apply each selected segment wholesale; do not mix its fields implicitly. Brand or Deck identity overrides any identity-adjacent defaults carried by Style. A Style direction may adapt to that resolved identity, but cannot relabel its candidates as official brand facts. - -**Hard rule — an owned segment governs visual weight, not only values**: when a -segment owner declares how a value should dominate, recede, or stay rare, that -instruction carries the same authority as the value itself. A Style's -composition or whitespace tendency never demotes a Brand's declared dominant -color to an incidental accent. - -Before Style overlays Layout or Deck guidance, verify that its method fits the -selected structure and, for Deck, serves its reusable context. On mismatch, -require omitting Style or choosing a compatible Style/structure; never silently -weaken a segment. Default final Stage 2 separately checks the result against the -confirmed project contract; Quick checks it against the current request/content -before authoring. - -Field-level micro-adjustments such as a primary-color override are not a workspace selection. Default carries them into the normal final Stage-2 confirmation fields; Quick treats explicit adjustments as direct active-context authoring constraints. +Apply each segment wholesale; never mix fields implicitly. Brand or Deck identity overrides Style's identity-adjacent defaults; a Style direction adapts to that identity but cannot relabel its candidates as brand facts. **Hard rule — an owned segment governs visual weight, not only values**: when an owner declares how a value dominates, recedes, or stays rare, that instruction carries the value's authority; a Style's whitespace tendency never demotes a Brand's dominant color to an accent. Before Style overlays Layout or Deck guidance, verify its method fits the structure (and, for Deck, its reusable context); on mismatch require omitting Style or choosing a compatible pair, never silently weakening a segment. Field-level micro-adjustments such as a primary-color override are not a workspace selection: Default carries them into the Stage-2 confirmation fields, Quick treats them as direct authoring constraints. ### 5.2 Selection Conflicts -Duplicate kinds are selection errors. Layout plus Deck is valid: Layout owns -structure; Deck keeps its other segments. Default returns duplicates to Stage -1; Quick asks for narrower roots. Never split a multi-kind root, average -same-kind specs, or choose by path order. +Duplicate kinds are selection errors: Default returns them to Stage 1, Quick asks for narrower roots. Layout plus Deck is valid — Layout owns structure, Deck keeps its other segments. Never split a multi-kind root, average same-kind specs, or choose by path order. ### 5.3 Installed Set -Each installed file keeps its own frontmatter `kind` and `<id>` from its source -workspace; nothing is relabelled. There is no combined capability label and no -merged spec: the installed set is exactly what was selected, and the routing -consequence is derived while reading — structure comes from Layout when -present, otherwise Deck; identity comes from Brand or Deck; direction comes -from Style. A project-local Brand + Layout pair does not become a reusable library -Deck; its application remains current-project context. +Each installed file keeps its own frontmatter `kind` and `<id>`; nothing is relabelled or merged. Routing is derived while reading — structure from Layout, else Deck; identity from Brand or Deck; direction from Style. A project-local Brand + Layout pair does not become a reusable library Deck. -**Completion receipt**: Report `roots=<unique normalized roots>; sources=<library|explicit per root>; kinds=<all contributed kinds per root>; segments=identity:<owner>,structure:<owner>,application_context:<owner>,direction:<owner>; active_roster=<layout|deck|none>:<source root>; install=<in-place|copied>; installed_specs=<comma-separated design_spec.<kind>.<id>.md>`. +**Completion receipt**: `roots=<unique normalized roots>; sources=<library|explicit per root>; kinds=<all contributed kinds per root>; segments=identity:<owner>,structure:<owner>,application_context:<owner>,direction:<owner>; active_roster=<layout|deck|none>:<source root>; install=<in-place|copied>; installed_specs=<comma-separated design_spec.<kind>.<id>.md>`. ## ✅ Template Workspace Applied -- [x] Every selected input was an index-derived library root or an exact explicit/Create Template root satisfying a listed workspace contract +- [x] Every selected input was an index-derived library root or an exact explicit/Create Template root satisfying a listed contract - [x] Every kind schema passed preflight; structured SVG checks ran only for Layout/Deck inputs -- [x] Duplicate kinds and all destination collisions were rejected before one atomic install; Layout-over-Deck precedence selected exactly one active structural roster -- [x] `<project_path>/templates/` and any portable sibling assets are complete and are the only downstream template source +- [x] Duplicate kinds and destination collisions were rejected before one atomic install; Layout-over-Deck precedence selected exactly one active roster +- [x] `<project_path>/templates/` and portable sibling assets are complete and the only downstream template source - [ ] **Next**: Default completes the template-selection handoff and continues [`generate-pptx.md`](../generate-pptx.md) Step 4 Stage 2; Quick returns to [`quick-generate`](../profiles/quick-generate.md) §2 diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/stages/customize-animations.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/stages/customize-animations.md index 5cc9136f..39a105f8 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/stages/customize-animations.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/stages/customize-animations.md @@ -4,490 +4,118 @@ description: Optional post-processing stage for per-slide and per-object animati # Customize Animations Stage -> Optional Generate-PPTX post-processing stage for per-slide or per-object -> animation control. Run when `<project_path>/animations.json` already exists, -> when the user explicitly asks to customize slide-specific motion, object -> order, effects, timing, or reveals, or when the effective Custom Animations -> outcome in `design_spec.md §I` is enabled. Deck-wide transitions, -> auto-advance, and deck-wide per-element settings without page-specific motion -> or an existing sidecar use [`animations.md`](../../references/animations.md) -> directly and do not activate this stage. In Quick Generate, the current agent -> may activate either path from the request/deck in active context without a -> Design Spec or user interaction. +> Optional Generate-PPTX post-processing stage for per-slide or per-object motion. Run when `<project_path>/animations.json` exists, the user explicitly asks for slide-specific motion, object order, effects, timing, or reveals, or the effective Custom Animations outcome in `design_spec.md §I` is enabled. Deck-wide transitions, auto-advance, and deck-wide per-element settings without page-specific motion or a sidecar use [`animations.md`](../../references/animations.md) directly. Quick may activate either path from the request/deck in active context without a Design Spec or interaction. The sidecar grammar is documented in [`pptx-animations.md`](../../scripts/docs/pptx-animations.md). ## When to Run | Condition | Action | |---|---| -| Effective Custom Animations outcome in `design_spec.md §I` is enabled | Run this stage after the final SVG quality gate and any enabled speaker-note pass, before Generate Step 7; use §IX suggestions as advice | -| User asks for per-slide or per-object animation, reveal order, timing, or effect changes | Run this stage | -| `<project_path>/animations.json` already exists | Run this stage to resolve preserve/adjust/replace/suppress intent before export | -| §IX contains `Motion suggestion`, but no trigger above is active | Do not run; retain the suggestion as Strategist advice and keep normal export defaults | -| No motion request, enabled outcome, or existing sidecar; user only wants the default deck | Do not run; normal export keeps page transitions and no element builds | -| No existing sidecar; user only wants deck-wide page transitions, auto-advance, or one per-element object animation policy | Do not run; apply [`animations.md`](../../references/animations.md) with exporter flags such as `-a auto` or `-a emphasis_spin` | -| Only a page-transition sound is requested, with no object-specific motion or existing sidecar | Do not run the full stage solely for sound; resolve a sparse transition sidecar through [`animations.md`](../../references/animations.md) §2.2 at export time | -| An object-animation sound is requested | Run this stage because the cue must bind to a resolved animation row and real object target | -| `svg_output/*.svg` is missing | Complete the main Executor phase first | +| Effective Custom Animations outcome enabled | Run after the final SVG quality gate and any speaker-note pass, before Generate Step 7; §IX suggestions are advice | +| User asks for per-slide or per-object animation, reveal order, timing, or effect changes | Run | +| `animations.json` already exists | Run to resolve preserve/adjust/replace/suppress intent before export | +| §IX `Motion suggestion` only, no trigger above | Do not run; keep the suggestion as advice and normal export defaults | +| No request, outcome, or sidecar | Do not run; export keeps page transitions and no builds | +| Only deck-wide transitions, auto-advance, or one per-element policy, no sidecar | Do not run; apply `animations.md` with exporter flags such as `-a auto` or `-a emphasis_spin` | +| Only a page-transition sound, no object motion or sidecar | Do not run; resolve a sparse transition sidecar through `animations.md` §2.2 at export | +| An object-animation sound is requested | Run — the cue must bind to a resolved row and real target | +| `svg_output/*.svg` missing | Complete the Executor phase first | -**Decision precedence**: latest explicit instruction → final Stage-2 policy → -workflow default `false`; provenance stays in Design Spec §I, never the -lock. Final Stage-2 `false` blocks creation, not an existing sidecar. Existing -sidecars enter this stage; explicit disables follow the table without deletion. +**Decision precedence**: latest explicit instruction → final Stage-2 policy → workflow default `false`; provenance stays in §I, never the lock. A final Stage-2 `false` blocks creation, not an existing sidecar; explicit disables follow the table without deletion. --- ## 1. Resolve Intent and Read Semantic Context -**Context read**: before editing `animations.json`, read every semantic planning file below that exists. +Before editing `animations.json`, read every semantic file that exists — `design_spec.md` (content intent, narrative role, emphasis), `spec_lock.md` (page rhythm, layout role, chart/template constraints), `notes/total.md` or `notes/*.md` (speaker flow for reveal order, delays, emphasis). They inform but do not gate this stage: state what is missing and proceed with the rest plus visible SVG content; with none of them, use only explicit instructions, visible SVG, and `animations.md`'s resolution rules without inferring choreography beyond what the page expresses. -| File | Use | -|---|---| -| `<project_path>/design_spec.md` | Understand each slide's content intent, narrative role, and visual emphasis | -| `<project_path>/spec_lock.md` | Confirm page rhythm, layout role, chart/template constraints, and execution contract | -| `<project_path>/notes/total.md` or `<project_path>/notes/*.md` | Use speaker flow to tune reveal order, delays, and emphasis | - -**Existing sidecar intent gate**: - -| User intent | Action | +| Existing-sidecar intent | Action | |---|---| | Explicit Custom Animations disable | Preserve and validate the sidecar; return `-a none` | -| Explicit all-motion disable | Preserve and bypass the sidecar; return `--no-animations` | -| Explicit regeneration / rewrite / replacement | Rebuild the semantic grouping plan and replace `animations.json`; the previous choreography is not a constraint | -| Explicit adjustment / tuning / repair | Validate first, preserve the existing choreography where its semantic units remain valid, and migrate affected group references after any required regrouping | -| Stage activated with an existing sidecar and new §IX suggestions but no user replacement request | Validate first; preserve valid existing choreography and adjust only the affected semantic units | -| Existing sidecar with no new motion instruction | Validate and preserve it unchanged; if invalid, repair the owning sidecar/group reference before export | -| Ambiguous generation request | Default Generate asks whether to regenerate or modify; Quick Generate decides from the request, visible SVG, and existing sidecar, then continues | +| Explicit all-motion disable | Preserve and bypass it; return `--no-animations` | +| Explicit regeneration / rewrite / replacement | Rebuild the grouping plan and replace `animations.json`; prior choreography is not a constraint | +| Explicit adjustment / tuning / repair | Validate first; preserve valid semantic units; migrate affected references after regrouping | +| Stage activated with a sidecar and new §IX suggestions, no replacement request | Validate first; preserve valid choreography, adjust only affected units | +| Sidecar with no new instruction | Validate and preserve unchanged; repair an invalid sidecar/group reference before export | +| Ambiguous request | Default asks regenerate-or-modify; Quick decides from the request, SVG, and sidecar | -Unless explicit all-motion disable bypasses it, validate an existing sidecar -before deciding to preserve, modify, or suppress object motion: +Unless an all-motion disable bypasses it, validate an existing sidecar first: `python3 skills/ppt-master/scripts/animation_config.py validate <project_path>`. -```bash -python3 skills/ppt-master/scripts/animation_config.py validate <project_path> -``` +**Hard rule**: semantic files determine motion intent and unit boundaries; the current `svg_output/*.svg` supplies visible content and implementation structure, and its existing `<g>` hierarchy is never accepted as the plan merely because it exists. -**Hard rule**: semantic files determine both animation intent and animation -unit boundaries. The current `svg_output/*.svg` supplies visible content and -implementation structure, but its existing `<g>` hierarchy is not accepted as -the animation plan merely because it already exists. +**Decision ownership — understand, then design**: a §IX `Motion suggestion` states the communication job and relationship; it neither activates this stage nor locks implementation. Understand it, then develop the motion brief from the final SVG's semantic units, visible states, composition, and speaker flow — never a mechanical mapping to groups, effects, order, or timing. Executor may preserve, adapt, simplify, decline, or choose `none`; explicit user requirements bind; never change page content to justify animation. -**Optional-context fallback**: these semantic files inform this supporting stage but are not its gate artifacts. If any are absent, state what is missing and proceed with every remaining file plus visible SVG content. If all three context inputs are absent, use only explicit user instructions, visible SVG content, and the resolution rules in [`animations.md`](../../references/animations.md); do not infer detailed choreography beyond what the page itself expresses. +**Hard rule — existing visible-layer boundary**: regroup only under §2 visual equivalence; never create or modify a crop, comparison layer, scrim, lens, hotspot, annotation, or other visible image state for motion. When a required state is missing and ordinary Slide-local authoring can supply it, return to Generate Step 6, rerun the final gate (and notes when enabled), then resume; when a structural boundary prevents that, simplify a non-binding suggestion to legal units, a page transition, or `none`, and let an explicit requirement follow failure recovery. -**Decision ownership — understand, then design**: A §IX `Motion suggestion` -expresses the Strategist's communication job and semantic relationship; it -neither activates this stage nor locks implementation. Once active, understand -that intent, then develop the motion brief from the final SVG's semantic units, -visible states, composition, and speaker flow. Do not mechanically map it to -groups, effects, order, or timing. Executor may preserve, adapt, simplify, -decline, or choose `none`; an unchanged realization is valid and requires no -novelty. Explicit user motion requirements bind. Never change page -content merely to justify animation. - -**Hard rule — existing visible-layer boundary**: This stage may regroup existing content only under §2 visual equivalence; it MUST NOT create or modify a crop, comparison layer, scrim, lens, hotspot, annotation, or other visible image state to satisfy motion intent. When a required state is missing and ordinary Slide-local authoring can supply it, return to Generate Step 6, rerun the final SVG gate and regenerate notes only when speaker notes are enabled, then resume here. If a structural boundary prevents that repair, simplify a non-binding suggestion to legal existing units, a page transition, or `none`; an explicit requirement follows failure recovery instead of changing structure. - -**No-op is complete**: Evaluate suggestions before regrouping SVG content. If -no `animations.json` exists, every page should retain the normal `fade` -transition and no object builds, and no explicit user requirement remains -unmet, change no SVG, create no sidecar, and return to Generate Step 7. Never -author motion merely to expose a capability. +**No-op is complete**: if no sidecar exists, every page should keep the normal `fade` transition with no builds, and no explicit requirement is unmet, change no SVG, create no sidecar, and return to Step 7. Never author motion to expose a capability. --- ## 2. Rebuild Semantic Motion Units When Needed, Then List IDs -**Mandatory when object-targeted motion is in scope — content-first grouping -audit**: inspect each affected slide's visible content against its communication -job and speaker flow before treating any top-level `<g>` as an animation -anchor. The affected set is the page named by an adopted suggestion or explicit -object-motion request, plus both endpoints of each deterministic Morph pair. -Untouched pages need no animation audit. Existing groups are implementation -evidence only. Keep a current group unchanged only after confirming that it -already represents exactly one audience-facing motion unit or one continuing -Morph object. A page-transition-only plan without explicit Morph pairs skips -regrouping and group listing. +**Mandatory when object-targeted motion is in scope — content-first grouping audit**: inspect each affected slide's visible content against its communication job and speaker flow before treating any top-level `<g>` as an anchor. The affected set is the page named by an adopted suggestion or explicit request plus both endpoints of each Morph pair; untouched pages need no audit; a page-transition-only plan without Morph pairs skips regrouping and listing. Keep a group unchanged only when it already represents exactly one audience-facing motion unit or one continuing Morph object. -| Content condition | Required grouping action | +| Content condition | Grouping action | |---|---| -| One current group contains several independently narrated rows, cards, steps, claims, or stages | Split it into descriptive direct-root sibling groups, one per motion unit | -| One motion unit is scattered across groups or root primitives | Merge or wrap its background, icon, label, value, and supporting text into one direct-root group | -| A connector or arrow explains entry into a node or stage | Keep it with the relationship or target unit that makes the connection intelligible | -| A hero visual, overview graphic, takeaway, or warning has its own communication role | Give it its own semantic group | -| The same semantic object continues across adjacent Morph pages | Isolate each endpoint as one direct-root group and keep both endpoints as compatible object kinds | -| Several atoms express one inseparable idea | Keep them together; do not animate the atoms separately | -| Page chrome, structural layers, or static framing | Preserve their structure and exclude them from ordinary animation targets | +| One group holds several independently narrated rows, cards, steps, claims, or stages | Split into descriptive direct-root siblings, one per unit | +| One unit is scattered across groups or root primitives | Merge or wrap its background, icon, label, value, and text into one direct-root group | +| A connector or arrow explains entry into a node or stage | Keep it with the relationship or target that makes it intelligible | +| A hero visual, overview graphic, takeaway, or warning has its own role | Its own group | +| The same object continues across adjacent Morph pages | Isolate each endpoint as one direct-root group of compatible kinds | +| Several atoms express one inseparable idea | Keep them together | +| Page chrome, structural layers, static framing | Preserve and exclude from ordinary targets | -**Hard rule — visual equivalence**: regrouping changes object boundaries only. -Preserve all visible content, paint order, coordinates, transforms, inherited -paint, opacity, clipping, filters, references, and native metadata. Keep -rendering-bearing implementation wrappers nested inside the new semantic group -when flattening or distributing their attributes could change appearance. +**Hard rule — visual equivalence**: regrouping changes object boundaries only — preserve every visible pixel, paint order, coordinate, transform, inherited paint, opacity, clip, filter, reference, and native metadata; keep rendering-bearing wrappers nested when flattening could change appearance. **Hard rule — structural boundary**: never split or merge across `data-pptx-layer`, `data-pptx-placeholder`, native chart/table carrier, native preset, or imported logical-object boundaries; structural/static objects stay non-animatable; ordinary direct-root groups follow [`shared-standards-core.md`](../../references/shared-standards-core.md) §4.3 (descriptive unique `id`, positive root-coordinate `data-pptx-bounds`, no bounds on nested groups). -**Hard rule — structural boundary**: never split or merge across -`data-pptx-layer`, `data-pptx-placeholder`, native chart/table carrier, native -preset, or imported logical-object boundaries. Structural/static objects remain -non-animatable. Ordinary Slide-local content groups follow -[`shared-standards-core.md`](../../references/shared-standards-core.md) §4.3: -every visible direct-root group has a descriptive unique `id` and positive -root-coordinate `data-pptx-bounds`; nested implementation groups carry no -bounds. +**Forbidden — group-list-first choreography**: choosing effects or order from `list-groups` before the audit; keeping a coarse wrapper because it has an `id`; splitting one idea into shapes or lines to raise the count; merging unrelated ideas to lower it; adding animation `data-*` attributes to SVG. There is no target group count. -**Forbidden — group-list-first choreography**: - -- Choosing effects or order from the pre-existing `list-groups` output before the content-first audit -- Keeping a coarse wrapper only because it already has an `id` -- Splitting one semantic idea into individual shapes or text lines to increase animation count -- Merging unrelated ideas to reduce animation count -- Adding animation-specific `data-*` attributes to SVG - -There is no target group count. Granularity follows the page's actual claims, -comparisons, sequence, causality, and narration beats. - -After any regrouping, rerun the final SVG quality gate because `svg_output/` -changed. Use the owning route's checker form; Quick Generate must add its -lockless profile flag: - -```bash -python3 skills/ppt-master/scripts/svg_quality_checker.py <project_path> --canonical-authoring --stage final --json -# Quick Generate: insert --quick-generate before --stage. -``` - -Then list the **post-regroup** anchors: - -```bash -python3 skills/ppt-master/scripts/animation_config.py list-groups <project_path> -``` - -Output is one line per slide: `<slide_basename>: id1, id2, id3`. Default chrome -groups (`bg` / `*-header` / `*-footer` / `*-decor` / `nav` / `watermark` / -`logo` / `pagenumber`) are excluded. This post-regroup list is the source of -truth when planning §3 and editing §4; never invent a slide or group key. - -An explicit sidecar entry may override only the marker-free legacy id-name -heuristic. A group carrying `data-pptx-layer` or an explicit static -role/placeholder marker can never animate, even when it is named explicitly. - -If `animations.json` does not exist and a starting file is useful, scaffold -only after semantic regrouping: - -```bash -python3 skills/ppt-master/scripts/animation_config.py scaffold <project_path> -``` - -The scaffold is neutral: its default object effect is `none`, and listed groups -may remain empty `{}` placeholders until adopted. Creating it does not select -generic entrance animation. Do not read the full scaffold unless it is needed -as an editing starting point. +After any regrouping, rerun the final gate (`svg_quality_checker.py <project_path> --canonical-authoring --stage final --json`; Quick inserts `--quick-generate` before `--stage`), then list the post-regroup anchors with `animation_config.py list-groups <project_path>` (one line per slide, chrome groups `bg` / `*-header` / `*-footer` / `*-decor` / `nav` / `watermark` / `logo` / `pagenumber` excluded). That list is the only source of slide and group keys for §3–§4. An explicit sidecar entry overrides only the marker-free legacy id-name heuristic; a group carrying `data-pptx-layer` or a static role/placeholder marker never animates. If a starting file is useful, `animation_config.py scaffold <project_path>` after regrouping creates a neutral scaffold (default object effect `none`, groups as empty `{}` placeholders) — creating it selects nothing, and it need not be read in full. --- ## 3. Plan Slide and Object Motion -**Mandatory**: plan the requested motion layers for each affected slide before -editing `animations.json`. A local object-animation request does not require a -deck-wide transition review. +**Mandatory**: plan the requested layers for each affected slide before editing — page transition (`defaults.transition` / `slides.<slide>.transition`), deterministic Morph pair (`slides.<destination>.morph`), page animation defaults (`defaults.animation` / `slides.<slide>.animation`), object lifecycle (`slides.<slide>.groups.<group_id>` as one legacy row or an ordered `effects[]`). A local object request needs no deck-wide transition review. -| Layer | Config path | Use | -|---|---|---| -| Page transition | `defaults.transition` or `slides.<slide>.transition` | Control how one slide enters from the previous slide | -| Deterministic Morph pair | `slides.<destination>.morph` | Bind one real source group to one real destination group when semantic identity continues across adjacent slides | -| Page animation defaults | `defaults.animation` or `slides.<slide>.animation` | Control the default object-animation behavior for animated groups on a slide | -| Object lifecycle | `slides.<slide>.groups.<group_id>` | Assign one legacy effect row or an ordered `effects[]` sequence to a real SVG motion unit | - -**Per-affected-page motion brief**: classify the communication job—including -none—and each unit's lifecycle. Choose only the required transition, effect, -order, timing, and one dominant Start rhythm; mix modes or add emphasis and -exit only for a distinct job with a restrained, fitting effect. Read -`design_spec.md`, `spec_lock.md`, speaker notes, and SVG group ids for role, -rhythm, order, and target validity. - -**Mandatory — select from meaning, not catalog coverage**: run the -page-relationship and lifecycle selection playbooks in -[`animations.md`](../../references/animations.md) §3 and §4 before choosing any -specific effect. Their candidates are recall aids, not coverage targets; this -stage binds the selected duties to real targets. - -**Title motion decision**: when a title participates, classify its lifecycle, -then choose immediate, delayed, synchronized, post-hero, or narration-cued -timing from slide intent. Use the sidecar override for a marker-free legacy -chrome-like id; repair an incorrect explicit structural/static marker before -animating it. - -**Default — inherit unaffected motion layers (may override when the page's -communication job requires it)**: a custom object-animation pass may leave the -page transition and every untouched page on exporter or sidecar defaults. Add a -slide-specific `transition` only when the affected page needs one; never add -variation for coverage. - -**Timing guidance**: use shorter motion for dense/repeated scan content and -longer motion for conceptual pivots, hero diagrams, section boundaries, and -final takeaways. Uniform timing is valid when it fits the requested style. - -**Reference — not a constraint: motion judgment.** Decide the communication -job, lifecycle, tone, audience order, and whether direction carries meaning -before using geometry. If motion adds no clarity or intended feeling, classify -the unit `static`; use `none`, `entrance_appear`, or `entrance_fade` only when -that result matches the lifecycle. Layout direction alone does not require -special motion; variation follows a real content/tone change, never a quota. +**Per-affected-page motion brief**: classify the communication job (including none) and each unit's lifecycle; choose only the required transition, effect, order, timing, and one dominant Start rhythm; mix modes or add emphasis/exit only for a distinct job with a restrained effect. **Mandatory — select from meaning, not catalog coverage**: run the page-relationship and lifecycle playbooks in `animations.md` §3–§4 before any specific effect; candidates are recall aids. **Title motion**: classify the lifecycle, then choose immediate, delayed, synchronized, post-hero, or narration-cued timing; use the sidecar override for a marker-free chrome-like id and repair an incorrect structural marker before animating it. **Default — inherit unaffected layers (may override when the page's job requires it)**: leave the transition and untouched pages on defaults; add a slide-specific `transition` only when the page needs one. **Timing**: shorter for dense/repeated scan content, longer for pivots, hero diagrams, section boundaries, and takeaways; uniform timing is valid. **Reference — motion judgment**: decide job, lifecycle, tone, audience order, and whether direction carries meaning before geometry; a unit that gains no clarity or feeling is `static` (`none`, `entrance_appear`, or `entrance_fade` only when that matches the lifecycle); layout direction alone requires no motion; variation follows content or tone, never quota. ### 3.1 Supported Page Transitions -Use one of the 48 canonical native effects from the complete shared registry in -[`animations.md`](../../references/animations.md) §3. It covers all current -PowerPoint Subtle, Exciting, and Dynamic Content gallery effects. The eight old -names are readable only as compatibility inputs; do not write them in new -plans or sidecars. They normalize to a canonical effect plus native -`effect_options` before writing. `none` removes the visual page transition -while allowing timed advance to remain. - -**Transition fields**: - -| Field | Behavior | -|---|---| -| `effect` | One supported page transition effect; `none` removes only the visual effect | -| `effect_options` | Optional object containing only the selected native effect's PowerPoint Effect Options; requires an explicit `effect` | -| `duration` | Finite transition duration in seconds; must be greater than zero | -| `auto_advance` | Optional finite non-negative seconds before automatic slide advance; click remains enabled, and this field is valid with `effect: none` | -| `sound` | Optional project-relative `.wav` cue; select and sync it only after the transition solution is resolved | - -Run -`python3 skills/ppt-master/scripts/pptx_animations.py --describe-transition <effect>` -before authoring Effect Options. Never infer that one effect accepts another -effect's direction, shape, pattern, or boolean fields. - -For a cross-slide object continuation that must not depend on PowerPoint's -automatic matching, put one explicit `morph` block on the destination slide. -Its `from` slide must be the immediately preceding exported SVG; each stable -pair key binds one source direct-root group id to one destination direct-root -group id. The exporter supplies PowerPoint's `!!` prefix. Use Morph by object; -word/character Morph does not accept this object-pair contract. +One of the 48 canonical native effects in `animations.md` §3 (the complete Subtle, Exciting, and Dynamic Content gallery); the eight old names are compatibility inputs only and normalize to a canonical effect plus `effect_options`; `none` removes the visual effect while timed advance remains. Fields: `effect`; `effect_options` (only the selected effect's native options — run `pptx_animations.py --describe-transition <effect>` first and never infer another effect's fields); `duration` (> 0 s); `auto_advance` (non-negative seconds, click still enabled, valid with `effect: none`); `sound` (project-relative `.wav`, selected only after the transition is resolved). For a cross-slide continuation that must not depend on PowerPoint's automatic matching, put one `morph` block on the destination whose `from` is the immediately preceding SVG and whose pair keys bind one source direct-root group to one destination group (the exporter supplies `!!`); Morph by object only. ### 3.2 Supported In-Slide Animations -Use the 203 canonical PowerPoint-native keys: 53 `entrance_*`, 33 -`emphasis_*`, 64 `path_*`, and 53 `exit_*`. Run -`python3 skills/ppt-master/scripts/pptx_animations.py --list` for the exact -categorized names. Each key preserves PowerPoint's complete authored behavior -tree. Media-only commands remain in the audio/video workflows. - -| Choice | Behavior | -|---|---| -| `entrance_*` / `emphasis_*` / `path_*` / `exit_*` | Select one explicit canonical PowerPoint object effect | -| `auto` | Generic `enter` only: map content roles to canonical entrances; image-like ids use a richer canonical pool | -| `mixed` | Generic `enter` only: cycle 16 canonical entrance presets by group order | -| `random` | Generic `enter` only: select deterministically from the same canonical entrance pool | -| `none` | Exclude the object or slide from in-slide animation | - -The 29 old short names remain readable only as compatibility inputs; do not use -them in new plans or sidecars. All Fly direction names normalize to -`entrance_fly`, all Wipe direction names normalize to `entrance_wipe`, and the -other old names normalize to their matching `entrance_*` preset. `cut` -normalizes to `entrance_appear`. Compatibility Fly/Wipe aliases preserve their -direction as `effect_options.direction`; legacy `wheel` preserves its historical -four-spoke amount. - -`auto`, `mixed`, and `random` never choose emphasis, motion-path, or exit -effects implicitly. Use them only after classifying a unit as a generic -`enter`; select an explicit canonical key for every adopted `emphasize`, -`move`, or `exit` duty. - -**Hard rule — explicit semantic choreography**: When an adopted plan depends -on a specific lifecycle, relationship, or order, target its real groups with -explicit canonical effects and order; do not delegate those material decisions -to `auto`, `mixed`, or `random`. Those modes remain valid only when generic -entrance treatment is sufficient. - -**Start modes**: - -| Trigger | Behavior | -|---|---| -| `after-previous` | Default click-free cascade | -| `with-previous` | One coordinated beat together | -| `on-click` | Controlled semantic reveal | +The 203 canonical keys — 53 `entrance_*`, 33 `emphasis_*`, 64 `path_*`, 53 `exit_*` (`pptx_animations.py --list`), each preserving PowerPoint's complete behavior tree. `auto` / `mixed` / `random` apply to generic `enter` only (`auto` maps roles to canonical entrances with a richer pool for image-like ids; `mixed` cycles 16 presets by group order; `random` selects deterministically from the same pool) and never choose emphasis, path, or exit implicitly; `none` excludes the object or slide. The 29 old short names are compatibility inputs (Fly/Wipe directions → `entrance_fly` / `entrance_wipe` with `effect_options.direction`, `cut` → `entrance_appear`, legacy `wheel` keeps its four-spoke amount). **Hard rule — explicit semantic choreography**: when a plan depends on a specific lifecycle, relationship, or order, target real groups with explicit canonical effects and order; generic modes are valid only when generic entrance treatment suffices. Start modes: `after-previous` (click-free cascade), `with-previous` (one coordinated beat), `on-click` (controlled reveal). ### 3.3 Optional Sound Pass -Run this pass only after the visual transition, object lifecycle, effect, -order, and timing decisions above are complete. Sound selection is -post-processing state: do not recover it from or write it back to -`design_spec.md` / `spec_lock.md`, and do not treat it as a pre-SVG resource. - -| Need | Action | -|---|---| -| No resolved cue needs sound | Omit every `sound` field; do not create `<project_path>/sounds/` | -| A bundled cue fits one resolved transition or animation row | Read the complete [`sound-vocabulary.md`](../../templates/sounds/sound-vocabulary.md), choose from the resolved auditory job, then sync only the selected namespaced id(s) into the project | -| The project already contains user-provided audio | Use its project-relative path when its format is valid; no library sync is required | - -```bash -# Optional exact filtering after reviewing the complete vocabulary -python3 skills/ppt-master/scripts/sound_sync.py list --query <term> -python3 skills/ppt-master/scripts/sound_sync.py \ - <project_path> <namespace>/<sound_id> [<namespace>/<sound_id> ...] -``` - -Use the corresponding `sounds/<namespace>/<file>.wav` path in -`transition.sound`, `animation.sound`, or the selected group/effect row. Never -reference `skills/ppt-master/templates/sounds/` from `animations.json`. The -global library is a selection source, not an exporter fallback. - -This pass owns only native PPTX cue selection and configuration. When direct -narrated MP4 delivery is active, leave gain, limiting, and video mixing to -[`generate-audio`](./generate-audio.md) after the final narrated export; do not -write those post-production values into `animations.json`. +Only after visual transition, lifecycle, effect, order, and timing are complete; sound is post-processing state never written to or recovered from the Design Spec or lock. No resolved cue → omit every `sound` field and create no `sounds/`. A bundled cue fits one resolved row → read the complete [`sound-vocabulary.md`](../../templates/sounds/sound-vocabulary.md), choose from the auditory job, then sync only the selected ids (`sound_sync.py list --query <term>` for optional filtering; `sound_sync.py <project_path> <namespace>/<sound_id> ...`) and reference `sounds/<namespace>/<file>.wav` in `transition.sound`, `animation.sound`, or the group/effect row. User-provided audio in the project uses its own path when the format is valid. Never reference `skills/ppt-master/templates/sounds/` from `animations.json`; the global library is a selection source, not an exporter fallback. Gain, limiting, and video mixing belong to [`generate-audio`](./generate-audio.md), never this sidecar. --- ## 4. Edit `animations.json` -**Hard rule — sparse overrides reference real targets**: write only affected -slides and only fields that differ from exporter or sidecar defaults. An -unlisted SVG inherits the resolved deck-wide settings; a listed slide may -contain only `transition`, `animation`, `groups`, or `morph` fields that it -actually overrides. `defaults` is optional and belongs only to intentional -deck-wide settings. Group-level overrides remain opt-in. Chrome groups stay out -(the exporter pins them to `none` by default). Name a legacy chrome-like id only -when the user explicitly wants that content animated and the SVG has no -explicit structural layer, role, or placeholder marker. +**Hard rule — sparse overrides reference real targets**: write only affected slides and only fields that differ from exporter or sidecar defaults; an unlisted SVG inherits deck-wide settings; a listed slide carries only the `transition`, `animation`, `groups`, or `morph` fields it overrides; `defaults` is optional and deck-wide only; chrome groups stay out (the exporter pins them to `none`), and a legacy chrome-like id is named only on explicit reviewed intent with no structural marker. **Forbidden**: a slide absent from `svg_output/`; a missing, ambiguous, or structural group; enumerating every group to restate the slide default; listing a group with `data-pptx-layer` or a static role/placeholder marker; animation `data-*` attributes in SVG. -**Forbidden**: - -- Referencing a slide that does not exist in `svg_output/` -- Referencing a missing, ambiguous, or structural group -- Enumerating every content group in a slide just to restate the slide-level default effect -- Listing a group with `data-pptx-layer` or an explicit static role/placeholder marker -- Listing a legacy chrome-like id without an explicit, reviewed intent to override the name heuristic - -| Field | Behavior | -|---|---| -| `transition.effect` | Slide-specific page transition effect | -| `transition.effect_options` | Effect-specific native PowerPoint options; requires an explicit slide-specific `transition.effect` | -| `transition.duration` | Slide-specific page transition duration | -| `transition.sound` | Optional project-relative `.wav` cue copied during §3.3; valid with `effect: none`; set a slide override to `null` to clear an inherited default sound | -| `morph.from` | Immediately preceding SVG stem for an explicit deterministic Morph transition | -| `morph.pairs.<key>.from` / `.to` | Unique source/destination direct-root group ids that receive the shared PowerPoint name `!!<key>` | -| `animation.effect` | Slide-specific default object animation effect | -| `animation.duration` | Slide-specific default object schedule duration | -| `animation.stagger` | Slide-specific delay between object animation rows | -| `animation.trigger` | Slide-specific start mode | -| `groups.<id>.effects` | Non-empty ordered array for a multi-duty lifecycle; every row explicitly names `effect`, and `effects` cannot coexist with legacy single-effect fields in the same group block | -| `groups.<id>.effect` | Backward-compatible single-row form: one canonical native effect, `auto`, `mixed`, `random`, or `none`; old names are read-only compatibility inputs | -| `effects[].trigger` / legacy `trigger` | Row-specific Start mode; omitted values inherit `animation.trigger` | -| `order` | Page-wide order for ordinary rows; ties retain SVG group order and then `effects[]` index. `trigger_shape` rows keep relative order in separate interactive sequences; SVG layer order never changes | -| `delay` | Row-specific seconds added to the resolved Start or shape trigger | -| `duration` | Per-row schedule duration in seconds; scalable native behavior trees keep their internal timing ratios, while `entrance_appear` and instantaneous native presets retain their PowerPoint-authored duration and use this value for subsequent `after-previous` spacing | -| `effect_options` | Effect-specific PowerPoint parameters; requires an explicit canonical `effect` in the same legacy block or `effects[]` row | -| `trigger_shape` | Different top-level group id for native **On Click of**; row-only and not inherited. It implies `on-click`; an explicit row `trigger` may accompany it only when also `on-click` | -| `repeat_count` / `repeat_duration` | Repeat count or total repeat span; mutually exclusive | -| `auto_reverse`, `rewind` | Reverse each cycle and/or restore the pre-animation state | -| `accelerate`, `decelerate`, `bounce_end` | `0..1` timing ratios; acceleration plus deceleration must not exceed `1`; bounce requires an interpolated effect and cannot combine with deceleration | -| `restart` | `always`, `when-not-active`, or `never` | -| `after_effect` | `none`, `dim` with `color`, `hide`, or `hide-on-next-click` | -| `sound` | Object-animation cue. Existing low-level inputs accept project-relative or absolute `.m4a`, `.mp3`, or `.wav`; bundled selections use the synced project-relative `.wav` path from §3.3 | - -**Hard rule — one group representation**: A populated -`groups.<id>` object uses either the backward-compatible single-effect fields -or `effects[]`, never both. `effects[]` must contain at least one object, and -every row explicitly names `effect`. An untouched scaffold `{}` is a neutral -placeholder. Omitted row duration, Start, timing/completion controls, and sound -inherit the resolved slide animation values exactly as the legacy form does. - -`effect_options` may contain `direction`, `amount`, `color`, `font_name`, -`relative`, or `size`, but validation permits only fields supported by the -selected effect. Before writing a parameterized effect, run -`python3 skills/ppt-master/scripts/pptx_animations.py --describe -<canonical_effect>` and use the returned values exactly. `duration` owns -PowerPoint Speed; `accelerate`/`decelerate` own smooth start/end, so do not -invent duplicate fields. Change Font's `font_name` is one concrete -target-installed PowerPoint face, never a CSS font stack. - -Use the coherent multi-category `effects[]` example in -[`animations.md`](../../references/animations.md) §2. Its static frame stays -unlisted while one real unit runs enter → move → emphasize → exit. Keep the -legacy object for one-row overrides; never convert old sidecars mechanically. - -Use the complete two-slide deterministic Morph example in -[`animations.md`](../../references/animations.md) §2.1; do not copy the source -group into the destination slide's `groups` block merely to establish identity. - -**Forbidden — SVG pollution**: do not add `data-*` animation attributes to SVG files. Animation customization belongs in `animations.json`. +**Hard rule — one group representation**: a populated `groups.<id>` uses either the legacy single-effect fields or `effects[]` (non-empty, every row naming `effect`), never both; an untouched scaffold `{}` is neutral; omitted row duration, Start, timing/completion controls, and sound inherit the resolved slide values. `effect_options` may hold `direction`, `amount`, `color`, `font_name`, `relative`, or `size`, but only fields the selected effect supports — run `pptx_animations.py --describe <canonical_effect>` before writing a parameterized effect; `duration` owns Speed and `accelerate` / `decelerate` own smooth start/end (no duplicate fields); Change Font's `font_name` is one target-installed face, never a CSS stack. The complete field reference — transition, morph, slide animation defaults, per-row trigger, order, delay, duration, `trigger_shape`, repeat, reverse/rewind, timing ratios, restart, after-effect, sound — is [`pptx-animations.md`](../../scripts/docs/pptx-animations.md) §8. Use the multi-category `effects[]` example in `animations.md` §2 and the two-slide Morph example in §2.1 (never copy the source group into the destination `groups` to establish identity); keep the legacy object for one-row overrides and never convert old sidecars mechanically. --- ## 5. Validate and Return to Generate Export -When `animations.json` was newly created or changed after the §1 validation, -run: +When `animations.json` was created or changed after §1, run `python3 skills/ppt-master/scripts/animation_config.py validate <project_path>`, then return to the owning export path — Default [`generate-pptx.md`](../generate-pptx.md) Step 7.1; Quick [`quick-generate.md`](../profiles/quick-generate.md) §4 — both of which read the sidecar automatically. If §2 changed `svg_output/`, complete the owning route's final SVG rerun before returning; never finalize or export from this stage. -```bash -python3 skills/ppt-master/scripts/animation_config.py validate <project_path> -``` - -After validation succeeds, return to the owning export path: - -- Default Generate → [`generate-pptx.md`](../generate-pptx.md) Step 7.1, which - owns note splitting, `finalize_svg.py`, native export, and the published - postflight receipt. -- Quick Generate → [`quick-generate.md`](../profiles/quick-generate.md) §4, - which skips finalization and exports with `--quick-generate`. - -Both exporters read `<project_path>/animations.json` automatically. If §2 -changed `svg_output/`, complete the owning route's required final SVG quality -rerun before returning. Do not finalize or export independently from this -stage. - -**Validation**: The later native export must reflect the per-slide and -per-object overrides. `--animation none` still disables all per-element -animation and overrides `animations.json`. Unknown animation -effects/modes/triggers; unsupported effect options; incompatible, boolean, -non-finite, or out-of-range timing parameters; non-positive durations; negative -delay/stagger; invalid order; missing slides/groups; and structural-layer -targets fail validation. Transition validation remains strict. None of these -failures substitutes a fallback effect or silently drops a requested target. -Deterministic Morph also rejects non-adjacent source slides, missing or -ambiguous direct-root groups, conflicting or undeclared shared keys, non-object -Morph, and any target that does not remain one compatible Slide-local object -after structure processing. - -**Validation boundary**: a passing sidecar, timing-tree read-back, and sound -relationship check proves the PPTX configuration only. It does not prove the -PowerPoint-exported MP4 audio track contains those cues. - -Generate Step 7 export reads back row order, including repeated rows targeting -one shape, trigger, target, resolved effect, duration, offset, timing placement, -IDs, and shape references. Narration -preserves these rows. Direct-PPTX routes fingerprint and preserve source object -animation; they never author it. See -[`pptx-animations.md`](../../scripts/docs/pptx-animations.md). +**Validation**: unknown effects/modes/triggers; unsupported options; incompatible, boolean, non-finite, or out-of-range timing; non-positive durations; negative delay/stagger; invalid order; missing slides/groups; structural targets; and Morph pairs with non-adjacent sources, missing or ambiguous groups, conflicting or undeclared keys, non-object Morph, or a target that does not remain one compatible Slide-local object all fail — never replaced by a fallback or silently dropped. `--animation none` still disables all per-element animation. A passing sidecar, timing-tree read-back, and sound relationship check prove the PPTX configuration, not an exported MP4 audio track. Step 7 export reads back row order, trigger, target, effect, duration, offset, placement, IDs, and shape references; narration preserves them; direct-PPTX routes preserve source animation and never author it. ### 5.1 Optional Video Motion Handoff -When a downstream video renderer will enhance the deck, have Generate Step 7.3 -append `--conversion-trace`. After that final export succeeds, derive the motion -plan from its resolved trace: - -```bash -python3 skills/ppt-master/scripts/video_motion_plan.py \ - <project_path>/validation/<output_stem>.trace.json \ - -o <project_path>/validation/video_motion_plan.json \ - --style adaptive \ - --force -``` - -For narrated output, use the final `--recorded-narration` trace. When resolved -sound cues exist and the native-export mix branch is selected, that same final -trace and the final narrated PPTX feed `video_sound_mix.py`; never infer cue -timing from the raw sidecar or filenames. An explicit slideshow capture already -records PowerPoint's native cue playback and does not use the trace for sound -mixing. The video plan locks identity, effect, direction, order, bounds, and -timing; it may refine renderer parameters but cannot replace the source effect. -See -[`video-motion-plan.md`](../../scripts/docs/video-motion-plan.md). +When a downstream renderer will enhance the deck, have Step 7.3 append `--conversion-trace`, then derive the plan from the final resolved trace (the `--recorded-narration` trace for narrated output): `python3 skills/ppt-master/scripts/video_motion_plan.py <project_path>/validation/<output_stem>.trace.json -o <project_path>/validation/video_motion_plan.json --style adaptive --force`. The plan locks identity, effect, direction, order, bounds, and timing and may refine renderer parameters only ([`video-motion-plan.md`](../../scripts/docs/video-motion-plan.md)). With resolved sound cues on the native-export branch, the same final trace and narrated PPTX feed `video_sound_mix.py`; an explicit slideshow capture records native cue playback and uses no trace for mixing. --- ## ✅ Customize Animations Complete -- [x] Applicable semantic context and motion intent were resolved +- [x] Semantic context and motion intent resolved - [x] Adopted object targets use real post-regroup SVG ids when object motion is in scope -- [x] Sparse `animations.json` overrides are valid when present; a no-op path creates none +- [x] Sparse `animations.json` overrides valid when present; a no-op path creates none - [x] Any regrouped SVG passed the final quality gate -- [x] Control returned to Generate Step 7 for preview, export, read-back, and package validation -- [x] Any requested video plan waits for the final resolved conversion trace +- [x] Control returned to Generate Step 7; any video plan waits for the final resolved trace diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/stages/generate-audio.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/stages/generate-audio.md index 20ab51eb..dd622b7d 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/stages/generate-audio.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/stages/generate-audio.md @@ -4,152 +4,60 @@ description: Shared post-processing stage for narration audio, PPTX embedding, P # Generate Audio Stage -> Shared narration stage. Run after the owning route's notes step. Edge, ElevenLabs, MiniMax, and timestamp-capable CosyVoice produce per-slide audio/SRT from synthesis timing. Qwen is audio-only because its TTS API exposes no timing. The caller owns final PPTX integration. +> Shared narration stage, run after the owning route's notes step. Edge, ElevenLabs, MiniMax, and timestamp-capable CosyVoice produce per-slide audio/SRT pairs; Qwen is audio-only because its API exposes no timing. The caller owns final PPTX integration. Context-independent: it reads `notes/*.md` and the selected voice catalog, chooses no route, and patches no slide design. Tool behavior, prerequisites, keys, and every flag are documented in [`narration.md`](../../scripts/docs/narration.md). -This stage is **context-independent**: it reads `notes/*.md` and queries the selected TTS voice catalog, so either owning route may invoke it in a fresh session. It does not choose the top-level route and does not patch slide design. +**Trigger**: Generate PPTX — the effective `Narration Audio` outcome in `design_spec.md` §I is `enabled` (a later explicit request first updates that outcome and provenance); Quick — the request or active-context decision selects narration; Edit Native PPTX — the confirmed plan enables narration. -**Trigger**: In Generate PPTX, run when the effective `Narration Audio` outcome -in `design_spec.md` §I is `enabled`; a later explicit request first updates that -outcome and its provenance. Quick Generate instead runs when the request or -current agent's active-context decision selects narration. In Edit Native -PPTX, run when the confirmed plan enables narration. - -**Hard dependency — speaker notes**: Audio requires complete per-slide speaker -notes. Generate PPTX additionally requires its effective `Speaker Notes` -outcome to be enabled; Edit Native PPTX follows its confirmed plan, where -narration requires a note for every output page. Quick records the same dependency -in active context. Do not enter audio generation while the owning route's notes -are missing or incomplete; generate and validate those notes first, then resume -this stage. +**Hard dependency — speaker notes**: audio requires complete per-slide notes: Generate additionally requires its effective `Speaker Notes` outcome enabled; Edit Native follows its confirmed plan (a note for every output page); Quick records the same dependency. Never enter audio generation with missing or incomplete notes — generate and validate them first. Missing notes recover through the owning route: Generate returns to its notes branch and runs `total_md_split.py <project_path>`; Edit Native returns to [`edit-native-pptx`](../edit-native-pptx.md) §6 and writes `notes/<svg-stem>.md` per output page; never run the Generate splitter on a round-trip workspace. ## When to Run -- Per-page narration files exist at `notes/*.md`. In Generate PPTX, split `notes/total.md` during Step 7.1. In Edit Native PPTX, notes are `notes/<svg-stem>.md` keyed by output page; the round-trip roster comes from `page_plan.json` and copies inherit source notes. -- Default mode: `edge-tts` is installed (`python3 -m pip install edge-tts`). -- The stage is page-level only: one note becomes `audio/<stem>.<audio-ext>` plus `audio/<stem>.srt` on provider-timed paths, or one audio file with Qwen / explicit CosyVoice audio-only mode. Never substitute one long track or automatic splitting. -- Final/literal script notes are synthesized verbatim. Source SRT timecodes are pacing evidence only; new provider timing owns the generated audio/SRT set. -- SRT bound to an authoritative existing recording does not enter TTS. Recorded narration requires page-level audio or an explicit page/time map; automatic long-track splitting is unsupported. -- A fully successful run writes a compact `audio/manifest.json` with only provider/model, audio/subtitle format, relevant voice settings, and a SHA-256 fingerprint instead of the raw cloud voice ID. It has no per-slide inventory, artifact hashes, or API keys and is not a normal generation input. The flat `audio/` directory is the single active narration set; do not create provider subdirectories unless the user explicitly asks to preserve multiple variants. -- PPT narration assets must be PowerPoint-reliable audio: `m4a` (AAC), `mp3`, or `wav`. The built-in TTS path defaults to `mp3`; provider formats such as `pcm`, `opus`, or `flac` must be transcoded before embedding. -- PowerPoint recorded narration export requires `ffprobe` so slide timings can be written from actual audio duration. -- Optional automatic video export requires Windows PowerPoint 2016+ and runs - through `powerpoint_video.py`; the command waits for PowerPoint's native - encoder to finish before returning. -- Optional slideshow capture is an explicit manual Windows PowerPoint handoff; - it is never an automatic fallback or project dependency. -- macOS PowerPoint may export MP4/MOV manually, but it has no equivalent - `CreateVideo` automation contract and its movie export does not preserve - animation effects. Do not replace the missing API with UI scripting. -- Optional post-export video calibration requires `ffmpeg` plus `numpy`; it runs only after a finished PowerPoint video is supplied or created. -- Direct MP4 delivery with resolved transition/object-animation sound cues also - requires `ffmpeg` plus `numpy`. It renders an independent SFX stem, mixes it - after native PowerPoint export, and validates the actual mixed audio track. -- High-quality cloud mode: provider API key is set before use: - - ElevenLabs: `ELEVENLABS_API_KEY` - - MiniMax: `MINIMAX_API_KEY` - - Qwen: `QWEN_API_KEY` or `DASHSCOPE_API_KEY` - - CosyVoice: `COSYVOICE_API_KEY` or `DASHSCOPE_API_KEY` - - Keys may live in the current process environment or the first `.env` found in this order: current working directory, skill directory (e.g. `~/.agents/skills/ppt-master/.env`), clone repo root, `~/.ppt-master/.env` -- The deck is in a single dominant language (mixed-language decks: pick the dominant one — the AI uses judgment, not a heuristic). - -If per-slide notes are missing, recover through the owning route. Generate -PPTX returns to its enabled notes branch and then runs -`total_md_split.py <project_path>`; Edit Native PPTX returns to -[`edit-native-pptx`](../edit-native-pptx.md) §6 and writes `notes/<svg-stem>.md` -per output page. Never run the Generate splitter against a round-trip workspace. +- Per-page notes exist at `notes/*.md` — split from `notes/total.md` in Generate Step 7.1, or `notes/<svg-stem>.md` keyed by output page in Edit Native (roster from `page_plan.json`, copies inherit source notes). +- The stage is page-level only: one note → one audio file (plus SRT on provider-timed paths). Never substitute one long track or automatic splitting; SRT bound to an authoritative existing recording does not enter TTS, and recorded narration requires page-level audio or an explicit page/time map. +- Final/literal script notes are synthesized verbatim; source SRT timecodes are pacing evidence only. +- The deck is in one dominant language (mixed decks: pick the one the audience hears most — judgment, not a heuristic). +- Optional native video export runs only through `powerpoint_video.py` on Windows PowerPoint 2016+; slideshow capture is an explicit manual Windows handoff, never an automatic fallback; direct MP4 delivery with resolved sound cues additionally needs `ffmpeg` plus `numpy`. --- ## Step 1: Determine the deck's language -The AI already knows the deck's language from writing the notes. No detection script needed. - -- Identify the primary language from the notes content: `zh` / `en` / `ja` / `ko` / etc. -- For mixed-language decks (e.g. Chinese with English technical terms), pick the language the audience will hear most of. -- For Chinese specifically: pick the locale based on context — `zh-CN` (mainland mandarin, default), `zh-TW` (Taiwanese mandarin), or `zh-HK` (Cantonese). Default Generate may ask when context is unclear; Quick chooses the best supported default and continues. +The AI already knows it from writing the notes — no detection script. Identify `zh` / `en` / `ja` / `ko` / …; for Chinese choose `zh-CN` (default), `zh-TW`, or `zh-HK` from context — Default may ask when unclear, Quick chooses the best supported default. --- ## Step 2: Choose audio backend and pull the voice catalog -Default to **edge** unless the user explicitly asks for a cloud provider / higher-quality cloud narration / a cloned voice. - -**edge backend**: +Default to **edge** unless the user asks for a cloud provider, higher-quality cloud narration, or a cloned voice. ```bash python3 skills/ppt-master/scripts/notes_to_audio.py --list-voices --locale <locale> +python3 skills/ppt-master/scripts/notes_to_audio.py --provider <elevenlabs|minimax|qwen|cosyvoice> --list-voices ``` -**ElevenLabs backend**: - -```bash -python3 skills/ppt-master/scripts/notes_to_audio.py --provider elevenlabs --list-voices -``` - -**Cloud providers using explicit voice IDs/names**: - -```bash -python3 skills/ppt-master/scripts/notes_to_audio.py --provider minimax --list-voices -python3 skills/ppt-master/scripts/notes_to_audio.py --provider qwen --list-voices -python3 skills/ppt-master/scripts/notes_to_audio.py --provider cosyvoice --list-voices -``` - -The output is a flat list of all available voices for the selected provider. From this list, the AI picks **3–6 candidates** to recommend, applying these rules: - -- **Cover both genders** when both exist for the locale. -- **For edge**: prefer `COMMON_VOICES`-listed voices (curated set inside `notes_to_audio.py`) when the locale has them — they are battle-tested. -- **For ElevenLabs**: prefer voices already present in the user's account; if the user provides a specific `voice_id`, do not override it. -- **For MiniMax / Qwen / CosyVoice**: if the user provides a cloned `voice_id`, use it directly. Do not attempt voice cloning inside this narration stage. -- **For CosyVoice subtitles**: use a cloned voice from a supported v3.5/v3/v2 model or a system voice marked timestamp-supported. Model and voice families must match. Use `--cosyvoice-audio-only` only when the user accepts no page-local SRT. -- **Match the deck's tone** — pick the strongest recommendation based on style: - - Chinese consultant / data-driven / financial-report deck → a steady male voice (e.g. `zh-CN-YunjianNeural`) or a clear female voice (e.g. `zh-CN-XiaoxiaoNeural`) - - Chinese general / teaching / product-introduction deck → a bright female or young male voice (e.g. `zh-CN-XiaoyiNeural` / `zh-CN-YunxiNeural`) - - Chinese launch event / broadcast deck → a broadcast-toned male voice (e.g. `zh-CN-YunyangNeural`) - - English consultant deck → `en-US-GuyNeural` (steady) or `en-US-JennyNeural` (clear) - - Japanese / Korean → pick from `ja-JP-*` / `ko-KR-*` neural voices, mark gender + tone - -For each candidate, write a **one-line description in the user's chat language** covering: gender · tone · best-fit scenario. For cloud providers, include the voice name/ID exactly as it must be passed to `--voice-id`. +From the flat list, pick **3–6 candidates**: cover both genders when the locale has them; for edge prefer the curated `COMMON_VOICES` set; for ElevenLabs prefer voices already in the user's account and never override a user-supplied `voice_id`; for MiniMax / Qwen / CosyVoice use a supplied cloned `voice_id` directly and never attempt cloning here; for CosyVoice subtitles use a timestamp-capable model/voice pair, and `--cosyvoice-audio-only` only when the user accepts no page-local SRT. Match the deck's tone — a Chinese consultant / financial deck leans a steady male (`zh-CN-YunjianNeural`) or clear female (`zh-CN-XiaoxiaoNeural`) voice; teaching / product decks a bright female or young male (`zh-CN-XiaoyiNeural` / `zh-CN-YunxiNeural`); launch / broadcast decks `zh-CN-YunyangNeural`; English consultant decks `en-US-GuyNeural` or `en-US-JennyNeural`; Japanese / Korean from `ja-JP-*` / `ko-KR-*` with gender + tone noted. Describe each candidate in one line in the user's chat language (gender · tone · best-fit scenario), with the exact name/ID to pass to `--voice-id` for cloud providers. --- ## Step 3: Resolve generation settings -**Quick exception**: do not pause. Apply explicit user values, then resolve -unspecified provider, voice, rate, and embed choices from the recommended-value -rules below. Keep video off unless the caller selected direct video; then embed -the narrated PPTX and continue to native video only when -`powerpoint_video.py --check` succeeds. If final resolved motion contains sound -cues, continue automatically through the post-export mix without another -question. An explicit slideshow-capture request instead stops at the -capture-ready narrated PPTX until the user supplies the recorded MP4; it never -silently switches to native export. Require a timestamp-capable provider only -when narration-cue sync or subtitle delivery needs page-local SRT; on the -native-export branch, audio-only narration can still calibrate the sound mix -from its complete per-page tracks. +**Quick exception**: do not pause. Apply explicit user values, resolve the rest from the recommended-value rules, keep video off unless the caller selected direct video (then embed the narrated PPTX and continue to native video only when `powerpoint_video.py --check` succeeds); with resolved sound cues continue automatically through the post-export mix. An explicit slideshow-capture request stops at the capture-ready narrated PPTX until the user supplies the recorded MP4 — never silently switching to native export. Require a timestamp-capable provider only when cue sync or subtitle delivery needs page-local SRT. -**Default / Edit Native — one-shot interaction (mandatory)**: +**Default / Edit Native — one-shot interaction (mandatory)**: send one message that resolves all five decisions with a recommended value each; never split into rounds. Run `powerpoint_video.py --check` before offering automatic video export (an explicit slideshow-capture choice skips the check and uses the manual handoff). **Cloned-voice fast path**: when the user mentioned a cloned voice / 克隆音色 / 复刻音色 / "my own voice" with a `voice_id`, skip the recommendation list, pin the named provider and `voice_id`, and confirm only rate + embed + video. "Embed" means SVG re-export for Generate or `svg_to_pptx.py --roundtrip --recorded-narration audio` for Edit Native. -For Default or Edit Native, send one message that resolves all five configuration decisions and recommends each value. Before offering automatic video export, run `python3 skills/ppt-master/scripts/powerpoint_video.py --check`; do not present an unavailable local capability as executable. Do NOT split into multiple rounds. -An explicit slideshow-capture choice does not run this availability check; it -uses the manual Windows playback handoff below. - -**Cloned-voice fast path**: if the user mentioned a cloned voice / 克隆音色 / 复刻音色 / "my own voice" along with a `voice_id`, skip the voice-recommendation list — set the named provider (`elevenlabs` / `minimax` / `qwen` / `cosyvoice`) and pin that `voice_id`. Quick applies its exception above; Default and Edit Native confirm only rate + embed + video. - -**Message template** (Chinese; translate to user's chat language if different). “Embed” means caller-specific integration: SVG re-export for Generate PPTX, or `svg_to_pptx.py --roundtrip --recorded-narration audio` for Edit Native PPTX. +**Message template** (Chinese; translate to the user's chat language): > 检测到 notes 主语言为 **<语言>**(locale: `<locale>`)。基于 deck 调性(<风格>),我推荐以下配置: > -> **生成模式**:⭐ 推荐 `<edge|elevenlabs|minimax|qwen|cosyvoice>`(理由:<一句话,如"无需配置,稳定生成"或"用户要求高质量云端音色">)。 +> **生成模式**:⭐ 推荐 `<edge|elevenlabs|minimax|qwen|cosyvoice>`(理由:<一句话>)。 > > **音色**: > - **[1] <ShortName>** — <性别·调性·适用场景> ⭐ **推荐** > - [2] <ShortName> — <性别·调性·适用场景> > - [3] <ShortName> — <性别·调性·适用场景> -> - [4] <ShortName> — <性别·调性·适用场景> -> - [5] <ShortName> — <性别·调性·适用场景> > - 也可直接输入清单中的其他 ShortName。 > -> **语速/风格参数**:⭐ 推荐 `<rate or provider defaults>`(理由:<一句话,如"页均 2–3 句,正常语速听感最稳"或"ElevenLabs 默认 voice settings 保留音色原始表现最稳">)。 +> **语速/风格参数**:⭐ 推荐 `<rate or provider defaults>`(理由:<一句话>)。 > > **生成完是否重新导出嵌入音频的 PPTX**:⭐ 推荐 **是**(一次到位,自动按音频时长设页面停留)。 > @@ -157,293 +65,60 @@ uses the manual Windows playback handoff below. > > 直接回"好"用全部推荐值,或告诉我想改的部分(如"音色 2,语速 -5%"或"用 MiniMax 的 voice_id xxx")。 -**Recommended-value rules**: -- **Generation mode**: default `edge`; follow the user's choice when they name a cloud provider / voice ID. Do not recommend Qwen when page-local SRT, subtitle animation, or video subtitles are needed; if the user insists, state that only audio is delivered and skip the SRT step. -- **Voice**: pick the Step 2 candidate that fits the deck's tone best. -- **Rate**: edge defaults to `+0%`; recommend `-5%` for dense notes (>4 long sentences per page) and `+5%` for short, tight notes; going outside this range needs a stated reason. Cloud providers keep provider defaults unless the user explicitly asks to change speed or style. -- **Embed**: recommend yes by default, unless the user already has a customized PPTX they do not want overwritten. -- **Video**: recommend native encoding when `powerpoint_video.py --check` succeeds; use slideshow capture only on an explicit user choice. When automation is unavailable, deliver the narrated PPTX; never silently switch to screen recording or a third-party renderer. +**Recommended-value rules**: mode — `edge` by default, the user's named provider/voice otherwise; never recommend Qwen when page-local SRT, subtitle animation, or video subtitles are needed, and if the user insists state that only audio is delivered. Voice — the Step 2 candidate that best fits the tone. Rate — edge `+0%`; `-5%` for dense notes (>4 long sentences per page), `+5%` for short tight notes, anything beyond needs a stated reason; cloud providers keep defaults unless asked. Embed — yes unless the user has a customized PPTX they do not want overwritten. Video — native encoding when `--check` succeeds; slideshow capture only on explicit choice; when automation is unavailable, deliver the narrated PPTX and never switch to screen recording or a third-party renderer. --- ## Step 4: Execute (no further interaction) -**Blocking notes preflight**: `notes_to_audio.py` resolves the complete notes -roster from `svg_output/*.svg` on Generate projects or from `page_plan.json` / -the identity roster on Edit Native PPTX round-trip workspaces (copies inherit -source notes). Before any TTS request, -every expected note must exist, be readable, and contain spoken text. Exit code -`2` returns the caller to its notes-generation step; never continue with partial -audio generation. - -Run sequentially — do NOT bundle: +`notes_to_audio.py` runs a blocking notes preflight (every expected note exists, is readable, and contains spoken text); exit `2` returns the caller to notes generation — never continue with partial audio. Run sequentially, never bundled; if a dependency or API key is missing, fix it and re-run, never swallow the error. ```bash -# 1A. Generate audio with edge (default) -python3 skills/ppt-master/scripts/notes_to_audio.py <project_path> \ - --voice <chosen-ShortName> --rate <chosen-rate> +# 1. Generate audio (one provider form; flags in narration.md) +python3 skills/ppt-master/scripts/notes_to_audio.py <project_path> --voice <ShortName> --rate <rate> +python3 skills/ppt-master/scripts/notes_to_audio.py <project_path> --provider <elevenlabs|minimax|qwen|cosyvoice> --voice-id <id> [provider model flag] -# 1B. Or generate audio/SRT pairs with ElevenLabs -python3 skills/ppt-master/scripts/notes_to_audio.py <project_path> \ - --provider elevenlabs --voice-id <chosen-voice-id> \ - --elevenlabs-model eleven_multilingual_v2 +# 2A. Only when narration-cue sync is selected and page SRT + animations.json exist +python3 skills/ppt-master/scripts/narration_sync.py animations <project_path> --narration-start-floor 0.8 --narration-padding 0.5 --force -# 1C. Or generate audio with MiniMax -# Defaults to the China endpoint; set MINIMAX_TTS_BASE_URL=https://api.minimax.io/v1/t2a_v2 for overseas access. -python3 skills/ppt-master/scripts/notes_to_audio.py <project_path> \ - --provider minimax --voice-id <chosen-voice-id> \ - --minimax-model speech-2.8-hd +# 2B. Re-export with audio embedded (Quick adds --quick-generate --with-notes; the native-export +# mix branch also passes --conversion-trace <final_narrated_trace>) +python3 skills/ppt-master/scripts/svg_to_pptx.py <project_path> --recorded-narration audio --narration-start-floor 0.8 --narration-padding 0.5 --inherit-motion-from "<base_postflight_report>" +# narration-independent custom motion: add --animation-config animations.json; all-motion-off: --no-animations instead of --inherit-motion-from -# 1D. Or generate audio only with Qwen TTS (the API returns no timestamps) -python3 skills/ppt-master/scripts/notes_to_audio.py <project_path> \ - --provider qwen --voice-id <chosen-voice> \ - --qwen-model qwen3-tts-flash --qwen-language-type Chinese +# 2C. Only when page-local SRT exists +python3 skills/ppt-master/scripts/narration_sync.py subtitles <project_path> --pptx <final_narrated_pptx> --force -# 1E. Or generate audio/SRT pairs with a timestamp-capable CosyVoice voice -python3 skills/ppt-master/scripts/notes_to_audio.py <project_path> \ - --provider cosyvoice --voice-id <chosen-voice> \ - --cosyvoice-model cosyvoice-v3-flash +# 2D. Optional native video through installed Windows PowerPoint +python3 skills/ppt-master/scripts/powerpoint_video.py <final_narrated_pptx> -o <raw_powerpoint_video.mp4> -# 2A. Only when narration-cue sync is selected and page SRT + animations.json -# exist, author or refresh narration_timing.json -# by matching SVG group semantics to SRT topics, then derive the narrated -# sidecar. Reuse current SVG semantics when complete; otherwise read only -# the missing or stale svg_output pages. -python3 skills/ppt-master/scripts/narration_sync.py animations <project_path> \ - --narration-start-floor 0.8 --narration-padding 0.5 --force +# 2E. Only when final resolved motion has sound cues and direct MP4 delivery is selected +python3 skills/ppt-master/scripts/video_sound_mix.py <project_path> --pptx <final_narrated_pptx> --trace <final_narrated_trace> --video <raw_powerpoint_video.mp4> -o <final_mixed_video.mp4> --stem-output <final_sfx_stem.wav> --report-output <sound_mix_report.json> --force -# 2B. Re-export with audio embedded -# Use the base export's [REPORT] path to preserve source-bound deck motion. -# Quick Generate adds --quick-generate --with-notes to every re-export below. -# For the native-export mix branch when final motion has sound cues, also -# pass --conversion-trace <final_narrated_trace>. Explicit slideshow capture -# does not require that trace for sound delivery. -python3 skills/ppt-master/scripts/svg_to_pptx.py <project_path> \ - --recorded-narration audio \ - --narration-start-floor 0.8 --narration-padding 0.5 \ - --inherit-motion-from "<base_postflight_report>" - -# Optional: use the canonical presentation animation instead -python3 skills/ppt-master/scripts/svg_to_pptx.py <project_path> \ - --recorded-narration audio \ - --narration-start-floor 0.8 --narration-padding 0.5 \ - --animation-config animations.json \ - --inherit-motion-from "<base_postflight_report>" - -# Optional: export narration with no object or page-transition animation -python3 skills/ppt-master/scripts/svg_to_pptx.py <project_path> \ - --recorded-narration audio \ - --narration-start-floor 0.8 --narration-padding 0.5 \ - --no-animations - -# 2C. Only when page-local SRT exists, merge it against timing values read -# from the final PPTX -python3 skills/ppt-master/scripts/narration_sync.py subtitles <project_path> \ - --pptx <final_narrated_pptx> --force - -# 2D. Optional: export the raw video through installed Windows PowerPoint -# and wait for completion -python3 skills/ppt-master/scripts/powerpoint_video.py \ - <final_narrated_pptx> -o <raw_powerpoint_video.mp4> - -# 2E. Only when final resolved motion has sound cues and direct MP4 delivery is -# selected, derive the exact embedded sounds from the final narrated PPTX, -# calibrate cue times against raw video narration, and publish the verified -# SFX stem, mixed MP4, and report. Defaults are about 35% for transitions, -# 25% for object cues, and a -1 dBFS limiter. -python3 skills/ppt-master/scripts/video_sound_mix.py <project_path> \ - --pptx <final_narrated_pptx> \ - --trace <final_narrated_trace> \ - --video <raw_powerpoint_video.mp4> \ - -o <final_mixed_video.mp4> \ - --stem-output <final_sfx_stem.wav> \ - --report-output <sound_mix_report.json> --force - -# 2F. Only when page-local SRT exists, align the frozen narration text against -# the final delivery video: mixed when 2E ran, captured when the explicit -# slideshow-capture handoff returned an MP4, otherwise the raw video. -python3 skills/ppt-master/scripts/video_subtitles.py <project_path> \ - --video <final_delivery_video.mp4> --language <language> --force +# 2F. Only when page-local SRT exists: align against the final delivery video (mixed, captured, or raw) +python3 skills/ppt-master/scripts/video_subtitles.py <project_path> --video <final_delivery_video.mp4> --language <language> --force ``` -**Explicit slideshow capture**: desktop Windows PowerPoint plays the final -narrated PPTX full-screen from the beginning with automatic, click-free timing; -capture only the deck frame and one application/system-audio source, with mic, -UI, pointer, and notifications absent. Trim short head/tail handles. Human-check -streams, narration, every cue once, complete motion, and no dropped frames. The -capture has no machine cue receipt and must never enter `video_sound_mix.py`. -If the host cannot capture, report only the capture-ready PPTX handoff. Align -page SRT against an accepted capture and append one compact `workflow_log.py` -note. +**Mandatory when narration-cue sync is selected — semantic animation context**: before writing or refreshing `narration_timing.json`, confirm the active context holds the current top-level SVG group IDs and visible group-content semantics for every affected page; reuse it without rereading when complete and still matching `svg_output/`, otherwise read only the missing or stale pages read-only. Combine those semantics with the page SRT topics/timestamps and `animations.json` — group order alone is not a semantic mapping, and the positional fallback's warning is required repair. Preserve the title reveal decision from the custom-animation pass: assign a title group a `cue` only when the user or the motion plan explicitly chose `narration-cued`; never infer it because notes mention the title. -**Default — bounded Edge concurrency (may override)**: Generate up to three -slide-level audio/SRT pairs concurrently. Use `--concurrency <N>` to tune the -Edge path or `--concurrency 1` for serial troubleshooting. Cloud providers -remain serial. - -If `notes_to_audio.py` errors with a missing dependency or missing provider API key, fix the prerequisite and re-run — do NOT swallow the error. - -The edge command writes each MP3 and its internal page SRT from the same `edge-tts` stream. SRT cues use the service's `WordBoundary` timing: sentence-ending punctuation always closes a cue; text over the default 20-visible-character limit first splits at commas, semicolons, or colons, then at the nearest word boundary. Override the limit with `--subtitle-max-chars`. Adjacent timing overlap up to 100 ms is tolerated by moving the later cue start to the previous cue end; larger overlap fails instead of silently distorting timing. Each SRT uses a page-local timeline whose origin is `00:00:00,000`, including any leading silence before the first cue. - -MiniMax reads word timing from its synchronous subtitle file. ElevenLabs uses `/with-timestamps` and original-text character alignment. CosyVoice enables HTTP streaming plus `word_timestamp_enabled`, then uses the final audio URL and word timing from that synthesis; unsupported model/voice pairs fail without replacing the prior pair unless `--cosyvoice-audio-only` was explicit. Qwen exposes no timing, so it remains audio-only and this stage never estimates SRT timing. - -Provider-timed paths share punctuation-first, `--subtitle-max-chars`-bounded regrouping, exact-text validation, and rollback-safe pair publication. See [`docs/audio-narration.md`](../../../../docs/audio-narration.md) for current model and audio-parameter recommendations. - -Before generation starts, `notes_to_audio.py` removes stale `audio/manifest.json` and `audio/total.srt`; an incomplete run therefore cannot claim the previous set's provenance or merged timeline. A successful audio-only provider run also removes same-stem stale SRT files. The new manifest is published atomically only after the complete page roster succeeds. - -**Mandatory when narration-cue sync is selected — semantic animation context**: Before writing or refreshing `<project_path>/narration_timing.json`, determine whether the active context already contains the current top-level SVG group IDs and visible group-content semantics for every affected page. Reuse that context without rereading SVG when it is complete and still matches the current `svg_output/`. If any page is missing, stale, or represented only by group IDs/order without content meaning, read only that page's SVG as a read-only source and extract the missing group semantics. Always combine those semantics with the page SRT topics/timestamps and `animations.json`; group order alone is not a semantic narration mapping. - -> Narration-cue sync with `animations.json` requires `narration_timing.json`. -> Narration-independent custom motion instead passes `--animation-config animations.json` -> and makes no object-sync claim. Explicit `--no-animations` -> bypasses both. Without a timing sidecar, `narration_sync.py animations` maps -> groups **positionally** (group N → cue N) and warns when later objects may -> reveal during an earlier topic. Treat that warning as required repair: author -> the semantic plan and re-derive. - -**Narration animation ownership**: When narration-cue sync is selected, `animations.json` remains read-only. The audio stage deep-copies it to `narration_animations.json`, preserves transitions, effects, durations, order, and explicit `effect: none`, then changes only the derived trigger/delay values needed for click-free narration playback. The authored `narration_timing.json` maps each animated content group—not each effect row—to the SRT cue that speaks about that content. For `effects[]`, the cue anchors the group's first active row; later rows keep global order and their relative delay. The command may still read an affected SVG page to resolve structural group order when a sparse sidecar cannot identify every effective group; this structural fallback does not replace the semantic-context step and never edits SVG, notes, or `animations.json`. Unmatched groups keep their canonical relative delay. - -**Title timing handoff when canonical animation exists**: preserve the title reveal decision already made by the custom-animation pass. Assign a title group to an SRT cue only when the user's request or the active motion plan explicitly chose `narration-cued`; otherwise leave its `cue` omitted in `narration_timing.json` so it keeps the canonical relative delay from `animations.json`. Do not infer `narration-cued` merely because speaker notes mention the title. - -**Narrated export animation selection**: - -| Sidecar state | Behavior | +| Sidecar state | Narrated export | |---|---| -| `narration_animations.json` exists and narration-cue sync is selected | Use it | -| Only canonical `animations.json` exists and narration-cue sync is selected | Block until narration synchronization creates the derived sidecar | -| Canonical `animations.json` exists and motion is narration-independent, whether or not a derived sidecar also exists | Pass `--animation-config animations.json`; do not claim object sync | -| Both are absent | Create no sidecar; inherit the base report's deck motion | +| `narration_animations.json` exists and cue sync is selected | Use it | +| Only canonical `animations.json` exists and cue sync is selected | Block until synchronization creates the derived sidecar | +| Canonical `animations.json` exists and motion is narration-independent | `--animation-config animations.json`; claim no object sync | +| Both absent | No sidecar; inherit the base report's deck motion | -Generate passes the base report through `--inherit-motion-from`: inherited -`-a none` preserves explicit objects-off, while final Stage-2 `false` does not. -Only explicit all-motion-off uses `--no-animations`. Invalid reports block; -page-start lead-in, audio duration, and page-tail padding own final advance. +Pacing defaults are `narration_start_floor=0.8` s and `narration_padding=0.5` s without a confirmation question unless the user supplies values. For Qwen or explicit CosyVoice audio-only mode, embed/export normally but skip `narration_timing.json`, `narration_sync.py animations`, SRT merge, and final-video subtitle alignment; pass canonical narration-independent motion explicitly when present; a native-export sound mix may still run from page audio. Never present missing subtitle artifacts or object sync as generated. -**Narration pacing controls**: page-front and page-tail timing are independent, -optional parameters. Unless the user supplies values, use -`narration_start_floor=0.8` seconds and `narration_padding=0.5` seconds without -adding a confirmation question. For a destination-page transition of `T` -seconds, the post-transition lead-in is -`max(0, narration_start_floor - T)`: narration never begins during the -transition, while a longer transition is not stretched. Apply the same -lead-in to embedded narration, cue-bound object animation, subtitle offsets, -and slide advance. Uncued title or decorative animation keeps its canonical -relative timing. Setting the start floor to `0` means narration begins as soon -as the transition completes; it does not bypass the transition. - -When canonical custom animation is synchronized, -`<project_path>/narration_timing.json` is the explicit semantic mapping for -narrated object animation. It is fingerprinted to the ordered SRT set; `cue` -is the 1-based subtitle cue, and omitted `cue` keeps that group's canonical -relative delay. Reuse a complete current mapping when its fingerprint and SVG -group semantics remain valid; rebuild only affected pages when either input -changed. - -Get the exact fingerprint value with: - -```bash -python3 skills/ppt-master/scripts/narration_sync.py fingerprint <project_path> -``` - -```json -{ - "version": 1, - "srt_sha256": "<sha256 of the ordered page-local SRT set>", - "narration_start_floor": 0.8, - "narration_padding": 0.5, - "slides": { - "01_title": { - "groups": [ - { "id": "page-title", "cue": 1 }, - { "id": "supporting-visual" } - ] - } - } -} -``` - -`narration_sync.py subtitles` may still write `<project_path>/audio/total.srt` as a PPTX-timeline diagnostic. It is not the delivery subtitle for a finished video. - -When video export was selected, `powerpoint_video.py` opens the final narrated -PPTX through local Windows PowerPoint, requests its native video encoder with -recorded timings and narrations enabled, and polls `CreateVideoStatus` until the -MP4 succeeds, fails, or times out. The interface is synchronous to its caller -even though PowerPoint performs encoding asynchronously. It preserves the -native visual-animation and narration path rather than re-rendering the deck, -but does not reliably write transition or object-animation sounds into the MP4 -audio track. This is the default automated video path; an explicitly selected -slideshow capture bypasses `CreateVideo` but still uses desktop PowerPoint as -the real-time renderer and audio player. - -If native video export fails, keep the narrated PPTX as a successful upstream -artifact and report the video failure separately. Do not regenerate audio or -the PPTX unless their own validation failed. - -On the native-export path, when the final narrated trace and PPTX contain sound -cues, treat the PowerPoint MP4 as a raw intermediate. `video_sound_mix.py` -cross-checks that trace against the final PPTX read-back, extracts the exact -embedded sound relationships, calibrates every page against the raw video's -narration, renders a float SFX stem, and mixes it with narration at unity gain. -Transition cues default to about 35%, object cues to about 25%; `amix` -normalization and ducking remain off, and a -1 dBFS peak limiter follows the -mix. The receipt must prove a non-silent stem, preserved video-stream hash, -changed and present final audio, duration parity, non-clipping true peak, and -correlation between the added final-audio component and the stem. A valid -`animations.json` or OOXML package alone is not MP4 audio acceptance. - -After the final delivery MP4 exists, `video_subtitles.py` takes the exact -narration text frozen in the page SRT set and force-aligns it against that -finished video's actual audio track with `stable-ts`. Use the mixed MP4 when -sound mixing ran, the accepted capture when slideshow recording ran, otherwise -the raw PowerPoint MP4. Long delivery cues may be split for display at this -final stage. This writes a same-stem external SRT without changing the MP4, -notes, page SRT, or animation files. - -This stage keeps subtitles as external SRT files and never burns them in. -Automatic export is an optional Windows PowerPoint integration. When it is -unavailable, stop after the narrated PPTX unless explicit capture is selected; -that handoff remains incomplete until a real capture is accepted. - -**Caller integration**: +**Explicit slideshow capture**: desktop Windows PowerPoint plays the final narrated PPTX full-screen from the beginning with automatic timing; capture only the deck frame and one application/system-audio source with mic, UI, pointer, and notifications absent; trim short head/tail handles; human-check streams, narration, every cue once, complete motion, and no dropped frames. The capture has no machine cue receipt and never enters `video_sound_mix.py`. If the host cannot capture, report only the capture-ready PPTX handoff; align page SRT against an accepted capture and append one compact `workflow_log.py` note. If native video export fails, keep the narrated PPTX as the successful upstream artifact and report the video failure separately. Subtitles stay external SRT and are never burned in. | Caller | After audio generation | |---|---| -| Generate PPTX | Derive narration-cued motion when selected; otherwise pass canonical motion, inherit base motion, or use explicit all-motion-off. Export with `--recorded-narration audio`; Quick also passes `--quick-generate --with-notes`. Native video uses conversion trace plus raw export and cue mix as required. Explicit capture returns the narrated PPTX for the handoff above, skips trace-only sound work and mixing, then aligns subtitles against the accepted capture. | -| Edit Native PPTX | Return to [`edit-native-pptx`](../edit-native-pptx.md) §7 and export with `--roundtrip --recorded-narration audio --use-narration-timings`. Native video passes its final PPTX to `powerpoint_video.py`; explicit capture uses the same handoff above and skips mixing. | - -For Qwen or explicit CosyVoice audio-only mode, embed/export the audio normally -but skip `narration_timing.json`, `narration_sync.py animations`, SRT merge, and -final-video subtitle alignment. Pass canonical narration-independent custom -motion explicitly when present. On the native-export branch, a direct-MP4 sound -mix may still run because page audio, not SRT, supplies its correlation -template. Never present missing subtitle artifacts or object sync as generated. - -For Generate PPTX, `--recorded-narration audio` prepares PowerPoint's recorded timings and narrations: every slide must have a matching supported audio file, every duration must be readable by `ffprobe`, and object animations must not use `--animation-trigger on-click`. Use `after-previous` or `with-previous` for narrated/video export. Narration changes the slide-advance layer only: the resolved page-transition effect remains unchanged, `-t none` remains visually transition-free, and narration advance disables click while using page-start lead-in plus audio duration plus page-tail padding. The re-export is saved as `exports/<project_name>_<timestamp>_narrated.pptx`, telling it apart from silent exports. - -**Narrated SVG export**: use the default text-flow mode. It keeps authored line breaks in one editable, no-wrap text frame; narration does not require per-line text frames. +| Generate PPTX | Derive narration-cued motion when selected; otherwise pass canonical motion, inherit base motion, or use explicit all-motion-off. Export with `--recorded-narration audio` (Quick also `--quick-generate --with-notes`). Native video uses conversion trace plus raw export and cue mix as required; explicit capture returns the narrated PPTX for the handoff, skips trace-only sound work and mixing, then aligns subtitles against the accepted capture | +| Edit Native PPTX | Return to [`edit-native-pptx`](../edit-native-pptx.md) §7 and export with `--roundtrip --recorded-narration audio --use-narration-timings`; native video passes the final PPTX to `powerpoint_video.py`; explicit capture uses the same handoff and skips mixing | --- ## Step 5: Completion report -Output one summary block listing: - -- Number of audio files generated and their location (`<project_path>/audio/*`). -- For provider-timed subtitles, number of matching page-local SRT files and their location (`<project_path>/audio/*`); for Qwen or explicit CosyVoice audio-only mode, report that no page-local SRT was generated. -- Narration provider/model plus the `<project_path>/audio/manifest.json` provenance path. -- For narrated object animation, whether current SVG semantics were reused or which missing/stale pages were reread, plus semantic mapping coverage and fallback count. -- For Generate PPTX, report derived narration animation coverage/path when cue sync ran, the canonical config path for narration-independent custom motion, or inherited/all-motion-off state. -- When native video export was selected, the raw PowerPoint MP4 path/status. - When resolved cues triggered sound mixing, also report the final mixed MP4, - SFX stem, cue count, and `video_sound_mix.py` receipt; otherwise identify the - raw MP4 as final. -- For slideshow capture, report the capture-ready PPTX handoff or accepted MP4 - plus system-audio and human picture/narration/all-cue status; never report a - mix receipt. -- When page-local SRT was merged, the PPTX-timeline `audio/total.srt` path. -- When final-video subtitle alignment ran, the aligned delivery SRT path and - whether its source was the mixed, captured, or raw final video; - otherwise do not claim a video-aligned subtitle. -- The provider, voice, and rate/settings actually used. -- The caller-owned integration result: narrated SVG export path, enhanced native PPTX path, or “audio only”. -- For Generate PPTX when embedding was skipped, one-line hint: `python3 skills/ppt-master/scripts/svg_to_pptx.py <project_path> --recorded-narration audio`. +One summary block: audio file count and location (`<project_path>/audio/*`); page-local SRT count and location, or "no page-local SRT" for Qwen / CosyVoice audio-only; provider/model plus the `audio/manifest.json` path; for narrated object animation, whether SVG semantics were reused or which pages were reread, plus mapping coverage and fallback count; for Generate, the derived narration animation coverage/path, the canonical config path for narration-independent motion, or the inherited/all-motion-off state; the raw PowerPoint MP4 path/status when native export was selected, and with sound mixing the final mixed MP4, SFX stem, cue count, and `video_sound_mix.py` receipt (otherwise the raw MP4 is final); for slideshow capture, the capture-ready PPTX handoff or accepted MP4 plus system-audio and human picture/narration/all-cue status, never a mix receipt; the PPTX-timeline `audio/total.srt` path when merged; the aligned delivery SRT path and its source video when alignment ran; provider, voice, and rate/settings used; the caller-owned integration result (narrated export path, enhanced native PPTX path, or "audio only"); and, when Generate embedding was skipped, the one-line hint `python3 skills/ppt-master/scripts/svg_to_pptx.py <project_path> --recorded-narration audio`. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/stages/live-preview.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/stages/live-preview.md index 98183fb4..4193a8c2 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/stages/live-preview.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/stages/live-preview.md @@ -4,103 +4,38 @@ description: Main-pipeline editor stage for starting live preview and applying s # Live Preview Stage -> **Purpose**: (1) start/reopen the browser SVG editor when no preview service is currently running, and (2) apply user-submitted annotations after Step 7 export completes. -> -> **Not in scope**: Executor's mandatory auto-startup — that lives in [`generate-pptx`](../generate-pptx.md) Step 6. Do not re-launch a preview that is already running. +> (1) Start/reopen the browser SVG editor when no preview service is running; (2) apply user-submitted annotations after Step 7 export. Executor's mandatory auto-startup lives in [`generate-pptx`](../generate-pptx.md) Step 6 — never re-launch a preview that is already running. Editor behavior, lifecycle, ports, and remote access are documented in [`svg_editor.md`](../../scripts/docs/svg_editor.md). ## When to Run -- **Start (Step 1)** — preview service is not currently running and the user wants to look at the deck or click an element. Typical cases: post-export re-entry in a fresh chat, or the user clicked **Exit preview** earlier and now wants it back. -- **Apply annotations (Step 2)** — Step 7 has produced at least one PPTX, and the user signals that submitted annotations should now be applied. Triggers include: - - quoting the browser prompt (`Changes saved to svg_output...` / `修改已保存到 svg_output...`) - - saying `apply my annotations` / `apply my edits` / `应用注解` / `开始应用` / or equivalent expressions +- **Step 1** — no preview service is running and the user wants to look at the deck or click an element (post-export re-entry in a fresh chat, or the user clicked **Exit preview** earlier). +- **Step 2** — Step 7 has produced at least one PPTX and the user signals that annotations should be applied: quoting the browser prompt (`Changes saved to svg_output...` / `修改已保存到 svg_output...`) or saying `apply my annotations` / `apply my edits` / `应用注解` / `开始应用`. -## When NOT to Run - -- The preview service is already running → just give the user the URL; do not restart. -- The user gave a precise chat edit ("change page 3 title to X") → edit the SVG directly. -- The user wants a full regeneration → use the main workflow. -- Step 7 has never run for this project → annotations cannot be applied yet; finish the main pipeline first. +**When not to run**: the service is already running → give the URL; a precise chat edit ("change page 3 title to X") → edit the SVG directly; a full regeneration → main workflow; Step 7 has never run → finish the main pipeline first. --- ## Step 1: Start / reopen the editor -**Precondition**: no preview service running on this project. - ```bash python3 ${SKILL_DIR}/scripts/svg_editor/server.py <project_path> --daemon ``` -(Plain mode — no `--live`. The `--live` flag is reserved for Step 6's auto-startup.) +Plain mode, no `--live` (reserved for Step 6). Launch immediately — the user already asked. Report the actual URL from the launch output or `<project_path>/live_preview/lock.json`, never an inferred `6060`; on a remote host add `--no-browser` and forward the port. Then tell the user, in their language, in one short message: -The launcher starts the server in the background on its selected port, waits for `GET /api/health`, records the actual pid + port in `<project_path>/live_preview/lock.json`, opens the browser when possible, and edits `<project_path>/svg_output/` in place. After it prints the running URL, tell the user in their language, in one short message: - -- editor is at the URL reported by the launcher, e.g. `http://127.0.0.1:6060` -- **Direct edit** (deterministic tweaks — wording, color, coordinates, SVG attributes): select an element → change the controls in the right panel → preview updates immediately, but nothing is written to `svg_output/` until **Apply changes**. `Ctrl+Z` or the **Undo** button drops staged edits step by step; applied changes are logged to `<project>/live_preview/edits.jsonl`. Re-export stays chat-driven and separate: say "re-export" / "重新导出" to refresh the PPTX. -- **Annotate** (changes that need AI judgement / re-layout): select an element → write the instruction, optionally starting from a quick type such as move / resize / replace image / copy / relayout → click **Add annotation** to stage it → click **Apply changes** to write annotation markers → return to the chat and say `apply my annotations` (or quote the browser prompt) -- to skip the editor, just describe the change in chat - -Launch immediately — the user already asked for preview. Report the actual URL from the output or project lock; never infer it from `6060`. Remote access → see the appendix. +- the editor URL; +- **Direct edit** for deterministic tweaks (wording, color, coordinates, attributes): select an element → change the right-panel controls → preview updates immediately, nothing is written until **Apply changes**; `Ctrl+Z` / **Undo** drops staged edits; re-export stays chat-driven ("re-export" / "重新导出"); +- **Annotate** for changes needing AI judgement or re-layout: select an element → write the instruction (optionally from a quick type such as move / resize / replace image / copy / relayout) → **Add annotation** → **Apply changes** → return to chat and say `apply my annotations`; +- to skip the editor, describe the change in chat. --- ## Step 2: Apply submitted annotations -🚧 **GATE**: `<project_path>/exports/` contains at least one `*.pptx` (Step 7 has completed). If not, do not apply annotations — tell the user to finish the main pipeline first. +🚧 **GATE**: `<project_path>/exports/` contains at least one `*.pptx`; otherwise tell the user to finish the main pipeline first. -Triggered by the user signals listed in "When to Run". - -1. Discover annotations: - ```bash - python3 ${SKILL_DIR}/scripts/check_annotations.py <project_path> - ``` - The output already lists each pending change as `file → element_id → annotation text → content preview`. Use it directly as the to-do list; no need to re-parse SVG attributes yourself. -2. If the output says no annotations: tell the user, stop. -3. For each listed annotation: - - Edit the targeted element in `<project_path>/svg_output/<file>` per the annotation text. - - Remove `data-edit-target` and `data-edit-annotation` from that element. - - Append one `annotation_applied` JSONL record to `<project_path>/live_preview/annotations.jsonl` with `ts`, `file`, `element_id`, and the original annotation text. -4. Re-enter [`generate-pptx`](../generate-pptx.md) Step 7.2, wait for its success criterion, then run Step 7.3. Do not rerun Step 7.1 unless speaker notes changed. -5. Tell the user (in their language): annotations applied, new PPTX exported, preview is still running. If the browser still shows the old slide, refresh or reselect the page. -6. Loop: more annotations submitted → repeat from step 1. User signals done or "stop preview" → end. - ---- - -## Notes (editor invariants — referenced from Generate Step 6) - -- **UI**: four-language (中文 / 繁體中文 / English / 日本語); auto-detects from `navigator.language`, persists in `localStorage`, switched via the language dropdown on the right panel. The right panel is an **Edit / Annotate** surface: direct SVG edits and AI-needed annotations are visually separated, with a pending-status strip showing staged direct edits and pages with unsaved annotations. Slide navigation: first/prev/next/last buttons at the top of the center panel, plus `←` / `→` / `Home` / `End` (suppressed while typing in the annotation textarea). -- **Buttons**: `Add annotation` stages annotation text in memory; `Apply changes` writes staged direct edits plus annotation markers to disk and keeps the service running; `Exit preview` is the only UI action that stops Flask. -- **Direct edit (no AI)**: selection mode determines the right-panel surface. Single element = full object inspector (geometry, safe text content, computed text styles for the selected text node or descendant text inside a selected textbox/group, raw SVG attributes except protected fields like `id`, UI `class`, event handlers, and hrefs). SVG `<g>` group = group-level edit surface; select via `Alt/Option` + click or **Select parent group** from a child element. Multi-select = limited batch editor over top-level selected objects only: shared x/y plus `fill` / `stroke` / `opacity`; text style fields (`font-size` / `font-family` / `font-weight` / `text-anchor`) appear only when every selected object is `text`/`tspan`. Preview updates immediately; disk writes wait for **Apply changes**. -- **Drag to move**: press and drag an already-selected element on the canvas to reposition it (selection stays a separate click, so the background is never dragged by accident); the whole selection moves together under multi-select. The pointer delta is mapped through each element's own CTM, so moves track the cursor regardless of viewport scale or group transforms. Each release stages one direct edit per moved element (the same `x`/`y`-or-`transform` write the geometry inputs produce), previewed live and written only on **Apply changes**; dragging on empty canvas is still rubber-band selection. A failed stage rolls the canvas back to the pre-drag position. -- **Arrow-key nudge**: with one or more elements selected, `↑ ↓ ← →` moves the selection 1px and `Shift + arrow` moves 10px (suppressed while typing in the annotation box). Arrow keys navigate slides only when nothing is selected. Same staging/coalescing path as drag, so a burst of nudges collapses to one undo step. -- **Overlap picker**: right-click anywhere on the canvas to list every selectable element under the pointer (top→bottom), so stacked shapes can be reached without blind cycling. Left-click is unchanged (selects the topmost). Hovering a row highlights that element; clicking it selects it; `Esc` or an outside click closes the list. With exactly one element under the pointer, right-click selects it directly. -- **Undo**: `Ctrl+Z` or the **Undo** button drops the last staged direct edit on the current slide (per-slide LIFO, this session). Consecutive edits to the *same element and same field set* (e.g. nudging one color or coordinate several times) coalesce into a single undo step, keeping the original pre-edit value; switching element or field starts a new step. Applied old→new history is appended to `<project>/live_preview/edits.jsonl`; annotation save/update/remove history is appended to `<project>/live_preview/annotations.jsonl`; un-applied staged edits are in-memory only. -- **Unsaved-work guard**: staged direct edits and annotation changes (added or removed) live in server memory until **Apply changes**; closing the tab triggers the browser's native "leave site?" prompt while any are unapplied, since an idle timeout or process kill would drop them. -- **Re-export is chat-driven**: applying changes updates `svg_output/` only. Refreshing the PPTX (finalize + svg_to_pptx) stays a chat step — the editor never runs the export pipeline or presents browser-side export as part of applying edits. -- **Stop conditions**: the service stops when the user clicks **Exit preview** in the browser, asks in chat to stop it, the idle timeout fires, or the process is killed externally. -- **Port**: without `--port`, use the first free port from `6060`; `--port N` binds `N` strictly and fails if unavailable. Read the actual URL from launch output or `<project_path>/live_preview/lock.json`. -- **Idle timeout**: plain mode `900s`, `--live` mode `7200s`; override with `--timeout <seconds>` (`0` disables). -- **Single instance per project**: `<project_path>/live_preview/lock.json` records the running pid + actual port and is the discovery source for project-local consumers. A second launch reuses the live instance unless an explicit, different `--port N` was requested; that mismatch fails and requires `--shutdown` before restart. Stale locks (dead pid) are overwritten on the next launch. Legacy root locks at `<project_path>/.live_preview.lock` are still detected when they point to a live process. -- **Transient ids**: each element gets a temporary `_edit_N` id while the editor is running. On save, only annotated elements keep their id; unannotated `_edit_N` ids are stripped before write-back. -- **Browser preview**: the server inlines `<use data-icon>` placeholders and serves `images/*` so SVG renders correctly; the on-disk SVG is unchanged by this preview. - ---- - -## Appendix: Remote access - -If the project lives on a remote Linux server, run with `--no-browser`: - -```bash -python3 ${SKILL_DIR}/scripts/svg_editor/server.py <project_path> --daemon --no-browser -# or for Step 6's auto-startup on a remote host: -python3 ${SKILL_DIR}/scripts/svg_editor/server.py <project_path> --live --daemon --no-browser -``` - -Let `<P>` be the port in launch output or `<project_path>/live_preview/lock.json`: - -- **VS Code / Cursor Remote-SSH**: in the **PORTS** panel, forward `<P>`. -- **Termius**: add a Local rule with Binding and Destination both `127.0.0.1:<P>`, then start it. -- **Plain SSH**: `ssh -L <P>:127.0.0.1:<P> <user>@<host>`. - -Then open `http://localhost:<P>` locally. +1. `python3 ${SKILL_DIR}/scripts/check_annotations.py <project_path>` — its output lists each pending change as `file → element_id → annotation text → content preview`; use it directly as the to-do list. If it reports none, tell the user and stop. +2. For each annotation: edit the targeted element in `<project_path>/svg_output/<file>` per the text; remove `data-edit-target` and `data-edit-annotation` from it; append one `annotation_applied` JSONL record (`ts`, `file`, `element_id`, original text) to `<project_path>/live_preview/annotations.jsonl`. +3. Re-enter [`generate-pptx`](../generate-pptx.md) Step 7.2, wait for its success criterion, then run Step 7.3; rerun Step 7.1 only when speaker notes changed. +4. Tell the user, in their language: annotations applied, new PPTX exported, preview still running (refresh or reselect the page if the browser shows the old slide). +5. More annotations → repeat from 1; "done" or "stop preview" → end. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/stages/refine-spec.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/stages/refine-spec.md index a6c92c69..4c6395af 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/stages/refine-spec.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/stages/refine-spec.md @@ -4,59 +4,36 @@ description: Optional main-pipeline stage for reviewing and revising the complet # Refine Spec Stage -> **Opt-in Generate-PPTX stage**. Default writes `design_spec.md` + `spec_lock.md` and proceeds. With explicit refinement, produce and audit the complete Design Spec, then **stop before the lock** for unrestricted user review/revision. +> **Opt-in Generate-PPTX stage.** Default writes `design_spec.md` + `spec_lock.md` and proceeds. With explicit refinement, produce and audit the complete Design Spec, then **stop before the lock** for unrestricted user review. -This stage is **conditional**, same shape as the split-mode choice: it never fires on its own and the default path is unchanged. The Strategist confirmation stage settles design directions up front as abstract recommendations; this pass lets the user revise the **concrete spec** the Strategist produced from them. It is most valuable for a zero-background user, who can judge a finished spec far better than the up-front recommendations — and the spec's content outline (`§IX`) is usually what they most want to adjust. +The confirmation stage settles design directions as abstract recommendations; this pass lets the user revise the concrete spec produced from them — most valuable for a zero-background user, who judges a finished spec far better than up-front recommendations, and usually wants to adjust the content outline (§IX). ## When to Run -The user **explicitly asks** to refine / review / revise the spec before generation. Recognize any of: - -| Pattern | Example | -|---|---| -| "refine the spec / review the spec first" | "produce the spec first, let me review before slides" | -| "let me revise the spec, then continue" | "send me the spec to confirm, I'll edit it" | -| Any request to inspect/iterate the design spec before generation | "draft the full plan, I want to adjust it, then generate" | - -**Default is OFF.** Strategist surfaces this option as one short opt-in line inside the Strategist confirmation stage (see [`generate-pptx`](../generate-pptx.md) Step 4). No request → the spec is written in one go and the pipeline auto-proceeds as usual; this stage never starts. - -**Prerequisite**: the Strategist confirmation stage is settled (mode + visual style + the rest). This pass revises the spec produced from that stage; it does not re-open the confirmation stage itself. +Only when the user explicitly asks to refine / review / revise the spec before generation ("produce the spec first, let me review", "send me the spec to confirm, I'll edit it", "draft the full plan, I want to adjust it, then generate"). **Default is OFF**: Strategist surfaces it as one short opt-in line inside the confirmation stage ([`generate-pptx`](../generate-pptx.md) Step 4); without a request the spec is written in one go. **Prerequisite**: the confirmation stage is settled; this pass never reopens it. --- ## Step 1: Produce the complete Design Spec -Run [`generate-pptx`](../generate-pptx.md) Step 4 through the complete `design_spec.md` (§I–X) and initial Gate 1 audit. Read relevant `sources/` so §IX carries facts, not skeleton points. +Run [`generate-pptx`](../generate-pptx.md) Step 4 through the complete `design_spec.md` (§I–X) and the initial Gate 1 audit, reading relevant `sources/` so §IX carries facts, not skeleton points. -**Hard rule — no lock before approval**: Do not create, update, use, or validate `spec_lock.md` during review. On a resumed project, any prior lock is stale derived state until Gate 2 resynchronizes it after approval. +**Hard rule — no lock before approval**: do not create, update, use, or validate `spec_lock.md` during review; on a resumed project a prior lock is stale derived state until Gate 2 resynchronizes it after approval. --- ## Step 2: ⛔ HARD STOP — present, discuss, and revise -Present the Design Spec and **wait for explicit revision or approval before anything else**. Review the one project `design_spec.md` in chat; do not create a second draft, parallel summary, or fixed-field questionnaire. +Present the one project `design_spec.md` in chat and wait for explicit revision or approval — no second draft, parallel summary, fixed-field questionnaire, scores, or field-by-field confirmation. The user may revise any part, any number of rounds; discuss in prose and let the user drive. -The user may revise **any part of the spec** and request any number of changes per round. Discuss in **prose**; do not emit scores or force field-by-field confirmation. Let the user drive. +**Reference — review lenses, not a checklist**: raise these in plain language as directions, never numbers (no HEX, px, ratios, page quotas, or grades): outline — logical build, information density, one idea per page, register matched to the audience, hook and payoff, chapter balance; color — fit to mood and audience, enough hierarchy and contrast; typography — clear contrast or clean concord between title and body, legible size hierarchy, character matched to the visual style; layout — structure following each page's information weight rather than one uniform symmetric grid; icon/image — one consistent icon character, images that serve the content; page rhythm — `anchor` / `dense` / `breathing` tracking the narrative. They overlap what the confirmed `mode`, visual style, and §6.1 already shape; they are discussion angles, not permission to redo a decision without the user's explicit revision. -**Reference — review lenses, not a checklist or score**: raise these in plain language to surface what is worth discussing. They name a *direction*, never a number — never convert any into HEX values, px sizes, ratios, page quotas, or grades. - -- *Outline*: logical clarity (do the points build on each other), information density (right amount per page — nothing padded or crammed), focus (each page lands one idea), register (spoken vs formal, matched to the audience), emotional resonance (a hook to open, a payoff to close), chapter balance (page budget not lopsided). -- *Color*: does the scheme fit the content's mood and audience, and is there enough hierarchy and contrast to read comfortably — not which exact HEX. -- *Typography*: do title and body form a clear contrast or a clean concord, is the size hierarchy legible, does the type character match the visual style — not which px. -- *Layout*: does structure follow each page's information weight, or does it fall back to one uniform symmetric grid (the "AI-generated" look). -- *Icon / image*: one consistent icon character throughout; images that serve the content (hero / atmosphere used on purpose) rather than decorate. -- *Page rhythm*: do `anchor` / `dense` / `breathing` track the narrative, or is everything flatly dense. - -These overlap with what the confirmed `mode`, visual style, and §6.1 already shape — treat them as discussion angles to surface what is worth talking about, not permission for the Strategist to redo a decision without the user's explicit revision. - -**Revise one Design Spec only**: Apply each user-requested round incrementally to `design_spec.md`; affected decisions supersede earlier values, while unaffected confirmed decisions and cross-section coherence remain intact. Do not regenerate the document for a local change or touch lock anchors. Iterate until explicit approval. - -**Re-run the route/template preflight after reuse revisions.** For changed reuse/prototype decisions, repeat [`strategist-template.md`](../../references/strategist-template.md) preflight before approval. `style` later locks flat; `mirror` / `layout` require a complete structured contract. Update only human-facing Design Spec decisions during review; Gate 2 derives structure mappings. Legacy prototypes remain unselectable. +**Revise one Design Spec only**: apply each round incrementally; affected decisions supersede earlier values while unaffected confirmed decisions and cross-section coherence stay intact. Do not regenerate the document for a local change or touch lock anchors. After a changed reuse/prototype decision, repeat the [`strategist-template.md`](../../references/strategist-template.md) preflight before approval (`style` later locks flat; `mirror` / `layout` require a complete structured contract; Gate 2 derives structure mappings; legacy prototypes stay unselectable). Iterate until explicit approval. --- ## Step 3: Approve and author the lock -After explicit approval, return to [`generate-pptx`](../generate-pptx.md) Step 4 Gate 2. Author or resynchronize `spec_lock.md` once from the approved Design Spec plus current context, validate, then continue to Step 5 or Step 6. Do not reopen `result.json`. +After explicit approval, return to [`generate-pptx`](../generate-pptx.md) Step 4 Gate 2: author or resynchronize `spec_lock.md` once from the approved Design Spec plus current context, validate, then continue to Step 5 or Step 6. Do not reopen `result.json`. -> Note: this stage does NOT duplicate Strategist content. It inserts a review-and-revise checkpoint between Design Spec Gate 1 and lock Gate 2. [`strategist.md`](../../references/strategist.md) and [`generate-pptx`](../generate-pptx.md) remain authoritative for artifact content and route sequencing. +> This stage inserts a review-and-revise checkpoint between Gate 1 and Gate 2; [`strategist.md`](../../references/strategist.md) and [`generate-pptx`](../generate-pptx.md) remain authoritative for content and sequencing. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/stages/resume-execute.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/stages/resume-execute.md index f996ece7..63a19749 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/stages/resume-execute.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/stages/resume-execute.md @@ -4,130 +4,52 @@ description: Main-pipeline control stage for resuming execution in a fresh chat # Resume Execute Stage -> Generate-PPTX control stage for a fresh execution session. Run when [`generate-pptx`](../generate-pptx.md) Step 1–5 completed in a previous chat and the user wants to continue with SVG generation + export. Loads project state from disk and runs Step 6 + Step 7 inside the already selected Generate route. +> Generate-PPTX control stage for a fresh execution session: [`generate-pptx`](../generate-pptx.md) Steps 1–5 completed in a previous chat and the user wants SVG generation + export. Loads project state from disk and runs Steps 6–7 inside the already selected Generate route. -This stage is **context-independent**: it owns the execution session starting from a fresh chat — no upstream conversation context required. Persisted project artifacts replace the planning session's confirmation dialogue and image-acquisition history. - -`validation/workflow.log` is a cold command/outcome audit log with optional -important manual entries, not persisted planning state. Do not open or replay -it while resuming. Use the real artifacts in Step 1 to establish current state; -inspect the log only when the user explicitly asks to review the prior run. Run -inherited Python commands normally; their shared CLI bootstrap records a -bounded material outcome selection automatically, not the full console stream. +Context-independent: persisted project artifacts replace the planning session's confirmation dialogue and image-acquisition history. `validation/workflow.log` is a cold audit log, not planning state — never open or replay it while resuming; inspect it only when the user asks to review the prior run. ## When to Run -The user opens a new chat and gives a phrase that names a project path and signals continuation. Recognize any of: - -| Pattern | Example | -|---|---| -| "继续生成 projects/<project_name>" | "继续生成 projects/ppt169_joe_hisaishi" | -| "resume execution projects/<project_name>" | "resume execution projects/ppt169_joe_hisaishi" | -| Project path + any "继续 / 恢复 / 继续做 / 接着做" semantic | "把 projects/ppt169_joe_hisaishi 继续做完" | - -**Prerequisite**: the planning session must have completed in the named project. Verified by file presence in Step 1; do NOT auto-trigger planning on missing state. +The user opens a new chat naming a project path with continuation intent — "继续生成 projects/<name>", "resume execution projects/<name>", or a project path plus any 继续 / 恢复 / 接着做 semantic. **Prerequisite**: planning completed in that project, verified by file presence in Step 1; never auto-trigger planning on missing state. --- ## Step 1: Sanity check -Verify the two root planning artifacts exist before loading their contents: - -| File | Required when | Reason | -|---|---|---| -| `<project_path>/design_spec.md` | Always | Upstream approved design narrative and §IX page outline; its complete read occurs after the Executor role core loads | -| `<project_path>/spec_lock.md` | Always | Downstream execution anchors and routing contract; its complete read follows the Design Spec | - -If either file is missing, report it and stop this stage. Recover through -[`failure-recovery.md`](../governance/failure-recovery.md) §3; do not enter Step -6, read an orphan lock as authority, or invent a replacement artifact. +`<project_path>/design_spec.md` (approved narrative and §IX outline) and `<project_path>/spec_lock.md` (execution anchors and routing contract) must both exist; their complete reads happen after the Executor role core loads. If either is missing, stop and recover through [`failure-recovery.md`](../governance/failure-recovery.md) §3 — never enter Step 6, treat an orphan lock as authority, or invent a replacement. --- ## Step 2: Load the Generate authority, proceed from Step 6 -``` -Read skills/ppt-master/workflows/generate-pptx.md -``` +Read `skills/ppt-master/workflows/generate-pptx.md` and jump to `### Step 6: Executor Phase`, which loads `executor-base.md` and applies its context policy: read the complete Design Spec, then the complete lock, once; resolve the effective Speaker Notes / Custom Animations / Narration Audio outcomes from `design_spec.md §I` (missing outcomes default `enabled` / `disabled` / `disabled`; never from the lock). -Then jump to `### Step 6: Executor Phase`. It first loads `executor-base.md`, -then applies that role core's context policy: +Before the first SVG, verify every conditional dependency discoverable from that pair: -- Read the complete project Design Spec, then the complete `spec_lock.md`, once to establish the fresh execution context -- Resolve the effective Speaker Notes, Custom Animations, and Narration Audio - outcomes from `design_spec.md §I`. Missing outcomes use the workflow defaults - `enabled` / `disabled` / `disabled`; these production decisions never come - from `spec_lock.md` - -Before the first SVG, verify every conditional dependency now discoverable -from that retained pair: - -| File / Directory | Required when | Reason | +| File / Directory | Required when | Recovery when missing | |---|---|---| -| `<project_path>/notes/total.md` | Design Spec §X records a supplied final/literal narration script | Frozen verbatim narration input; never reconstruct it from the planning chat | -| `<project_path>/images/` plus files whose row status requires existence | `spec_lock images` references any image | `Existing` / `Generated` / `Sourced` files must exist; an absent `Needs-Manual` file remains allowed until the Step 7 readiness gate | -| `<project_path>/templates/` | `spec_lock page_layouts` references any | Layout / mirror prototypes required by execution | -| Resolver-returned Chart/Table SVG | `spec_lock page_visualizations` or legacy `page_charts` references a live Chart/Table key | Shared page-local SVG selected through the two live catalogs | +| `notes/total.md` | §X records a supplied final/literal narration script | Return to Step 4's prepared final narration branch; never rewrite the script from memory | +| `images/` plus files whose row status requires existence (`Existing` / `Generated` / `Sourced`; an absent `Needs-Manual` file is allowed until the Step 7 gate) | `spec_lock images` references any image | By provenance: `Acquire Via: user` / `Existing` is a required manual artifact (`failure-recovery.md` §2, wait for the exact file); a template-bundled bitmap returns to Step 3 to restore the workspace; AI, web, or slice output uses its `failure-recovery.md` §1 row. Formula markers never create a required image file | +| `templates/` | `spec_lock page_layouts` references any prototype | Restore the workspace through Step 3 and [`apply-template-workspace`](apply-template-workspace.md); if unavailable or invalid, run Create Template again rather than reconstructing a template here | +| Resolver-returned Chart/Table SVG | `page_visualizations` or legacy `page_charts` references a live key | Failed, missing, or ambiguous resolution is a missing planning dependency and stops this stage | -Resolve every live Chart/Table value through the shared catalog resolver. -Validate canonical `family/key` from `page_visualizations` directly; opt into -bare-key resolution only for a live Chart/Table value read from legacy -`page_charts`: +Resolve every live Chart/Table value through the shared resolver — canonical `family/key` directly, `--legacy-bare` only for a value read from legacy `page_charts` — and require every returned SVG to exist; never construct a path from the key. A retired Structure bare key is semantic intent only: recover it from §IX or return to Step 4 when §IX is insufficient. ```bash -python3 skills/ppt-master/scripts/visualization_recall.py validate \ - <family/key> [<family/key> ...] -python3 skills/ppt-master/scripts/visualization_recall.py validate \ - --legacy-bare <legacy-key> [<legacy-key> ...] +python3 skills/ppt-master/scripts/visualization_recall.py validate <family/key> [<family/key> ...] +python3 skills/ppt-master/scripts/visualization_recall.py validate --legacy-bare <legacy-key> [...] ``` -Require every returned SVG to exist. Never construct a path from the key, -guess a family directory, or prefer one registry. Failed, missing, or ambiguous -live resolution is a missing planning dependency and stops this stage. A -retired Structure bare key carries semantic intent only and requires no SVG; -recover its relationship from §IX, or return to Step 4 when §IX is insufficient. +Then continue the documented Step 6–7 pipeline exactly as `generate-pptx.md` lists it: read the frozen `notes/total.md` once when §X declares a final/literal script; when mid-deck, read the latest completed SVG and current image metadata after their paths are verified; read the Step 6 construction core and one locked preset file or only the exact `*_references` of a custom, never reopening the mode or visual-style catalogs; load only the branches the condition table selects; make the per-page Structure decision from retained §IX before any geometry; when structured, read the template Design Spec and each selected prototype once. Use `page-context` only for explicit diagnostics or an unresolved path-SHA question ([`artifact-ownership.md`](../../references/artifact-ownership.md) §1), never as a routine pre-page load. Then the quality gate, conditional notes, conditional custom animation, Step 7 (`total_md_split` → `finalize_svg` → `svg_to_pptx`; disabled notes use `--no-notes`), and `generate-audio` when Narration Audio is enabled. -If a conditional dependency is missing, stop before page authoring and recover -by artifact owner: +A newer explicit instruction after final Stage 2 updates only its effective outcome and provenance in `design_spec.md §I`, then resumes at the owning step — no Confirm UI, no lock entry; apply Generate's notes/audio dependency gate before writing and its sidecar suppression rules at export. -- Missing frozen `notes/total.md` when §X declares a final/literal script → return to Generate Step 4's prepared final narration branch; never rewrite the script from memory. -- Missing `images/`, or a file whose status requires existence → recover by provenance: an `Acquire Via: user` / `Status: Existing` file is a required manual artifact, so use `failure-recovery.md` §2 and wait for the user to restore that exact file; a template-bundled bitmap returns to [`generate-pptx`](../generate-pptx.md) Step 3 to restore the selected workspace; an AI, web, or slice output uses its matching row in `failure-recovery.md` §1 to reacquire or derive it. An absent `Needs-Manual` file is not a resume failure. Formula markers are SVG authoring content and never create a required image file. -- Missing `templates/` inputs → restore the selected workspace through [`generate-pptx`](../generate-pptx.md) Step 3 and [`apply-template-workspace`](apply-template-workspace.md). If the workspace is unavailable or invalid, run Create Template again rather than reconstructing a template inside this stage. +**Source verification**: read only the `sources/` passages needed to resolve explicit `Fact IDs` / source references or verify facts, quotes, names, and data required by the current §IX block, under [`executor-base.md`](../../references/executor-base.md) §2.1's content-vs-expression contract; verification never authorizes a second outline. If §IX lacks executable content, stop and return to Step 4 for Design Spec repair. -Then continue the documented pipeline: - -- When §X records a final/literal narration script, read the verified frozen `notes/total.md` once and retain its page segments through SVG authoring and the late notes validation -- If resuming mid-deck, read the latest completed SVG and current image metadata after their required paths have been verified -- Read the remaining Step 6 construction core exactly as listed in [`generate-pptx.md`](../generate-pptx.md), then read one locked preset file or only the exact `*_references` of a custom; apply one basis under its behavior or synthesize several by their stated contributions. Never reopen or glob the mode or visual-style catalogs, and load only the branches selected by the condition table -- For each page, make the mandatory Structure decision from retained §IX after its content/communication move is established and before any geometry; a `yes` result loads `executor-structure.md` before realization and creates no artifact or lock row -- Design Parameter Confirmation -- When structured, read the template Design Spec and each selected prototype once; retain unchanged references in the fresh context. A later bounded repair follows [`executor-base.md`](../../references/executor-base.md) §2.1 only while that context remains valid and uncompacted -- Generate pages sequentially from the retained planning artifacts. Use `page-context` only for the on-demand diagnostic/telemetry triggers in Executor §2.1, never as a routine pre-page load -- Quality Check Gate -- Speaker notes generation only when the effective Speaker Notes outcome is enabled -- Conditional custom-animation handling under the effective outcome, - provenance, explicit instruction, and existing-sidecar rules -- Step 7: Post-processing & Export (conditional `total_md_split` → `finalize_svg` - → `svg_to_pptx`; disabled speaker notes use `--no-notes`) -- After the base export, run `generate-audio` when the effective Narration Audio - outcome is enabled; narration implies speaker notes are enabled - -Reload the Generate authority and required execution references; do not reconstruct or replay the earlier planning conversation. - -If the user gives a newer explicit instruction after final Stage 2, update only the -affected effective outcome and provenance in `design_spec.md §I`, then resume at -its owning step. Do not reopen Confirm UI or add the decision to -`spec_lock.md`. Before writing, apply Generate's single notes/audio dependency -gate; at export, apply its sidecar suppression rules. - -**Source verification**: the execution session is fresh. Read only the relevant `sources/` passages needed to resolve explicit `Fact IDs` / source references or verify facts, quotes, names, and data required by the current §IX block. Follow [`executor-base.md`](../../references/executor-base.md) §2.1's content-vs-expression contract; source verification never authorizes a second outline. If §IX lacks executable content or evidence, stop and return to Generate Step 4 for Design Spec repair. - -> Note: this stage does NOT duplicate Step 6 / Step 7 content. `generate-pptx.md` is the authoritative procedure; resume-execute only adds the resumption entry, sanity check, and source-verification guidance. +> This stage does not duplicate Steps 6–7; `generate-pptx.md` is the authoritative procedure. Resume adds only the entry, sanity check, and source-verification guidance. --- ## Step 3: Hand-back -When Step 7 completes and `exports/<project_name>_<timestamp>.pptx` is produced, the stage ends. Report the export path to the user. - -If the deck contains data charts, the [`verify-charts`](verify-charts.md) stage runs between Step 6 and Step 7 as documented in [`generate-pptx`](../generate-pptx.md); resume mode handles it the same way as continuous mode. +When Step 7 produces `exports/<project_name>_<timestamp>.pptx`, the stage ends; report the export path. [`verify-charts`](verify-charts.md) runs between Steps 6 and 7 exactly as in continuous mode. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/stages/topic-research.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/stages/topic-research.md index 937f98ad..307cdaca 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/stages/topic-research.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/stages/topic-research.md @@ -4,130 +4,64 @@ description: Generate source-intake stage that fills factual gaps and records ad # Topic Research Stage -> Factual preparation inside the active Generate profile's source intake. -> Default Generate hands its output to Strategist; Quick Generate's main agent -> consumes the same output. Run immediately for topic-only input, or after -> supplied material is converted and read when it leaves planning-critical -> factual gaps. Output is exactly a research supplement plus stable fact -> provenance for project import. Adopted webpage URLs remain in the provenance -> file and are not expanded during the project-initialization handoff. - -This stage supplies facts needed to build the requested deck and records the -webpages actually adopted during that research. It makes no deck image -selection and performs no independent image search or generation. The facts -JSON is provenance, not a page-download queue: `project_manager.py -import-sources` imports the research pair without fetching its `source_url` -values. A page may be fetched later only for the bounded image fallback below. +> Factual preparation inside the active Generate profile's source intake: Default hands its output to Strategist, Quick's main agent consumes it. Run immediately for topic-only input, or after supplied material is converted and read when it leaves planning-critical factual gaps. Output is exactly a research supplement plus stable fact provenance for project import. The facts JSON is provenance, not a page-download queue: `import-sources` imports the pair without fetching `source_url` values; a page may be fetched later only through the bounded image fallback below. This stage makes no deck image selection and performs no image search or generation. ## When to Run | Material state | Action | |---|---| -| Topic or requirements with no supporting facts | Research the factual baseline needed for the requested outcome | -| Supplied files or chat content cover only part of the requested outcome | After conversion and reading, research only the identified externally verifiable gaps | -| Supplied material already supports the requested outcome | Skip this stage and continue the active Generate profile's source preparation | -| User requires a closed corpus, source-only transformation, or no external enrichment | Skip this stage and keep planning within supplied material | +| Topic or requirements with no supporting facts | Research the factual baseline for the requested outcome | +| Supplied material covers only part of the outcome | After conversion and reading, research only the identified externally verifiable gaps | +| Supplied material already supports the outcome | Skip; continue the profile's source preparation | +| User requires a closed corpus, source-only transformation, or no external enrichment | Skip; plan within supplied material | -**Sufficiency test**: a gap exists when the active content owner would otherwise need to invent, omit, or leave unsupported an externally verifiable claim required by the user's requested outcome. File presence, source length, and a generic topic taxonomy do not decide sufficiency. +**Sufficiency test**: a gap exists when the content owner would otherwise have to invent, omit, or leave unsupported an externally verifiable claim the requested outcome needs; file presence, source length, and topic taxonomy do not decide it. -**Hard rule — preserve supplied facts**: supplement the user's material; never -silently replace it. Record a material source conflict in the research output -for the active content owner instead of choosing a different claim without -disclosure. Do not research omissions outside the requested scope. +**Hard rule — preserve supplied facts**: supplement the user's material, never silently replace it; record a material source conflict in the research output instead of choosing a different claim without disclosure. Do not research omissions outside the requested scope. --- ## Step 1: Define the gap brief -**Clarification boundary**: Default Generate bundles only genuinely missing -scope or research-boundary decisions into one clarifier. Quick Generate applies -the defaults below and continues without interaction; stop only when a required -permission or safety boundary cannot be inferred responsibly. Skip clarification -when the request and supplied material are already clear. - | Item | Default if unspecified | |---|---| -| Topic | From the user request | -| Requested scope / outcome | From the user request; otherwise broad overview | +| Topic / scope / outcome | From the request; otherwise broad overview | | Supplied-material baseline | Facts and claims already available | -| Research gaps | Only facts needed to support the requested outcome | -| External-source boundary | External factual enrichment allowed; supplied facts remain authoritative inputs | +| Research gaps | Only facts needed to support the outcome | +| External-source boundary | External enrichment allowed; supplied facts remain authoritative | | Output language | Match user input | -| Target audience / communication intent | Use what is explicit; Default leaves final confirmation to Strategist, while Quick resolves routine gaps in active context | -| Research stem (`<research_slug>`) | `<topic_slug>_research`; choose another unused snake_case stem rather than overwrite an existing file | +| Audience / communication intent | Use what is explicit; Default leaves confirmation to Strategist, Quick resolves routine gaps in context | +| Research stem `<research_slug>` | `<topic_slug>_research`, or another unused snake_case stem rather than overwriting | -Do not repeat the full default-pipeline confirmation here. Default Generate -confirms the complete communication contract in Step 4; Quick Generate adds no -confirmation stage. +Default bundles only genuinely missing scope or research-boundary decisions into one clarifier; Quick applies the defaults and continues, stopping only when a required permission or safety boundary cannot be inferred responsibly. Do not repeat the full-pipeline confirmation here. --- ## Execution Context -**Default — isolated research when available**: The main agent owns the sufficiency decision and gap brief. When the current AI editor supports and permits an isolated subagent with web/fetch access and write access to the declared outputs, dispatch exactly one research worker. Otherwise the main agent runs Steps 2–3 locally. +**Default — isolated research when available**: the main agent owns the sufficiency decision and brief. When the host supports an isolated subagent with web/fetch access and write access to the declared outputs, dispatch exactly one research worker with the topic/outcome, baseline or source paths, declared gaps, output language, two exact unused output paths, and this stage's absolute path as execution authority (paths, not pasted source bodies). The worker reads this file completely, follows Steps 2–3, limits project writes to the two artifacts, and makes no image, deck-planning, or design decisions. Otherwise the main agent runs Steps 2–3 locally. -| Actor | Contract | -|---|---| -| Main agent | Supply the topic/outcome, baseline or relevant source paths, declared gaps, output language, two exact unused output paths, and this stage's absolute path as execution authority; use paths instead of pasting source bodies when possible | -| Research worker | Read the supplied stage file completely, then follow Steps 2–3 using the brief and declared source paths as its baseline; limit project writes to the two output artifacts; perform no independent image search/generation and make no deck-planning, image-selection, or design decisions | +**Hard rule — isolate retrieval, not research**: raw page content stays in the worker context. The 250-word limit applies only to its chat receipt (`status`, artifact paths, covered/unresolved gap counts, external-fact count, material conflicts), never to the artifacts. After validation and import, the content owner reads the complete imported pair into the main context; never use the receipt as content. -**Hard rule — isolate retrieval, not research**: Raw page content and fetch transcripts stay in the worker context. The 250-word limit applies only to its chat receipt: return `status`, exact artifact paths, covered/unresolved gap counts, external-fact count, and material conflicts. It does not cap or replace the two artifacts. After validation and import, the active content owner reads the complete imported research supplement and fact-provenance JSON into the main context before planning or direct SVG authoring; never use the receipt or validation summary as content. - -**Validation**: Before import, the main agent verifies both exact files exist, the Markdown contains `## Research Brief` and no source list or URL, the JSON parses with schema `ppt-master.fact-provenance.v1` and unique sequential IDs, and the two files agree. Return an invalid pair to the research worker for owning-artifact repair; use main-context web research only when isolated execution is unavailable. +**Validation**: before import, verify both files exist, the Markdown contains `## Research Brief` and no source list or URL, the JSON parses with schema `ppt-master.fact-provenance.v1` and unique sequential IDs, and the two agree. Return an invalid pair to the worker for repair; use main-context research only when isolation is unavailable. --- ## Step 2: Gather factual sources -Use the web search and fetch tools available in the active research context. An isolated worker without them returns `blocked: web-tools-unavailable`. If no usable research context has search/fetch tools, the main agent pauses and asks the user for authoritative URLs covering the declared gaps, then fetches each with: +Use the search and fetch tools available in the research context; an isolated worker without them returns `blocked: web-tools-unavailable`. With no usable search/fetch context, pause and ask the user for authoritative URLs covering the gaps, then fetch each with `web_to_md.py <URL> -o projects/<research_slug>_web_sources/<source_slug>.md --no-images` (remote image links stay in the Markdown; nothing is downloaded). -```bash -python3 ${SKILL_DIR}/scripts/source_to_md/web_to_md.py <URL> \ - -o projects/<research_slug>_web_sources/<source_slug>.md --no-images -``` +Orient (map authoritative sources to the gaps) → deep fetch (read the highest-signal primary pages in full) → targeted fill (search only for gaps still unsupported). Prefer primary sources, official sites, institutional releases, standards, and original research; then authoritative reference works and academic sources; then reputable reporting; avoid unsourced reposts, unverifiable summaries, and stock-aggregator pages. -Preserve the resulting Markdown and conversion profile for research. Remote -inline-image links remain in the Markdown; no image files are downloaded. - -| Phase | Action | -|---|---| -| Orient | Search only far enough to map authoritative sources to the declared gaps | -| Deep fetch | Read the highest-signal primary or authoritative pages in full | -| Targeted fill | Search only for gaps still unsupported after those reads | - -| Priority | Source | -|---|---| -| 1 | Primary sources, official sites, institutional releases, standards, or original research | -| 2 | Authoritative reference works and reputable academic sources | -| 3 | Reputable reporting or analysis when primary evidence is unavailable | -| Avoid | Unsourced reposts, unverifiable summaries, and stock-aggregator pages | - -**Adopted webpage boundary**: Record a page URL only in the matching fact's -`source_url`, and only when it materially supports that retained fact. Do not -retain a page merely because its images may be useful, and do not add unopened -search results or pages found through a separate image-search pass. - -**Stop condition**: stop when every declared gap has enough sourced evidence for -the active content owner to decide whether and how to include it. Do not expand -into unrelated overview / history / outlook sections merely to make the -research look complete. +**Adopted webpage boundary**: record a URL only in the matching fact's `source_url`, and only when it materially supports that fact — never because its images may be useful, and never from unopened search results or a separate image-search pass. Stop when every declared gap has enough sourced evidence for the content owner to decide inclusion; do not add overview/history/outlook sections to look complete. --- ## Step 3: Save the factual supplement -Write two artifacts under `projects/`: +Write `projects/<research_slug>.md` and `projects/<research_slug>.facts.json` — under `projects/`, never the repository root; never overwrite an existing user file; no research-image manifest or downloaded images. -| Artifact | Path | -|---|---| -| Research supplement | `projects/<research_slug>.md` | -| Fact provenance | `projects/<research_slug>.facts.json` | - -**Hard rule — location and preservation**: write both files under `projects/`, never the repository root. Do not overwrite an existing user file; choose a new research stem instead. Do not create a research-image manifest or download embedded images. - -Begin the research Markdown with a compact `## Research Brief` containing the supplied-material baseline, declared gaps, audience / intent already known, and requested outcome. Organize the body by gap, include concrete facts only, flag material conflicts, and cite claims by `fact_id`. Do not add `## Sources` or URLs; the facts JSON is the only URL authority. - -Write every externally sourced claim that may enter the deck to `<research_slug>.facts.json` with a stable sequential ID, especially quantitative, date, ranking, attribution, and named-entity claims. Do not include user-supplied claims or invented scenario values. When no external claim is retained, write the schema with an empty `facts` array. +The Markdown begins with a compact `## Research Brief` (baseline, declared gaps, known audience/intent, requested outcome), then organizes the body by gap with concrete facts only, flags material conflicts, and cites claims by `fact_id`; no `## Sources` or URLs — the JSON is the only URL authority. The JSON records every externally sourced claim that may enter the deck (especially quantitative, date, ranking, attribution, and named-entity claims) with immutable sequential IDs — correct a claim under the same ID, never reuse a removed ID; no user-supplied claims or invented scenario values; an empty `facts` array when nothing external is retained. ```json { @@ -146,58 +80,26 @@ Write every externally sourced claim that may enter the deck to `<research_slug> } ``` -IDs are immutable within the file. Correct a claim under the same ID; never reuse a removed ID for a different fact. The research Markdown and provenance file must agree. - --- ## Hand-off -After project initialization, import the research pair and user-supplied -sources. The facts JSON is imported as an ordinary source file; its `source_url` -values are never expanded, so this command performs no webpage retrieval. +After project initialization, import the pair with the user sources; the facts JSON is an ordinary source file and no webpage is retrieved: ```bash -python3 ${SKILL_DIR}/scripts/project_manager.py import-sources \ - projects/<project_name> [<source_paths...>] \ - projects/<research_slug>.md projects/<research_slug>.facts.json +python3 ${SKILL_DIR}/scripts/project_manager.py import-sources projects/<project_name> [<source_paths...>] projects/<research_slug>.md projects/<research_slug>.facts.json ``` -If planning later exposes a required factual gap, return to this stage and -repair the research supplement plus facts JSON before continuing. Do not let -Strategist or Quick consume a newly fetched claim without updating that pair. +If planning later exposes a required gap, return here and repair the pair before continuing; Strategist or Quick never consumes a newly fetched claim without updating it. The imported pair is the compact evidence-facing content authority, not a locked contract: Default's Strategist reads both files completely before confirmation; Quick's agent does the same before its content, design, and resource decisions. -Only after normal web-image providers, ranked thumbnail pages, and materially -different queries fail may an image owner with visual capability select one -relevant `source_url` from the facts JSON and fetch that one webpage package: - -```bash -python3 ${SKILL_DIR}/scripts/source_to_md/web_to_md.py "<source_url>" \ - -o <project_path>/sources/<source_slug>.md -``` - -This writes the page Markdown, conversion profile, and companion -`<source_slug>_files/` image package with `image_manifest.json`. Review that -package, then copy only accepted image files into `<project_path>/images/`; -leave every rejected or unused file in the source package. Fetch another page -only after the current package has no usable image. Do not pass the URL to -`project_manager.py import-sources`, which would promote every companion image -into the runtime pool. Without vision, skip this fallback and retain -`Needs-Manual`. - -The imported research pair remains the compact evidence-facing content -authority, not a locked presentation contract. Default Generate has Strategist -read both files completely before confirmation and use them with the imported -source inventory to select the content, page roster, and image resource plan. -Quick Generate has the current agent do the same before its active-context -content, design, and resource decisions. A webpage Markdown enters the project -only through the post-exhaustion single-page image fallback above. +**Single-page image fallback**: only after normal web-image providers, ranked thumbnail pages, and materially different queries fail may an image owner with visual capability select one relevant `source_url` from the facts JSON and fetch that one page package with `web_to_md.py "<source_url>" -o <project_path>/sources/<source_slug>.md`, review the companion `<source_slug>_files/` package, and copy only accepted images into `<project_path>/images/` — never pass the URL to `import-sources`, which would promote every companion image into the pool. Fetch another page only after the current package has no usable image; without vision, retain `Needs-Manual`. ```markdown ## ✅ Topic Research Complete - [x] Research execution: <isolated worker | main-context fallback> - [x] Research supplement: `projects/<research_slug>.md` (N declared gaps covered) - [x] Fact provenance: `projects/<research_slug>.facts.json` (N external facts) -- [x] Artifact contract validated: `## Research Brief`, no Markdown source list, `ppt-master.fact-provenance.v1`, unique sequential IDs, and Markdown/JSON agreement -- [x] Adopted webpage URLs: N unique `source_url` values in the facts JSON; no webpage automatically imported and no image copied into the runtime pool -- [ ] **Next**: Default returns to [`generate-pptx`](../generate-pptx.md) Step 2; Quick returns to [`quick-generate`](../profiles/quick-generate.md) §2. Import the source artifacts plus research pair, then fully read the imported pair before planning or direct SVG authoring +- [x] Artifact contract validated: `## Research Brief`, no Markdown source list, `ppt-master.fact-provenance.v1`, unique sequential IDs, Markdown/JSON agreement +- [x] Adopted webpage URLs: N unique `source_url` values; no webpage auto-imported, no image copied into the runtime pool +- [ ] **Next**: Default returns to [`generate-pptx`](../generate-pptx.md) Step 2; Quick returns to [`quick-generate`](../profiles/quick-generate.md) §2. Import the sources plus research pair, then fully read the imported pair before planning or direct SVG authoring ``` diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/stages/verify-charts.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/stages/verify-charts.md index fd8feaaf..4ec1ca41 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/stages/verify-charts.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/stages/verify-charts.md @@ -4,21 +4,14 @@ description: Conditional quality-gate stage for data-chart geometry and encoding # Verify Charts Stage -> Conditional Generate-PPTX quality stage. Run after a deck containing data charts has finished SVG generation, before post-processing & export. Catches coordinate and visual-encoding errors introduced while mapping source values into SVG marks. - -In Default Generate this stage is **context-independent**: it reads -`design_spec.md` and the generated SVGs, then runs the calculator script. The -lockless Quick branch is deliberately context-dependent: run it in the same -active session from the page decisions just authored. If that context is lost, -restart Quick rather than inventing a page plan from finished files. +> Conditional Generate-PPTX quality stage. Run after a deck containing data charts has finished SVG generation and before post-processing/export; it catches coordinate and encoding errors introduced while mapping source values into SVG marks. Default runs it context-independently from `design_spec.md` plus the SVGs; the lockless Quick branch runs in the same active session from the page decisions just authored — if that context is lost, restart Quick rather than inventing a page plan from finished files. ## When to Run -- The deck contains one or more data visualization charts where source values determine SVG geometry or visual encoding: bar lengths/heights, point positions, arc angles, polygon vertices, connector endpoints, bubble centers/radii, flow widths/paths, cell colors, or word sizes. -- SVGs are generated to `<project_path>/svg_output/`. Default enters from its declared quality-gate order; Quick runs this stage before its one lockless final checker. -- Post-processing (`finalize_svg.py`, `svg_to_pptx.py`) has **not yet** run. +- The deck contains at least one chart where source values determine SVG geometry or encoding (bar lengths, point positions, arc angles, polygon vertices, connector endpoints, bubble centers/radii, flow widths, cell colors, word sizes). +- SVGs exist in `<project_path>/svg_output/` and `finalize_svg.py` / `svg_to_pptx.py` have not run. Default enters from its quality-gate order; Quick runs it before its one lockless final checker. -The calculator has direct CLI models for simple bars, lines/scatter, pie/donut, radar, and grid layouts. Composite/derived charts are **not automatically out of scope**: if their geometry reduces to repeated direct calculations, include them as `decomposable-calc`; if the calculator has no layout model but the SVG geometry is still data-driven, include them as `manual-verify` so they are not silently skipped. +The calculator has direct models for bars, lines/scatter, pie/donut, radar, and grids. Composite charts are not out of scope: geometry that reduces to repeated direct calculations is `decomposable-calc`; data-driven geometry with no layout model is `manual-verify`, never silently skipped. --- @@ -26,280 +19,60 @@ The calculator has direct CLI models for simple bars, lines/scatter, pie/donut, | Active profile | Object-list authority | |---|---| -| Default Generate | `design_spec.md §IX` plus the legacy §VII fallback below | -| Quick Generate | The still-active semantic object keys and page decisions that produced the SVGs, cross-checked against every `chart-plot-area` marker; no Design Spec, lock, or substitute planning artifact is created | +| Default Generate | `design_spec.md §IX` — every semantic object key whose `Visualization` entry declares value-driven SVG geometry; §VII only resolves a selected catalog reference, and one real §VII data-chart row may supply one legacy object for a page whose §IX predates object keys | +| Quick Generate | The still-active semantic object keys and page decisions, cross-checked one-for-one against every `chart-plot-area` marker found by one search of `svg_output/`; add a missing scoped marker, investigate an unexpected one, keep the list in active context only | -For Default, read `<project_path>/design_spec.md` §IX Content Outline as the -authoritative roster and include every semantic object key whose -`Visualization` entry declares SVG geometry driven by data values. Cross-check -§VII only to resolve a selected catalog reference; absence means no reusable -reference was selected. For a legacy spec whose §IX predates object keys, one -real §VII data-chart row may supply one legacy chart object for that page. - -For Quick, enumerate every promoted chart object's semantic key and page, then -search `svg_output/` once for `chart-plot-area`. Compare objects and marker -wrappers one-for-one. Add a missing scoped marker before continuing; -investigate an unexpected marker instead of silently adding or dropping an -object. Keep the list in active context only. - -Classify each included chart object into exactly one mode: - -Incidental microvisuals not promoted under the active profile authority are not -inferred into this list. Default repairs that object's §IX `Visualization` first; -Quick makes the promotion decision immediately in active context and updates -the SVG marker before verification. +Incidental microvisuals not promoted by the profile authority are not inferred into the list: Default repairs §IX first; Quick decides promotion in active context and updates the marker before verification. Never guess from SVG content when §IX declares no data-driven object. | Mode | `charts_index.json` keys | Notes | |------|--------------------------|-------| -| `direct-calc` | `column_chart`, `horizontal_bar_chart`, `histogram_chart` | Use `calc bar`; add `--horizontal` for horizontal bars. Histogram bins use contiguous bars on the numeric x-axis. | -| `direct-calc` | `line_chart`, `area_chart`, `scatter_chart` | Use `calc line`; area uses line output as the top boundary, then closes to `y_max`. | -| `direct-calc` | `pie_chart`, `donut_chart` | Use `calc pie`; donut passes `--inner-radius`. | -| `direct-calc` | `radar_chart` | Use `calc radar`; separate subcommand, not under `calc pie`. | -| `decomposable-calc` | `stacked_bar_chart`, `stacked_area_chart`, `grouped_bar_chart`, `dumbbell_chart`, `pareto_chart`, `dual_axis_line_chart`, `bullet_chart`, `butterfly_chart`, `waterfall_chart`, `box_plot_chart`, `gantt_chart`, `bar_of_pie_chart`, `pie_of_pie_chart`, `stock_chart` | Verify by repeated direct calculations; see recipes below. | -| `partial-calc` | `bubble_chart`, `matrix_2x2` | Use `calc line` for x/y-driven `cx/cy`; verify radius only when a size scale is explicit. | -| `formula-verify` | `progress_bar_chart`, `gauge_chart`, `funnel_chart`, `sunburst_chart` | Record the formula and resulting length/angle/width in the receipt; sunburst verifies each ring's value-derived arc lengths and offsets. | -| `manual-verify` | `sankey_chart`, `heatmap_chart`, `treemap_chart`, `word_cloud` | Data-driven geometry or encoding exists, but the current calculator has no complete layout model. Inspect and report; do not silently skip. | +| `direct-calc` | `column_chart`, `horizontal_bar_chart`, `histogram_chart` | `calc bar`; `--horizontal` for horizontal bars; histogram bins are contiguous bars on the numeric x-axis | +| `direct-calc` | `line_chart`, `area_chart`, `scatter_chart` | `calc line`; area uses the line output as the top boundary, then closes to `y_max` | +| `direct-calc` | `pie_chart`, `donut_chart` | `calc pie`; donut passes `--inner-radius` | +| `direct-calc` | `radar_chart` | `calc radar` (separate subcommand) | +| `decomposable-calc` | `stacked_bar_chart`, `stacked_area_chart`, `grouped_bar_chart`, `dumbbell_chart`, `pareto_chart`, `dual_axis_line_chart`, `bullet_chart`, `butterfly_chart`, `waterfall_chart`, `box_plot_chart`, `gantt_chart`, `bar_of_pie_chart`, `pie_of_pie_chart`, `stock_chart` | Repeated direct calculations per the [verification recipes](../../scripts/docs/svg-pipeline.md#verification-recipes) | +| `partial-calc` | `bubble_chart`, `matrix_2x2` | `calc line` for x/y-driven `cx/cy`; radius only with an explicit size scale | +| `formula-verify` | `progress_bar_chart`, `gauge_chart`, `funnel_chart`, `sunburst_chart` | Quote the formula and resulting length/angle/width in the receipt | +| `manual-verify` | `sankey_chart`, `heatmap_chart`, `treemap_chart`, `word_cloud` | Data-driven, but no layout model; inspect and report | -**Family boundary**: this table covers every canonical key in -`templates/charts/charts_index.json` exactly once. Do not put qualitative shape -composition or a Table reference in the receipt merely because it contains -shapes or numbers. Named quadrants are composed through -[`executor-structure.md`](../../references/executor-structure.md); -`chart/matrix_2x2` is reserved for plotted x/y and optional radius data. Every -embedded data chart is its own keyed §IX `Visualization` object. - -Resulting list: +**Family boundary**: this table covers every canonical `charts_index.json` key exactly once. Qualitative shape composition and Table references never enter the receipt merely because they contain shapes or numbers; named quadrants are composed through [`executor-structure.md`](../../references/executor-structure.md), and `chart/matrix_2x2` is reserved for plotted x/y data. Every embedded data chart is its own keyed §IX object. ``` P03 market-share 03_market_share.svg type=bar mode=direct-calc -P03 margin-trend 03_market_share.svg type=line mode=direct-calc -P11 share-split 11_share_split.svg type=pie mode=direct-calc P15 pareto-causes 15_pareto.svg type=pareto mode=decomposable-calc ``` -In Default, if §VII is absent, continue from §IX; this is the normal state when -all chart objects use custom structures. Do not guess from SVG content when §IX -declares no data-driven object. In Quick, marker search is only the required -cross-check, never a replacement for active authoring decisions. - -If the filtered list is empty, output `verify-charts: active profile declares no data-driven chart objects, nothing to verify` and stop. +If the list is empty, output `verify-charts: active profile declares no data-driven chart objects, nothing to verify` and stop. --- ## Step 2: Per object — read its SVG scope, calculate, compare, update -For each object in the Step 1 list: - -1. Read `<project_path>/svg_output/<page>.svg`. -2. Locate `<g id="<object-key>">` and its one plot-area marker. The marker - payload starts `chart-plot-area: object=<object-key> |` and belongs inside - `<g id="<object-key>-chartArea">`. Accept a legacy unscoped marker and - `id="chartArea"` only when the page has exactly one verified chart. A - multi-chart page may not mix scoped and unscoped markers. If a marker is - missing, derive it from that object's axes or center/radius and add the - scoped marker before continuing. -3. Read only that object's data series and label/value elements. -4. **Read axis tick labels for every axis-based chart inside the same object scope.** Locate the `<text>` elements along the value axis — X-axis labels for horizontal bars, Y-axis labels for vertical bars, and Y-axis labels for line-like charts. Extract the first and last tick values to determine the axis range (e.g. `0%` to `120%` → range `0,120`). Pass this range as `--value-range`, `--y-range`, or `--x-range` as appropriate. Use the attached `--*-range=min,max` form, which also keeps a negative minimum from being parsed as another option. Radar uses `--max-value` instead of a range: read the outermost ring's tick value and pass it as `--max-value`. If the SVG has no explicit tick labels (data labels only, no grid), omit the range and let the calculator auto-normalize — but flag the receipt as `scale=auto (no ticks)`. - - **Local vs absolute coordinates.** Many chart templates wrap chart content in `<g transform="translate(cx, cy)">` or similar, so child `<circle>`/`<polygon>`/`<rect>` coords are relative to that origin (e.g. radar polygon at `0,-198`, donut paths starting from `0,0` inside a translated `<g>`, dumbbell circles at `cy="0"` inside a per-row translated `<g>`). The calculator outputs **absolute** SVG coordinates. Before comparing, either add the wrapping translate's offset to the SVG coords or subtract it from the calculator's output — pick one direction and apply it consistently. -5. Run the matching calculator command: +1. Read `<project_path>/svg_output/<page>.svg`; locate `<g id="<object-key>">` and its one plot-area marker (`chart-plot-area: object=<object-key> | …` inside `<g id="<object-key>-chartArea">`). A legacy unscoped marker with `id="chartArea"` is accepted only when the page has exactly one verified chart; a multi-chart page never mixes scoped and unscoped markers. Derive and add a missing scoped marker from the axes or center/radius before continuing. +2. Read only that object's data series and label/value elements. +3. **Read axis tick labels for every axis-based chart** — X-axis labels for horizontal bars, Y-axis labels for vertical bars and line-like charts. The first and last tick values give the axis range; pass it as attached `--value-range=min,max` / `--y-range=…` / `--x-range=…` (the attached form also protects a negative minimum). Radar takes `--max-value` from the outermost ring. With no tick labels, omit the range, let the calculator auto-normalize, and flag the receipt `scale=auto (no ticks)`. +4. **Local vs absolute**: content inside `<g transform="translate(cx, cy)">` has relative coordinates; the calculator outputs absolute ones. Add the translate to the SVG values or subtract it from the calculator output — one direction, consistently. +5. Run the matching command (see the [calculator documentation](../../scripts/docs/svg-pipeline.md#svg_position_calculatorpy) and recipes for decomposable, partial, formula, and manual modes): ```bash - # column_chart / horizontal_bar_chart (add --horizontal for the latter) - # IMPORTANT: always pass --value-range from axis tick labels (step 4) - python3 skills/ppt-master/scripts/svg_position_calculator.py calc bar \ - --data "Label1:Value1,Label2:Value2" --area "x_min,y_min,x_max,y_max" \ - --bar-width 120 --value-range=0,axis_max - - # line_chart / area_chart / scatter_chart — area uses line output as the top boundary, then closes to y_max - python3 skills/ppt-master/scripts/svg_position_calculator.py calc line \ - --data "x1:y1,x2:y2,..." --area "x_min,y_min,x_max,y_max" --y-range=0,max - - # pie_chart — default start angle is -90 (12 o'clock); pass --start-angle only if the SVG starts elsewhere - python3 skills/ppt-master/scripts/svg_position_calculator.py calc pie \ - --data "Slice1:Value1,Slice2:Value2" --center "cx,cy" --radius 200 --start-angle -90 - - # donut_chart (pie with inner-radius) - python3 skills/ppt-master/scripts/svg_position_calculator.py calc pie \ - --data "Slice1:Value1,Slice2:Value2" --center "cx,cy" --radius 200 --inner-radius 120 --start-angle -90 - - # radar_chart (separate subcommand) — pass --max-value from the outermost ring tick - python3 skills/ppt-master/scripts/svg_position_calculator.py calc radar \ - --data "Dim1:Value1,Dim2:Value2,Dim3:Value3" --center "cx,cy" --radius 200 --max-value 100 + python3 skills/ppt-master/scripts/svg_position_calculator.py calc bar --data "L1:V1,L2:V2" --area "x_min,y_min,x_max,y_max" --bar-width 120 --value-range=0,axis_max + python3 skills/ppt-master/scripts/svg_position_calculator.py calc line --data "x1:y1,x2:y2" --area "x_min,y_min,x_max,y_max" --y-range=0,max + python3 skills/ppt-master/scripts/svg_position_calculator.py calc pie --data "S1:V1,S2:V2" --center "cx,cy" --radius 200 [--inner-radius 120] --start-angle -90 + python3 skills/ppt-master/scripts/svg_position_calculator.py calc radar --data "D1:V1,D2:V2,D3:V3" --center "cx,cy" --radius 200 --max-value 100 ``` - Area chart fill path closes to the bottom edge of the plot area: +6. **Scale-aware comparison**: before declaring a mismatch, confirm every invocation used the axis range, plot area, center/radius, start angle, or size scale the SVG visually declares — for `calc bar` the header must show `Value scale: axis ticks (...)` when the SVG has ticks; `auto (max*1.1)` means go back to step 3. Never update the SVG with mismatched-scale output. When the scale matches and coordinates genuinely differ, update by hand — no regex or bulk replacement. - ```svg - M first_x,first_y ... L last_x,last_y L last_x,y_max L first_x,y_max Z - ``` - -6. **Scale-aware comparison.** Compare calculator output against the SVG's existing coordinates. Before declaring a mismatch, verify that every calculator invocation used the same axis range, plot area, center/radius, start angle, or size scale that the SVG visually declares. For `calc bar`, the output header must show `Value scale: axis ticks (...)` when the SVG has explicit ticks; if it shows `auto (max*1.1)`, go back to step 4 and re-run with the correct `--value-range`. **Do NOT update the SVG with mismatched-scale output.** Only update SVG attributes when the scale is confirmed to match and coordinates genuinely differ. Update by hand (do NOT use regex / bulk replacement — coordinates are positional and easy to swap incorrectly). - -After updating any page, follow the active profile's checker order. Default -reruns its quality checker to confirm nothing broke: - -```bash -python3 skills/ppt-master/scripts/svg_quality_checker.py <project_path> --canonical-authoring --stage final --json -``` - -This rerun writes the current `final` report required by Step 7.3. - -Quick completes every chart comparison/repair first, then returns to -`quick-generate.md` §4 and runs its one lockless final checker. Do not insert a -checker call between Quick chart pages. - ---- - -## Stacked recipe - -`stacked_bar_chart` and `stacked_area_chart` are not single-call but reduce cleanly to repeated calls on existing primitives. The operator already had to compute cumulative values to draw the SVG — verify-charts reuses them. - -**Stacked bar** — for N stacked series on the same x categories, run `calc bar` N times. Pass each segment's **height** as the data value, and shift `--area`'s `y_max` down by the sum of all lower segments for that category. Compare each segment's `(x, y, width, height)` against the SVG. - -```bash -# Example: two-series stack at category "Q1" with bottom=30, top=20, plot area y from 100 to 500 -# Run 1 — bottom segment (origin = baseline) -python3 skills/ppt-master/scripts/svg_position_calculator.py calc bar \ - --data "Q1:30,Q2:..." --area "x_min,100,x_max,500" \ - --bar-width 80 --value-range=0,axis_max -# Run 2 — top segment (origin shifted up by bottom segment's height in pixels) -python3 skills/ppt-master/scripts/svg_position_calculator.py calc bar \ - --data "Q1:20,Q2:..." --area "x_min,100,x_max,<500 - bottom_height_px>" \ - --bar-width 80 --value-range=0,axis_max -``` - -**Stacked area** — for N stacked series, run `calc line` N times on **cumulative** y-values (series 1 raw; series 2 = series1+series2; …). Each call yields the top boundary of one band. Each band's SVG path closes to the **previous** band's top boundary (not to `y_max`). - -If a stack page's segment positions don't reduce to this recipe (e.g., negative segments, percent-stacked with non-100 totals), mark it `manual-verify` in the receipt and inspect by hand — do not silently pass. - ---- - -## Decomposable recipes - -Use these recipes for `decomposable-calc` and `partial-calc` pages. Each recipe must produce a receipt line; if a page cannot be reduced cleanly, mark `manual-verify` with the reason instead of dropping it. - -**Dumbbell chart** — for before/after or two-state values across categories. The two endpoints are **points**, not bar ends — `calc bar --horizontal` always anchors at `x_min`, which only matches the right endpoint. Use `calc line` × 2 instead, treating category index as the y axis: - -1. Number categories `0.5, 1.5, …, N-0.5` so each row's y lands on its band center; set `--y-range=0,N`. The same convention applies to vertical dumbbells with the axes swapped. -2. Set `--x-range` to the shared value-axis range read from ticks. -3. Run `calc line` once per endpoint series with identical `--area`, `--x-range`, `--y-range`. Each output `(SVG_X, SVG_Y)` is the matching endpoint circle's `(cx, cy)`. -4. Compare both endpoint circles and the connector line (`x1=cx_left, x2=cx_right, y1=y2=cy`) against the two calculated point sets. - -```bash -# Horizontal dumbbell, 3 categories, value axis 0–100, plot area (100,100)–(700,460). -# Encode category index as the y value: row 1 → 0.5, row 2 → 1.5, row 3 → 2.5. -python3 skills/ppt-master/scripts/svg_position_calculator.py calc line \ - --data "42:0.5,55:1.5,37:2.5" --area "100,100,700,460" \ - --x-range=0,100 --y-range=0,3 -python3 skills/ppt-master/scripts/svg_position_calculator.py calc line \ - --data "68:0.5,71:1.5,49:2.5" --area "100,100,700,460" \ - --x-range=0,100 --y-range=0,3 -``` - -**Pareto chart** — split into descending bars plus cumulative line: - -1. Run `calc bar` on the descending category values with the bar axis range from ticks. -2. Precompute cumulative percentages in category order. -3. Run `calc line` on `0.5:cum1,1.5:cum2,...,N-0.5:cumN` with `--x-range=0,N`, the right-side percentage axis as `--y-range` (usually `--y-range=0,100`), and the same `--area` as the bars. The `n - 0.5` offset puts each cumulative point on the matching bar's center; using `1,2,…,N` shifts the polyline left by half a bar width. -4. Compare bar rects, cumulative line path, and cumulative markers separately. - -**Dual-axis line chart** — split by axis: - -1. Read the left and right Y-axis tick ranges independently. -2. Run `calc line` once per series using its own `--y-range`; use the same `--x-range` and plot area for both. -3. Compare each series' polyline/path points against the matching axis scale. Never use the left-axis scale for the right-axis series or vice versa. - -**Bullet chart** — performance bands + actual bar + target marker, all anchored at the same `x_min`. The bands occupy the **same** y row (they stack visually by overlapping, not by category), so run `calc bar --horizontal` once **per band** with a single data point — multi-category calls would spread y across rows: - -1. Read the value-axis range from the band edges (the widest band's right edge = axis max). -2. For each band, run `calc bar --horizontal --data "<band_name>:<right_edge_value>" --area "<x_min>,<band_y>,<x_max>,<band_y+band_height>" --bar-width <band_height>`. Each call returns one rect at the shared `(x_min, band_y)` with the value-mapped width. Compare against the band rect. -3. Run `calc bar --horizontal` with a single data point for the actual value, using the actual bar's inset area (`y` and `bar-width` shrunk so the bands are visible). Compare against the actual rect. -4. The target marker is a `<line>` at `x = x_min + target/axis_max × area_width`, spanning the full band height. Compute by hand and compare. - -**Butterfly chart** — mirrored horizontal bars around a vertical center line at `cx`: - -1. Read the value-axis range and the center-line `cx` from the SVG. -2. Run `calc bar --horizontal` once per side using a plot area whose `x_min = cx` and `x_max = cx + side_width`. The right-side bars' `x` and `width` map directly. -3. For the left side, reuse the same calc output and mirror: each left bar's `x = cx - width`, `width` unchanged. Compare against the left rects. -4. Category `y` is shared across both sides — verify left and right rows align on the same `y + height/2`. - -**Grouped bar chart** — N series sharing the same x categories, side-by-side instead of stacked: - -1. Read the value-axis range and the plot area. -2. Compute the inner-group spacing: if there are `N` series and the visual group spans width `W` per category, each series-bar's width is `W/N` and its x offset within the group is `(i - 1) × W/N`. Read these from the SVG (the first category's bars give you both). -3. Run `calc bar` once per series with the **same** `--area` and `--value-range` but with each call's `--bar-width` set to the inner width. The calc's per-category center X gives the **group** center; each series-bar's actual `x = group_center - W/2 + (i-1) × W/N`. Compare against the SVG. - -**Box plot chart** — Q1/Q3 box + median line + whiskers. All five quantities are y-values on the same axis: - -1. Read the y-axis range and plot area. For each category, the five values are min / Q1 / median / Q3 / max. -2. Run `calc bar` once treating each category's box (Q3 − Q1) as a synthetic "stacked" segment with the area's `y_max` shifted to `y_axis_top - Q1 × pixels_per_unit` (the Q1 baseline). The output's `y, height` should match the box rect. -3. Median y = `y_axis_top + (axis_max - median) × pixels_per_unit`. Whisker endpoints (min, max) follow the same formula. Compare each against the SVG's `<line>` y1/y2 and `<rect>` y/height. - -**Gantt chart** — task bars where each bar's `x` and `x + width` are the start and end positions on a timeline axis: - -This remains a Chart even when the source used a physical PowerPoint table for -the row grid. A qualitative stage/lane plan whose positions are not derived -from dates or durations uses [`executor-structure.md`](../../references/executor-structure.md) -and does not enter this verification stage. - -1. Read the timeline tick positions (the header row's x coordinates per date unit). Pixels-per-unit = `(x_unit_n - x_unit_1) / (n - 1)`. -2. Run `calc line` once over `start_index:row_y` per task — output `SVG_X` gives the bar's `x`. Run it again over `end_index:row_y` — output `SVG_X` gives `x + width`. Subtract for width. -3. Compare each task rect's `(x, width)` against the calculated start and end. Row y can be read directly (categories are not value-driven). - -**Waterfall chart** — floating bars connected by running totals. Each bar's top and bottom edge correspond to two points on the same value axis (`cum_before`, `cum_after`): - -1. Read the y-axis tick range and the plot area; compute running totals in category order (start with `cum[0] = base_value`, then `cum[i] = cum[i-1] + delta[i]` for increase, `cum[i-1] - delta[i]` for decrease, reset to delta for totals). -2. Build two virtual series: `top[i] = max(cum_before, cum_after)`, `bot[i] = min(cum_before, cum_after)`. Run `calc bar` twice on these with identical `--area`, `--bar-width`, `--value-range`. The `top` run's `Y` is the bar's `y`; `height = bot.Y - top.Y` for that index. -3. Compare each waterfall rect's `(x, y, width, height)` against the calculated pair. Connector lines should run from `(x + width, top_or_bot[i].Y)` to `(x_next, top_or_bot[i+1].Y)` at the matching shared cumulative value. -4. Total bars (full-height start/end) use `bot = 0` and the calc reduces to the standard `calc bar` recipe. - -**Bubble chart / plotted 2×2 matrix** — partial calculator support: - -1. Use `calc line` to verify bubble centers (`cx/cy`) from the X/Y values and axis ticks. -2. For `matrix_2x2`, verify that the axis midpoint matches the quadrant split. If the visible axes say only Low/High, read the explicit numeric mapping from the active §IX decision or SVG comment; without one, record `xy=manual (scale missing)` instead of inventing a range. -3. Verify radius only if `design_spec.md`, the Quick active-context decision, or SVG comments declare a size scale such as `radius = sqrt(value) * k` or explicit min/max radius mapping. `spec_lock.md` carries only the primary family/key reference and is not a size-scale authority. -4. If the size scale is missing, record `radius=manual (scale missing)` and inspect relative ordering by hand. - -**Bar-of-pie / pie-of-pie** — decompose the primary and expanded views: - -1. Replace the expanded tail in the primary data with one aggregate tail value, then run `calc pie` for the main pie. -2. For `pie_of_pie_chart`, run `calc pie` again on the tail values at the secondary center/radius. For `bar_of_pie_chart`, verify each stacked detail height as `tail_value / sum(tail_values) × detail_height` and confirm the segments fill the declared detail bar without gaps or overlap. -3. Verify that the aggregate tail slice equals the sum of the expanded values and that connector endpoints touch the two declared plot regions. - -**Stock chart** — decompose each OHLC observation into four y-values: - -1. Read the shared price-axis range and ordered date positions. -2. Run `calc line` for open, high, low, and close using the same plot area and ranges. For each date, the wick spans `high_y` to `low_y`; the body spans `min(open_y, close_y)` to `max(open_y, close_y)`. -3. Verify the body color/direction against `close >= open`, and verify that every body stays within its wick. - -**Progress bar / gauge / funnel / sunburst — formula-verify** (no calc call needed): - -- Progress bar: `fill_width = value / max × track_width`. Read `value`, `max`, and `track_width` from the SVG; compute and compare against the fill rect's `width`. -- Gauge: `needle_angle = start_angle + value / max × sweep_angle`. Read `start_angle` and `sweep_angle` from the SVG's arc path (e.g. half-circle `start_angle=-180`, `sweep_angle=180`). Compare against the needle's `transform="rotate(α ...)"` value (the most common form), or against endpoint `(cx + L·cos α, cy + L·sin α)` when the needle is drawn as an explicit line/path. -- Funnel: each trapezoid's `top_width = prev.bottom_width`, `bottom_width = top_width × next_value / curr_value`. Verify by walking the segments: for segment `i`, `(top_left_x, top_right_x) → bottom_x_inset = (top_width - bottom_width) / 2`. The first segment's top width comes from the design's outer frame. -- Sunburst: for each ring, `circumference = 2πr` and each node's arc length is `node_value / root_total × circumference`; offsets follow cumulative sibling values plus any explicitly declared separator gap. Verify that child arcs remain inside their parent span and that sibling values sum to the parent. -- Receipt should quote the formula and resulting value (e.g. `formula=value/max×track_width=0.92×700=644px`, or `formula=600×850/1000=510 bottom width`). - -**Sankey / heatmap / treemap / word cloud — manual verification:** - -- Sankey: no layout model for node stacking, link routing, or flow-width normalization. Verify that link widths are proportional to flow values and that node-side totals match (in = out). -- Heatmap: cell positions are a fixed grid (not value-driven); the value-to-color binning is what's data-driven. Verify that the color of each cell falls in the bin matching the cell's number, and that high/low extremes use the legend's high/low colors. -- Treemap: rectangle areas reflect value proportions but the recursive squarify layout has no calculator equivalent. Verify each rect's `width × height ≈ total_area × value / sum(values)` for top-level cells, and that nested cells sum to their parent. -- Word cloud: verify that keyword font sizes are monotonic with their declared weights (or match the declared weight bins), then inspect the final text bounds for overlap and clipping. Position is layout-driven; do not invent a coordinate formula. +After updating any page, follow the profile's checker order. Default reruns `svg_quality_checker.py <project_path> --canonical-authoring --stage final --json`, which writes the current `final` report Step 7.3 requires. Quick completes every chart comparison/repair first, then returns to `quick-generate.md` §4 for its one lockless final checker — no checker call between chart pages. --- ## Step 3: Per-object receipt -Output one line per chart object from the Step 1 list. Include its semantic key; -receipt count MUST equal Step 1 -list length — that is the gate-closing evidence. Quick does not persist these -lines as a generation plan or resume record. +One line per Step 1 object, including its semantic key; receipt count MUST equal the list length — that is the gate-closing evidence. Quick does not persist these lines. ``` verify-charts: 03_market_share.svg | object=market-share | type=bar | mode=direct-calc | scale=0-100 (from ticks) | calc=ran | svg=updated -verify-charts: 03_market_share.svg | object=margin-trend | type=line | mode=direct-calc | scale=0-120 (from ticks) | calc=ran | svg=unchanged verify-charts: 11_share_split.svg | object=share-split | type=pie | mode=direct-calc | scale=N/A | calc=ran | svg=updated | marker=added verify-charts: 14_revenue_mix.svg | object=revenue-mix | type=stacked-bar | mode=decomposable-calc | scale=0-200 (from ticks) | calc=ran×3 | svg=updated verify-charts: 18_market_bubbles.svg | object=market-bubbles | type=bubble | mode=partial-calc | xy=ran | radius=manual (scale missing) | svg=unchanged @@ -311,7 +84,4 @@ verify-charts: 19_flow.svg | object=flow | type=sankey | mode=manual-verify | li ## After verification -Default continues with [`generate-pptx`](../generate-pptx.md) Step 7. Quick -returns to [`quick-generate`](../profiles/quick-generate.md) §4 for its one final -checker and direct export. Those authorities own the remaining serial commands, -gates, and success criteria. +Default continues with [`generate-pptx`](../generate-pptx.md) Step 7; Quick returns to [`quick-generate`](../profiles/quick-generate.md) §4 for its final checker and direct export. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/stages/visual-review.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/stages/visual-review.md index 6ccac964..8b4f96bb 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/stages/visual-review.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/stages/visual-review.md @@ -4,51 +4,24 @@ description: Optional quality-gate stage for per-page rubric-based visual review # Visual Review Stage -> Optional Generate-PPTX quality stage. Goal: reduce human iteration by letting AI subagents visually self-check each rendered slide against a fixed rubric and apply atomic position/spacing fixes. -> -> Reads `<project>/svg_output/<page>.svg` and a pre-rendered PNG of each slide, then either applies a fix or flags `needs_human`. When an installed Style exists, it also reads that workspace's `Review Focus` as supplemental acceptance context. **Never touches** brand decisions, layout structure, or other files. -> -> This stage is **context-independent** — invokable in a fresh chat session with only `<project_path>` as input. No upstream conversation context required. - -## Positioning - -This is an **optional auxiliary loop**, opt-in only. The [`generate-pptx`](../generate-pptx.md) Step 1–7 pipeline does not invoke it; trigger only when the user explicitly asks for a visual re-pass on the generated SVGs before export. - -**Token cost**: each batch subagent re-reads the rubric + `design_spec.md` + `spec_lock.md` + the short Style Review Focus when present, and processes K SVG+PNG pairs. For a 20-page deck with K=5, expect on the order of 100–150K additional input tokens on top of the main generation run. +> Optional, opt-in Generate-PPTX quality stage: AI subagents visually self-check each rendered slide against the fixed rubric in [`references/visual-review.md`](../../references/visual-review.md) and apply atomic position/spacing fixes or flag `needs_human`. When an installed Style exists, its `Review Focus` is supplemental acceptance context. Never touches brand decisions, layout structure, or other files. Context-independent — invokable in a fresh chat with only `<project_path>`. ## When to Run -- Executor ([`generate-pptx`](../generate-pptx.md) Step 6) has finished all pages -- `svg_quality_checker.py` has passed -- Post-processing (`finalize_svg.py`, `svg_to_pptx.py`) has **not** yet run -- The user has explicitly requested visual review +Only when the user explicitly requests visual review — never auto-invoked from model capability or deck size — after Executor has finished all pages and `svg_quality_checker.py` has passed, before `finalize_svg.py` / `svg_to_pptx.py`. Run [`verify-charts`](./verify-charts.md) first for decks with data charts; this stage covers rhythm, collision, and alignment, not coordinate math. Do not run when `svg_output/` is incomplete, the static checker has not passed, or the user is already in a `live-preview` annotation loop. -For decks containing data charts, run [`verify-charts`](./verify-charts.md) first — visual-review focuses on visual rhythm / collision / alignment, not chart coordinate math. - -## When NOT to Run - -- The project has no `svg_output/<page>.svg` files yet — finish Executor first -- `svg_quality_checker.py` has not been run or has failed — fix static violations first -- User has already applied annotations via the `live-preview` stage and is in a fixed-edit loop — describe changes directly, do not re-trigger rubric -- The user has not asked for it — do not auto-invoke based on inferred model capability or deck size +**Token cost**: each batch subagent re-reads the rubric + `design_spec.md` + `spec_lock.md` (+ Style Review Focus) and processes K SVG+PNG pairs — on the order of 100–150K additional input tokens for a 20-page deck at K=5. --- ## Prerequisites ```bash -# 1. playwright + chromium installed (the PNG renderer) -pip install playwright -python3 -m playwright install chromium - -# 2. live-preview server running for this project (provides inlined SVG fetch) -python3 skills/ppt-master/scripts/svg_editor/server.py <project_path> --no-browser -# (single instance per project — if it's already running, skip) +pip install playwright && python3 -m playwright install chromium # PNG renderer +python3 skills/ppt-master/scripts/svg_editor/server.py <project_path> --no-browser # live-preview server (skip if already running) ``` -The renderer (`visual_review.py`) does **not** auto-start the live-preview server. Without `--server-url`, it discovers the actual port from the target project's `live_preview/lock.json`; an explicit `--server-url` overrides discovery. In either case it validates `/api/health` against the resolved target project before rendering and rejects a server for another project. - -> **Why playwright, not cairosvg**: cairo's text API has no font-fallback chain, so CJK characters render as tofu boxes for any deck whose font-family list relies on system fallback (Microsoft YaHei / PingFang SC / etc.). Playwright drives a real chromium and produces output identical to what the live-preview browser shows — the only fidelity-preserving option for bilingual decks. +The renderer does not auto-start the server; it discovers the port from `live_preview/lock.json` (or an explicit `--server-url`) and validates `/api/health` against the target project. Playwright, not cairosvg, because cairo has no font-fallback chain and renders CJK as tofu; chromium output matches the live-preview browser. --- @@ -58,121 +31,48 @@ The renderer (`visual_review.py`) does **not** auto-start the live-preview serve python3 skills/ppt-master/scripts/visual_review.py <project_path> ``` -This writes one PNG per page to `<project_path>/.preview/<page>.png`, sized from that SVG root's `viewBox`, with `<use data-icon>` inlined and `<image href>` resolved exactly as the live-preview browser sees them. Each successful page record in the JSON summary includes the exact canvas plus its raster dimensions. Renders are serialized via a project-local file lock — safe to invoke concurrently. +Writes one PNG per page to `<project_path>/.preview/<page>.png`, sized from the root `viewBox` with icons inlined and images resolved; each successful record carries the exact canvas and raster dimensions (contract and exit codes in [`svg-pipeline.md`](../../scripts/docs/svg-pipeline.md#visual_reviewpy)). -Exit codes: - -- `0` — all pages rendered -- `2` — live-preview server unreachable or serving a different project (start the target project's server per Prerequisites) -- `3` — playwright python / chromium not installed (or browser failed to launch) -- `4` — one or more page-level render failures (see stderr; partial output is on disk) - -If any page comes back with `"all_background": true` in the JSON summary, that page rendered to a blank surface — investigate before continuing (broken `<use>` reference, missing image asset, etc.). - -**Mandatory — normalize partial renders before dispatch**: parse the renderer -summary before Step 2. Dispatch only records with `"ok": true`, -`"all_background": false`, and a complete `canvas` object. For every other page, -the main agent adds a `render_failed` row directly to the aggregate with the -renderer error or blank-surface reason; no per-page `.review/<page>.json` is -expected until that page renders successfully. Exit `2` or `3` stops dispatch -entirely. Exit `4` may still review the successful subset, but the stage cannot -finish cleanly until every failed page is retried or handed off per Step 4. +**Mandatory — normalize partial renders before dispatch**: dispatch only records with `"ok": true`, `"all_background": false`, and a complete `canvas`. For every other page the main agent adds a `render_failed` row to the aggregate with the renderer error or blank-surface reason (a blank surface usually means a broken `<use>` reference or missing image asset). Exit `2` or `3` stops dispatch; exit `4` may review the successful subset, but the stage cannot finish until every failed page is retried or handed off per Step 4. --- ## Step 2 — Spawn the review team -Create a team and dispatch one orchestrator agent. The orchestrator partitions the N pages into batches of ≤ K pages (default **K = 5**) and spawns one subagent per batch **in parallel** (single message, `ceil(N/K)` parallel `Agent` calls). Each batch subagent reads the fixed inputs (rubric + `design_spec.md` + `spec_lock.md` + conditional Style Review Focus) **once**, then iterates over its assigned pages sequentially. - -Before dispatch, look for `<project>/templates/design_spec.style.*.md`. For each one found, read only its `## VII. Review Focus` once and include those checks in every batch prompt. Otherwise pass no Style supplement. This lookup never triggers visual review; it runs only after the user has already activated this stage. The supplement cannot weaken the fixed rubric or widen edit permissions. +Before dispatch, look for `<project>/templates/design_spec.style.*.md`; for each, read only its `## VII. Review Focus` once and include those checks in every batch prompt — this lookup never triggers the stage and cannot weaken the rubric or widen edit permissions. ```text TeamCreate(team_name="visual-review-<project>", agent_type="orchestrator") -Agent( - team_name="visual-review-<project>", - subagent_type="general-purpose", - name="orchestrator", - prompt=<orchestrator-prompt>, -) +Agent(team_name="visual-review-<project>", subagent_type="general-purpose", name="orchestrator", prompt=<orchestrator-prompt>) ``` -The orchestrator prompt must be self-contained and is the **single** place where dispatch shape, batch size, and forbid lists are stated — the rubric (`references/visual-review.md`) defines the contract those prompts must satisfy. Required fields (all absolute paths): +The orchestrator partitions N pages into batches of ≤ K (default 5) and spawns one subagent per batch in parallel; each subagent reads the fixed inputs once, then iterates its pages. The orchestrator prompt is self-contained and the single place stating dispatch shape, batch size, and forbid lists; it carries (absolute paths): `<project_path>`; the full page list with `page_role` and each successful renderer record's `canvas` (parse `design_spec.md` §IX — **fixed compatibility default**: a `design_spec.md` without §IX uses `content` for every page and flags it in the report; a missing `design_spec.md` is restored through [`failure-recovery.md`](../governance/failure-recovery.md) §3 first); batch size K (10 for token-sensitive large decks, 3 for high-fidelity short decks — rubric §6.1); iteration budget (default 1; 2 only for final-cut runs — see the appendix); the rubric path; the Style Review Focus excerpt with its wording and source path when found; the dispatch contract reference (rubric §6); and the subagent forbid list (no edits to other pages, `design_spec.md`, `spec_lock.md`, `templates/`, `animations.json`, `image_prompts.json`, `images/`). -- `<project_path>` — project root -- Full page list with `page_role` and the successful renderer record's `canvas` per page (parse `<project>/design_spec.md` §IX outline; **fixed compatibility default**: if an existing `design_spec.md` lacks §IX, use `content` for every page and flag this in the final report; if `design_spec.md` itself is missing, restore it through [`failure-recovery.md`](../governance/failure-recovery.md) §3 before dispatch). Pass `canvas` through verbatim; do not assume a fixed slide size. -- Batch size `K` (default 5; raise to 10 for token-sensitive runs on large decks, lower to 3 for high-fidelity short decks — see rubric §6.1) -- Iteration budget per page (default 1; 2 only for high-stakes / final-cut runs — see [Appendix: Iteration loop](#appendix-iteration-loop-opt-in)) -- Path to the rubric: `skills/ppt-master/references/visual-review.md` -- Style Review Focus excerpt, only when the conditional lookup above found one; preserve its wording and source path -- Dispatch contract reference: rubric [§6](../../references/visual-review.md#6-dispatch--messaging-contract) (batched parallel spawn, self-contained prompts, mandatory `SendMessage` on idle, anonymous-name tolerance) -- Subagent forbid list: do not edit any other page, `design_spec.md`, `spec_lock.md`, anything under `templates/`, `animations.json`, `image_prompts.json`, or `images/` - -**Host compatibility**: `TeamCreate` and `SendMessage` are Claude-Code-specific multi-agent primitives. On hosts without those primitives (Cursor, VS Code + Copilot, Codebuddy, etc.) the main agent processes batches sequentially — same partitioning, same per-batch prompts, no parallel dispatch. Token savings from shared fixed inputs still apply; wall-clock time grows roughly N/K-fold. +**Host compatibility**: `TeamCreate` and `SendMessage` are Claude-Code primitives; on other hosts the main agent processes the same batches sequentially with the same prompts — token savings persist, wall-clock grows roughly N/K-fold. --- ## Step 3 — Aggregate findings -The orchestrator emits the aggregate Markdown table back to you (the main agent): - -``` -| page | role | status | hard_hits | soft_hits | fixes_applied | needs_human_reason | -|------|------|--------|-----------|-----------|---------------|---------------------| -``` - -Statuses: - -- `ok` — page passed clean, no fixes applied -- `fixed` — at least one fix applied, all Hard rules now pass -- `needs_human` — fix attempted but rolled back (rule §4.2), or rule violation requires brand/structure decision outside the rubric's scope -- `render_failed` — Iteration 0 PNG sanity failed (rare; usually means renderer / server issue) -- `prereq_failed` — static checker hadn't been run - -Plus a brand-token aggregate at `<project>/.review/brand_review.json` if any §1.1 escalations occurred — review this once at the end of the run, not per page. +The orchestrator returns `| page | role | status | hard_hits | soft_hits | fixes_applied | needs_human_reason |`, where `ok` = clean, `fixed` = fixes applied and Hard rules pass, `needs_human` = a fix was rolled back (rubric §4.2) or the violation needs a brand/structure decision, `render_failed` = iteration-0 sanity failed, `prereq_failed` = static checker not run — plus `<project>/.review/brand_review.json` when §1.1 escalations occurred, reviewed once at the end. --- ## Step 4 — Decide next move -For each row in the table: - -- `ok` / `fixed` — no action; the SVG has been updated in-place (originals are at `<project>/.review/backup/<page>.iter<N>.svg`) -- `needs_human` — read the page's JSON `needs_human_items[].suggested_fix_summary`, decide with the user whether to apply or defer -- `render_failed` — re-run `visual_review.py` for that page only (`--pages <token>`); if it persists, hand off to manual review -- `prereq_failed` — go back and run `svg_quality_checker.py` - -If `brand_review.json` is non-empty, that's a single decision applied across the deck (e.g., bump footer text color from `#6E7681` to `#8B949E` — one change, every page benefits). Do this once, then optionally re-run visual-review for the affected pages only. - -After the table is clean, continue to [`generate-pptx`](../generate-pptx.md) -Step 7. That authority owns the serial commands, gates, and success criteria for -post-processing and export. +`ok` / `fixed` — nothing to do; the SVG was updated in place with originals at `<project>/.review/backup/<page>.iter<N>.svg`. `needs_human` — read `needs_human_items[].suggested_fix_summary` and decide with the user. `render_failed` — re-run `visual_review.py --pages <token>`; if it persists, hand off to manual review. `prereq_failed` — run `svg_quality_checker.py`. A non-empty `brand_review.json` is one deck-wide decision (e.g. bump a footer token deck-wide); apply it once, then optionally re-review the affected pages. When the table is clean, continue to [`generate-pptx`](../generate-pptx.md) Step 7. --- ## Notes & invariants -- **Single source of truth for rules**: [`references/visual-review.md`](../../references/visual-review.md). This stage file is just the orchestration — never restate or paraphrase rules here. -- **Concurrency**: `visual_review.py` serializes renders via `<project>/.preview/.render.lock`. Subagents must never call the renderer directly without the lock. -- **Iteration budget**: default 1 iteration. Bumping to 2 doubles render cost and roughly triples token cost. Only worth it for high-stakes / final-cut decks. -- **Don't-touch (rubric §3)** is hard-enforced by subagents. If you want the subagent to e.g. change a brand color, that is **out of scope** — make the change manually first, then re-render & re-review. -- **Backups**: every modified SVG has a `.review/backup/<page>.iter<N>.svg` rollback anchor. Restore by `cp`. -- **The rubric is not the designer**: it catches collisions, drift, and rhythm errors — it does not improve a fundamentally weak layout. If 80%+ of pages come back `needs_human`, the Design Spec's pattern selection or Executor's realization geometry is the root cause, not this stage. -- **Playwright output discipline**: when an agent uses the playwright MCP tool `browser_take_screenshot` directly (outside the `visual_review.py` script), the `filename` parameter is resolved against the CWD (typically the repo root) — passing a bare relative path will create stray directories inside the repository. Always pass an absolute path: - - One-off probe / ad-hoc inspection → `/tmp/probe-<topic>-<n>.png` - - Project artifact (replaces what the script would have produced) → `<project_path>/.preview/<page>.png` (absolute) - - Never write to `<repo>/<anything>.png` or `<repo>/<some_dir>/...` — those are caught by `.gitignore` patterns but the cleanup burden is real - - The `visual_review.py` script handles output paths correctly on its own; this rule only applies to direct playwright MCP usage during interactive exploration or recovery. +- The rubric is the single source of rules; this file is orchestration only and never restates them. +- Don't-touch (rubric §3) is hard-enforced: a brand color change is out of scope — make it manually, then re-render and re-review. +- The rubric catches collisions, drift, and rhythm errors, not a fundamentally weak layout; if 80%+ of pages come back `needs_human`, the root cause is the Design Spec's pattern selection or Executor geometry. +- Direct playwright MCP `browser_take_screenshot` resolves `filename` against the CWD (usually the repo root): always pass an absolute path — `/tmp/probe-<topic>-<n>.png` for ad-hoc probes, `<project_path>/.preview/<page>.png` for project artifacts; never write under the repository. `visual_review.py` handles its own paths. --- ## Appendix: Iteration loop (opt-in) -Default behavior is single-iteration review: one scan, fix in place, write the report. The full iteration loop in [`references/visual-review.md`](../../references/visual-review.md) §4.1 supports: - -1. Iteration 1: scan + fix -2. Re-render via `visual_review.py --pages <token>` -3. Iteration 2: re-verify changed elements + scan for new Hard hits -4. Rollback on any new Hard hit introduced by a fix - -To enable, set iteration budget = 2 in the orchestrator prompt (this is a prompt-level instruction to subagents; neither `visual_review.py` nor the harness enforces it). Each added iteration roughly doubles render cost and triples token cost on the affected pages — reserve for final-cut runs only. +Default is one iteration. With budget 2 in the orchestrator prompt (a prompt-level instruction; neither the script nor the harness enforces it): iteration 1 scan + fix → re-render via `visual_review.py --pages <token>` → iteration 2 re-verify changed elements and scan for new Hard hits, rolling back any fix that introduced one (rubric §4.1–§4.2). Each added iteration roughly doubles render cost and triples token cost; reserve for final-cut runs. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/stages/web-image-review.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/stages/web-image-review.md index de9a6616..f00261f6 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/stages/web-image-review.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/stages/web-image-review.md @@ -4,71 +4,45 @@ description: Conditional isolated multimodal review of bounded web-image thumbna # Web Image Review Stage -> Supporting Generate stage for choosing from thumbnail pages already prepared -> by the web-image acquisition path. It reviews pixels only: it never searches, -> downloads, changes the locked image intent, or writes project artifacts. +> Supporting Generate stage for choosing from thumbnail pages already prepared by the web-image acquisition path. It reviews pixels only: it never searches, downloads, changes the locked image intent, or writes project artifacts. ## When to Run +After `--save-candidates` has produced `Needs-Selection` rows and before any `--promote` command. + | Review capability | Action | |---|---| -| An isolated worker can inspect the declared local images | Dispatch exactly one reviewer for all pending sheets in the current acquisition batch | +| An isolated worker can inspect the declared local images | Dispatch exactly one reviewer for all pending sheets in the current batch; reuse it for later candidate pages of the same run when the host supports follow-up messages — never one reviewer per row | | Only the active image owner can inspect images | Read this stage and review the same batch locally | -| No available context can inspect images | Skip this stage and use the strict metadata-only acquisition path | - -Run after `--save-candidates` has produced `Needs-Selection` rows and before any -`--promote` command. When the host supports follow-up messages, reuse the same -reviewer for later candidate pages in that acquisition run; never dispatch one -reviewer per resource row. +| No available context can inspect images | Skip; use the strict metadata-only acquisition path | --- ## Execution Context -**Default — isolate thumbnail pixels when available**: The active image owner -retains query, search, pagination, promotion, status, and provenance ownership. -Supply the reviewer only this stage's absolute path and these per-row records: - -| Input | Required value | -|---|---| -| Row identity | Resource filename or stable batch-row identifier | -| Acceptance intent | Exact locked `Reference` and `Crop Policy` | -| Candidate state | Current page, `has_more_candidates`, and `next_candidate_page` when present | -| Local evidence | Absolute `review_sheet.jpg` and `candidates.json` paths | - -The isolated reviewer reads this file completely, then inspects only the -declared sidecars and review images. It does not read `image-base.md`, -`image-searcher.md`, the Design Spec, the lock, or source files. It runs no -network request, command, or project write. If any declared path is unreadable -or image inspection is unavailable, return `blocked` with the exact reason. +The active image owner keeps query, search, pagination, promotion, status, and provenance ownership and supplies the reviewer only this stage's absolute path plus, per row: the resource filename or stable row identifier; the exact locked `Reference` and `Crop Policy`; current page, `has_more_candidates`, and `next_candidate_page`; absolute `review_sheet.jpg` and `candidates.json` paths. The reviewer reads this file completely, inspects only the declared sidecars and images, reads no other project or prompt files, runs no network request, command, or write, and returns `blocked` with the exact reason when a path is unreadable or image inspection is unavailable. --- ## Review Contract -Apply the gates in order for every row: - | Order | Gate | |---:|---| -| 1 | Reject a candidate unless its `license_tier` is `no-attribution` or `attribution-required`; also reject unreadable previews or known dimensions that cannot serve the planned placement | -| 2 | Confirm the exact subject or identity; `visual-verification-required` passes only when the pixels establish the missing identity evidence | +| 1 | Reject unless `license_tier` is `no-attribution` or `attribution-required`; reject unreadable previews or known dimensions that cannot serve the placement | +| 2 | Confirm the exact subject or identity; `visual-verification-required` passes only when the pixels establish the missing evidence | | 3 | Check orientation, focal placement, crop safety, and usable quiet region against the locked intent | | 4 | Check the requested view, action, and mood | | 5 | Among passing candidates, prefer lower expected crop loss and higher usable resolution, then no-attribution | -**Mandatory — bounded detail inspection**: Triage with `review_sheet.jpg`. -Open an individual `review/candidate_NN.jpg` only when exact identity or a fine -detail cannot be resolved from the sheet; never bulk-open every candidate. +**Mandatory — bounded detail inspection**: triage with `review_sheet.jpg`; open an individual `review/candidate_NN.jpg` only when exact identity or a fine detail cannot be resolved from the sheet, never bulk-open every candidate. -**Hard rule — no least-bad promotion**: Select only a candidate that passes all -applicable gates. When none passes, return `no-pass`; do not weaken the locked -Reference or Crop Policy. +**Hard rule — no least-bad promotion**: select only a candidate that passes every gate; otherwise return `no-pass` without weakening the locked Reference or Crop Policy. --- ## Receipt and Hand-off -Return one compact table and no embedded images: +Return one compact table, no embedded images, under 200 words: ```markdown | row | decision | candidate | reason | next | @@ -76,12 +50,4 @@ Return one compact table and no embedded images: | <id> | selected / no-pass / blocked | candidate_NN.jpg / — | <short evidence> | promote / next-page / pool-exhausted / repair-input | ``` -For `selected`, name exactly one candidate from that row's current page. For -`no-pass`, use `next-page` when `has_more_candidates` is true; otherwise use -`pool-exhausted`. Keep the entire chat receipt under 200 words. - -The active image owner validates every selected filename against -`candidates.json`, runs `--promote`, and verifies the downloaded original's -readable dimensions and provenance. A no-pass row advances to the next ranked -page before query replacement. An invalid receipt returns to the same reviewer -for correction; it never authorizes an arbitrary promotion. +`selected` names exactly one candidate from the row's current page; `no-pass` uses `next-page` when `has_more_candidates` is true, otherwise `pool-exhausted`. The image owner validates every selected filename against `candidates.json`, runs `--promote`, and verifies the downloaded original's dimensions and provenance; a no-pass row advances to the next ranked page before query replacement; an invalid receipt returns to the same reviewer and never authorizes an arbitrary promotion. diff --git a/plugins/codex/plugins/shadcn/THIRD_PARTY_SOURCE.json b/plugins/codex/plugins/shadcn/THIRD_PARTY_SOURCE.json index 07dd4076..40aa1b15 100644 --- a/plugins/codex/plugins/shadcn/THIRD_PARTY_SOURCE.json +++ b/plugins/codex/plugins/shadcn/THIRD_PARTY_SOURCE.json @@ -2,8 +2,8 @@ "sourceId": "shadcn", "repo": "https://github.com/shadcn-ui/ui.git", "ref": "main", - "commit": "683a5a9b370acdb7785a0529434e6a3b8c7e0441", + "commit": "b4a618b97e35f5dadf3a00d51f410c84a2567d4d", "adapter": "claude-skill", "sourcePath": "skills/shadcn", - "syncedAt": "2026-08-26T16:00:00Z" + "syncedAt": "2026-08-30T16:00:00Z" }