$npx -y skills add wanshuiyin/ARIS-Movie-Director --skill comic-json-compilerPhase-1 (S9, the FINAL comic-author step) — assemble the LOCKED storyboard + locked per-panel blueprints into ONE schema-valid comic.json (the comic-ir/1.0 contract boundary handed to comic-director / run_comic.py). Project the page_order + each panel's condition{} + render fie
| 1 | # comic-json-compiler — locked storyboard + blueprints → one schema-valid `comic.json` (S9) |
| 2 | |
| 3 | The **last node of the left third of Figure 1**: take the locked `storyboard_spec` (the authoritative page |
| 4 | order + the MOTIF STATE TABLE) and the locked per-panel `blueprint` nodes and **compile** them into the single |
| 5 | `comic.json` (comic-ir/1.0) that is the contract boundary to [`comic-director`](../comic-director/SKILL.md) |
| 6 | (Phase 2/3). You don't hand-write this file panel-by-panel — that already happened upstream; this step is the |
| 7 | deterministic *projection* + *reconciliation* that turns the authoring nodes into the IR and **catches the |
| 8 | integrity bugs that only show up once everything is assembled** — chiefly the page-count / orphan-panel |
| 9 | mismatch (the **orphan-panel class**). The two deterministic scripts the compile gate runs are |
| 10 | **per-page** (`run_comic.py` needs `--page`/`--panels`) and the JSON schema leaves `condition`/`content_svg` |
| 11 | OPTIONAL — so **neither of them sees the whole `pages[]`/`panels{}` set and neither catches an orphan.** That |
| 12 | whole-comic reconciliation against the storyboard authority is **THIS skill's own inline job** (the ~7-line set |
| 13 | diff below), run *before* the gate; the gate then certifies the per-page + wiki-conformance floor. |
| 14 | |
| 15 | ```text |
| 16 | locked storyboard_spec (page_order = AUTHORITY) ┐ |
| 17 | locked motif_ledger (per-panel ground-truth) │ |
| 18 | locked panel_spec × N (the 9-field specs) ├─▶ ① ASSEMBLE pages[] + panels{} per comic.schema.json |
| 19 | locked blueprint × N (content_svg + expected_literals) │ (author ONLY authored fields; engine fields EMPTY) |
| 20 | locked prompt_bundle × N (optional, identity refs) ┘ ▼ |
| 21 | ② RECONCILE page-count integrity ── INLINE python (this skill; no phantom script) |
| 22 | (orphans · dangling refs · page_count vs page_order · grid2x2==4 · recap legitimacy) |
| 23 | ▼ |
| 24 | ③ VALIDATE jsonschema(comic.schema.json) — SHAPE only (it does NOT enforce content_svg/literals) |
| 25 | ▼ |
| 26 | ④ FAIL-CLOSED contracts (every panel a content_svg · baked figure ⇒ expected_literals) ← THIS skill asserts; schema won't |
| 27 | ▼ |
| 28 | ⑤ comic-cross-layer-gate decision:compile_<slug> --gate compile (DETERMINISTIC: run_comic.py --dry-run per page AND cli/validate_wiki.py both exit 0) |
| 29 | ▼ |
| 30 | approve? ─ revise ─▶ fix the OFFENDING node upstream, recompile (you don't invent content) |
| 31 | │ approve |
| 32 | ▼ |
| 33 | ⑥ EMIT comic.json (output-versioning) + movie.project.json pointer-hub + asset-copy manifest |
| 34 | ``` |
| 35 | |
| 36 | ## Constants |
| 37 | - **CONTRACT BOUNDARY** = `comic.json` (`comic-ir/1.0`) + the assets it references. Everything downstream |
| 38 | (`comic-director`, `run_comic.py`, the Phase-3 viewer build `packages/viewer/build_comic.py`) reads ONLY this |
| 39 | file + its assets — so a bug that survives this step survives to production |