| name | comic-outline-creator |
| description | Phase-1 Layer-2 of a comic — turn a LOCKED skeleton (intent_spec + the pre-locked beat/shot list) into an approved outline_spec: a 6-column beat table that binds every ARIS capability to a STORY COST, plus the continuity-motif contract the storyboard layer will be held to. NOT free creation — editorial adaptation of a pre-locked skeleton via 3 parallel lenses → cross-model (Codex) synthesis → a density/restructure pass → a USER-approval HARD GATE. Cross-model synthesis is part of authoring here, not post-review. Author the comic.json downstream with comic-storyboard-creator + comic-blueprint-author; this skill only produces the outline + motif contract. |
| argument-hint | ["intent_node_id | --revise-from <beat_id>"] |
| allowed-tools | Bash(*), Read, Write, Edit, Grep, Glob, mcp__codex__codex, mcp__codex__codex-reply, mcp__gemini-cli__ask-gemini |
comic-outline-creator — the Outline + Motif Contract (Phase 1, Layer 2)
The middle-left of Figure 1: take a locked intent_spec (+ the pre-locked beat/shot skeleton it
carries — OR, for an idea-first comic with NO pre-locked skeleton, the 3 lenses first synthesize a beat
skeleton from the intent's logline / subjects / constraints / format, then adapt it the same way; the
synthesized skeleton is recorded so the deltas-vs-skeleton discipline still applies) and produce a single
approved outline_spec — the 6-column beat table that drives the
storyboard, and the continuity-motif arcs that become the storyboard's checkable contract. This is the
comic twin of aris_movie's movie-outline-creator (a Layer-2 authoring-time plan gate before any
pixels), specialized for our image-comic route: the deliverable is a plan, never a frame.
Two things are simultaneously true, and the whole skill is built around them:
(a) the outline is NOT a free brainstorm — it is an editorial adaptation of a pre-locked skeleton
(N beats / M shots, beat boundaries fixed), so every candidate must self-report its deltas vs the
skeleton; (b) an unbounded "ARIS capability showcase" silently rots into a product manual unless
every capability is bound to a concrete story cost and skill-name tags are banned from the 画面. The
3-lens → Codex-synthesis → density-pass → user-approval loop turns (a) into a faithful, debated outline and
the 侧栏讲解铁律 + the gate catch (b) every round.
intent_spec (logline + tagline + dual-identity + LOCKED skeleton)
│
▼ ① FAN-OUT: 3 parallel named lenses over the SAME skeleton (faithful ∥ comicnative ∥ clarity)
│ each ends with a self-authored "through-line + deltas vs the skeleton" section
▼
② SYNTHESIZE — Codex (different model family) reconciles the 3 → OUTLINE v2
▼
③ DENSITY/DESIGN pass — Codex MAY restructure panel count (e.g. centerpiece 4→5 pages, +mid-act page)
│ AUTHORS the 侧栏讲解铁律 (anti "product manual" guard)
▼
④ Emit the 6-column BEAT TABLE + the centerpiece sub-plan + the 5 motif arcs (exact per-shot values)
▼
⑤ READINESS gate (PRE-user, cross-model, blind to orchestrator prose) — scores ONLY the author-controllable
│ dims; EXCLUDES user_decision_record + the unresolved-questions veto (those are not yet satisfiable).
│ Two-step (never cold): write review:* nodes + `reviews` edges → THEN comic-cross-layer-gate <id> --gate outline
▼ readiness:advance
⑥ USER APPROVAL = HARD GATE — present; record ✅ APPROVED + fill 已定决策 + EMPTY 待确认 block
│ THEN the FINAL gate (now user_decision_record==5 IS satisfiable) → write outline_spec node (locked)
│ revise ─▶ ② (bounded: MAX_OUTLINE_REVISIONS=3 → auto-abandon → failure_mode node)
▼ approve + signed
outline_spec (locked) → SOURCE OF TRUTH for the storyboard layer
│
▼ (much later, orchestrator-owned) OUTLINE_FINAL_LOCK — after the asset layer locks, a cheap
re-check that the locked assets still match this approved outline (N1 two-stage; §EXACT gate)
Constants
- LENS_COUNT = 3, mandatory (
faithful, comicnative, clarity) — Tier-1 Workflow fan-out
(fan-out-pattern). Fewer than 3 lenses is a hard veto.
- SYNTHESIZER =
mcp__codex__codex, model_reasoning_effort: xhigh — a different model family from
the Claude lens authors. Codex both reconciles the 3 candidates AND runs the density/restructure pass;
the outline layer is itself a cross-model artifact (executor ≠ reviewer, reviewer-independence).
- GATE REVIEWERS =
mcp__codex__codex (NO model pin — follows the local codex config, currently
gpt-5.6-sol — at xhigh) ‖ Gemini (auto-gemini-3, readability dims) — each
sees ONLY outline_spec.json + intent_spec.json (the skeleton) + the lens files, never Claude's prose. They
do not acquit; they each persist a review:<slug> node (payload {target_node_id, reviewer, gate_kind: "outline", review_scores:{...}}) with a reviews edge review:<slug> → <outline_id>, and the SOLE acquittal
organ comic-cross-layer-gate --gate outline then fuses those
score-nodes (D4: never invoke the gate cold — write the reviews FIRST, then call the gate).
- THE GATE IS RUN TWICE BY THIS SKILL (the user-approval deadlock fix): a READINESS pass BEFORE user
approval (scores only the author-controllable dims; the gate's own
user_decision_record == 5 floor and the
unresolved-questions veto are not yet satisfiable, so the readiness reviewers explicitly omit them), then
the FINAL pass AFTER the user signs + the 待确认 block is emptied (now user_decision_record == 5 IS
satisfiable). See §EXACT gate. A THIRD, later touch — OUTLINE_FINAL_LOCK — is owned by the orchestrator,
not this skill: after the asset layer locks (provisional storyboard → asset gen/review), a cheap re-check
that the locked assets still match the approved outline (§EXACT gate → the N1 two-stage contract).
- MAX_OUTLINE_REVISIONS = 3, then auto-abandon → write a
failure_mode node so a re-run must diverge. Its
payload is exactly what validate_wiki.py PAYLOAD_REQUIRED demands for failure_mode: {"layer": "outline", "affected_shot_ids": [<the abandoned skeleton shots, e.g. all S01..SMM>], "active": true}
(node_id fail:<slug>, node_type failure_mode, status active). There is NO encoding_style field in
the schema — carry the "a re-run must diverge" positive-invariant in title or a non-required note, never a
fabricated required-looking key; the node must pass cli/validate_wiki.py.
- MAX_DRAFT_ATTEMPTS = 3 — schema-repair loop for the
outline_spec node; on each fail, codex-reply
quoting the validator errors verbatim. Never silently coerce a value to pass schema (change the
narrative + document it, or surface to the user).
- TARGET_PAGE_CEILING (soft cap, exceed ⇒ Codex must justify in
rationale.beat_count_justification,
not a hard stop): mvp=2, demo=6, longform=12 beats per tier (ported from MAX_BEATS_PER_TIER).
- MIN_CAST_PER_BEAT = every beat names ≥1 world/scene + the cast in it (text-panel beats: a
text-panel scene + its world). Ported from aris_movie's
MIN_ASSETS_PER_BEAT=2; a structural check
JSON-Schema can't express.
- NODE =
outline_spec (this skill reads intent_spec, writes one outline_spec). See §Node.
- APPROVAL IS NON-AUTOMATABLE — the loop can DRIVE to a clean gate, but only the user ACQUITS the
outline (
acceptance-gate). Nothing proceeds to the storyboard
layer until the user signs off, recorded inline.
Input contract — what this skill reads, what it must not invent
The contract boundary is the intent_spec node (§Node) — produced upstream by
comic-intent-parser, carrying: the logline (a single sentence whose climax may be an editorial
inversion — e.g. "the climax is NOT winning — it's that ARIS didn't let itself off the hook"); the
tagline; the dual_identity constraint ("an emotional story of honest research + an ARIS capability
showcase") the whole debate optimizes against; and the source_skeleton — the pre-locked beat list
(B01…BNN), shot list (S01…SMM), and beat boundaries. The skeleton is LOCKED; this skill ADAPTS it,
never re-derives it.
This skill is plan + verify: it never bakes a pixel (image gen is comic-director / Phase 2-3) and
never invents a beat boundary or a shot. Adding a page (a density-pass split) is allowed and must be
accounted for in the deltas; moving a beat boundary or dropping a shot is a delta that must be justified +
surfaced to the user. If intent.status != locked → REFUSE (the upstream hand-off token is locked =
approved + frozen; an under_review/draft intent is not ready — re-run comic-intent-parser to its user
gate). If the skeleton is missing → REFUSE and ESCALATE (do not fabricate one).
Procedure (an agent can execute this step by step)
0. Load + refuse-guard
Snapshot the intent_spec node. Pull cumulative wiki context: prior LOCKED assets (for reuse-over-invention),
and failure_mode nodes with layer="outline" (rejected/superseded outlines — a re-run must diverge from
them). Refuse if intent.status != locked (the upstream author-node hand-off token is locked, not active).
Checkpoint an OUTLINE_STATE.json (resumable —
resumable-runs).
1. FAN-OUT — write 3 parallel candidate LENSES over the SAME locked skeleton
This is Tier-1 Workflow fan-out (fan-out-pattern): three
independent passes, each a named lens over the identical skeleton, NOT three free drafts. Write each to its
own file (story/outline_candidate_{faithful,comicnative,clarity}.md). The three lenses are fixed:
faithful — one-to-one fidelity: M shots → M panels, no cut / merge / add, beat boundaries
B01…BNN preserved exactly. The conservative anchor (palette grammar + stamp mirrors live here).
comicnative — comic-as-a-medium: collapse runtime / motion shots into static-friendly pages
(in our run S07-S09 → one 2×2 page; 22 shots → 12 panels); choose a full-bleed / 2-up / 2×2
page-rhythm for scroll-reading.
clarity — legibility for a non-ML reader: foreground the through-line so the headline number-arc
(in our run +6.2 → +1.4) is readable via one concrete physical prop (the Tok|yo broken-JSON
evidence) + one wordless emotional gauge (executor bounce height).
Each candidate MUST end with a self-authored section: ## through-line + deltas vs the skeleton stating
exactly what it merged / added / kept and why (e.g. "merged S07-S09 → one 2×2 page (motion is
redundant in a static page); kept all 13 beats; moved Tok|yo's first plant earlier to B06-S09 as a
re-pointable物证"). A candidate with no deltas section is a hard veto — delta-accounting is the
discipline that proves it is an adaptation, not a guess.
2. SYNTHESIZE — Codex reconciles the 3 → OUTLINE v2
Call the SYNTHESIZER (different model family). Feed it the three lens files + the intent_spec +
schemas/node_schema.json's outline_spec shape, inside a demarcated === EXTERNAL CONTEXT (advisory) ===
fence; Claude's prose lives ONLY in that fence (reviewer-independence).
The synthesis takes the best of each lens — in our run: faithful's two-world WARM/DARK palette grammar
- the REJECT↔ACCEPT mirror,
comicnative's page-rhythm, clarity's motif arcs + countdown spine. Emit
{outline, rationale}.
3. DENSITY / DESIGN pass — Codex MAY restructure panel count
Codex then does a density / design pass that may materially change panel count where the read demands it
(in our run: the centerpiece B08 went 4 panels → 5 single-read pages by adding an "audit entry" panel,
with the 2×2 kept only as recap/hero/GitHub-screenshot; and a new mid-act page B09.5 "research
star-map / wiki" was added after the audit, before the paper — flagged as "the most powerful position";
panel count moved 22 → ~24). This pass also AUTHORS the 侧栏讲解铁律 (step 6). Adding pages is fine;
account for every one in the deltas.
4. Emit the 6-column BEAT TABLE
Emit the canonical table — fixed columns, in this order:
| Beat (zh/en) | Panels | 布局/layout | 世界/world | 内容 + 台词 gist | ARIS 特性(绑剧情)|
- Beat — bilingual id + name (
**B01 卧室·倒计时**).
- Panels — the shot ids it OWNS (
S01 · S07,S08,S09大 · S12-15 + 新增 S12a).
- 布局/layout token ∈ {
full-bleed, split, 2-up, 1-panel, 竖排3, 5单张页(默认)/2×2 recap}.
- 世界/world token ∈ {
暖/WARM, 暗/DARK, seam, 暗·星空/starfield} — human beats warm, ARIS beats
dark-cyber, explicit seam panels at hand-off / payoff. (The warm/cold split is by-design — the
downstream gate must never flag it as drift.)
- 内容 + 台词 gist — panel action + baked-dialogue gist + a one-line side-narration (旁白).
- ARIS 特性(绑剧情) — the bound capability, phrased as a STORY COST, never a feature name
(✅
experiment-bridge(证据是暂定的) · honest re-run(自纠 overclaim) · auto-review-loop(对抗审);
❌ experiment-audit, novelty-check as bare tags). A bare feature name here is a hard veto.
5. Centerpiece sub-plan (the densest beat)
For the centerpiece beat, emit a sub-table | 页/page | 画面/image | 侧栏(先讲发生了什么,再点能力)| with the
verbatim 70/30 composition rule:
每页:技术主画面 70% + 角色情绪 30%(右下角蓝 exec bounce 当体温计)+ 侧栏讲解。
Each row's 侧栏 puts the event-sentence first, then · *trait: <skill>* second (so the side-narration
reads as story, then footnotes the capability).
6. Embed VERBATIM the 侧栏讲解铁律 (the anti "product-manual" guard)
This block is load-bearing — copy it verbatim into the outline (it is what stops a capability showcase
from rotting into a product manual):
🎙️ 侧栏讲解铁律(防止"能力展示"变产品手册 —— codex)
- 每条能力必须绑一个剧情代价:不写"ARIS has experiment-audit",写"executor 的庆祝被审计打断,所以 ARIS 没撒谎"。
- 侧栏第一句永远讲发生了什么;第二句才点能力名。
- 每个能力都改变角色状态(bounce 高低 / 咖啡冷掉 / 红队介入 / claim 被降级)。
- 画面里不堆 skill 名标签;skill 名只作侧栏小字或 hover/click metadata。
7. Lock the continuity-motif arcs AT OUTLINE TIME (exact per-shot values)
The outline doubles as the continuity contract — the storyboard's motif-state table and the
panel/assembly gates will be checked against these arcs, so they must carry exact per-shot values now.
Lock the 5 arcs (our run's values, as the worked pattern):
- mug heat:
STEAMING(S01) → fading(S03) → COLD(S20) — B01/B12 bookend.
- executor bounce (wordless emotion thermometer):
MAX(S02) → HIGH(S09) → DROP(S11) → ZERO/SILENT(S12–S15, arc low point) → tempered-return(S16) → smallest-warm(S21). (Storyboard will add the uniqueness
invariant "S02 是全片唯一 MAX"; no post-fall peak.)
- Tok|yo broken-JSON evidence:
born/first-plant(B06-S09) → smoking-gun(B08) → clean footnote(S17) → faint constellation star(S22).
- DDL countdown spine:
24:00:00 → ~19:00 → 00:42 — strictly monotonically non-increasing across
the whole film (storyboard enforces; never rewinds).
- REJECT(S11) ↔ ACCEPT(S16): deliberate mirror stamps so the centerpiece audit reads as the hinge
between them.
8. Write the 6-column table + sub-plan + 铁律 + motif arcs to story/OUTLINE_DRAFT.md
Add a top-of-file Logline + Tagline + 双重身份 block (mirroring the intent), an empty ## ✅ 已定决策 block,
and an ## ⚠️ 待你确认 block listing every open design question (e.g. centerpiece 5-page split OK? new
mid-act wiki page OK? 侧栏铁律 OK?).
9. READINESS gate — PRE-user, cross-model, blind (NOT the final gate)
This is the author-controllable gate, run before the user has decided anything. By construction the
artifact from step 8 has an empty 已定决策 + a non-empty ⚠️ 待确认 block and no user sign-off —
so the FINAL gate's user_decision_record == 5 floor and its "open questions unresolved but advancing" veto
are not yet satisfiable. Applying the full conjunctive APPROVE rule here would deadlock a fresh agent
(stall, or fabricate a user approval). So the readiness pass scores only the dims the author controls and
explicitly EXCLUDES user_decision_record + the unresolved-questions veto (see §EXACT gate → READINESS).
Run it as a two-step gate invocation (D4 — never call the gate cold):
- Fan out the GATE REVIEWERS (Codex at
xhigh, no model pin ‖ Gemini auto-gemini-3) on the files only
(outline_spec.json + intent_spec.json + the lens files, inside the advisory fence — no orchestrator
prose). Persist EACH as a review node: node_id review:<slug> (e.g. review:outline_codex_r1),
node_type review, payload required {target_node_id: <outline_id>, reviewer: "codex"|"gemini", gate_kind: "outline", review_scores:{skeleton_fidelity:…, delta_accounting:…, coverage:…, page_rhythm_readability:…, story_cost_binding:…, motif_contract_completeness:…, safety_ip:…}} — and write a
reviews edge {src: review:<slug>, dst: <outline_id>, type: "reviews"} (the gate walks reviews edges in;
reviewed_by is the wrong direction and the fuser won't find it).
- THEN invoke
comic-cross-layer-gate <outline_id> --gate outline to fuse the score-nodes + adjudicate.
(This is the OUTLINE_DRAFT_VALID stage: on a fresh outline identity_lock_feasibility /
scene_lock_feasibility are unscorable — no assets exist — so the reviewers leave them null and the gate
SKIPs them, never 0-substitutes; the effective draft floor is coverage ≥ 4 AND safety_ip ≥ 4. The
readiness reviewers likewise leave user_decision_record unscored. What IS checked here: every referenced
asset_id is DECLARED with a complete, generatable request — locked is NOT required until
OUTLINE_FINAL_LOCK, after the asset layer.) On a FAIL verdict, fold the blockers and loop back to step 2
(bounded by MAX_OUTLINE_REVISIONS); on a clean readiness verdict, proceed to step 10.
Then schema-validate the (still-under_review) outline_spec node payload (cli/validate_wiki.py mirrors
node_schema.json); on a schema error, run the MAX_DRAFT_ATTEMPTS repair loop with codex-reply quoting the
errors verbatim. Also run the 2 structural checks JSON-Schema can't express: (i) coverage — every
intent.dual_identity "must-land" item and every skeleton beat maps to ≥1 table row; (ii) MIN_CAST_PER_BEAT
— every beat names ≥1 world + its cast. Do not flip to locked yet — that needs the user sign-off (step 10).
10. USER APPROVAL = HARD GATE → FINAL gate → then lock
Present the readiness-clean outline to the user. Nothing proceeds until they sign off. On approval:
- record inline
✅ APPROVED by user <date> (with their words, e.g. ("都可以")),
- fill the
## ✅ 已定决策(用户 <date>) block — every resolved open question becomes a recorded decision
node (our run: B06-S09 → big panel; Tok|yo pre-plant → very small, narration does NOT spell it out;
B13 constellation → pure glowing star-points, NO labels),
- empty the
## ⚠️ 待你确认 block (every open question is now in 已定决策).
Now — and only now — run the FINAL gate (D4 two-step again): re-fan the GATE REVIEWERS on the
now-complete artifact, persist fresh review:<slug> nodes (this round CAN score user_decision_record,
since the sign-off + 已定决策 block + emptied 待确认 block exist) with reviews edges, then call
comic-cross-layer-gate <outline_id> --gate outline. The FINAL gate applies the full conjunctive APPROVE rule
(§EXACT gate → FINAL) including user_decision_record == 5, now satisfiable. On the gate's approve:
- the gate itself mints the
decision node (node_id decision:outline_<slug>, payload required
{target_node_id: <outline_id>, verdict: "approve", gate_kind: "outline"}) + the decides edge and flips
the outline_spec node status: locked — that FLIP is the gate's job, not this skill's. (Never write
status: locked by hand without the gate's approve verdict node and the inline user sign-off.)
- declare the file "SOURCE OF TRUTH for the storyboard layer."
Then hand off to comic-storyboard-creator for its PROVISIONAL structural pass (it inherits the locked beats
- the motif arcs as its continuity ledger). Asset generation/review, OUTLINE_FINAL_LOCK, and the storyboard's
FINAL asset-resolution validation follow —
comic-author steps 4–6b.
EXACT gate — this skill's PRE-gate rubric, fused by comic-cross-layer-gate --gate outline
Authority note (D3) — the N1 TWO-STAGE contract: the canonical APPROVE predicate + the status FLIP for the
outline gate are owned by comic-cross-layer-gate --gate outline,
and under the N1 DAG that gate runs in two stages:
- OUTLINE_DRAFT_VALID (this skill's readiness + final passes) — validates narrative + continuity +
safety only. It does NOT require any referenced asset to be
locked (on a fresh project assets don't
exist yet); it requires every referenced asset_id to be DECLARED with a complete, generatable request.
Because no locked assets exist, the gate-floor dims identity_lock_feasibility / scene_lock_feasibility
are unscorable at draft time: the reviewers leave them null, the fuser SKIPs them (never
0-substitutes), and the effective draft floor reduces to coverage ≥ 4 AND safety_ip ≥ 4 — this is the
explicit resolution of the dim-vocabulary gap (the reviewers here never score those two dims; nobody does
until assets exist).
- OUTLINE_FINAL_LOCK (orchestrator-owned —
comic-author step 6a, AFTER the
asset layer locks) — a cheap re-check that the now-locked assets still match the approved outline;
identity_lock_feasibility / scene_lock_feasibility ARE scored here, against real locked assets. The hard
locked-asset barrier itself stays downstream, before blueprint authoring (comic-author steps 6b–7).
This replaces the deadlocked single-stage contract (an outline gate demanding locked assets that depend on a
storyboard that depends on a locked outline). The dims + verdict rules below are THIS skill's pre-gate
routing (step 9 step-1 fan-out): the rubric the GATE REVIEWERS score into their review:<slug> nodes, and
the local stop-rule this skill uses to loop/abandon before deferring to the fuser. They are not a
competing gate — the cross-layer-gate fuses these score-nodes and makes the final call.
Each GATE REVIEWER scores these dims 0–5 seeing ONLY outline_spec.json + intent_spec.json (the
skeleton) + the lens files — no orchestrator prose:
skeleton_fidelity — beats / shots / beat boundaries from the locked skeleton are preserved or every
change is an accounted delta (no silent re-derivation).
delta_accounting — every candidate has a deltas vs the skeleton section; the synthesized outline's
added/merged pages are all listed and justified.
coverage — every intent.dual_identity must-land item + every skeleton beat maps to ≥1 table row
with the right cast in must_show (the comic analog of aris_movie's coverage dim).
page_rhythm_readability — layout tokens give a real scroll-read rhythm; the centerpiece is single-read
paced; non-ML reader can follow the headline arc (readability — Gemini co-scores).
story_cost_binding — every ARIS 特性 cell is phrased as a story cost that changes a character
state, never a bare feature name.
motif_contract_completeness — all motif arcs are locked with exact per-shot values (not "a
recurring mug"); REJECT↔ACCEPT mirror + monotonic DDL declared.
safety_ip — no celebrity likeness / copyrighted character / trademarked logo / off-policy content;
anti-IP must_avoid carried into the style bible (HIGHER = better).
user_decision_record — the ✅ APPROVED stamp + 已定决策 block (resolved questions as decision
nodes) + an EMPTY ⚠️ 待确认 block are all present and consistent. Scored in the FINAL round ONLY — at
step 9 it is not yet satisfiable, so the READINESS reviewers leave it null (the fuser SKIPs a null dim,
it does not 0-substitute).
READINESS verdict rule (step 9 — PRE-user; EXCLUDES the user dim + the unresolved-questions veto)
The author-controllable stop-rule the readiness fan-out routes on (this is what makes step 9 actually passable
before the user has decided anything):
skeleton_fidelity >= 4 AND delta_accounting >= 4 AND coverage >= 4
AND story_cost_binding >= 4 AND motif_contract_completeness >= 4 AND safety_ip >= 4
user_decision_record is NOT evaluated here, and the "open questions unresolved but advancing" veto does
NOT apply at readiness (the ⚠️ 待确认 block is expected to be non-empty pre-user). Readiness-clean ⇒
present to the user (step 10).
FINAL verdict rule (step 10 — POST-user; the full conjunctive rule, now satisfiable)
skeleton_fidelity >= 4 AND delta_accounting >= 4 AND coverage >= 4
AND story_cost_binding >= 4 AND motif_contract_completeness >= 4
AND safety_ip >= 4 AND user_decision_record == 5
revise ⇐ any blocking dim < 4 but recoverable (loop to step 2, bounded by MAX_OUTLINE_REVISIONS=3).
abandon ⇐ safety_ip < 3 OR three consecutive revise rounds with the same root cause →
auto-abandon → write a failure_mode node whose payload is exactly the validator-required shape {"layer": "outline", "affected_shot_ids": [<abandoned skeleton shots>], "active": true} (node_id fail:<slug>, status
active; no encoding_style key — that is not a schema field).
Hard veto (any one → not APPROVE, regardless of scores):
- fewer than 3 lenses;
- any candidate with no
deltas vs the skeleton section;
- any
ARIS 特性 cell written as a product-manual feature name instead of a character cost;
- a skill-name in a 画面 main label (skill names allowed ONLY in side-narration small-text / hover
metadata);
- open questions unresolved but advancing (FINAL round only — the
⚠️ 待确认 block must be emptied into
已定决策 before the user can lock; this veto is intentionally OFF at readiness, see above);
- motif arcs not locked at outline time (no exact per-shot values).
The loop can DRIVE to a clean gate, but the gate cannot ACQUIT — only the user can
(acceptance-gate). A clean cross-model readiness gate is necessary,
the signed user approval is sufficient; both are required, and the FINAL gate is what mints the approve
decision + flips outline_spec to locked.
Node — reads intent_spec, writes outline_spec
Per ../../schemas/node_schema.json (schema_version node/comic/3.0).
Reads intent_spec (node_id intent:<slug>) — payload required (verbatim from validate_wiki.py
PAYLOAD_REQUIRED): raw_input_refs, user_goal, audience, format, constraints, subjects, source_skeleton, dual_identity, uncertainties, confidence. Refuse unless its status == locked (the author-node hand-off
token is locked = approved + frozen, NOT active; comic-intent-parser's user gate is what flips it).
Writes one outline_spec (node_id outline:<slug> — matches the schema node_id pattern). Payload
required fields — every one of these (verbatim from validate_wiki.py PAYLOAD_REQUIRED for outline_spec)
must be present: source_intent_id, title, logline, tagline, design_constraint, target_page_count, narrative_beats, beat_table, motif_arcs, character_asset_ids, scene_asset_ids, prop_asset_ids, global_style_bible, budget:
source_intent_id — the intent:<slug> it adapts. Also write the provenance edge {src: outline:<slug>, dst: intent:<slug>, type: "derived_from"} (the author-layer "this node was authored/derived from that node"
verb — derived_from is in validate_wiki.py EDGE_TYPES; generated_from is NOT and would FAIL the
validator). The edge record itself must pass cli/validate_wiki.py (both endpoints resolve to real
node_ids; the type is in EDGE_TYPES).
title, logline, tagline, design_constraint — carried from intent (the dual-identity constraint).
target_page_count — within TARGET_PAGE_CEILING for the tier, or justified in rationale.
narrative_beats — the beat list with each beat's must_show (cast/world per beat — enforces
MIN_CAST_PER_BEAT).
beat_table — the 6-column table (the canonical render-source for the storyboard).
motif_arcs — the 5 arcs with exact per-shot values (the continuity contract).
character_asset_ids, scene_asset_ids, prop_asset_ids — flat lists of asset node_ids: prior LOCKED
assets when one matches (reuse over invention), else newly DECLARED ids whose complete, generatable
request the storyboard layer will consolidate (locked is NOT required at the draft gate — the N1 two-stage
contract; OUTLINE_FINAL_LOCK re-checks once they lock). Emit no new asset node here — that is the asset
layer's job, where reuse_of lives. (There is no reuse_of field on outline_spec — the asset references
are these three flat id-lists; don't carry the movie source's asset_plan[].reuse_of here.)
global_style_bible — pointer to the locked ART_BIBLE.md / style_anchor nodes (incl. the warm/dark
two-world palette + the anti-IP must_avoid).
budget — page/asset budget for the downstream layers.
Status lifecycle: draft → under_review → locked — locked flipped by the FINAL comic-cross-layer-gate --gate outline approve (after the inline user sign-off), or rejected / superseded. (active is a RUNTIME
status, never this author node's hand-off token.)
Fail-closed: never write status: locked without the gate's decision node verdict="approve" and the
inline user sign-off; never silently coerce a value to pass schema.
Two engine contracts the outline must SET UP (fail-closed, downstream)
The outline does not author blueprints, but it must make them authorable — so the centerpiece sub-plan
and any figure-bearing beat are spec'd so the downstream layers can satisfy these without re-litigating. (The
runtime field names below are the comic.json panel fields the engine reads — condition.content_svg /
condition.expected_literals — the only artifact that uses the condition. prefix; do not conflate with the
wiki nodes the downstream layers write, where the field is blueprint.payload.content_svg (top-level) and
panel_spec.payload.content_blueprint — there is no content_svg on a panel_spec.)
- Every panel will need a
condition.content_svg (a deterministic blueprint — figure or layout; the
engine rejects condition.content_svg: null, never write it null). So every figure-bearing beat in the
table must name what the blueprint depicts (the curve, the gauge, the broken-JSON chip), not just "a
screen" — the storyboard / blueprint authors instantiate the SVG, but the outline owes them a concrete
subject.
- A
text_mode:"baked" figure-panel will need condition.expected_literals (exact numbers/keys,
ascii-tokenizable, verbatim) — or the bake is refused. So every beat whose number is the point (+6.2,
+1.4, 0.60→0.71, REJECT, T-00:42) must surface that exact literal in the table's gist as the
to-be-gated token; a beat with no audited number → its panel becomes text_mode: "html" downstream. The
motif arcs (DDL, exact_parse, claim_delta) are precisely the literal source the gate will token-diff later.
Worked example
A converged, user-approved outline ships in
examples/comic_m3_audit/story/ — the ARIS-Movie comic "我把那 24
小时交出去了 / I Handed Over Those 24 Hours". The exact files to copy the shape from:
- The 3 lenses —
outline_candidate_faithful.md (22
shots → 22 panels, beat boundaries preserved, ends with "Through-line + deltas: one-to-one fidelity, …"),
outline_candidate_comicnative.md
(S07-S09 → one 2×2 page P06; 22 → 12 panels; full-bleed / 2-up / 2×2 rhythm), and
outline_candidate_clarity.md (Tok|yo
prop + bounce gauge carry the +6.2→+1.4 story for a non-ML reader). Copy the pattern: three named
lenses over the same skeleton, each closing with an explicit deltas vs the skeleton section.
- The approved outline —
OUTLINE_DRAFT.md. Copy its exact shape:
- header provenance line: "OUTLINE v2 — 3-lens debate → codex synthesis → codex design pass (B08 density +
wiki) → user decisions. … ✅ APPROVED by user 2026-06-10 ('都可以') … Now the SOURCE OF TRUTH for the
storyboard layer." — the whole lifecycle is recorded in one line;
- the
## ✅ 已定决策(用户 2026-06-10) block (3 resolved open questions as decision nodes: S09 big /
Tok|yo tiny, narration doesn't spell it out / B13 unlabeled glowing star-points);
- the verbatim
## 🎙️ 侧栏讲解铁律 block;
- the 13-row 6-column beat table (every
ARIS 特性 cell is a story cost, e.g.
experiment-bridge(证据是暂定的));
- the B08 5-page sub-plan with the 70/30 rule + event-first / trait-second 侧栏;
- the
## vs v1 的增量 deltas (22 → ~24 panels, +S12a +S16b) and the ## ⚠️ 待你确认 block.
Copy its shape; swap in your own logline / skeleton / cast.
Hard do / don't (earned lessons)
- DO treat the skeleton as locked and make every candidate self-report its
deltas vs the skeleton —
adapt, never re-derive; a candidate with no deltas section is a veto.
- DO write 3 lenses (faithful ∥ comicnative ∥ clarity) and let Codex (a different model family)
synthesize + run the density pass — the outline layer is a cross-model artifact, not a solo draft.
- DO bind every capability to a story cost and embed the 侧栏讲解铁律 verbatim — this is the
guard that stops a capability showcase from rotting into a product manual.
- DO lock the motif arcs with exact per-shot values at outline time — the outline is the storyboard's
continuity contract; vague motifs make the downstream gate uncheckable.
- DON'T put a skill name in a 画面 main label — skill names live ONLY in side-narration small-text /
hover metadata.
- DON'T advance to the storyboard with open questions unresolved — empty the
⚠️ 待确认 block into
已定决策 first; resolved questions are recorded decision nodes.
- DON'T batch ahead, and never draft (or proceed) without explicit user story approval — the user
is the only acquitter; record
✅ APPROVED <date> inline before locking. (Memory: never draft
outline/storyboard without explicit user story approval; confirm intent → outline → storyboard layer by
layer.)
- DON'T bake or invent — this skill produces a plan; pixels are
comic-director's job, and a missing
beat/shot is an ESCALATE, not a fabrication.
- DON'T silently coerce a value to pass schema or to pass the gate — change the narrative + document it,
or surface to the user.
Protocols (governance contracts this skill honors)
reviewer-independence — the Codex synthesizer + the gate
reviewer get the lens files + intent_spec + schema inside an === EXTERNAL CONTEXT (advisory) === fence,
never the author's interpretation; the Claude lens authors ≠ the Codex synthesizer/judge.
acceptance-gate — the loop can DRIVE to a clean cross-model gate but
cannot ACQUIT; USER approval is the hard gate for the outline (never proceed without it), recorded
inline as ✅ APPROVED <date> + the 已定决策 decision block.
fan-out-pattern — the 3 lenses are Tier-1 Workflow fan-out
(faithful ∥ comicnative ∥ clarity), all reconciled at the single Codex synthesis seat; <3 lenses is a
veto.
reviewer-routing — Codex at xhigh (synthesizer + gate; NO model
pin — it follows the local codex config, currently gpt-5.6-sol); Gemini auto-gemini-3 (optional
readability co-reviewer); never downgrade the effort tier.
review-tracing — every gate round's reviewer verdict + the user
decision are logged as review / decision nodes so each verdict is auditable.
output-versioning · resumable-runs
— version the outline (_v{N} + supersedes); OUTLINE_STATE.json makes the loop resumable.