返回 ppt-master
visual-review.md
根目录 / skills / ppt-master / workflows / stages / visual-review.md
1 ---
2 description: Optional quality-gate stage for per-page rubric-based visual review.
3 ---
4
5 # Visual Review Stage
6
7 > Optional Generate-PPTX quality stage. Goal: reduce human iteration by letting AI subagents visually self-check each rendered slide against a fixed rubric and apply atomic position/spacing fixes.
8 >
9 > Reads `<project>/svg_output/<page>.svg` and a pre-rendered PNG of each slide, then either applies a fix or flags `needs_human`. When an installed/fused Style exists, it also reads that workspace's `Review Focus` as supplemental acceptance context. **Never touches** brand decisions, layout structure, or other files.
10 >
11 > This stage is **context-independent** — invokable in a fresh chat session with only `<project_path>` as input. No upstream conversation context required.
12
13 ## Positioning
14
15 This is an **optional auxiliary loop**, opt-in only. The [`generate-pptx`](../generate-pptx.md) Step 1–7 pipeline does not invoke it; trigger only when the user explicitly asks for a visual re-pass on the generated SVGs before export.
16
17 **Token cost**: each batch subagent re-reads the rubric + `design_spec.md` + `spec_lock.md` + the short Style Review Focus when present, and processes K SVG+PNG pairs. For a 20-page deck with K=5, expect on the order of 100–150K additional input tokens on top of the main generation run.
18
19 ## When to Run
20
21 - Executor ([`generate-pptx`](../generate-pptx.md) Step 6) has finished all pages
22 - `svg_quality_checker.py` has passed
23 - Post-processing (`finalize_svg.py`, `svg_to_pptx.py`) has **not** yet run
24 - The user has explicitly requested visual review
25
26 For decks containing data charts, run [`verify-charts`](./verify-charts.md) first — visual-review focuses on visual rhythm / collision / alignment, not chart coordinate math.
27
28 ## When NOT to Run
29
30 - The project has no `svg_output/<page>.svg` files yet — finish Executor first
31 - `svg_quality_checker.py` has not been run or has failed — fix static violations first
32 - User has already applied annotations via the `live-preview` stage and is in a fixed-edit loop — describe changes directly, do not re-trigger rubric
33 - The user has not asked for it — do not auto-invoke based on inferred model capability or deck size
34
35 ---
36
37 ## Prerequisites
38
39 ```bash
40 # 1. playwright + chromium installed (the PNG renderer)
41 pip install playwright
42 python3 -m playwright install chromium
43
44 # 2. live-preview server running for this project (provides inlined SVG fetch)
45 python3 skills/ppt-master/scripts/svg_editor/server.py <project_path> --no-browser
46 # (single instance per project — if it's already running, skip)
47 ```
48
49 The renderer (`visual_review.py`) does **not** auto-start the live-preview server. Without `--server-url`, it discovers the actual port from the target project's `live_preview/lock.json`; an explicit `--server-url` overrides discovery. In either case it validates `/api/health` against the resolved target project before rendering and rejects a server for another project.
50
51 > **Why playwright, not cairosvg**: cairo's text API has no font-fallback chain, so CJK characters render as tofu boxes for any deck whose font-family list relies on system fallback (Microsoft YaHei / PingFang SC / etc.). Playwright drives a real chromium and produces output identical to what the live-preview browser shows — the only fidelity-preserving option for bilingual decks.
52
53 ---
54
55 ## Step 1 — Pre-render all PNGs
56
57 ```bash
58 python3 skills/ppt-master/scripts/visual_review.py <project_path>
59 ```
60
61 This writes one PNG per page to `<project_path>/.preview/<page>.png` at 1280×720, with `<use data-icon>` inlined and `<image href>` resolved exactly as the live-preview browser sees them. Renders are serialized via a project-local file lock — safe to invoke concurrently.
62
63 Exit codes:
64
65 - `0` — all pages rendered
66 - `2` — live-preview server unreachable or serving a different project (start the target project's server per Prerequisites)
67 - `3` — playwright python / chromium not installed (or browser failed to launch)
68 - `4` — one or more page-level render failures (see stderr; partial output is on disk)
69
70 If any page comes back with `"all_background": true` in the JSON summary, that page rendered to a blank surface — investigate before continuing (broken `<use>` reference, missing image asset, etc.).
71
72 ---
73
74 ## Step 2 — Spawn the review team
75
76 Create a team and dispatch one orchestrator agent. The orchestrator partitions the N pages into batches of ≤ K pages (default **K = 5**) and spawns one subagent per batch **in parallel** (single message, `ceil(N/K)` parallel `Agent` calls). Each batch subagent reads the fixed inputs (rubric + `design_spec.md` + `spec_lock.md` + conditional Style Review Focus) **once**, then iterates over its assigned pages sequentially.
77
78 Before dispatch, inspect `<project>/templates/design_spec.md`. If it declares `kind: style` or its fused provenance contains an active Style segment, read only `## VII. Review Focus` once and include those checks in every batch prompt. Otherwise pass no Style supplement. This lookup never triggers visual review; it runs only after the user has already activated this stage. The supplement cannot weaken the fixed rubric or widen edit permissions.
79
80 ```text
81 TeamCreate(team_name="visual-review-<project>", agent_type="orchestrator")
82 Agent(
83 team_name="visual-review-<project>",
84 subagent_type="general-purpose",
85 name="orchestrator",
86 prompt=<orchestrator-prompt>,
87 )
88 ```
89
90 The orchestrator prompt must be self-contained and is the **single** place where dispatch shape, batch size, and forbid lists are stated — the rubric (`references/visual-review.md`) defines the contract those prompts must satisfy. Required fields (all absolute paths):
91
92 - `<project_path>` — project root
93 - Full page list with `page_role` per page (parse `<project>/design_spec.md` §IX outline; **fixed compatibility default**: if an existing `design_spec.md` lacks §IX, use `content` for every page and flag this in the final report; if `design_spec.md` itself is missing, restore it through [`failure-recovery.md`](../governance/failure-recovery.md) §3 before dispatch)
94 - Batch size `K` (default 5; raise to 10 for token-sensitive runs on large decks, lower to 3 for high-fidelity short decks — see rubric §6.1)
95 - Iteration budget per page (default 1; 2 only for high-stakes / final-cut runs — see [Appendix: Iteration loop](#appendix-iteration-loop-opt-in))
96 - Path to the rubric: `skills/ppt-master/references/visual-review.md`
97 - Style Review Focus excerpt, only when the conditional lookup above found one; preserve its wording and source path
98 - Dispatch contract reference: rubric [§6](../../references/visual-review.md#6-dispatch--messaging-contract) (batched parallel spawn, self-contained prompts, mandatory `SendMessage` on idle, anonymous-name tolerance)
99 - Subagent forbid list: do not edit any other page, `design_spec.md`, `spec_lock.md`, `templates/design_spec.md`, `animations.json`, `image_prompts.json`, or `images/`
100
101 **Host compatibility**: `TeamCreate` and `SendMessage` are Claude-Code-specific multi-agent primitives. On hosts without those primitives (Cursor, VS Code + Copilot, Codebuddy, etc.) the main agent processes batches sequentially — same partitioning, same per-batch prompts, no parallel dispatch. Token savings from shared fixed inputs still apply; wall-clock time grows roughly N/K-fold.
102
103 ---
104
105 ## Step 3 — Aggregate findings
106
107 The orchestrator emits the aggregate Markdown table back to you (the main agent):
108
109 ```
110 | page | role | status | hard_hits | soft_hits | fixes_applied | needs_human_reason |
111 |------|------|--------|-----------|-----------|---------------|---------------------|
112 ```
113
114 Statuses:
115
116 - `ok` — page passed clean, no fixes applied
117 - `fixed` — at least one fix applied, all Hard rules now pass
118 - `needs_human` — fix attempted but rolled back (rule §4.2), or rule violation requires brand/structure decision outside the rubric's scope
119 - `render_failed` — Iteration 0 PNG sanity failed (rare; usually means renderer / server issue)
120 - `prereq_failed` — static checker hadn't been run
121
122 Plus a brand-token aggregate at `<project>/.review/brand_review.json` if any §1.1 escalations occurred — review this once at the end of the run, not per page.
123
124 ---
125
126 ## Step 4 — Decide next move
127
128 For each row in the table:
129
130 - `ok` / `fixed` — no action; the SVG has been updated in-place (originals are at `<project>/.review/backup/<page>.iter<N>.svg`)
131 - `needs_human` — read the page's JSON `needs_human_items[].suggested_fix_summary`, decide with the user whether to apply or defer
132 - `render_failed` — re-run `visual_review.py` for that page only (`--pages <token>`); if it persists, hand off to manual review
133 - `prereq_failed` — go back and run `svg_quality_checker.py`
134
135 If `brand_review.json` is non-empty, that's a single decision applied across the deck (e.g., bump footer text color from `#6E7681` to `#8B949E` — one change, every page benefits). Do this once, then optionally re-run visual-review for the affected pages only.
136
137 After the table is clean, continue to [`generate-pptx`](../generate-pptx.md)
138 Step 7. That authority owns the serial commands, gates, and success criteria for
139 post-processing and export.
140
141 ---
142
143 ## Notes & invariants
144
145 - **Single source of truth for rules**: [`references/visual-review.md`](../../references/visual-review.md). This stage file is just the orchestration — never restate or paraphrase rules here.
146 - **Concurrency**: `visual_review.py` serializes renders via `<project>/.preview/.render.lock`. Subagents must never call the renderer directly without the lock.
147 - **Iteration budget**: default 1 iteration. Bumping to 2 doubles render cost and roughly triples token cost. Only worth it for high-stakes / final-cut decks.
148 - **Don't-touch (rubric §3)** is hard-enforced by subagents. If you want the subagent to e.g. change a brand color, that is **out of scope** — make the change manually first, then re-render & re-review.
149 - **Backups**: every modified SVG has a `.review/backup/<page>.iter<N>.svg` rollback anchor. Restore by `cp`.
150 - **The rubric is not the designer**: it catches collisions, drift, and rhythm errors — it does not improve a fundamentally weak layout. If 80%+ of pages come back `needs_human`, the Design Spec's pattern selection or Executor's realization geometry is the root cause, not this stage.
151 - **Playwright output discipline**: when an agent uses the playwright MCP tool `browser_take_screenshot` directly (outside the `visual_review.py` script), the `filename` parameter is resolved against the CWD (typically the repo root) — passing a bare relative path will create stray directories inside the repository. Always pass an absolute path:
152 - One-off probe / ad-hoc inspection → `/tmp/probe-<topic>-<n>.png`
153 - Project artifact (replaces what the script would have produced) → `<project_path>/.preview/<page>.png` (absolute)
154 - Never write to `<repo>/<anything>.png` or `<repo>/<some_dir>/...` — those are caught by `.gitignore` patterns but the cleanup burden is real
155
156 The `visual_review.py` script handles output paths correctly on its own; this rule only applies to direct playwright MCP usage during interactive exploration or recovery.
157
158 ---
159
160 ## Appendix: Iteration loop (opt-in)
161
162 Default behavior is single-iteration review: one scan, fix in place, write the report. The full iteration loop in [`references/visual-review.md`](../../references/visual-review.md) §4.1 supports:
163
164 1. Iteration 1: scan + fix
165 2. Re-render via `visual_review.py --pages <token>`
166 3. Iteration 2: re-verify changed elements + scan for new Hard hits
167 4. Rollback on any new Hard hit introduced by a fix
168
169 To enable, set iteration budget = 2 in the orchestrator prompt (this is a prompt-level instruction to subagents; neither `visual_review.py` nor the harness enforces it). Each added iteration roughly doubles render cost and triples token cost on the affected pages — reserve for final-cut runs only.
170
170 lines MARKDOWN