PPT Master produces a high-quality editable PowerPoint draft, not a sealed final deck. The workflow reasons about the message, designs the pages, and authors or preserves native PowerPoint objects under an explicit route contract. The user reviews the direction and owns the final-mile judgment in PowerPoint. Remaining work should be refinement of a real deck, not reconstruction from slide images or a thin editable skin.
The workflow supplies presentation-specific reasoning, state, contracts, and quality gates; deterministic tools handle conversion, validation, packaging, and repeatable file operations. The selected model still sets the quality ceiling, while the user's taste and judgment guide review and finishing.
PPT Master does not aim to convert arbitrary SVG into PPTX. svg_output/ uses a project-canonical SVG intermediate language: it borrows SVG's XML syntax and two-dimensional graphics model, while the project contract closes the allowed elements, attributes, units, metadata, structural contracts, and DrawingML mappings. The direction is intentional: SVG adapts to PPT Master; PPT Master does not expand to follow the entire SVG standard.
The intermediate language distinguishes three input states:
| State | Definition | Handling |
|---|---|---|
| Canonical authoring input | The single recommended expression generated by prompts, templates, and examples | Validate and compile through registered mappings without alias warnings |
| Compatible input | An explicitly documented historical or manual spelling with one safe, deterministic normalization | The checker emits a non-blocking warning; the converter normalizes it without feeding the alias back into prompts |
| Invalid or unsupported input | An expression with no mapping, ambiguous meaning, a broken structural contract, or a risk of invalid DrawingML/PPTX | The checker reports an error and blocks the standard flow; the converter fails when its own preflight or package validation encounters the same invalid condition |
For example, project typography uses SVG px semantics, with finite unitless values such as font-size="24" as the canonical spelling. Another unit remains compatible input only when the converter has a deterministic normalization and the checker accepts it as compatible; it must not become a new generated spelling. Compatible reads are a controlled migration boundary, not permission to widen the authoring language.
The three layers have separate responsibilities and cannot substitute for one another:
| Layer | Single responsibility | Explicit non-responsibility |
|---|---|---|
| Prompts, templates, and examples | State the project-canonical spelling precisely and reduce drift and warnings at the source | They are not a correctness or safety boundary |
svg_quality_checker.py |
Enforce the project contract on authoring state; errors block and non-blocking warnings pass | It does not silently rewrite pages or guess design intent |
svg_to_pptx.py |
Defensively validate compiler mappings and the package, normalize supported compatible forms, and link the upstream SVG quality report into postflight | It does not rerun the complete svg_quality_checker.py or treat file creation as proof that the upstream quality gate passed |
The diagram below covers the default Generate PPTX lifecycle, including its
beautify-pptx profile. The explicit quick-generate profile stays inside the
same route but bypasses its separate planning/confirmation, first-page gate,
and preview finalization. Source understanding and resource preparation still
run as needed; one lockless final quality gate remains mandatory.
Create Template has its own workspace lifecycle, while Fill Native PPTX and
Enhance Native PPTX operate directly on OOXML; the route table later in this
document covers all four.
User Input (PDF/DOCX/XLSX/PPTX/URL/Markdown/topic text)
↓
[Source Processing & Factual Sufficiency] → source_to_md.py dispatches by type; topic-only or planning-critical factual gaps enter topic-research
└── Raw or converted content is ready; research writes supplemental Markdown and fact provenance for project import
↓
[Create Project] → project_manager.py init <project_name> --format <format>
↓
[Archive Sources & Project Analysis (when source files exist; conversation text skips)] → project_manager.py import-sources <project_path> <sources...>
├── First move/copy supplied files into sources/ under the ownership boundary
├── Then run intake on each archived PPTX and write analysis/<stem>.identity.json, <stem>.slide_library.json, source_profile.json
├── If canonical same-stem Markdown is absent, run ppt_to_md.py against that archived PPTX
└── Content-type files in sources/ become the content contract
↓
[Template / Brand / Layout (optional)] — default: skip, proceed with free design
Trigger only on an explicit current-contract Brand/Layout/Deck workspace-root path: either a global-library entry root or a project workspace root
Raw PPTX template requests route to template-fill; reusable SVG templates are created by create-template first
↓
[Strategist] - three-stage Strategist confirmation stage & Design Specifications → design_spec.md + spec_lock.md
↓
[Image Acquisition] (when any resource row needs AI generation, web search, or slicing)
↓
[Executor]
├── Live preview starts and stays available during generation
├── Generate P01 → svg_quality_checker.py --stage first-page --json
├── Use P01 as a method sample to classify the complete issue set; fix every blocking error and selected advisory warnings
├── Generate P02 through the final page continuously → svg_output/ (no checker calls in between)
├── [Quality Check] svg_quality_checker.py --stage final --json (mandatory — 0 errors; warnings are non-blocking)
└── [Speaker notes, conditional] effective Speaker Notes outcome enabled → complete notes/total.md
↓
[Chart calibration (conditional)] → verify-charts stage (required for decks containing data charts)
↓
[Visual self-check (optional, opt-in)] → visual-review stage (only when the user explicitly requests it)
↓
[Post-processing] → [total_md_split.py when notes are enabled] → finalize_svg.py → svg_to_pptx.py (defensive validation, then compilation; --no-notes when disabled)
↓
Output:
svg_final/
└── *.svg ← Mandatory derived visual previews; attempt to inline supported images, with EMF/WMF external-reference exceptions
exports/
├── <project_name>_<timestamp>.pptx ← Default native-shape output (DrawingML)
├── <project_name>_<timestamp>_native_charts_tables.pptx ← Explicit --native-charts-and-tables variant
└── <project_name>_<timestamp>_narrated.pptx ← --recorded-narration or --narration-audio-dir variant
validation/
├── svg_quality_report.json ← Blocking/introduced/inherited/source-import SVG findings
└── <output_stem>.report.json ← Postflight package/resource audit linked to the final SVG quality report
# Default-flow mode (no -o) creates the backup directory, then attempts a best-effort source copy
backup/<timestamp>/
└── svg_output/ ← A successful copy can rebuild the PPTX from frozen authored SVG
The explicit shortcut removes the separate planning and confirmation phase, not the inputs or resources needed to build the deck:
Source material or topic
-> convert/read sources and research identified factual gaps as needed
-> decide content, page structure, visual system, and resources in active context
-> prepare required images/icons/formulas and resource manifests
-> hand-author svg_output/ under the shared SVG standards
-> svg_quality_checker.py --quick-generate --stage final --json
-> svg_to_pptx.py --quick-generate
-> exports/<name>_<timestamp>.pptx
These decisions are made automatically by the current agent without Strategist,
Confirm UI, design_spec.md, or spec_lock.md.
In the default flow, without an explicit -o, the native-object and narration
flags may combine into
<project_name>_<timestamp>_native_charts_tables_narrated.pptx; explicit -o
preserves the caller-supplied filename. Quick generation accepts the same
optional native-object and narration flags.
For every workflow that authors or redesigns visual slides through SVG, svg_output/ is the complete page-design authority, but SVG here means project-canonical SVG accepted by the project contract—not any SVG a browser can render. Every visible text, image, shape, diagram, chart/table fallback, background, and template-derived layout element that should appear on a slide must already exist in that page SVG or be explicitly referenced by it. In the default pipeline, templates, design_spec.md, and spec_lock.md guide SVG authoring; quick-generate instead uses active-context decisions and explicit SVG values. The exporter never uses planning inputs as a second visual layer that fills in missing page content.
Minimal semantic markers do not weaken that closure. Free-design, brand-only, quick-generate, and template_reuse_scope: style pages use flat Slide-local ownership: every represented object stays on the Slide and no Master/Layout identity, layer, or placeholder metadata is authored. Default export materializes one clean project-owned Master plus one Blank Layout from the current color/typography lock; lockless quick-generate uses converter-default theme scaffolding. Neither promotes Slide content. Only template_reuse_scope: mirror|layout uses the structured route, where every new page declares its Master/Layout identity from the first SVG draft. Fixed Master/Layout visuals are direct atomic root children, while reusable content slots are top-level groups with explicit design-zone bounds and one compatible carrier; composite object regions use an explicit proxy fallback, and zero-slot Layouts are valid. data-pptx-role is reserved for the few structural page-frame objects whose package or animation behavior is not already expressed by specialized metadata. A semantic-legacy template package is not upgraded in place or accepted as a structured Step 3 input: create a new workspace through create-template, using a native PPTX's still-present package facts or an old SVG's visuals only as reference, then author new pages through the AI-derived application route. A flat project is intentionally unmapped, not legacy. Export never infers, repairs, or migrates Master/Layout structure or placeholders.
| Domain | Authority |
|---|---|
| Visible page content and layout on SVG-authoring routes | Final page SVG in svg_output/ |
| Project-canonical SVG syntax, compatible forms, and mapping boundary | The split authority set selected through references/shared-standards.md |
| Master/Layout/Slide packaging and native-object mapping | SVG-to-PPTX translation; it may reorganize represented content but does not invent visible content |
| Animations, transitions, speaker notes, and narration | Dedicated sidecars/assets and PPTX package post-processing |
| Direct native-PPTX editing | The selected native workflow's PPTX/OOXML contract |
This is a page-design closure rule, not a claim that SVG describes the entire PPTX package. Rebuilding the visible slide from its completed SVG is the relevant invariant; reconstructing notes, audio, timing, relationships, or direct native edits from SVG alone is not.
svg_final/ does not change that boundary. In the default pipeline, Step 7 derives visual previews from svg_output/: supported bitmap/SVG resources are inlined when processing succeeds, while EMF/WMF stay external for native passthrough; unresolved ordinary images retain their original references, and the current finalizer counts those processing errors without failing the whole run. These files support IDE/browser inspection and manual insertion as SVG pictures. They are not a second PPTX export route and carry no PowerPoint Convert-to-Shape compatibility contract. Editable shapes come only from the project converter translating svg_output/ into native DrawingML PPTX.
Existing-PPTX requests split by mutation model: the two native workflows bypass SVG, while beautify-pptx remains a Generate PPTX profile that regenerates the visible design:
| Workflow | Input role | Output mechanics | Why it is separate |
|---|---|---|---|
template-fill-pptx |
a native PPTX template deck plus new material | clone selected slides and patch text / tables / charts in OOXML | preserves the user's PowerPoint slide shells instead of converting them into SVG |
native-enhance-pptx |
a finished PPTX whose layout/content should remain stable | patch notes, narration, timings, and transitions directly in OOXML | appends native enhancements without regenerating design |
beautify-pptx |
an existing PPTX whose page count/order/wording must stay 1:1 | extract source facts, regenerate a native deck through the SVG pipeline | changes layout and hierarchy only; it is not direct in-place editing |
Executable route selection is authoritative in workflows/routing.md; this section is a rationale-oriented quick reference, not a second route matrix to maintain.
Use this table before reasoning about implementation details. Most failed runs start with the wrong route, not the wrong command.
| Request shape | Route | Boundary |
|---|---|---|
| Topic only, or supplied material lacks facts required by the requested outcome | Generate PPTX + topic-research inside Step 1 |
topic-only research starts immediately; source-backed research follows conversion/read and fills only identified factual gaps |
| Source files or conversation text, deck structure may be rethought | Generate PPTX | Strategist may split, merge, drop, reorder, and redesign |
| Explicit quick generation | Generate PPTX + quick-generate profile |
convert/read sources, research factual gaps, and prepare required resources as needed; explicit user requirements are followed and the current agent decides every remaining content, page, visual, and resource question in active context, skips Strategist/confirmation/spec/lock/finalize, hand-authors SVG, passes one lockless final gate, and exports the final PPTX |
| PPTX as source material, user allows a new story/page structure | Generate PPTX via ppt_to_md + pptx_intake |
PPTX identity/geometry are facts and candidates, not replica constraints |
| Raw PPTX template plus new material/topic | Fill Native PPTX (template-fill-pptx) |
clone/fill native slides; no SVG generation |
| Existing PPTX, preserve page count/order/wording 1:1, improve layout | Generate PPTX + beautify-pptx profile |
regenerate through SVG; content and pagination are locked |
| Finished PPTX, keep content/layout stable, add notes/audio/timings/transitions | Enhance Native PPTX (native-enhance-pptx) |
direct OOXML patch; no design regeneration |
| User wants a reusable template workspace from one or more PPTX/SVG files, images/PDFs, documents/websites, brand assets, direct text, or a mixed reference bundle | Create Template (create-template) |
the fixed entry reads every applicable evidence channel, dispatches one Create Brand, Create Layout, or Create Deck child workflow, then returns a workspace root for Generate Step 3; structured children may export a review PPTX |
| User supplies an explicit current-contract template path | Generate PPTX Step 3 | Brand/Layout/Deck workspaces resolve templates/design_spec.md; flat roots may resolve direct design_spec.md; semantic-legacy packages are rejected and replaced through Create Template |
| User asks to tune object-level animation order/effect/timing | Generate PPTX + customize-animations stage |
optional export policy via animations.json |
| User asks to preview, select, annotate, or re-export browser edits | Generate PPTX + live-preview stage |
annotations apply only at defined handoff points |
Ambiguous "optimize this PPT" requests reduce to one discriminator: preserve the original page count/order/wording, or treat the deck as source material and rebuild the story. Both use Generate PPTX; preservation selects the beautify-pptx profile, while restructuring uses the normal profile.
The pipeline: AI generates SVG → post-processing converts to DrawingML (PPTX).
The default full flow breaks into three stages:
Stage 1 — Content Understanding & Design Planning Source documents (PDF/DOCX/XLSX/PPTX/URL/Markdown/topic text) are converted into the content and analysis facts the Strategist needs. The Strategist confirms an open communication contract, derives a complete deck solution from it, resolves production mechanics, and produces the design specification.
Stage 2 — AI Visual Generation The Executor role generates each slide as an SVG file. The output of this stage is a design draft, not a finished product.
Stage 3 — Engineering Conversion Post-processing scripts convert supported SVG vector elements to DrawingML. Text and vector shapes stay native PowerPoint objects — clickable, editable, and restylable — while raster assets are copied as PPT picture media instead of flattening the slide into one image.
quick-generate retains the source-understanding and resource-preparation work
needed by the deck, but skips the separate Strategist planning/confirmation
phase, first-page gate, and finalize_svg.py. The current agent follows every
explicit user requirement and makes the remaining content, page, visual, and
resource decisions automatically in active context, then authors under the
shared SVG standards, runs one lockless final quality gate, and uses the same
DrawingML converter and postflight.
Artifact source/derived ownership is authoritative in artifact-ownership.md; this section visualizes the same dataflow for architecture rationale.
The workflow is easier to maintain if the artifacts are read as a dataflow rather than as folders that happen to exist:
sources/<content files> ────────┐
sources/*.facts.json ───────────┤
analysis/source_profile.json ───┼─> Strategist -> design_spec.md + spec_lock.md
analysis/image_analysis.csv ────┘
design_spec.md + spec_lock.md + images/ + icons/ + templates/
└─> Executor -> svg_output/
├─> planning artifacts/references stay in the valid active context
├─> project_manager.py page-context <project> P<NN> [on demand]
│ └─> --record-usage -> analysis/page-context/P<NN>.usage.json
├─> svg_quality_checker.py -> validation/svg_quality_report.json
├─> finalize_svg.py -> svg_final/
└─> svg_to_pptx.py -> exports/<name>_<ts>.pptx + validation/<output_stem>.report.json
backup/<ts>/svg_output/ [default output path; copy is best-effort after directory creation]
Quick Generate:
source material or topic
└─> conversion/read + factual-gap research [as needed]
└─> active-context content/page/visual/resource decisions
└─> images/ + icons/ + formula/resource manifests [as needed]
└─> hand-authored svg_output/
└─> svg_quality_checker.py --quick-generate --stage final --json
└─> svg_to_pptx.py --quick-generate -> exports/*.pptx
+ validation/<output_stem>.report.json
+ backup/<ts>/svg_output/ [default output path]
Direct OOXML routes:
analysis/<stem>.slide_library.json + source PPTX + fill_plan.json
└─> template_fill_pptx.py -> exports/*.pptx
source PPTX project copy + enhancement plan + notes/audio/timing assets
└─> native_enhance_pptx.py -> exports/*.pptx
The critical split is that svg_output/ is authored state, while svg_final/, exports/, and backup/ are derived delivery or archival state. Deleting that distinction makes validation, re-export, and manual repair much harder to reason about.
SVG sits at the center of this pipeline. The choice was made by elimination.
Direct DrawingML generation seems most direct — skip the intermediate format, have AI output PowerPoint's underlying XML. But DrawingML is extremely verbose; a simple rounded rectangle requires dozens of lines of nested XML. AI has far less training data for it than SVG, output is unreliable, and debugging is nearly impossible by eye.
HTML/CSS is one of the formats AI knows best. But HTML and PowerPoint have fundamentally different world views. HTML describes a document — headings, paragraphs, lists — where element positions are determined by content flow. PowerPoint describes a canvas — every element is an independent, absolutely positioned object with no flow and no context. This isn't just a layout calculation problem; it's a structural mismatch. Even if you solved the browser layout engine problem (what Chromium does in millions of lines of code), an HTML <table> still has no natural mapping to a set of independent shapes on a slide.
WMF/EMF (Windows Metafile) is Microsoft's own native vector graphics format and shares direct ancestry with DrawingML — the conversion loss would be minimal. But AI has essentially no training data for it, so this path is dead on arrival. Notably, even Microsoft's own format loses to SVG here.
SVG as embedded images is the simplest path — render each slide as an image and embed it. But this destroys editability entirely: shapes become pixels, text cannot be selected, colors cannot be changed. No different from a screenshot.
SVG wins because it shares the same world view as DrawingML: both are absolute-coordinate 2D vector graphics formats built around the same concepts:
| SVG | DrawingML |
|---|---|
<path d="..."> |
<a:custGeom> |
<rect rx="..."> |
<a:prstGeom prst="roundRect"> |
<circle> / <ellipse> |
<a:prstGeom prst="ellipse"> |
transform="translate/scale/rotate" |
<a:xfrm> |
linearGradient / radialGradient |
<a:gradFill> |
fill-opacity / stroke-opacity |
<a:alpha> |
This table shows conceptual counterparts, not a commitment to the entire SVG standard or a promise of lossless semantics. Every supported capability must have an explicit mapping in the applicable module selected by the shared-standards.md router, identifying its project-canonical spelling, accepted compatible inputs, target DrawingML expression, fidelity, and rejection boundary; capabilities that support PPTX import must also identify the source PPTX/OOXML semantics. A mapping may be exact, deterministically normalized, an explicit fallback, a sidecar, or unsupported. Package semantics such as notes, animations, and relationships do not need to be forced into SVG, but their owning route must be explicit.
For a PowerPoint-first, feature-by-feature view of those relationships, see the PowerPoint Feature ↔ Project SVG Mapping Guide. It owns the public capability and PPTX-import recovery map; the authority set routed by shared-standards.md owns generated authoring.
The main generation route uses canonical narrow writes and controlled compatible reads. New svg_output/ and reusable templates use only project-canonical spellings—for example, uppercase opaque #RRGGBB, with transparency carried by the matching fill-opacity, stroke-opacity, stop-opacity, flood-opacity, or atomic-element opacity. Historical or manual input proceeds only when the compatibility contract documents it, the conversion has one meaning, and the output is valid. The checker emits a non-blocking warning for such input, and the converter normalizes it at the compilation boundary. Anything that requires guessing, lacks a mapping, or could produce a damaged PPTX is an error.
Conversion is therefore not format guessing between arbitrary SVG and DrawingML. It is a registered, fidelity-described, testable compilation from project-canonical SVG to DrawingML.
SVG is also the only format that simultaneously satisfies every role in the pipeline: AI can reliably generate it, humans can preview and debug it in any browser, and scripts can translate it under an explicit compatibility contract — all before a single line of DrawingML is written.
Source documents (PDF / DOCX / EPUB / XLSX / PPTX / web pages) are normalized before Strategist work starts, but there is no single "everything becomes Markdown and nothing else matters" channel anymore. The current design has two fact channels with explicit ownership:
| Channel | Artifact | Owner | Used for |
|---|---|---|---|
| Content contract | sources/ content-type files (primarily <stem>.md) |
source_to_md/* converters + import-sources |
text, tables, chart values, SmartArt node wording, citations, and source narrative |
| Structured analysis | analysis/*.json / analysis/*.csv |
intake and analysis tools | PPTX identity, slide geometry, native tables/charts, SmartArt relationships, and measurable image facts such as dimensions, aspect ratio, reference count, media type, and renderability |
For a PPTX source, project_manager.py import-sources first moves or copies the original into the project's sources/ under the ownership boundary, then runs pptx_intake.py against that archived path. Only when no explicit or existing canonical same-stem Markdown is present does it finally invoke ppt_to_md.py. A normal first import therefore produces both fact channels, while deduplication may skip redundant Markdown conversion and an intake failure is recorded as an import note rather than fabricated analysis. Markdown remains the main generation pipeline's content source. A successful intake bundle writes <stem>.identity.json, <stem>.slide_library.json, and merges a compact multi-deck index into analysis/source_profile.json. Strategist reads the compact index for source facts and opens raw per-deck artifacts only when a workflow needs them. That distinction matters: the main pipeline may rethink page count and story, while template-fill and beautify promote parts of the same intake facts into stronger constraints.
Converter-generated image assets are also normalized. Companion <stem>_files/ directories are imported into the project images/ pool, image_manifest.json is merged by filename, and Markdown asset references are rewritten when imported names change. Office vector images (.emf / .wmf) are first-class runtime assets: they are not rasterized during intake, finalize_svg.py leaves them external for the native path, and svg_to_pptx.py embeds them as Office vector media so CJK fonts and vector detail are not lost.
Two converter design choices still shape the system:
Native-Python first, external binaries as fallback. Common formats are handled by pure-Python wheels; pandoc is only invoked for the long tail of niche formats. Forcing every user to install system binaries they may not have permission for is a usability tax that does not pay off when most inputs are docx / pdf / html / pptx.
TLS fingerprint impersonation for high-security sites. Web fetching uses the Python web_to_md.py path by default and relies on curl_cffi when available for Chrome-like TLS impersonation. WeChat Official Accounts and several CDNs block Python's default handshake outright; keeping this in the Python converter path avoids making a Node fetcher the primary architecture.
project_manager.py init creates the standard project working directories;
--quick-generate creates only svg_output/, omits the project README, and
leaves other directories on demand. The explicit
quick-generate
profile omits planning artifacts and svg_final/, but its project may still
contain converted sources, analysis, images, icons, rendered formulas, and
required resource manifests. It hand-authors svg_output/, writes a lockless
final quality report, and retains the ordinary postflight and default-path
backup around the final PPTX. The default delivery lifecycle is:
| Directory | Role |
|---|---|
sources/ |
archived originals, normalized Markdown, and converter companion files |
analysis/ |
machine-extracted facts: PPTX intake bundles and regenerated image analysis |
images/ |
single runtime image pool for user, extracted, formula, web, AI, sliced, EMF/WMF assets |
icons/ |
project-local icon set copied by icon_sync.py; global library fallback at export exists only for legacy compatibility |
templates/ |
copied template specs / SVG references / non-image template assets |
svg_output/ |
the only hand-authored SVG source directory |
svg_final/ |
mandatory normal-flow derived visual-preview SVGs; supported bitmap/SVG resources are inlined when possible, while EMF/WMF retain an external-reference exception; used for IDE/browser preview or manual insertion as SVG pictures |
live_preview/ |
preview server state, edit history, and annotation logs |
notes/ |
total.md and split per-slide speaker notes |
validation/ |
SVG quality reports and PPTX postflight audit reports |
exports/ |
timestamped native PPTX deliverables |
backup/<timestamp>/ |
default export creates the timestamped directory, then attempts a frozen svg_output/ copy; copy failure does not fail export, but directory-creation failure is not currently downgraded |
The CLI supports --move, --copy, and an automatic default, with one fixed ownership boundary: only sources already under the repository's projects/ tree may move into a target project's sources/; every other local path is copied and remains untouched, even when --move is supplied. --copy preserves a projects-local input. Generate PPTX uses the automatic mode so canonical repository documents and external user files cannot be removed during intake.
Executable artifact ownership invariants are authoritative in artifact-ownership.md; this section explains why those boundaries matter architecturally.
These invariants are stronger than ordinary implementation preferences. If a change violates one, it is probably changing the architecture rather than refactoring it.
| Invariant | Practical consequence |
|---|---|
sources/ content-type files are the Generate content contract |
text, tables, and chart values come from content-type files in sources/ (Markdown is primary, but .txt / .csv / .json / .yaml / … count too); known sidecars (*.conversion_profile.json, *_files/image_manifest.json) are excluded |
analysis/ stores machine facts, not design contracts |
source_profile.json and intake artifacts inform Strategist in the default pipeline and the current agent in quick-generate; they do not lock page count/order except in workflows that say so |
design_spec.md explains the design; spec_lock.md executes it in the default pipeline |
both remain owning artifacts there; quick-generate persists neither, and the current agent follows explicit user requirements while keeping every remaining content, page, visual, and resource decision in active context |
| Planning context is retained until invalidated | continuous execution reuses the complete Design Spec, lock, and triggered references; fresh/resumed/restarted or compacted execution reloads them once |
page-context is on demand |
the read-only projector supports diagnostics, deterministic routing checks, and optional usage telemetry; it is not a pre-page gate |
svg_output/ is the only hand-authored SVG directory |
quality checks, manual edits, re-export, and update_spec.py target authored source |
svg_final/ is mandatory but derived in default delivery |
it is regenerated from svg_output/ for visual preview or manual insertion as an SVG picture; supported resources are inlined when possible while EMF/WMF retain an external-reference exception, and it never becomes the native export source of truth; quick-generate skips this artifact |
Native PPTX export reads svg_output/ by default |
converter preserves icons, preserveAspectRatio, rounded rects, and native image crop metadata before finalization rewrites them |
| PowerPoint Convert to Shape is outside the compatibility contract | svg_final/ may be inserted as an SVG picture, but the converted structure and visual result are not guaranteed and do not constrain the supported SVG feature set |
| Direct OOXML routes do not enter the SVG pipeline | preservation workflows patch native PPTX parts directly |
| Image facts come from regenerated metadata | analysis/image_analysis.csv is re-derived from the live images/ folder; in the default pipeline Strategist uses source context first and inspects only a specifically ambiguous asset when semantics or safe placement cannot otherwise be resolved, while in quick-generate the current agent applies the same bounded analysis while preparing resources; SVG authoring does not rescan source pixels |
| Raw PPTX templates are not Step 3 templates | Step 3 consumes reusable template directories only |
PPT Master is not PPT-only — the same SVG → DrawingML pipeline produces square posters, 9:16 stories, A4 prints. Format-specific conventions (ratios, safe zones, brand areas) live in references/canvas-formats.md.
The architectural choice worth flagging: viewBox is in pixels, not absolute units. Pixel space makes layout reasoning unambiguous for the AI Executor (x="100" is unambiguously left + 100px) and inspectable in any browser. Conversion to PowerPoint's EMU happens once at export — picking pixels means the rest of the pipeline (Strategist, Executor, quality checker, post-processing) never thinks in EMU, which would be hostile both to AI generation and to human debugging.
Templates are opt-in, not default. The default Strategist flow is free design — AI invents the visual system from the source content alone. The template path activates only on an explicit directory path supplied by the user.
Why default to free design. Templates are floors that easily become ceilings: they lock the deck into the template's visual idioms regardless of how the content actually wants to be presented. Free-design layouts derive structure from the source content rather than imposing it from a fixed grammar, so the visual rhythm tracks the content rather than fighting it. Constrained mode is genuinely better in narrow cases (brand-locked decks, strongly-typed scenarios like academic defense or government report), so it stays available — but the AI doesn't proactively reach for it; the user does.
Mechanical trigger, not semantic matching. A bare name like presentation_core, a brand mention, or a style phrase such as "McKinsey style" does not trigger Step 3 even if a matching library directory exists. Step 3 consumes an explicit path. Current Brand/Layout/Deck workspaces resolve templates/design_spec.md; compatible flat-directory packages resolve direct design_spec.md only when their SVGs already satisfy the current contract. Directory shape never authorizes structure migration. A package with legacy Master/Layout/placeholder semantics must be replaced by a newly created template workspace before Step 3. Discoverability is handled by template indexes and explicit Q&A ("what templates are available?"), not by runtime fuzzy matching.
All current Brand/Layout/Deck packages use one workspace routing contract. Brand workspaces omit the SVG roster; empty optional directories are omitted:
<template_workspace>/
├── templates/ # design_spec.md; Create Layout / Create Deck also include SVG prototypes
├── images/ # optional; bitmap assets referenced as ../images/<name>
├── icons/
│ └── imported/ # optional; canonical imported vector assets
└── exports/ # optional, on-demand review files; Git-ignored in the library
<template_workspace> is either skills/ppt-master/templates/<kind>/<id>/ or projects/<name>/. Step 3 receives that root. The workspace is portable between locations without reshaping; global index registration is the only scope-specific behavior. Empty optional directories are absent, and template application never copies exports/.
For Create Layout / Create Deck, standard and fidelity write new SVG documents and a new Master/Layout/slot system; source topology is visual evidence only and is neither preserved nor distilled. mirror materializes a new workspace from the source page order, Master/Layout identities and parentage, placeholder facts, and supported visuals that are actually present and validated, without semantic synthesis or gap filling. Layout mirror is legal only when that preserved source is already brand-neutral and application-neutral; otherwise author a new Layout or retain the facts as Deck. Because structural layers cannot be <g>, fixed-layer source group wrappers are mechanically expanded into direct atoms while preserving ownership, paint order, and appearance. Create Brand analyzes and materializes identity fragments only; it does not enter these structural replication strategies or produce an SVG roster.
The three template kinds own different segments of the design contract:
| Kind | Owns | Typical contents | Effect on Strategist |
|---|---|---|---|
brand |
identity | colors, typography, logo, voice, icon style | locks identity; structure remains free |
layout |
brand-neutral structure | canvas, page structure, semantic text roles/spatial behavior, page types, SVG roster | exposes structure; identity and communication application remain downstream decisions |
deck |
application + integrated identity/structure | recurring situations, audiences/outcomes, representative page roles, identity, and actual SVG roster | contributes descriptive context and prototypes that Strategist compares with the independently confirmed Stage-1 contract and current content before deriving the application plan |
Theme, Slide Master, Slide Layout, and Placeholder are compiled PowerPoint
objects, not additional template kinds. Layout owns topology, placement,
semantic text roles, and spatial behavior; Brand owns identity values and
assets. Under template_reuse_scope: layout, export resolves final placeholder
formatting from those rules plus the confirmed reading mode/type scale;
mirror preserves literal source formatting and text topology. Export may
place both rule sets into the same native Master/Layout graph.
When several paths are supplied, fusion is segment-level, not field-level. A brand overrides the identity segment, a layout overrides the structure segment, and a deck supplies the application segment. A Layout may replace Deck structure only when its page roles and slots can express the Deck's required narrative/content roles; otherwise fusion surfaces a conflict. A project-local Brand + Layout composition gets its application context from Stage 1 and is not automatically promoted into a reusable library Deck. Same-kind conflicts are surfaced rather than resolved by implicit ordering. This keeps template composition debuggable: a fused spec can say exactly which bundle owns each segment.
Raw PPTX files cannot be Step 3 workspaces. Normal Generate may use a PPTX as source material, and beautify-pptx may redesign it while preserving page count, order, and per-page wording 1:1; neither treats the source PPTX as a Step 3 template. When a raw PPTX is used as a template or native slide shell and filled with new material, the default route is Fill Native PPTX. If the request permits splitting, merging, dropping, reordering, or narrative restructuring, it remains Generate. Only a request to create a reusable template workspace and reuse that design system in SVG-route Step 3 first runs Create Template and then supplies the generated workspace root.
Layouts are opt-in; charts and icons are not. The asymmetry isn't an inconsistency — layout is what locks visual idiom (the floor/ceiling problem above), while charts and icons are reusable primitives that don't impose deck-wide style. Same templates/ directory, different role in the visual contract.
PPT Master uses role switching within one main agent rather than parallel sub-agents. Strategist, Image_Generator, Executor, and workflow-specific modes are instruction scopes loaded on demand; they are not independent agents with their own stale copies of the deck state. The choice has three connected reasons:
Why one agent, not parallel sub-agents. Page design depends on the full upstream context — Strategist's color choices, the image resources that actually got acquired (vs failed and substituted), prior pages' visual rhythm. Sub-agents would start with a stale partial snapshot of that context and produce visually drifting decks. The same logic forbids batched page generation (e.g., five pages per turn): batching accelerates context compression and the deck's visual consistency degrades faster than the speed gain is worth.
Why role-specialized references, not one mega prompt. Strategist runs in "negotiate with user" mode (open-ended, conversational, willing to back up); Executor runs in "produce strict XML" mode: it may not reselect upstream decisions or omit required attributes, but it still owns geometry, composition, hierarchy, and visual treatment inside implementation dimensions the Design Spec leaves open. Mixing both into one prompt forces the model to hold incompatible discipline in the same turn — every prompt-engineering pathology of mode-mixing shows up. Splitting into per-role files lets each role load only what it needs and discard the rest.
The Strategist confirmation stage is the main user design-decision gate on the default continuous route. Strategist uses one dependency-ordered three-stage gate. Stage 1 confirms an open communication contract and canvas. Its delivery_context recommendation distinguishes presenter-led, reader-led, hybrid, and recorded/self-running use in one prose field, names the primary context, and records any secondary use; hybrid never stands alone without its lead mode. The prose boxes remain editable and none requires a non-empty answer: confirmation persists the current text exactly, and a cleared value stays empty instead of falling back to the recommendation. Stage 2 is authored once from that contract and confirms the complete deck solution: reading mode, narrative mode, page count, coordinated visual system, image sources, and generated-image rendering. When a template is installed, Strategist also derives its page/prototype application plan from the actual workspace and current content and exposes that plan as editable natural-language prose; only the internal reuse/adherence modes stay hidden. Reading mode decides how meaning is carried by page, visuals, presenter, and notes; its cards do not present px values. The browser may apply the deterministic reading mode → body baseline → unpinned role sizes dependency locally, while manual size edits pin visible values. It never regenerates Stage 2. Stage 3 is authored once and contains production mechanics only: conditional AI acquisition, formula policy, generation mode, the Design Spec review toggle, and whether the agent should proactively generate speaker notes, custom animations, or narration audio. Those three values are fallback policies, not capability bans: the latest explicit user instruction wins, then Stage 3, then the fixed defaults true / false / false. Strategist still records non-binding Motion suggestions when useful; a suggestion alone does not activate custom-animation execution. The compatibility key delivery_purpose means reading mode. Generated images inherit the selected deck color anchors directly; there is no independent image-palette choice. Final state has two equivalent carriers: the default UI path reads confirm_ui/result.json exactly once after the final wait, while an explicit chat-only or delegated path retains an equivalent final confirmation summary and may produce no result.json. Both paths first resolve and persist every effective production outcome into one design_spec.md and complete Gate 1 fidelity. With refinement off, lock authoring proceeds immediately. With refine_spec: true, the pipeline stops before spec_lock.md; the user may revise any part of that same Design Spec through normal chat for any number of rounds, and explicit approval then releases Gate 2 lock authoring. No second Design Spec or parallel lock is maintained. Normal lock authoring and downstream execution do not reread either confirmation channel. Required manual assets may still introduce their own conditional blocking points, so this is not an exclusive claim over every runtime gate. Project validation requires the compact audience / objective / core_message anchor set under spec_lock.md ## communication plus an Audience move in every §IX Slide block.
The three Stage 3 proactive values remain independent raw evidence. In particular, enabling narration may enable the effective Speaker Notes outcome in the Design Spec, but it never rewrites the raw speaker-notes choice.
Image analysis is metadata-first, with a narrow visual fallback. When images exist, analyze_images.py supplies the regenerated measured facts in analysis/image_analysis.csv; the CSV is a view over the live images/ folder, not a durable cache. In the default pipeline, Strategist first resolves supplied images from source placement and nearby prose, captions / alt text / titles, filenames, user notes, existing resource records, and that metadata. It may inspect one specific image only when a material ambiguity remains about selection, factual identity, page role, crop safety, or focal placement—never as a bulk inventory scan. The answer is written into Design Spec §VIII, after which Executor uses the plan and measured geometry without reopening source pixels for semantic discovery. In quick-generate, the current agent applies the same bounded analysis while automatically preparing the resource roster in active context; no Design Spec projection is written. User images, extracted images, web images, AI outputs, formulas, and sliced elements still converge into the same measured fact table.
Retained planning context carries continuity; the on-demand page projector is only a diagnostic described below.
Generate execution is governed by workflows/generate-pptx.md, which owns the default Step 1–7 sequence, the explicit quick-generation short circuit, and the generation-specific rules; SKILL.md owns only global execution discipline and the mandatory handoff to routing.md. Together, these rules may look bureaucratic but exist because LLMs default to "let me solve the whole problem in this turn", which is exactly the wrong shape for a serial pipeline where each step's output is bounded, checkpointed, and consumed by the next. They close failure modes that surfaced repeatedly in practice: out-of-order execution, AI proxying user design decisions, cross-phase bundling, missing prerequisites, speculative pre-work, sub-agent context loss, page-batching drift, long-deck color/font drift, batch/script-generated SVG drift, and routing ambiguity.
Global stop/continue policy is authoritative in failure-recovery.md; its concrete recovery matrix and resume pointers currently cover Generate PPTX. This section does not duplicate those rules.
Three boundaries are especially important to the architecture. First, page SVGs must be hand-authored by the current main agent, one page at a time; writing a Python/Node/shell generator to emit pages is prohibited because the resulting deck loses cross-page judgment and visual continuity. Second, default-pipeline cadence is P01 → first-page gate → uninterrupted remaining pages → final gate. P01 is a method sample: execution emits a gate-signal, then carries resolved method rules into later pages; no checker call or page batch interrupts P02 through the final page. quick-generate retains serial hand-authoring and P01 as its visual anchor, skips the first-page gate, and runs one lockless final gate after the complete roster exists. Third, routing is deterministic: raw PPTX template requests, beautify-profile requests, native enhancement, custom-animation stages, live-preview stages, and other registered triggers are not turned into open-ended user route questions when the repository already defines the boundary.
In the default pipeline, the Role Switching Protocol (mandated read of references/<role>.md before mode change) serves two reinforcing purposes: forcing fresh role instructions into context overrides drift from the previous mode, and the visible marker in the conversation transcript creates an audit trail so the user can see when the agent moved between modes — critical when reviewing why a particular decision was made.
In the default pipeline, the Strategist phase produces two artifacts that look redundant but serve different masters:
design_spec.md— human-readable narrative; the "why" of the deck (communication intent, audience outcome, narrative / template / visual rationale, page outline)spec_lock.md— machine-readable execution contract; the compactaudience/objective/core_messagecommunication anchors plus stable identity/reuse roles and routing values (core HEX/font roles, icon library, image resources, and structure mappings)
Why both? design_spec.md preserves the complete confirmed solution and rationale; spec_lock.md names the subset that must remain stable or routable across pages. It is authored from that Design Spec plus the page/resource/template context, not copied field by field from raw UI JSON or chat-summary payloads. Generate PPTX Step 6 retains both artifacts once per valid execution context. Fresh/resumed/restarted execution, compaction, or summary-only recovery reloads both once; an unchanged continuous context does not reread either file. Contextual tints, gradient/effect paints, and sparse non-structural display-font accents remain page decisions; recurrence or a stable semantic role requires an upstream lock role.
The view omits universal SVG/icon prohibitions already owned by the always-loaded Executor core and retains only project-specific forbidden rows. It selects images from the current page brief, explicit image-resource page assignments, and mirror prototype references. Images assigned elsewhere are excluded; any unresolved legacy image remains in a compatibility subset, and confirmed-none appears only when every locked image has a deterministic assignment elsewhere.
The lock is also the per-page routing table. Beyond global colors and typography, it carries page_rhythm (anchor / dense / breathing), page_charts (the selected page-local chart-catalog reference, which triggers reading the corresponding SVG and §VII Usage but does not lock the final chart type or geometry), image rows with placement/cropping contracts, and the locked mode / visual_style values that decide which execution rule files are loaded. A selected custom direction also carries its resolved mode_behavior / visual_style_behavior. When it actually combines or borrows catalog entries, the lock records their exact ids in optional mode_references / visual_style_references / image_rendering_references, and execution reads every listed file before synthesis; a genuinely novel custom omits the corresponding reference field. template_reuse_scope: mirror|layout locks additionally carry page_layouts (which input template SVG each page inherits), unique pptx_masters / pptx_layouts definitions, and page_pptx_layouts assignments. template_reuse_scope: style, free-design, and brand-only projects use pptx_structure.mode: flat and omit those sections entirely rather than writing empty values. Empty entries elsewhere are meaningful signals: no chart or no image is often a design decision rather than missing data.
page-context v2 remains an on-demand projector. Each invocation emits a compact global anchor set bound to lock_source.sha256, the current §IX/resource/routing delta, and scoped path/SHA fingerprints for large references; the projection is not a color/font allowlist or a replacement authority. It is used only for explicit diagnostics/telemetry or an unresolved page/template/chart path-SHA question. A bounded exact repair in a valid uncompacted context may use targeted fragment readback plus validation; fresh, compacted, external, unknown, structural, or mismatched changes require one complete Design Spec and lock read. Flat pages have no prototype reference; structured pages use the authoritative complete SVG. Manifests and text-slot sidecars remain derived tool diagnostics and are never injected into page authoring.
--record-usage writes a derived, input-hashed compact-output snapshot for an invoked page under analysis/page-context/. Token counting lazily uses o200k_base; a missing tiktoken installation records tokens: null without blocking execution. page-context-report excludes stale snapshots, reports existing snapshots, and lists unique reference fingerprints; telemetry may be partial. The once-loaded reference payloads and other session context remain intentionally unmeasured.
update_spec.py propagates an intentional deck-wide anchor change in two coordinated steps: plan and literal-replace the value across every svg_output/*.svg, then write the authoritative spec_lock.md only after those SVG updates succeed. The tool's scope is deliberately narrow — only colors.* (HEX values, case-insensitive replacement) and universal typography.font_family (attribute-scoped). A universal font replacement also sets every existing typography.*_family lock row to the same value in one lock-file write, so title/body/role locks cannot retain values that the command has removed from every SVG. Other fields (font sizes, per-role font changes, icons, images, canvas) are intentionally not supported because their replacements would need attribute-scoped or semantic awareness whose risk/benefit doesn't justify bulk propagation. This reverse lock update is also valid when repeated contextual use is deliberately promoted into a named semantic role; it must not be used merely to empty an informational checker comparison. For unsupported fields, edit the owning artifact and re-author the affected pages.
The tool refuses to back up: it relies on git for revert. Adding a backup mechanism would just duplicate git's job and create stale snapshots.
The cooking analogy is the canonical ownership model for the default Generate
pipeline, not just explanatory prose. quick-generate removes the separate
Strategist and confirmation layer; it does not remove preparation.
| Restaurant | PPT Master | Authority |
|---|---|---|
| Customer and initial ingredients | User confirmation and supplied sources/assets | Defines facts, intent, exclusions, acquisition permissions, and how specific the requested outcome is |
| Menu planner and preparation lead | Strategist, design_spec.md, spec_lock.md, and Strategist-owned acquisition stages |
Assesses sufficiency; fills permitted factual gaps; selects the content, resources, page roster, chart-reference/template-layout keys, fonts, palette anchors, icons, and crop boundaries; records optional capability/expression recommendations; readies the complete project-local inventory before execution |
| Cook | Executor | Uses only prepared project-local assets and realizes the plan through geometry, composition, hierarchy, spacing, and treatment without changing the selected “dish” or acquiring/substituting ingredients; may adapt fields explicitly labeled as suggestions or References |
Quick generation collapses planning into the current agent. Source conversion,
factual-gap research, and resource preparation still run when needed. The agent
automatically selects the content, page roster, visual system, and resource
needs in active context, prepares supplied/extracted/AI/web/sliced images,
icons, and formulas with their required manifests or provenance records, and
then hand-authors SVG. It does not invoke Strategist, Confirm UI,
design_spec.md, or spec_lock.md.
Default preparation has two clocks. Topic Research supplies facts before final confirmation: it starts immediately for topic-only input, or after supplied material is converted/read when planning-critical factual gaps remain. It supplements only those gaps and acquires no images. AI / web / slice image acquisition runs only after final confirmation and the completed design_spec.md §VIII / spec_lock.md, then reaches a terminal status before Executor starts. Strategist also resolves, syncs, and validates the icon inventory while authoring the final plan. Image_Generator, Image_Searcher, and icon-sync tooling are preparation mechanisms under Strategist ownership, not independent decision owners. Quick generation uses those preparation mechanisms as needed under the current agent's in-context decisions, without inserting a confirmation gate.
Prepared project-local assets are the boundary. In the default pipeline, images and other declared resources remain available only when Strategist has selected them, recorded them in the planning artifacts, and made their project paths resolvable or explicitly Needs-Manual. Icons are prepared when their SVG files exist under <project>/icons/; spec_lock.icons.inventory records the Strategist's planned bundled selection but is not an exhaustive execution whitelist. In quick generation, the active-context resource roster and its project-local files/manifests replace that planning projection; the current agent may acquire and prepare those resources before SVG authoring. Files elsewhere on disk are not authorized. Missing material returns to the owning preparation step; SVG authoring never silently substitutes it.
Specificity controls freedom. “Make Mapo tofu” fixes the result's identity: technique and presentation may vary, but tomato-and-eggs or tofu soup is a substitution. “Make a tofu dish” leaves an in-class choice. In the default pipeline, Strategist may resolve that choice; if the Design Spec deliberately leaves a dimension broad, Executor may realize it within that envelope. Once the Design Spec names a binding choice, execution cannot reopen it. In quick generation, the current agent resolves the equivalent choice in active context and keeps it stable while authoring. Fields explicitly labeled as suggestions or References—including a preferred page-local image pattern—remain expression guidance that may be adapted without changing content, resources, identity, or explicit constraints.
Garnish remains local. Sparse page-local font or color accents may add hierarchy, differentiation, or atmosphere without becoming a second visual system. In the default pipeline, structural/recurring fonts, palette roles, resources, or recurring cross-page identity patterns remain Strategist decisions and require an upstream Design Spec/lock update before reuse; in quick generation, the current agent establishes those anchors in active context and preserves them across pages. A default-pipeline page-local §VIII image pattern remains a preferred composition reference.
Prompt-refactor invariant. In the default pipeline, compression must preserve initial materials, user confirmation, Strategist-owned preparation, planning ownership, and execution freedom as separate layers. Moving acquisition into Executor, turning permission into quota, flexible realization into silent resource/identity reselection, or an exact binding plan into an approximate target is a semantic regression. The explicit quick profile consolidates the first layers under the current agent; it does not erase source or resource work. Default runtime authority lives in strategist.md and executor-base.md; Quick runtime authority starts at quick-generate.md and conditionally loads the same resource references. Prompt-writing governance lives in prompt-style.md.
Several architectural decisions shape this phase:
Provider-specific config keys, not a generic IMAGE_API_KEY. Every backend takes its own OPENAI_API_KEY / MINIMAX_API_KEY / etc. and the active one is selected by an explicit IMAGE_BACKEND=<name>. A unified IMAGE_API_KEY field looks tidier on first glance but causes silent confusion when a user has multiple providers configured at once and isn't sure which one is active — the kind of fault that surfaces only as "image generation gives weird results" with no clear failure point. Forcing per-provider keys makes "which backend am I using" a config-readable fact, not an inference.
Permissive-by-default license filter, with strict mode for credit-incompatible layouts. Web image search defaults to allowing CC BY / CC BY-SA images with inline attribution — most slides have visual room for a credit element. --strict-no-attribution is the escape hatch for full-bleed hero images and tight composition where there's no place to put a credit without breaking the design. Non-commercial (CC BY-NC*) and no-derivatives (CC BY-ND*) licenses are auto-rejected because the typical PPT Master output is shared in commercial or modified contexts; a permissive default with that floor is the failure mode users actually want.
Manifest-first acquisition. In-pipeline AI generation always writes images/image_prompts.json and renders the sidecar image_prompts.md, even for one image. The positional image_gen.py "prompt" form is intentionally limited to one-off debugging because it leaves no manifest/sidecar audit trail. Web acquisition mirrors this with images/image_queries.json for multi-row batches and image_sources.json for attribution/source tracking.
The Design Spec owns the image-execution path. Final confirmation from either the UI or chat is first persisted as AI Image Acquisition Path in design_spec.md §I; Image_Generator selects API, host-native, or manual from that value and may not reopen the decision during execution. image_gen.py --manifest belongs only to API Path A. The current CLI still contains a defensive guard that reads UI result.json and blocks an accidental Path A call when that file explicitly records host-native or manual. That guard is not an authority source, does not cover chat-only confirmation, and cannot replace Design Spec routing. It is a remaining implementation mismatch in the upstream authority chain, not a normal consumer path.
One coherent sheet when related spot illustrations fit it. Several same-family spots may share one AI illustration sheet plus slice rows when their cell shapes, detail, quality, and semantic needs are compatible; otherwise they may be generated independently. When the sheet path is chosen, slice_images.py cuts it into named transparent elements, those derived files join images/, and analyze_images.py is rerun so Executor sees their real dimensions.
Terminal status before Executor. Rows that require acquisition must end in Generated, Sourced, or Needs-Manual; Pending and Failed are not allowed to leak into Executor. A Needs-Manual row can continue through SVG generation only as a known placeholder/dependency, and Step 7 re-checks required files before final export.
External refs during development, two divergent embedding strategies for downstream outputs. While editing in svg_output/, images are external file references for fast iteration and single-point replacement. svg_final/ then Base64-inlines ordinary bitmaps and supported SVG resources, while retaining external EMF/WMF references for native PPTX passthrough; an individual inline failure increments the processing-error count, but it does not rewrite authored source or fail the finalizer as a whole. Native PPTX instead copies bitmaps or Office vectors into the package media folder and uses <a:srcRect> for supported bitmap cropping. The split exists because the preview and compiler serve different responsibilities: one is a derived visual reference, while the other produces editable DrawingML through the project converter. svg_final/ is not an unconditionally portable no-external-dependency interchange format or a compatibility source for PowerPoint Convert to Shape.
One rendering lock, inherited deck anchors, and per-image composition. When a deck includes AI-generated images, Stage 2 confirms the deck-wide rendering inside each coordinated design direction. Image colors are not a second user decision: Image_Generator starts from the core HEX roles in spec_lock.md colors, then interprets them with the completed Design Spec and each resource's type or hero-page composition. Rendering may derive coherent tints, material colors, lighting transitions, and atmospheric hues while preserving the core role meanings; it must not replace the deck identity with an unrelated image-only palette. A repeated derived tone may be promoted into a named lock role.
Whenever the image/formula branch is active, its compact placement vocabulary in references/image-layout-patterns.md is read alongside the layout math. Its current patterns are organized by composition responsibility:
- P · Primary Structures — single-visual, image-as-canvas, and multi-visual page skeletons.
- M · Modifier Layers — crop/reveal, tone/focus, and framing/placement/depth treatments applied to an existing skeleton.
- A · Asset-Dependent Treatments — compositions that require a prepared composite or appearance, cutout, or registered derivative.
- C · Cross-Page Continuity — persistent-state, camera, and matched-framing relationships across slides.
Why the catalog includes a combination playbook. Capability discovery alone does not teach repeatable composition. The playbook turns a page job into a compact sequence: select the P skeleton, name the integration need or stylistic role, add the smallest M that serves it, use A only when its prepared asset exists, add C only for an intentional cross-page relationship, then stop when another layer no longer earns its place. Its high-yield combinations are recall aids, not recipes that every deck must cover.
Why always reading the library does not impose a catalog or layer quota. It expands compositional choice rather than defining legal output. A page may use one or several P structures and any useful M, prepared A, or cross-page C patterns, cite no id at all, or use a free-form composition when that better serves the narrative and hierarchy.
Why the catalog uses two-level IDs. Handles such as #P2-01 and #M1-01 expose both composition responsibility and the local family, so combinations remain readable. The final number follows current browse order rather than preserving historical numbering. These are prompt vocabulary, not runtime effect codes: the Executor realizes the accompanying composition guidance, and the exporter does not map an ID to fixed DrawingML.
Why composition intent flows through Strategist's resource list. The Layout pattern column in §VIII Image Resource List carries one non-empty free-form suggestion and may optionally cite hierarchical ids from the library; Crop Policy separately records adaptive or no-crop. This preserves a useful starting point across session re-entry without making any catalog entry or id mandatory. Executor may resize, reflow, reposition, rebalance, replace the suggestion, or use another composition when that communicates better. Resource identity, must-use/content obligations, no-crop, and explicit user/template constraints remain binding; only changing those requires an upstream Design Spec update.
Why true hard constraints stay upstream. Cross-cutting SVG authoring and PPTX-compatibility exceptions live in the authority set routed by shared-standards.md. The layout patterns file points to that router rather than restating the contract, so each rule still has one owning module and no stale duplicate in the pattern catalog.
SVG and DrawingML are not equivalent expression models, so the main compiler route does not treat “the browser can render it” as “the project can export it.” Input is accepted only when the applicable module selected by references/shared-standards.md registers a project-canonical expression or an explicit compatible form with a deterministic DrawingML mapping. The split authority set owns syntax, structure, units, metadata, compatible aliases, fidelity, and rejection conditions; this architecture document defines the layering principle without duplicating individual rules.
Why local reuse is compile-time reuse, not a retained PowerPoint object. The canonical contract defines accepted authoring forms, and the shared validator enforces them. After validation, the pipeline recursively materializes each referenced subtree and rewrites clone-local IDs before export. PPTX-to-SVG import therefore returns expanded primitives rather than reconstructing the authoring-time reuse graph.
The architectural reasons worth knowing here:
- Why mappings are closed instead of accepting ordinary SVG by default. Project-canonical SVG is a compiler intermediate language, not a browser compatibility layer. Adding an element, attribute, or value requires corresponding input semantics, output mapping, validation, and regression verification; unregistered capabilities do not enter the main compiler route.
- Why compatible input is not authoring permission. A documented historical alias may be normalized deterministically and receive a non-blocking checker warning; prompts, templates, and examples still generate only the project-canonical spelling. Migration and manual-input compatibility must not widen generated syntax.
- Why warnings may pass. A warning is limited to a recommended spelling, deterministic normalization, known fidelity reduction, or visual-quality risk when legal output remains guaranteed. It does not change page semantics or require Executor re-authoring; any condition that must be corrected for delivery is an error.
- Why empirical, not derived from spec. The compatibility boundary grew from real PPT export failures, not from reading the OOXML specification. Some theoretically representable effects remain unreliable across PowerPoint versions, so the contract reflects the actually shippable subset.
- XML well-formedness remains a precondition. Malformed SVG fails before DrawingML compatibility matters. The canonical contract owns the accepted authoring forms so XML guidance cannot drift across architecture and prompt documents.
- Compatibility validation runs before post-processing.
svg_quality_checker.pyevaluatessvg_output/; post-processing rewrites SVG and could mask source-level violations. Blocking errors are re-authored by the Executor, while warnings do not trigger a rewrite. Generate proceeds to export only after the final checker reports zero errors. The converter does not rerun that full checker; it independently validates compiler mappings, ZIP integrity, slide count, and package structure, then records the upstream report stage, blocking count, and SVG-source fingerprint in postflight.
Why a checker exists at all. SVG generated by an LLM is not deterministic — compatibility violations creep in over long decks and only surface when svg_to_pptx aborts mid-conversion or PowerPoint silently drops elements. The checker turns "PowerPoint export failed at page 14" into "page 14 violates the SVG compatibility contract" — an order-of-magnitude faster diagnosis loop, which is what makes long decks economically feasible to iterate on.
Why placed before post-processing, not after. Post-processing rewrites SVG (icon embedding, image inlining), which would mask source-level violations. Reading svg_output/ directly catches the Executor's actual output, before any cleanup that might paper over a bug.
Why the default pipeline has first-page and final checks. The P01 gate treats the first page as a method sample: it separates method-level, page-local, and not-yet-exercised capabilities, reviews the complete issue set, then fixes every blocking error and selected advisory warnings in one consolidated loop. After it passes, P02 through the final page are generated continuously without checker calls; only the final gate inspects the complete authored set before release. The first calibrates method, while the second verifies the whole deck, so neither substitutes for the other.
Severity model: errors block, warnings do not, and there is intentionally no auto-fix. Severity is determined by whether the input maps deterministically and legally, not merely by whether it uses the recommended spelling:
| Severity | Classification | Pipeline behavior |
|---|---|---|
error |
A structural contract is broken; the input has no mapping or is ambiguous; required metadata is missing; a value is invalid; conversion may violate DrawingML/PPTX constraints; or PowerPoint may need to repair the file | The Executor must re-author and revalidate; Generate must not enter export while the final report still has blocking errors. If export reads such a final report, postflight marks quality_gate=failed, and the artifact must not be declared a successful delivery |
warning |
A unique, safe, legal conversion exists, but the input is not project-canonical or carries a documented normalization, fidelity reduction, or visual-quality risk | Record the diagnostic and allow publication; no acknowledgement or mandatory rewrite is required |
The gate follows the three-layer responsibility defined in the design philosophy. It intentionally has no auto-fix: a mechanical patch can silently overwrite valid design intent and ship a worse page.
Current implementation boundary. svg_to_pptx.py creates the PPTX before writing postflight. A quality_gate=failed result produces a failed report, but that state alone currently does not force a nonzero CLI exit or delete the generated file. Missing, non-final, stale, or unverifiable quality reports appear under their specific quality_gate values and put the report into passed-with-warnings; current Step 7 allows those artifacts to complete after the receipt is read and material warnings are disclosed. File existence or exit code 0 therefore does not prove success: a failed report must never be delivered, while passed-with-warnings requires judgment and disclosure based on its exact gate and warnings. The exporter has not yet closed quality_gate=failed into an independent nonzero exit or rollback; that is a defensive implementation gap, not relaxed error semantics.
If the same warning repeatedly appears in newly generated pages, fix the prompt, template example, or specification so default output returns to the project-canonical spelling. That is a generation-quality issue, not a reason to turn otherwise safe compatible input into an error. Conversely, if practice shows that a warning can produce an invalid file or ambiguous meaning, update the contract and checker together to classify it as an error.
Why chart coordinate verification hangs off the same gate. Chart pages have geometric correctness requirements (bar heights / pie sweep angles / axis tick positions) that aren't structural and aren't caught by SVG validity rules. The natural place to catch them is the same gate where the AI is asked to revisit its output — bundling the cognitive context "look at what you generated and fix it" into one phase, rather than splitting structural and geometric review into separate review rounds.
Why each artifact and module exists in the engineering conversion stage, and which workflows would break if you delete it. Read this before considering any simplification of
svg_final//finalize_svg.py/svg_to_pptx.py.
The post-processing and export stages keep authoring, validation, preview, delivery, and archival artifacts distinct. Each one serves a workflow that nothing else in the pipeline can replace. Every PPTX entry below is a variant of the same svg_output/ → native DrawingML route, not a parallel image-based converter.
| Artifact | Workflow it serves | Why nothing else replaces it |
|---|---|---|
svg_output/ |
source of truth, manual editing, update_spec.py, svg_quality_checker.py |
only directory whose contents are authored, not derived |
svg_final/ |
IDE/browser inspection and manual insertion as an SVG picture | .pptx is not openable in IDEs, while svg_output/ may render incompletely because icon/image refs are external. Ordinary resources are inlined when possible and EMF/WMF stay external; PowerPoint Convert to Shape is unsupported |
exports/<name>_<ts>.pptx (native) |
default primary deliverable — editable in PowerPoint as DrawingML shapes | default DrawingML object model; native Chart/Table and narration variants remain editable but have different object or playback behavior |
validation/svg_quality_report.json |
machine-readable final SVG gate | separates blocking failures, introduced advisories, inherited prototype findings, and source-import losses, and fingerprints the checked SVG bytes |
validation/<output_stem>.report.json |
published-PPTX postflight and resource audit | records actual ZIP/package part counts; reruns ZIP and Slide-count checks; labels relationship, structured-package, transition, and animation validation as build-time enforcement; accepts quality-report linkage only when its SHA-256 fingerprint matches the export inputs; and surfaces unresolved tokens, external images, and generic-only font stacks |
exports/<name>_<ts>_native_charts_tables.pptx (opt-in via --native-charts-and-tables) |
when data-pptx-replace-with markers should replace SVG-derived, shape-based charts/tables with PowerPoint-native Chart/Table objects |
data-backed objects with chart/table-specific controls; the default DrawingML shapes remain independently editable |
exports/<name>_<ts>_narrated.pptx (via --recorded-narration or --narration-audio-dir) |
embeds matched narration audio; complete recorded mode directly supports auto-play and PowerPoint video export | --recorded-narration requires matching audio for every slide and writes duration-plus-padding auto-advance; low-level --narration-audio-dir permits partial or zero coverage and writes auto-advance only with --use-narration-timings |
exports/<narrated_stem>.mp4 (optional via powerpoint_video.py) |
animation-faithful narrated video on Windows PowerPoint 2016+ | delegates to PowerPoint's native encoder and waits for completion; it is a post-PPTX integration, not a second deck renderer |
backup/<ts>/svg_output/ (default output path only; copy is best-effort after directory creation) |
re-export from frozen SVG sources without rerunning the LLM | after successful conversion the exporter creates the backup directory and attempts the copy; explicit -o creates none, copy failure does not block export, prints a warning outside quiet mode, and leaves postflight backup_path empty, while directory-creation failure remains fatal |
Validation JSON files are cold audit artifacts, not routine model inputs. The exporter reads the SVG quality report programmatically and, in the default non-quiet flow, prints a compact [POSTFLIGHT] receipt with the status, quality-gate result, Slide count, warning-category counts, and artifact paths. Successful agents consume that receipt instead of loading either complete JSON; only failure investigation or an explicit audit extracts targeted report fields.
This is easy to miss when reading the code. Shared cleanup modules, the local-reference expander, and the inline-geometry materializer are used both to write svg_final/ and in memory during native conversion. The checker, editor, and structure parser also share parts of the geometry interpretation, but they are not artifact consumers in this section.
Disk consumer — in the default Generate flow, finalize_svg.py writes svg_output/ → svg_final/ once per run, expanding both project icon placeholders and qualified local <use> references. This mandatory default-flow output feeds IDE/browser preview and may be inserted manually as an SVG picture; it is not converted into a separate PPTX artifact. Quick-generate skips the disk consumer.
Memory consumer — native pptx generation reads svg_output/ directly (no disk hop). It materializes author SVG inline geometry, expands project icon placeholders, materializes geometry injected by those icons, expands qualified local <use> references, and finally processes positional text runs:
| In-memory call site | Preprocessor | Why native pptx needs it |
|---|---|---|
svg_to_pptx/drawingml/converter.py |
svg_to_pptx.geometry_properties |
inline-style geometry must become XML attributes before translation and must run again after icon expansion |
svg_to_pptx/use_expander.py |
svg_finalize.embed_icons |
DrawingML doesn't recognize <use data-icon="...">; without expansion every icon silently drops |
svg_to_pptx/use_expander.py |
static local-reference expansion | DrawingML does not preserve SVG <use> instance graphs; qualifying subtrees must be materialized with instance-local IDs |
svg_to_pptx/tspan_flattener.py |
svg_finalize.flatten_tspan |
DrawingML text runs cannot reposition mid-paragraph; a dy-stacked block of <tspan>s would otherwise collapse onto one baseline, and an x-anchored tspan would render in the wrong column |
| Module | Disk consumer | Memory consumer | Delete impact |
|---|---|---|---|
geometry_properties.py |
finalize_svg.py after copy and again after icon expansion |
drawingml/converter.py; the checker, editor, and template structure parser share the same interpretation |
inline-style geometry no longer maps consistently into XML geometry, so preview, validation, and native conversion may diverge |
embed_icons.py |
finalize_svg embed-icons step (followed by local-use expansion) |
svg_to_pptx/use_expander.py |
native pptx loses all icons, and svg_final/ loses visual closure for supported icons |
svg_to_pptx/use_expander.py (local references) |
finalize_svg embed-icons step |
native converter preflight | finalize/native export can no longer materialize qualified local reuse |
flatten_tspan.py |
finalize_svg flatten-text step |
svg_to_pptx/tspan_flattener.py |
native pptx multi-line dy-stacked text collapses to one line |
align_embed_images.py |
finalize_svg align-images step |
— | svg_final/ loses ordinary-image embedding, so IDE/browser preview and manually inserted SVG pictures lose those images |
crop_images.py / embed_images.py / fix_image_aspect.py |
imported by align_embed_images.py |
— | align_embed_images ImportError, full chain broken |
svg_rect_to_path.py |
— (legacy standalone utility; no supported pipeline consumer) | — | no supported preview or native-PPTX artifact depends on it; PowerPoint's manual Convert to Shape command is outside the project contract |
Not every PPTX-related request should regenerate slides. PPT Master now has direct OOXML routes for cases where the native deck itself is the object being edited.
template_fill_pptx.py is a thin CLI wrapper over scripts/template_fill_pptx/. Its analyzer extracts a slide library with text slots, tables, charts, and geometry; the fill plan selects source slides, confirms replacements, then the applier clones slides and patches XML parts directly. This route deliberately avoids SVG: a user who supplies a PowerPoint template usually wants those native slide masters, placeholders, tables, and charts to remain PowerPoint-native.
native_enhance_pptx.py is the stable entry point for finished-deck enhancement. It delegates to native_enhance_pptx_core.py and patches the PPTX package from a project copy: notes, global or per-slide page transitions, recorded narration media, slide timings, and related metadata. Intake records a source hash and ordered slide-part roster; validate/apply reject source drift or incomplete requested material. A read-only delivery check inventories package integrity, fonts, media, hidden slides, size, and existing motion at intake/preflight, then audits the candidate before atomic publication. The retired native_narration_pptx.py name remains only as a thin CLI compatibility shim. The contract is preservation: existing content, layout, and formatting are not regenerated.
These direct routes share some analysis primitives with the main pipeline, but at different depths. Template Fill consumes the standard PPTX intake slide library. Native Enhance uses ppt_to_md.py for content understanding, generates its own lightweight slide_index.json from the archived package, and keeps machine delivery reports under validation/. Neither shares the SVG authoring or post-processing stages. That separation is intentional: SVG generation is a design synthesis path; direct OOXML editing is a preservation path.
svg_to_pptx.py implements the final defensive layer defined in the design philosophy; this section explains only the internal structure of that constrained compiler route.
Why per-element dispatch, not whole-file translation. SVG's hierarchical model maps cleanly onto DrawingML's group / shape / picture types — there's no need for a holistic optimizer that re-plans the slide. Each shape kind gets its own narrow translator, which keeps each translator simple enough to debug and unit-test in isolation. The output quality of a slide is the sum of independent local conversions; that property is fragile under whole-file translation but robust under element dispatch.
Why imported and authored shape metadata are separate. A lossless imported SVG may need native-shape metadata, hidden carriers, and preview fingerprints to recover an advanced PowerPoint shape. That representation stays immutable in the temporary analysis workspace as native-payload backing. svg_authoring_view.py creates the editable template-creation IR: lightweight SVGs with document-local source refs plus an authoring_manifest.json containing paths and initial hashes, not duplicated payload. standard / fidelity author project-canonical SVG and use the compact authored-preset group only for exact registered preset matches. Mirror materializes validated templates from the IR and rehydrates converter-supported metadata only for unchanged Slide-local/slot refs; fixed structural layers remain direct atoms, unsupported or edited objects keep their current SVG fallback, and IR-only refs do not enter final template SVGs.
Why there is only one PPTX compiler route. Native export reads authored SVGs and translates supported SVG elements into DrawingML shapes. The normal deck path reads svg_output/; when requested, create-template invokes the same structured compiler on validated template prototypes to produce exports/<id>_template_preview.pptx as review evidence. The project does not package whole-slide SVG media or alternate raster renderings into a second PPTX. svg_final/ is still generated on every standard deck run, but it is only a derived visual-preview / SVG-picture artifact rather than a PPTX source; PowerPoint's manual Convert to Shape command remains outside the supported contract.
Why structure is authored before visual generation on structured reuse routes. Master and Layout are not post-processing discoveries. With template_reuse_scope: mirror|layout, the Strategist writes unique Master/Layout definitions and complete page assignments before SVG generation; the Executor writes those identities, fixed atoms, and slots while composing each page, and export only compiles declared structure. template_reuse_scope: style, free-design, and brand-only decks make the opposite trade: they stay on mode: flat, keep every object Slide-local, author no structure metadata, and receive only a clean project-owned Master/Blank-Layout shell at export. Legacy inputs may inform a new create-template workspace, but they never enter an in-place structure-upgrade route; neither generation mode triggers heuristic Master/Layout promotion or placeholder inference.
Why Master/Layout visuals are atomic. A Master or fixed Layout object must be one direct root child. Group-level transforms, opacity, styles, and z-order from imported PPTX objects are pushed into individual atoms during reconstruction. This deliberately gives up source group-editing hierarchy in exchange for a simple, deterministic ownership model that can be compared across pages and rebuilt into native parts without nested structural ambiguity.
Why Layout slots use groups. A reusable slot is a top-level <g> with semantic type and design-zone bounds. A normal slot contains exactly one compatible carrier; export unwraps it into the real Slide placeholder binding. A genuinely composite object region uses an explicit proxy downgrade: the visible group stays ordinary and a hidden transparent placeholder supplies PowerPoint binding. Layouts may also have zero slots, so fixed visual pages do not need fake full-page placeholders.
Why reusable bounds are design zones, not measured text boxes. Slot bounds come from the intended safe area, column, panel inset, or picture frame—not glyph width, line count, or the current content's tight box. The current Slide retains its own authored carrier geometry, so 4:6, 3:7, and 5:5 instances may share one Layout when they express the same semantic composition. Text length therefore cannot accidentally split or mutate the reusable Layout contract.
Why the internal application plan retains two fields. Strategist derives template_reuse_scope to record literal mirror reuse, structural layout reuse, or flat style reference. Structured plans then derive template_adherence: strict|adaptive: page_layouts records the complete authoring prototype, pptx_masters / pptx_layouts record unique reusable definitions, and page_pptx_layouts records page assignment. Strict preserves the declared prototype contract. Adaptive retains its Master, and Strategist may declare a new Layout only when fixed Layout atoms or slot topology/bounds change. If construction reveals that need, execution returns upstream and resumes only after Strategist updates, reads back, and validates the definition and assignment; the exporter never infers it later. These are exporter values, not user confirmation options. A template-backed definition may remain unused and still register in the final package. Layout skin remains project-controlled, while mirror additionally preserves literal visuals and text-node topology. style has no adherence value or structure mappings.
Why explicit-Layout text defaults are split between Master and Layout. Both flat and structured export write the declared title anchor and a deterministic nine-level body hierarchy into Master defaults while preserving indentation and bullet settings. On structured routes, each generated Layout text slot additionally copies its carrier's first run size into the level-one default while retaining the prompt's direct size. This preserves Layout-specific scale when placeholder text is inserted or reset; direct runs on generated Slides remain unchanged.
Why structured output is read back before publication. Metadata preflight cannot prove package serialization preserved every relationship and registration. Export therefore reopens the temporary PPTX and validates published Slides separately from the complete Master/Layout roster, including definitions unused by all Slides. It checks Presentation → Master → Layout → Slide registration, physical part/content-type rosters, picker identities, exact static-object order, placeholder type/effective index/bounds, carrier bindings, hidden proxies, and zero-slot Layouts before publishing the file.
Why Create Layout / Create Deck have authored and preservation modes. pptx_template_import.py emits layered Master/Layout/Slide references plus native structure facts. standard / fidelity use those assets and visuals as references, then author a new topology from the confirmed reusable behavior. Mirror instead materializes a new workspace from the validated source roster and topology one-to-one, allowing only mechanical normalization required by the explicit structured contract and never inventing absent facts. The original PPTX remains immutable analysis evidence, not a packaged export dependency. Create Brand has no structural replication strategy.
Why create-template uses one workspace route in both scopes. create-template keeps library as its default indexed output and may instead write under an initialized project. Both roots require templates/; images/, icons/, and on-demand exports/ appear only when they contain real files, and existing SVG asset references follow the same rules. This makes the workspace migratable and reusable without a library-only package branch or a reduced project branch. The sole scope difference is global index registration. Both scopes share one portable workspace contract, but only Layout / Deck own a structured SVG contract; Brand remains identity-only.
Why each template SVG stays complete while still compiling to native structure. A template SVG repeats the inherited Master/Layout visuals together with sample Slide content so it opens as a complete standalone page. During generation, page_layouts selects that prototype and the output SVG remains complete. Export removes repeated inherited atoms, emits real Master/Layout parts, and leaves actual slot carriers and Slide-local content on the Slide.
Why PowerPoint-native Chart/Table reconstruction uses explicit replacement markers, not automatic object replacement. The standalone pptx_to_svg.py importer emits a visible SVG fallback plus data-pptx-replace-with and <metadata type="application/json"> only for validated table/chart subsets. Generated decks prepare that pair only when Strategist marks the §IX page block Native-ready: yes; §VII remains a positive catalog-reference inventory, and a catalog marker is a capability example rather than an execution decision. The parent marker determines the payload schema; ordinary shapes and connectors never use this contract. Table import covers exact physical row/grid topology, canonical rectangular merges with empty slaves, safe solid/no-fill per-side borders, plain multi-paragraph cells, and a closed run-rich paragraph form. A rich paragraph contains non-empty runs; every run requires text and may use only bold, italic, underline, strike, color, font_size, one font_family, lang, and alt_lang. Unknown source presentation-only run XML without a non-empty effectLst / effectDag normalizes into that schema; a table-cell run effect instead disables native replacement and adds a blocking effect diagnostic. Relationship-bearing text, extensions, line breaks, fields, tabs, bullets, malformed text topology, noncanonical merges, unsafe borders, and non-solid fills remain fallback-only. The normalized fallback for table style {5C22544A-7EE6-4342-B048-85BDC9FD1C3A} resolves wholeTbl, firstRow, horizontal banding, theme colors/fonts, and direct overrides; this is not a full built-in/custom style registry.
For supported parsed column/bar/line/area, pie/doughnut, scatter, and bubble charts, a missing baked preview is replaced by a deterministic readable SVG fallback marked data-pptx-fallback-kind="normalized". The importer also covers the verified column/line/area combo subset, canonical four-series OHLC stock, area charts with numeric date axes, verified scatter/bubble charts with the closed axes.x / axes.y contract, radar, safe of_pie serLines, axis/title/legend normalization, and bounded bar/column gap/overlap cases. gapWidth is accepted only as one integer in 0..500, and overlap only as one integer in -100..100; these presentation values intentionally normalize in native output, while malformed, duplicate, or out-of-range input fails closed. Combo plots may retain independent primary/secondary category caches and workbook ranges. XY import derives scatter_style from uniform effective series line/marker/smooth state. The closed category/value and XY axis contracts retain kind, position, visibility, label position, number format, min/max/major unit, reversal, and major gridlines for native read-back; the normalized XY fallback consumes only the two major_gridlines flags.
ChartEx import is deliberately closed to seven validated data models: treemap, sunburst, histogram, pareto, box_whisker, waterfall, and funnel. Their supported hierarchy/category/value/series/subtotal data topology round-trips through native output and reimport. Numeric caches must be non-empty and finite, with canonical non-negative counts/indexes and exact contiguous point topology. Source ChartEx style, axes, labels, and binning may normalize; this is not arbitrary ChartEx import or presentation fidelity. C4/C5 do not expand the normalized renderer, so valid active types outside it still use data-pptx-fallback-kind="placeholder" without a source preview. Full AxisSpec, arbitrary ChartEx families, arbitrary rich OOXML, rotated/flipped/3D charts, unverified combo/stock/date-axis variants, and other unmodeled semantics remain outside the active import subset. Native replacement may normalize payload-external presentation details and retains the data-model-first warning. Default export keeps fallback children as editable DrawingML shapes; only --native-charts-and-tables activates PowerPoint-native Chart/Table objects with a data source and object-specific editing model. Every active imported marker carries data-pptx-import-source="pptx" and data-pptx-fallback-sha256: stale visible edits, reachable SVG definition/reference changes, or marker transforms make native replacement fail rather than discard the SVG edit, while a hashless legacy imported marker that retains import provenance remains compatible with a warning. Generated authoring omits both importer provenance and a static baseline without warning. This importer/exporter pairing is a reconstruction aid, not a preservation-route substitute for template-fill-pptx or native-enhance-pptx.
The interesting design choice is the animation anchor, not the effect list.
Why anchor object animations on top-level <g> groups. PowerPoint's
animation timeline is shape-keyed—each animated object needs a stable shape ID.
Animating individual primitives would produce 30+ separately moving atoms per
slide, while animating only the slide as a whole loses visual storytelling.
Top-level groups are the natural granularity: Executor already uses
<g id="..."> to mark logical content blocks, so entrance, emphasis, path,
and exit effects share the same semantic units. The group identifies a
PowerPoint shape target rather than one timeline record: the legacy
single-effect object creates one Animation Pane row, while effects[] may
create several ordered rows that all target the same shape.
Why page structure is auto-skipped. Any top-level group with data-pptx-layer is static structure, and the current scanner also treats every explicit data-pptx-placeholder as static page framing; background / header / footer / decoration / watermark / page-number roles cover the remaining chrome. The ID-token fallback is not enabled or disabled per SVG: it applies to each top-level group that lacks layer, role, and placeholder markers, so a mixed new/legacy SVG may still use the legacy ID heuristic on only its unmarked groups. Separately, when an SVG has no top-level groups, no animation target has been found, and only one to eight root primitives qualify, those primitives form a bounded compatibility fallback. This is the scanner's actual scope; the animation reference's whole-page “marker-free legacy SVG” wording still needs separate alignment with the implementation.
Why object-level animation uses a sidecar, not SVG attributes. SVG remains
the static visual source of truth. Custom PPTX animation is export policy, so
per-object overrides live in optional animations.json keyed by slide stem and
top-level group id. A populated group uses either the fully compatible legacy
single-effect fields or a non-empty effects[] envelope, never both. Each
resolved row owns its effect, sequence order, delay, duration, Start mode,
and optional trigger_shape; the slide animation trigger supplies only the
inherited Start mode. The generated scaffold is neutral (effect: none) and
leaves groups as {} until motion is adopted. This keeps PowerPoint-specific
metadata out of SVG without forcing one semantic object to have only one
motion phase.
Why automatic modes remain entrance-only. auto, mixed, and random
answer one bounded question: how an otherwise generic reveal should enter.
They do not invent emphasis, movement, or exit intent. Those three categories,
and an explicitly selected entrance, use canonical effects in the sidecar so
the authoring decision remains inspectable.
Why the target model stops at top-level shape effects. The generated model does not infer paragraph/text-range builds, author custom freeform motion paths, sequence native Chart/SmartArt internals, or emit media playback commands. Native motion-path presets remain valid object effects; media playback remains in the audio/video workflows.
Why recorded narration drives auto-advance from clip duration. Recorded-narration mode targets video export, where no presenter clicks through the deck. It probes each clip's real duration and sets slide auto-advance to audio duration + --narration-padding; padding defaults to 0.5 seconds so the tail is not cut off. It does not use estimated reading speed or a fixed per-slide duration.
Why recorded narration rejects on-click object animation. PowerPoint can
record click timings during a real rehearsal, but PPT Master does not synthesize
object-level click events. The recorded narration path writes page-level audio
and slide auto-advance timings only, so click-driven object effects would leave
the export dependent on extra manual PowerPoint rehearsal. Decks exported with
--recorded-narration must therefore use click-free object animations
(after-previous or with-previous) on every resolved row; this also excludes
trigger_shape.
Why native video export is a separate command. Audio synthesis and PPTX
packaging are cross-platform project operations; PowerPoint video encoding is a
Windows desktop integration. powerpoint_video.py therefore accepts the final
narrated PPTX, invokes CreateVideo, and polls CreateVideoStatus to present a
synchronous CLI result without coupling Office automation to the TTS backends.
The tempting simplifications below have explicit costs. Treat them as negative contracts unless the surrounding architecture is deliberately redesigned.
| Do not collapse or add | Why |
|---|---|
| Do not fuzzy-match template names or style phrases to library paths | Step 3 must be deterministic; wrong template selection is harder to recover from than free design |
| Do not treat a raw PPTX template as a Step 3 template | when used as a template/page shell, it belongs to native cloning/filling; source use, 1:1 beautify, and restructuring instead follow their Generate boundaries rather than passing a PPTX directly to Step 3 |
Do not merge template-fill-pptx, beautify-pptx, and native-enhance-pptx into one "PPTX optimization" route |
their preservation contracts differ: native fill, 1:1 redesign, and direct enhancement are separate operations |
| Do not script-generate batches of Executor SVG pages | cross-page design judgment depends on sequential main-agent authoring |
Do not make image_analysis.csv a durable cache |
images/ is a live folder; facts must be regenerated on use |
Do not make svg_final/ the default native PPTX input |
svg_final/ rewrites resources for visual preview, while native conversion needs high-fidelity svg_output/ semantics |
Do not treat svg_final/ as a shape-recoverable or no-external-dependency interchange format |
it serves visual preview and SVG-picture insertion, but EMF/WMF retain external-reference exceptions; PowerPoint Convert to Shape is unsupported |
| Do not auto-enable object-level animations | page transitions are default; object motion is an explicit export policy |
| Do not default visual review, narration, chart verification, or animation customization into every run | these workflows have narrow triggers and extra dependencies |
Do not replace finalize_svg.py with a file copy |
finalization embeds icons/images, flattens special text, and prepares preview artifacts |
Do not use analysis/<stem>.slide_library.json as a second source of chart values in the main pipeline |
Markdown owns content values; intake chart/table entries are structural digests unless a direct-PPTX workflow owns them |
workflows/index.md is a maintainer-only inventory and does not enter the task-loading chain. Runtime route selection is authoritative in workflows/routing.md. PPT Master has exactly four top-level artifact routes: Generate PPTX, Create Template, Fill Native PPTX, and Enhance Native PPTX. A user request enters one of those routes; no supporting runbook competes with them.
Supporting files stay separate only to keep route contracts focused and load optional context on demand:
| Class | Runbooks | Owning route |
|---|---|---|
| Generation profiles | beautify-pptx, quick-generate |
Generate PPTX with either wording/page invariants or the explicit direct SVG-to-PPTX short circuit |
| Template child workflows | create-brand, create-layout, create-deck |
Create Template dispatches exactly one for identity-only, brand-neutral/application-neutral structure, or a recurring application with integrated identity/structure |
| Template-input stage | apply-template-workspace |
Generate PPTX Step 3; loaded only when an explicit workspace-root path triggers it |
| Generation stages | topic-research, resume-execute, refine-spec, verify-charts, visual-review, live-preview, customize-animations |
Generate PPTX at their defined intake, planning, editing, quality, or post-processing points |
| Shared stage | generate-audio |
Generate PPTX post-processing or Enhance Native PPTX narration integration |
| Governance | failure-recovery |
Global stop/continue policy for all four routes; concrete recovery matrix and resume pointers for Generate PPTX |
This classification is a responsibility boundary, not a filename preference. A new top-level route is justified only by a distinct artifact lifecycle and mutation model; kind-specific execution inside Create Template remains a child workflow, optional route behavior remains a profile or stage, and cross-route policy remains governance.