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, currentlygpt-5.6-sol— atxhigh) ‖ Gemini (auto-gemini-3, readability dims) — each sees ONLYoutline_spec.json+intent_spec.json(the skeleton) + the lens files, never Claude's prose. They do not acquit; they each persist areview:<slug>node (payload{target_node_id, reviewer, gate_kind: "outline", review_scores:{...}}) with areviewsedgereview:<slug> → <outline_id>, and the SOLE acquittal organcomic-cross-layer-gate--gate outlinethen 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 == 5floor 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 (nowuser_decision_record == 5IS 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_modenode so a re-run must diverge. Its payload is exactly whatvalidate_wiki.pyPAYLOAD_REQUIRED demands forfailure_mode:{"layer": "outline", "affected_shot_ids": [<the abandoned skeleton shots, e.g. all S01..SMM>], "active": true}(node_idfail:<slug>, node_typefailure_mode, statusactive). There is NOencoding_stylefield in the schema — carry the "a re-run must diverge" positive-invariant intitleor a non-required note, never a fabricated required-looking key; the node must passcli/validate_wiki.py. - MAX_DRAFT_ATTEMPTS = 3 — schema-repair loop for the
outline_specnode; on each fail,codex-replyquoting 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=12beats per tier (ported fromMAX_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 readsintent_spec, writes oneoutline_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 boundariesB01…BNNpreserved 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 runS07-S09 → one 2×2 page;22 shots → 12 panels); choose afull-bleed / 2-up / 2×2page-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 (theTok|yobroken-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-checkas 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 ‖ Geminiauto-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 areviewnode:node_id review:<slug>(e.g.review:outline_codex_r1), node_typereview, 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 areviewsedge{src: review:<slug>, dst: <outline_id>, type: "reviews"}(the gate walksreviewsedges in;reviewed_byis the wrong direction and the fuser won't find it). - THEN invoke
comic-cross-layer-gate <outline_id> --gate outlineto fuse the score-nodes + adjudicate. (This is the OUTLINE_DRAFT_VALID stage: on a fresh outlineidentity_lock_feasibility/scene_lock_feasibilityare unscorable — no assets exist — so the reviewers leave themnulland the gate SKIPs them, never 0-substitutes; the effective draft floor iscoverage ≥ 4 AND safety_ip ≥ 4. The readiness reviewers likewise leaveuser_decision_recordunscored. What IS checked here: every referencedasset_idis DECLARED with a complete, generatable request —lockedis NOT required until OUTLINE_FINAL_LOCK, after the asset layer.) On a FAIL verdict, fold the blockers and loop back to step 2 (bounded byMAX_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
decisionnode (node_id decision:outline_<slug>, payload required{target_node_id: <outline_id>, verdict: "approve", gate_kind: "outline"}) + thedecidesedge and flips theoutline_specnodestatus: locked— that FLIP is the gate's job, not this skill's. (Never writestatus: lockedby hand without the gate'sapproveverdict 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-authorsteps 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 referencedasset_idto be DECLARED with a complete, generatable request. Because no locked assets exist, the gate-floor dimsidentity_lock_feasibility/scene_lock_feasibilityare unscorable at draft time: the reviewers leave themnull, the fuser SKIPs them (never 0-substitutes), and the effective draft floor reduces tocoverage ≥ 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-authorstep 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_feasibilityARE 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 theirreview:<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 adeltas vs the skeletonsection; the synthesized outline's added/merged pages are all listed and justified.coverage— everyintent.dual_identitymust-land item + every skeleton beat maps to ≥1 table row with the right cast inmust_show(the comic analog of aris_movie'scoveragedim).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— everyARIS 特性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-IPmust_avoidcarried into the style bible (HIGHER = better).user_decision_record— the✅ APPROVEDstamp +已定决策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 itnull(the fuser SKIPs anulldim, 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 skeletonsection; - 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 theapprovedecision + flipsoutline_spectolocked.
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— theintent:<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_fromis invalidate_wiki.pyEDGE_TYPES;generated_fromis NOT and would FAIL the validator). The edge record itself must passcli/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— withinTARGET_PAGE_CEILINGfor the tier, or justified inrationale.narrative_beats— the beat list with each beat'smust_show(cast/world per beat — enforcesMIN_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 (lockedis 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, wherereuse_oflives. (There is noreuse_offield onoutline_spec— the asset references are these three flat id-lists; don't carry the movie source'sasset_plan[].reuse_ofhere.)global_style_bible— pointer to the lockedART_BIBLE.md/style_anchornodes (incl. the warm/dark two-world palette + the anti-IPmust_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 rejectscondition.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 needcondition.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 becomestext_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), andoutline_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 explicitdeltas vs the skeletonsection. - 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 → ~24panels, +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;<3lenses is a veto.reviewer-routing— Codex atxhigh(synthesizer + gate; NO model pin — it follows the local codex config, currentlygpt-5.6-sol); Geminiauto-gemini-3(optional readability co-reviewer); never downgrade the effort tier.review-tracing— every gate round's reviewer verdict + the user decision are logged asreview/decisionnodes so each verdict is auditable.output-versioning·resumable-runs— version the outline (_v{N}+supersedes);OUTLINE_STATE.jsonmakes the loop resumable.