$npx -y skills add wanshuiyin/ARIS-Movie-Director --skill comic-panel-prompt-builderPhase-1 step of comic-author — the DETERMINISTIC compiler (搬运工原則) that turns ONE gate-approved panel_spec + its status:locked blueprint into the EXACT fixed-section bake string for the spiral engine via the shipped scripts/build_prompt.py (+ the canonical scripts/_validate.py vet
| 1 | # comic-panel-prompt-builder — the Deterministic Bake Compiler (搬运工原則) |
| 2 | |
| 3 | The **last authoring step before a pixel ever gets baked**. Given ONE upstream-approved `panel_spec` and its |
| 4 | `status: locked` `blueprint`, this skill COMPILES — it does not brainstorm — the *exact* message |
| 5 | [`comic-director`](../comic-director/SKILL.md) (Phase 2/3) will hand to the agent `mcp__codex__codex` sidecar |
| 6 | bake (Codex's native image tool), plus the locked identity-ref list. It is the comic twin of the framework's |
| 7 | `shot-prompt-builder`: a pure Layer-3 transform |
| 8 | with **no Codex call in the happy path** — it only emits a `prompt_bundle`; the spiral engine submits it. |
| 9 | Everything the generation backend ever sees passes through here, so this is where the **搬运工原則** is |
| 10 | enforced at emit time: the bake backend (Codex's native image-generation tool; the underlying image model is |
| 11 | not pinned or attested by this repo) owns optics; `ART_BIBLE.md` owns style; **no camera / |
| 12 | lens / lighting / "8K hyperrealistic cinematic" padding leaks into the bake**, and **no bubble text gets |
| 13 | baked** unless the panel is explicitly `text_mode: "baked"`. The author (storyboard/blueprint layers) decides |
| 14 | *what*; this skill decides *nothing* — it transcribes a locked spec into a backend-legal string and FAILS |
| 15 | (it never papers over) when the spec is malformed. |
| 16 | |
| 17 | ```text |
| 18 | panel_spec (status:locked) ─▶ ① RESOLVE — load panel_spec + its blueprint + ART_BIBLE style_prefix |
| 19 | + blueprint (status:locked) enforce 4 prerequisites (node_type, blueprint status:locked, REAL refs, style_prefix resolves) |
| 20 | ▼ |
| 21 | ② COMPOSE — fixed-section condition_string (order is load-bearing, do NOT refactor) |
| 22 | ▼ style_prefix + [BAKED DIALOGUE only if text_mode==baked] + SCENE + FIXED ELEMENTS |
| 23 | ▼ + ALLOWED CHANGE vs prior panel + FORBIDDEN + SCREEN-TEXT WHITELIST(expected_literals) |
| 24 | ▼ |
| 25 | ②·5 INJECT (retry only) — active failure_mode positive-invariants to the FRONT |
| 26 | ▼ |
| 27 | ③ VALIDATE — banned-vocab + length + no-baked-bubbles + real-refs on the COMPOSED string |
| 28 | ▼ (the hard gate — ANY hit = fail-closed, push the fix UPSTREAM) |
| 29 | ▼ |
| 30 | ④ EMIT — write the prompt_bundle node; route html_bubbles[] to the JSON viewer ONLY |
| 31 | ▼ |
| 32 | pass? ─ no ─▶ exit 4 (banned/length) | exit 7 (failure_mode trigger still fires) | exit 3 (prereq) |
| 33 | │ yes |
| 34 | ▼ |
| 35 | ⑤ stdout one-line JSON {prompt_bundle_id, panel_id, source_blueprint_id} |
| 36 | ``` |
| 37 | |
| 38 | ## Role |
| 39 | You are a **fail-closed transcriber**, not an author. You take a `panel_spec` that an upstream layer already |
| 40 | gate-approved and its `blueprint` that the cross-layer gate already flipped to `status: locked`, and you |
| 41 | produce the single exact `composed_prompt` (style_prefix + a fixed-section condition string) + the locked |
| 42 | identity-ref paths that the spiral engine will bake — together with the deterministic proof (a clean |
| 43 | `banned_vocab_scan`) that the message is backend-legal. You **never** invent a scene element, a number, a cast |
| 44 | member, or a style adjective; you **never** silently fix a malformed spec (you FAIL and point upstream); and |
| 45 | you **never** call Codex on the happy path (a Codex call only ever appears as a reported upstream bug). The |
| 46 | cross-model *judgement* of the baked pixels is not yours — that lives downstream in `comic-director`'s |
| 47 | `panel_gate`; keeping you deterministic is what stops the executor from self-acquitting. |
| 48 | |
| 49 | ## Node — what this skill reads / writes (`schemas/node_schema.json`) |
| 50 | - **Reads `panel_spec`** (node prefix `panel:`) — payload fields used: `source_storyboard_id`, `page_id |