Skip to content

I2V — Dissection of 20 Sequences, and What They Do to the Conflict Taxonomy

Cohort: the 20 most recently sent multi-shot sequence selections as of 2026-09-16, frozen by identity (sceneId + shot set) so the analysis is reproducible. The live "most recent 20" window has already moved past several of these — that is expected and does not affect the findings.

Method: every field of every shot in all 20 selections read verbatim from Mongo (read-only), plus the exact reference bundle that was sent with each. Nothing here is paraphrased from memory. Where a claim is not verified, it says so.

Purpose: the dissection is the input. The output is §5, the taxonomy rebuild — that is the point of the document.


1. The send-path contract — read this before any severity

Every severity in this document is computed against one question: does the contradicting field actually reach the video model? Most of the interesting conflicts in this corpus live in fields that never leave the database.

toShotBreakdown() in sequenceFlow.utils.ts:62-85 is the whole contract. What it puts in the bundle, per shot:

Sent to the model Not sent
description middleFrameInstructions
beatEmotion spatialState
charactersVisible[{title, assetId}] shot-level props[] (which shot uses which prop)
environment{title, assetId} environment.variantId
cameraMovement + cameraMovementDetails isMoneyShot / isKeyShot / moneyShotReason
cameraAngle + cameraAngleDetails voiceDirection, shotIndex
shotSize + shotSizeDetails sketchAnalyses[] (summaries, generationNotes)
timing preGenValidation (status, conflicts)
actingInstructions character variant
initialFrameInstructions the deprecated flat dialogue string
finalFrameInstructions
dialogues[{speaker, text}]
   AUTHORED / STORED                          SENT TO SEEDANCE
   ┌──────────────────────────┐               ┌──────────────────────────┐
   │ initialFrameInstructions │──────────────▶│ initialFrameInstructions │
   │ middleFrameInstructions  │───── ✖ ──────▶│        (nothing)         │
   │ finalFrameInstructions   │──────────────▶│ finalFrameInstructions   │
   │ actingInstructions       │──────────────▶│ actingInstructions       │
   │ spatialState             │───── ✖ ──────▶│        (nothing)         │
   │ camera*/shotSizeDetails  │──────────────▶│ camera*/shotSizeDetails  │
   │ props[] (per shot)       │───── ✖ ──────▶│        (nothing)         │
   └──────────────────────────┘               └──────────────────────────┘

Three consequences that drive everything below:

  1. middleFrameInstructions is authored, validated, and rewritten by sketches — and then thrown away. It is written by four generators (generateBeatPackage.template.ts:221, generateShotsFromPlan.template.ts:362, shotAutocomplete.template.ts:41, shotCascadeUpdate.template.ts:39), it is checked by preGenValidation (textTemporalStage.ts:84,154,193,259), and it is the single most common target of sketch rewrites in this cohort. It is absent from Seedance2ShotBreakdown (sequenceFlow.types.ts:14-15). The prompt's own "Acting synthesis note" (generateSequenceSeedancePrompt.template.ts:54) names exactly three lenses: actingInstructions, initialFrameInstructions, finalFrameInstructions.
  2. A contradiction confined to middleFrameInstructions or spatialState cannot cause a visual defect. It is still a real bug — the user's sketch intent is silently discarded, and every downstream checker reads a shot that disagrees with itself — but it is not a render risk. This is a different bug with a different fix, and the current validator does not distinguish the two.
  3. A contradiction in cameraAngleDetails / cameraMovementDetails / shotSizeDetails IS sent. These are free-prose fields nobody re-reads after a rewrite, and they are where the worst live conflicts in this cohort sit.

1b. The reference-bundle contract

Reference entries in the request carry {id, assetId, imageUrl, label} — and locations[]/props[] entries also carry variantId (Mongo-confirmed). But assignImageSlots() builds the prompt's sheet list as {name, imageRef} only (sequenceFlow.utils.ts:179-190).

The variantId reaches the backend and is destroyed before the prompt. Two variants of one room arrive as two sheets with one identical name, and the prompt instructs the model to tag each anyway:

"always include a terse image-tag line for every entry in the opening tag block, in slot order, including multiple entries with the same name (each is a separate bound sheet)" — generateSequenceSeedancePrompt.template.ts:85

And when a location is missing from the bundle, the model is explicitly told to skip it:

"Tag an environment @imageN only when that location is listed in bundle.environments." — generateSequenceSeedancePrompt.template.ts:41

So locations[] = NONE means the shot's environment.title arrives as bare text with no visual anchor, by design.

1c. The masterShot slot carries sketches

Confirmed by exact filename identity across both branches:

  • Shot has a selected image → that image is the masterShot. SEL 17: upload-12cc5d26 = shot 0 image[22] *SELECTED*; asset-0bdf56b9 = shot 1 image[8]; asset-ae8c5f8b = shot 2 image[5].
  • Shot has no image → its selected sketch is sent in the masterShot slot. SEL 8: asset-246d767b = shot 2 sketch[3] *SELECTED*, asset-f544f359 = shot 3 sketch[3], both shots images: 0. Same in SEL 7 (3 of 5), SEL 11 (3 of 4), SEL 9, SEL 16 (2 of 3), SEL 18 (3 of 4), SEL 19.

A rough line drawing is therefore presented to the model as a "master shot" reference, while the system prompt says the reference wins over the text:

"Conflict resolution: if the shot breakdown contradicts the storyboard, the storyboard wins … Do not flag, do not ask." — SEEDANCE2_SYSTEM_PROMPT_v20260803, ~line 132

1d. No ordering guarantee between validation and sending

Measured lags in this cohort (validation timestamp vs send timestamp):

Selection / shot validated sent lag
SEL 1 & 4 · shot 14 2026-08-29 2026-09-16 validated 18 days before
SEL 7 · shots 0, 4 Sep 4 / Sep 7 Sep 16 before
SEL 11 Sep 10 Sep 11 before (closest to a gate)
SEL 8 · shot 0 Sep 14 15:58 Sep 14 14:30 validated 1.5 h after
SEL 8 · shot 2 Sep 16 17:22 Sep 14 14:30 validated 2 days after
SEL 9 · shot 1 Sep 16 17:27 Sep 14 after
SEL 12 · shot 6 Sep 16 12:25 Sep 9 after
SEL 13 · shot 2 Sep 16 12:24 Sep 9 after

preGenValidation is not a gate. It runs on some shots, never on seams, and its result can post-date the send by days. Any conflict system that wants to block must be invoked on the send path, not read from stored state.


2. How to read a dissection block

shot 14 · 3.96s · MEDIUM_WIDE / TOP_ANGLE / STATIC
  start   Shuki L stands, holds log  ┊ UV R on ground, fists  ┊ Sunil R stands beside UV
  middle  Shuki L stands, arm out    ┊ UV R ON THE LOG        ┊ Sunil R SITS on same log   ← sketch(middle)
  end     Shuki L stands, holds log  ┊ UV R on ground, fists  ┊ Sunil R stands beside UV
  → sent: start ✓   middle ✖ DROPPED   end ✓

Severities:

  • BLOCKER — a viewer sees the break, or the audio is unusable. Fields involved are sent.
  • MEDIUM — likely visible, or the model must invent something material. Fields involved are sent.
  • SLIGHT — wasteful, cosmetic, or the model will recover.
  • STORED-ONLY — a real contradiction confined to middleFrameInstructions / spatialState. Cannot produce a render defect. Costs the user their sketch intent and corrupts every future checker's input.

3. The 20 dissections

Packaging table for the whole cohort

SEL scene sent order dur Σ timing Σ dialogue verdict
1 Countdown / Revelation [14,16] 12 9.11 5.12 +2.9
2 Countdown / Raft Building [0,5,8] 15 8.90 3.68 +6.1
3 Countdown / Revelation [1,8,10] 15 9.00 0 +6.0
4 Countdown / Revelation [13,14,15] 13 8.31 2.33 +4.7
5 Cart Rampage [4,5] 8 7.50 0 +0.5
6 Cart Rampage [1,2,3] 11 11.80 0 −0.8
7 Data Bot's Plea [0,1,2,3,4] 15 26.50 6.18 −11.5
8 Chairs / Warm Homecoming [0,2,3] 12 12.00 4.21 exact
9 Chairs / Warm Homecoming [0,1,3] 12 12.50 4.21 −0.5
10 Stan Arrives [0,1] 7 7.00 0 exact
11 Homecoming Lasagna Night [8,9,12,14] 10 31.47 35.45 −21.5
12 Tadej's Homecoming Dinner [6,7,8,9,10] 8 21.00 29.53 −13.0
13 Tadej's Homecoming Dinner [0,1,2,3] 7 17.00 6.71 −10.0
14 Countdown / Revelation [14,19,20] 12 9.98 5.76 +2.0
15 Becca Meets Malcolm [11,4,7,12] 15 22.00 14.63 −7.0
16 Countdown / Raft Building [14,15,17] 10 23.23 18.58 −13.2
17 Stan Arrives [0,1,2] 9 9.50 0 −0.5
18 Countdown / Revelation [2,9,11,12] 10 8.80 2.72 +1.2
19 Countdown / Revelation [2,11,12] 8 6.80 2.72 +1.2
20 Becca Meets Malcolm [1,11] 14 14.00 9.02 exact

9 of 20 send a video shorter than the shots sum to. 3 of 20 (SEL 11, 12, 16) send more dialogue than the video is long — SEL 11 packs 35.45 s of speech into 10 s. That is not a continuity problem, it is an arithmetic one, and it is the cheapest thing in this whole document to detect.

Send order: SEL 15 is genuinely out of story order on its latest send ([11,4,7,12], story order would be 4→7→11→12). SEL 20's pair was sent reversed at 11:28 ([11,1]) and in order at 12:49 ([1,11]). selectShots() maps over shotIds in the order given and nothing sorts them anywhere on the send path.


SEL 1 — The Countdown / Revelation and Countdown · shots [14,16]

b5e9fa49 · last sent 2026-09-16 14:38 · 12 s for 9.11 s

shot 14 · MEDIUM_WIDE

  start   James stands at screen-LEFT third  ┊ Shuki sits on a flat rock at screen-RIGHT third
  middle  Shuki sits at screen-LEFT on rock  ┊ James stands close behind/right of her at screen-RIGHT
  end     James fills the screen-LEFT half
  → sent: start ✓   middle ✖ DROPPED   end ✓
1 · Left→right→left flip in 3.68 s — STORED-ONLY. The middle frame puts James on the right; start and end put him on the left. The cause is in the data: sketchAnalyses connectedTo=middle, summary "Update only the middle-frame blocking so James is the standing figure positioned to the right of seated Shuki." The user drew a sketch, the system rewrote exactly one frame to match it, and that frame is the one that never ships. The seam is accidentally coherent because the rewrite was discarded.

2 · description ends with an authoring note — SLIGHT, live. "Characters are rendered in cel-shaded style." This string is also the masterShots[0] label, so a style instruction arrives as an image caption.

3 · locations[] = NONE for a named place with a declared variant — MEDIUM (see B-ENV-MISSING).


SEL 2 — The Countdown / Raft Building and Accusations · shots [0,5,8]

d4a2c89f · 2026-09-16 14:37 · 15 s for 8.90 s

1 · Intra-shot role swap + a "remains" with no antecedent — MEDIUM, live. Shot 0: Nishi changes from log-carrier to rope-puller across the frames, and UV goes from "stand close together near the shoreline" to "remains seated near camp supplies". "Remains" points at a state no earlier frame established. The word is in initialFrameInstructions/finalFrameInstructions — sent.

2 · preGenValidation: status = pass with THREE risky conflicts. Not one of them blocks.

3 · Registry corruption — SLIGHT, but it poisons every asset lookup. Badri ×2, Nishi ×2 (identical assetIds), Sunil twice with a non-UUID second id sunil-as, and "Dry Timber Logs" vs "Dry Logs" stored as two separate assets.

4 · charactersVisible = "James|James" on shot 8; characters = "Nishi|James|Nishi|James" on shot 5. Duplicate cast entries — the same defect family as PEA-2982.

5 · Empty imageURL on shot 0's images 1–3.

Not a conflict: water moving upper-right → frame-left across shot 0's frames is consistent with its PAN_RIGHT movement.


SEL 3 — The Countdown / Revelation and Countdown · shots [1,8,10]

b5e9fa49 · 2026-09-16 14:06 · 15 s for 9.00 s

1 · A genuine cross-shot lighting break — MEDIUM, live. Shot 1: "Soft diffused overcast light." Shot 10: "Background falls to near-black." Both in sent frame text, no intervening narration.

Calibrated down from blocker because shot 10's beatEmotion is panic_hallucination — a subjective POV insert legitimately breaks lighting continuity. This single case overturns the previous document's "day/night inside a sequence: 0 of 212 → do not build this gate." The gate is worth building; it needs a POV/dream exemption.

2 · Off-screen POV holder listed in charactersVisible — SLIGHT. Shot 10 lists Shuki while the frames put the camera at her eyes. One wasted character sheet.


SEL 4 — The Countdown / Revelation and Countdown · shots [13,14,15]

b5e9fa49 · 2026-09-16 14:02 · 13 s for 8.31 s

Shares shot 14 (and its discarded middle-frame flip) with SEL 1.

1 · True 180° break at seam 13→14 — MEDIUM, live. James jumps screen-right → screen-left, and the contact hand changes right → left. Adjacent shots, no cutaway, no camera-setup change to justify it. Shot 13 has no preGenValidation at all, and the validator never looks at seams regardless.

2 · charactersVisible = (none) on shot 15 while people are described in all three frames. On the derived reference path (deriveAssetNamesFromShots) this yields zero character sheets for a populated shot.

3 · masterShots[2] has a blank imageURL — an empty reference slot was sent.


SEL 5 — Not Good, Really Not Good / Data Center Cart Rampage · shots [4,5]

81d4dabd · 2026-09-16 12:21 · 8 s for 7.50 s

1 · The peak of a key shot is the part that gets dropped — STORED-ONLY, and the sharpest instance. Shot 4 is isKeyShot: true. Its sketch analysis is connectedTo=middle: "Update the middle frame so Stan's facial pose matches the sketch, with his mouth open." Result: middle says mouth open, start says "mouth is closed", end says "jaw is tight". preGenValidation: pass, 0 conflicts.

The user's whole edit — the emotional peak of the shot they marked as key — lands in the one field that is never sent. Nothing tells them.

2 · Eight blank imageURL entries on shot 4.

3 · actingInstructions empty on shot 5; shotJob and beatEmotion empty across the scene.

4 · "Bots (various)" in the cast with no sheet — a plural placeholder asset used as a character.


SEL 6 — Not Good, Really Not Good / Data Center Cart Rampage · shots [1,2,3]

81d4dabd · 2026-09-16 11:40 · 11 s for 11.80 s

1 · Two competing sketch analyses on the same frame — STORED-ONLY. Shot 1 has two connectedTo=middle analyses giving different track angles: "slight diagonal" vs "the steeper diagonal". The frames adopted "steeper". Nothing records that the other read lost, and nothing tells the user which of their two sketches won.

2 · Orphan analysis referencing upload-846637e1, a sketch absent from shot 1's own sketches[].

3 · A character named in frame text with no registry entry — "the Data Bot" appears in this scene's frames but is not in this scene's characters.

Not a conflict — two good calibration cases: - Seam 1→2 is a textbook clean seam: cart "nears frame-right about to exit" → "enters from frame-left". - Shot 3's L→R then R→L reversal is motivated by its own text ("the cart repeatedly crossing newly revealed levels"). A naive direction-flip detector must not fire on either.


SEL 7 — Not Good, Really Not Good / Data Bot's Plea and The Promise · shots [0,1,2,3,4]

3e6665ed · 2026-09-16 04:37 · 15 s for 26.50 s

1 · The sequence sends sheets for the wrong character — BLOCKER, live. The worst reference defect in the cohort. Confirmed by assetId, not by name:

  sent characters[4]:  "Old Bot"  asset=1fb52572  var=595b8dec
                       "Old Bot"  asset=1fb52572  var=e750fc6f
                       "Old Bot"  asset=1fb52572  var=8d8ab505
                       "Old Bot"  asset=1fb52572  var=e15aeaa9
  every shot declares: Data Bot   asset=a3b73b92
  scene registry:      Stan Padnick=0229a781, Data Bot=a3b73b92, Bots (various)=b7a9dc94

1fb52572 ≠ a3b73b92. Four sheets (four variants) of a character that appears in no shot and is not in the scene registry; zero sheets for the character in four of the five shots. An earlier send of the identical shot list (2026-09-15 08:17) shipped a sheet labelled literally "Upload from device" bound to Bots (various), plus an F1 Golf Cart prop that the 09-16 send silently dropped while shot 4's frames still describe the cart.

2 · 11.5 s of shots compressed into a 15 s video — the largest absolute overflow in the cohort after SEL 11.

3 · Registered props named in frame text, never sent: Rope Coil, Dry Logs, Nishi's Supply Crate, F1 Golf Cart (shots 0 and 4).

4 · Three of five masterShot slots are sketches (upload-d2ba2a41, upload-9e5bae51, upload-e21d8f84).

5 · Shots 1, 2, 3 have selected sketches with zero analysis.

Not a conflict — the case the brief explicitly called out. Seam 3→4: Stan goes from standing frame-left to seated inside the cart at frame-right across a cut. actingInstructions narrates it: "as both turn and exit frame-right". This is a cut bridging shot, not a teleport. Shot 2's empty middle + acting is a legitimate hold insert.


SEL 8 — Chairs / Warm Homecoming: Lasagna and Laughter · shots [0,2,3]

08ce9d26 · 2026-09-14 14:30 · 12 s for 12.00 s (exact)

1 · The arrival exists only in the frame that isn't sent — STORED-ONLY, high impact. Shot 3: start shows an empty chair, middle has "Tadej is now seated at screen-left", end shows him slumped. The only sent field carrying the arrival is actingInstructions ("Drops heavily into the chair at screen-left"). If that line had been dropped too, the character would appear from nothing.

2 · Both shots 2 and 3 have images: 0, so both masterShot slots are sketches (asset-246d767b, asset-f544f359).

3 · The asset title typo "Dinning room" is sent verbatim as the location label (also SEL 9, 11, 12, 13).

4 · Shot 3's selected sketch has no analysis.

Retracted from an earlier pass: shot 2's SKETCH_ANALYSIS_MISSING blocker is timestamped Sep 16 17:22, after the Sep 14 14:30 send. The honest claim is §1d — no ordering guarantee — not "a blocker was ignored".


SEL 9 — Chairs / Warm Homecoming: Lasagna and Laughter · shots [0,1,3]

08ce9d26 · 2026-09-14 14:24 · 0 of 1 rendered — [Byteplus] AuthenticationError: The API key format is incorrect. Request id: 0217893958901

1 · An action rewind at seam 0→1 — MEDIUM, live. Shot 0 ends in medium close-up on Tadej's grin inside the doorway. Shot 1 starts WIDE with him "mid-stride entering from the hallway threshold". The story moves backwards across the cut. Both frames are sent.

2 · Seam 1→3 loses and relocates him: screen-centre-right with a hand on a chair back → absent from shot 3's start → seated at screen-left.

3 · VARIANT_CHOICE_MISMATCH on shot 1 — "Tadej seems to use his cycling look, but he is at the family dinner table indoors". See §5's note: this flags a character variant, and there is no character-variant field anywhere in the sent bundle (characters[].variantId is undefined on every row in this scene). The validator is correct and the fix is unreachable from the text layer.

4 · Shot 1's masterShot slot is its sketch (asset-a0680ea2).


SEL 10 — Not Good, Really Not Good / Stan Arrives and Enters · shots [0,1]

13c35f57 · 2026-09-11 14:54 · 7 s for 7.00 s (exact)

1 · Three bots, one sheet — MEDIUM, live. Shot 1 says "Three Data Bots" in actingInstructions, spatialState and all three frames. One Data Bot sheet is sent. This is PEA-2982 live in a sequence: AssetRef has no count field.

2 · props[2] = Party Bubble ×2 — same assetId=98a35286, variants c2ba6038 and 487f7a1b, both labelled "Party Bubble". The model gets two images with one name and no way to choose.

3 · Two stages report the same physical fact as two separate conflicts. status: pass with SKETCH_ENVIRONMENT_MISMATCH (stage sketch_alignment) and ENVIRONMENT_VARIANT_MISMATCH (stage reference_feasibility) both saying the wall/doorway disagree. A dedupe gap, and it recurs in SEL 17.

4 · Authoring notes in description, sent as reference labels: shot 0 "…as per the sketch framing. No diamond blobs in the dome."; shot 1 "Stan, now repositioned and facing frame left as in the sketch, faces three Data Bots at frame right."

5 · Both shots' selected sketches have no analysis. image[2] on shot 1 has a blank URL.

Not a conflict — an important negative. Shot 0's three frames are byte-identical except "sits" → "remains". That is a legitimate 4 s locked hold. A "no change between frames" detector must not fire here.


SEL 11 — enlarged_conflicts / Homecoming Lasagna Night · shots [8,9,12,14]

14a03bd6 · 2026-09-11 12:15 · 10 s for 31.47 s of shots and 35.45 s of dialogue

1 · Dialogue is 3.5× the video length — BLOCKER, arithmetic. No continuity model needed to see this.

2 · Sixteen dialogue lines at offset 0 in one 20.47 s shot, in scrambled order — BLOCKER. Shot 14: "Tomorrow, you must be faster than today. / Thank you, Mama. / For recovery science. / For what? / But your mother's lasagna might. …" Answers precede questions. Compare the correctly-portioned clone of the same scene, SEL 12, whose shots carry contiguous portion.start/end offsets — so this is a data defect in this copy, not the design.

3 · actingInstructions choreographs quoted lines that exist in no dialogue field — MEDIUM, live. "I worry professionally", "Mostly lasagna", "Mostly Mother". The model is directed to perform speech it was never given. Recurs in SEL 12 shot 9.

4 · characters[4] contains Tadej twice — asset-cfa6c4b0 and upload-a2432899, two different assets with one name.

5 · spatialState contradicts every sent field — STORED-ONLY, and a perfect illustration. Shot 12's analysis said "removing Tadej from this frame", charMap says Tadej status=not_visible, and every sent field was updated. spatialState still says "Father and Tadej remain seated together on the right side of the dining table." Zero render impact. Real impact on any checker that reads it.

6 · Serving Spoon named in frame text, never sent. Three of four masterShot slots are sketches. Shot 8's selected sketch has no analysis.


SEL 12 — Enlarged_dev / Tadej's Triumphant Homecoming Dinner · shots [6,7,8,9,10]

37050fce · 2026-09-09 15:41 · 8 s for 21.00 s of shots and 29.53 s of dialogue

1 · A shot with no blocking at all — BLOCKER, live. Shot 10 has actingInstructions, initialFrameInstructions, middleFrameInstructions and finalFrameInstructions all blank. shotJob undefined, beatEmotion empty. It ships as the fifth shot of the sequence with four dialogue fragments and a selected sketch. What the model receives for this shot is a description, three *Details prose fields, and speech — and it is an EXTREME_CLOSE_UP of one face carrying four different speakers' fragments in 2 seconds.

2 · A live *Details contradiction the validator caught correctly — MEDIUM. Shot 6, review_required, two TEXT_FIELD_CONTRADICTIONs:

"Acting has Tadej's eyes lift to center-frame. End frame has Tadej's eyes down at the table." "End frame keeps Father chest-up on the left side of frame. Shot size details say it ends on Tadej."

Both pairs are sent fields. This is the class to build for.

3 · A sketch rewrote the room in one frame only — STORED-ONLY. Shot 6's analysis (connectedTo=start): "Replace the generic warm dining-room wall and kitchen doorway background with a door behind Father and a rainy window with curtains plus a potted plant behind Tadej." Start frame ✓ has the door, rainy window and plant. Middle frame still says "Warm dining-room wall and kitchen doorway remain behind them" — the old background. End frame says "Warm dining-room background stays softly visible" — neither. Within one 4.5 s dolly-in the room changes and then goes vague.

4 · A live left/right inversion in shotSizeDetails — BLOCKER, and the best example in the cohort. Shot 9:

  start / middle / end frames :  Father screen-LEFT   ┊ Tadej + Mother embracing screen-RIGHT
  shotSizeDetails             :  Father screen-RIGHT  ┊ pair embracing screen-LEFT
  description                 :  "...Tadej and Mother hugging at screen-left"
Two sent fields say pair-left, three sent fields say pair-right. Shot 9 has no preGenValidation.

5 · An unnarrated arrival at seam 7→8 — MEDIUM. Shot 7 is a top-down insert of a plate. Shot 8 opens with Mother "standing beside the dining table edge, holding a dessert plate in both hands" — she is in neither shot 6 nor 7 and no shot shows her enter. actingInstructions assumes her: "takes one step toward Mother at screen-right." A viewer accepts a mother walking into her own dining room, but nothing in the bundle says she does.

6 · An unregistered prop appears and changes state — SLIGHT. That "dessert plate" is not in the scene props registry (Lasagna Dish, Empty Plate, Serving Spoon) and not in shot 8's props. It is held at waist height in the start frame and "sits abandoned on the table edge" by the middle.

7 · Dialogue fragments sent as complete strings — MEDIUM. Shot 8 ends with Father: "But your"; shot 9 begins Father: "mother's lasagna might." The portion.start/end split is the designed mechanism and it works if the shots play adjacently at full length — but this sequence sends 8 s for 21 s, so the halves cannot line up.

Not a conflict: shot 7 is a well-authored positive control — internally consistent, physically precise ("plate slides 10 cm, edges 8 cm apart"), with all three declared props (Empty Plate, Lasagna Dish, Serving Spoon) actually sent. Its 90° camera jump from shot 6 is a standard insert.


SEL 13 — Enlarged_dev / Tadej's Triumphant Homecoming Dinner · shots [0,1,2,3]

37050fce · 2026-09-09 14:04 · 7 s for 17.00 s

1 · A flip and a flip back across three consecutive shots — BLOCKER, live. All three positions are sketch-derived and each declares itself authoritative:

  shot 1   Father screen-LEFT (annotated 27%)   ┊ Tadej screen-RIGHT (81%)
  shot 2   Father screen-RIGHT half             ┊ Tadej just left of Father's chair
  shot 3   Father screen-LEFT near left third   ┊ Tadej centre-right (60%)
Adjacent shots, same interior, no cutaway, charactersVisible identical. The audience loses who is where at the exact moment Tadej sits down next to his father. No validator entry covers a seam.

2 · A second live shotSizeDetails inversion — MEDIUM. Shot 3's shotSizeDetails says "Father partially visible at screen-right" while all three of its frames put Father at screen-LEFT. Second instance in this one scene, so the stale-*Details defect is not a one-off.

3 · An empty dialogue string with a named speaker — MEDIUM, live. Shot 3 carries Father: "[matter of fact]". stripVoiceParentheticals() deletes [...] and trims, so what ships is {speaker: "Father", text: ""}. Confirmed at both layers: the regex in code and the 0.6 s portion in Mongo.

4 · VARIANT_CHOICE_MISMATCH again on shot 2 — the cycling outfit at the indoor dinner table, same as SEL 9.

5 · Shot 2's sketchAnalyses[0] is a stub for a non-selected sketch.

Not conflicts — two negatives worth keeping: shot 2's placement annotation (Tadej 35%, Father 51%) is consistent with its frame text, so the annotation-vs-text check is not a blanket failure. And rain is described in all four shots' windows — a correctly maintained weather continuity, i.e. the day/night gate would produce a true negative here.


SEL 14 — The Countdown / Revelation and Countdown · shots [14,19,20]

b5e9fa49 · 2026-09-09 13:02 · 12 s for 9.98 s · 4 attempts, 4 rendered (the most re-rolled selection)

1 · Three sent fields describe a completely different shot — BLOCKER. The highest-severity live text conflict in the cohort. Shot 20:

  description        : "Shuki stares into the camera, scared."
  charactersVisible  : Shuki
  spatialState       : "Shuki is the only visible character... No other characters enter the frame."
  all three frames   : "No other characters are visible."
  ─────────────────────────────────────────────────────────────────────────────
  cameraMovementDetails : "Slow dolly in from medium two-shot to medium close-up on James's face over
                           3.5 seconds... Starts with both characters, ends isolating James's mouth
                           and glasses."
  cameraAngleDetails    : "Looking up at James from Shuki's seated position gives him dominance"
  shotSizeDetails       : "Begins framing James from waist up with Shuki's shoulder/head in lower frame,
                           ends tighter on James's chest-up as dolly completes, excluding Shuki at the
                           cut to black."
Five fields say Shuki alone; three sent fields describe a two-shot dolly onto James. Shot 20 has no preGenValidation at all. Shot 19 carries a milder version of the same defect.

2 · Intra- and cross-shot day/night contradiction — MEDIUM, live. Shot 14's description says "night scene" and "Lighting is cool and ambient, consistent with a night scene", while its own start frame says "grey sky" and shots 19/20 say "Overcast sky" / "a strip of overcast sky above". That description string is also the masterShot label.

3 · locations[] = NONE, props[] = NONE. Shuki's Camera is registered, declared, and held in her hands in all three of shot 14's frames — and no sheet is sent. (The Rope Coil is also unsent but every frame says it is off-screen, so that omission is correct — see the calibration rule in §5.)

4 · Shots 19 and 20 ship with: no image, a sketch that was never analysed (outcome=undefined), no validation, and camera fields describing the wrong shot. This is the modal failure shape of the cohort.

5 · A character sheet delivered as a base64-…png blob rather than an uploaded asset (base64-6c23e48d for James). Not verified yet: what produces these.


SEL 15 — Not Good, Really Not Good / Becca Meets Malcolm · shots [11,4,7,12]

fb33edb0 · 2026-09-09 11:15 · 15 s for 22.00 s · 3 of 3 rendered

1 · The sequence plays out of story order — BLOCKER, and it is not a text defect at all. Story order is 4→7→11→12. Sent order is 11→4→7→12. So the model is asked to render Becca's big arm-spread argument ("We ALL rely on our pensions, and our portfolios, and our packages") before her modest set-up ("don't want to oversell it... but..."). Cause and effect are reversed.

2 · One image occupies two reference roles — MEDIUM. upload-34ed8bba is simultaneously storyboard[1], masterShots[0], and shot 11's image[2] *SELECTED*. A single shot's still is given global storyboard authority over a four-shot sequence, and the system prompt says the storyboard wins.

3 · Four analyses on shot 11, two of them orphans, three targeting middle — STORED-ONLY. The selected-sketch analysis says "simplify the environment description to a generic wall and table silhouette instead of a detailed sleek central table with graph projections." The middle frame duly loses the room ("A plain table edge runs across the lower foreground, with simple wall panels in the background") while start and end keep "The sleek central table spans behind her at waist level, with bright conference room walls and faint red graph projections." The simplification never reaches Seedance.

The validator caught the consequence and passed it anyway — status: pass with a risky TEXT_FIELD_CONTRADICTION: "Start frame and End frame put the table behind Becca. Description and Middle frame put Becca behind the table." The full causal chain is visible in the data: sketch rewrites middle → middle contradicts its siblings → validator detects it → status pass → sent.

4 · Sibling analyses that directly contradict each other — STORED-ONLY. Shot 7 has three: one (connectedTo=middle) says "Add a rectangular transparent visor/glass element in front of Becca's right eye in the middle frame"; one (connectedTo=end) says "Do not copy rough sketch marks, bald head, or eyepiece; preserve Becca's established character design"; the third accepts the visor. The middle frame gained "A rectangular transparent visor piece sits in front of her right eye" and start/end did not — so a physical object appears on her face for one frame and vanishes. Because middle is never sent, the render is safe and the stored shot is wrong.

5 · Four analyses on shot 4, all "no metadata changes" — four LLM calls, zero effect.

6 · locations[] = NONE and props[] = NONE for a declared conference room with a declared variant. Prop assetIds in this scene are not UUIDs: tablet-b, one-fram, diary, long-map, remote.

Not a conflict: characters[1] = Becca Padnick only is correct — she is the sole entry in charactersVisible on all four shots. Sparse is right here.


SEL 16 — The Countdown / Raft Building and Accusations · shots [14,15,17]

d4a2c89f · 2026-09-09 07:40 · 10 s for 23.23 s of shots and 18.58 s of dialogue · 1 of 1 rendered

shot 14 · 3.96 s · MEDIUM_WIDE / TOP_ANGLE / STATIC

  start   Shuki L stands, holds log  ┊ UV R on the ground, fists  ┊ Sunil R STANDS beside UV
  middle  Shuki L stands, arm out    ┊ UV R ON the log            ┊ Sunil R SITS on the same log
  end     Shuki L stands, holds log  ┊ UV R on the ground, fists  ┊ Sunil R STANDS beside UV
  → sent: start ✓   middle ✖ DROPPED   end ✓        ← sketch(middle) caused the divergence

1 · The canonical case, in the validator's own words — STORED-ONLY. The sketch analysis (connectedTo=middle): "Update the middle frame blocking so Shuki is the standing figure on the left, with UV and Sunil both seated together on the same log at screen-right." The validator then reported it exactly:

TEXT_FIELD_CONTRADICTION — "Middle frame has Shuki extend one arm and puts UV and Sunil sitting on the log. Acting and Start frame and End frame keep Shuki holding the log while UV stays on the ground and Sunil stays beside him."

Inside one 3.96 s locked-off shot, Sunil stands → sits → stands. Status: pass.

2 · The suggested fix points at the human, not the data. SKETCH_POSE_ACTION_MISMATCH: "The sketch has UV's hands open on his knees. Middle frame and Acting have both fists closed near his lap." Suggestion: "Redraw the sketch with UV's fists closed near his lap." The user drew the sketch in order to change the text; the system asks them to redraw it to match the text.

3 · Dialogue alone overflows the video by 8.6 s (18.58 s of speech in a 10 s send). Speech cannot be sped up without pitch artifacts, which makes this stricter than the shot-timing overflow.

4 · The money shot is the least-checked shot in the selection. Shot 17 is isMoneyShot: true, isKeyShot: true, moneyShotReason: "Family weaponized against UV, trust collapses publicly" — and it has no preGenValidation, two stub analyses, and one of them is an orphan (upload-5a05ba25, absent from its sketches[]).

5 · locations[] = NONE; props[] = NONE while a log is held at chest height in every frame of shot 14 and both Dry Logs assets are registered.

6 · Two of three masterShot slots are sketches (shots 15 and 17 have images: 0).

Not a conflict — the key calibration pair. Shuki and Sunil swap screen sides between shot 14 and shot 17. Geometrically identical to SEL 13's blocker, but here it is acceptable: the shots are not adjacent (shot 15 is a close-up cutaway on UV between them) and the camera setup changes (TOP_ANGLE 30° elevated → EYE_LEVEL). Cutting away before crossing the axis is exactly the device that makes a reverse readable. Shot 17's frames also correctly narrow MEDIUM → MEDIUM_CLOSE_UP → "tighter than initial due to dolly-in", matching its DOLLY_IN.


SEL 17 — Not Good, Really Not Good / Stan Arrives and Enters · shots [0,1,2]

13c35f57 · 2026-09-08 14:11 · 9 s for 9.50 s · 4 of 4 rendered

1 · The variant path works — and the label throws the work away. MEDIUM. This is the only selection in the cohort that sends three variants of one place, and they map to the shots exactly:

  locations[3]:  "DATA Center Exterior"  asset=4d0cfc4b  var=5ee05be1   ← shot 0 declares 5ee05be1 ✓
                 "DATA Center Exterior"  asset=4d0cfc4b  var=3bc337f4   ← shot 1 declares 3bc337f4 ✓
                 "DATA Center Exterior"  asset=4d0cfc4b  var=9766b7e9   ← shot 2 declares 9766b7e9 ✓
Three correct images, three identical labels, and variantId is dropped before the prompt (§1b). The model receives three sheets it cannot tell apart and no per-shot mapping. props[2] repeats the pattern with Party Bubble (variants c2ba6038, 487f7a1b) and characters[3] with Data Bot (Default + variant c1df05f8).

2 · The two-stage duplicate conflict, second instance. Shot 1, status: pass, both risky: SKETCH_ENVIRONMENT_MISMATCH ("The sketch shows the bots against a flat exterior wall. Start frame puts the bots beside the data center doorway at frame-right.") and ENVIRONMENT_VARIANT_MISMATCH ("Location shows a blank exterior wall. Start frame needs the data center doorway visible behind the bots at frame-right."). One physical fact, two codes, two stages, no dedupe. Same scene as SEL 10, different shot — so the gap is systematic whenever a sketch and a location variant disagree with the same frame.

3 · Another "remain" with no antecedent — SLIGHT, live. Shot 1: start has "a flat exterior wall" and bots "near the data center entrance wall"; middle says "The entrance wall and doorway remain visible". The doorway was never established.

4 · A live acting-vs-frame contradiction, correctly found, not blocked — MEDIUM. Shot 2: TEXT_FIELD_CONTRADICTION — "End frame turns the bots toward frame-left foreground. Acting has their optical sensors aimed toward camera." Both fields sent. status: pass.

5 · Three selected sketches, zero analyses on all three shots.

6 · description carries the authoring note "No diamond blobs in the dome" into the masterShot label. image[2] on shot 1 has a blank URL.

Not conflicts — three of the most important negatives in the document. - Shot 0's three frames are identical except "sits" → "remains": a deliberate 4 s hold. pass, 0 conflicts is the right answer. - Seam 1→2: Stan goes from seated inside the vehicle at frame-centre to on foot in the frame-left foreground with no shot showing him get out. But shot 2's own description and actingInstructions narrate the entrance, and getting out of a car is strong world knowledge. Slight, not a teleport — the counterpart to SEL 7's seam 3→4. - Also at that seam: the bots go from a group at frame-right facing frame-left to a spread left-centre-right row facing camera. Both changes are explained by the camera moving from a WIDE profile to a MEDIUM_CLOSE_UP frontal. A naive screen-side comparator would fire here and be wrong. This is the single most important calibration rule for the whole 180°-break class.


SEL 18 — The Countdown / Revelation and Countdown · shots [2,9,11,12]

b5e9fa49 · 2026-09-08 13:43 · 10 s for 8.80 s · 2 of 2 rendered

1 · The attacker vanishes between two adjacent extreme close-ups — BLOCKER. Seam 11→12, both EXTREME_CLOSE_UP / EYE_LEVEL / STATIC, both 2 s, identical beatEmotion: suffocating_panic:

  shot 11 end  : "Two forearms remain locked across her neck from frame-left and frame-right, centered
                  tightly under her jaw... Her right hand remains hooked over the forearm at frame-left,
                  and her left hand remains pressed against the wrist at frame-right"
  shot 12 start: "The fingertips of her right hand appear at the lower frame edge pressed against the
                  left side of her throat... Background is an out-of-focus dark cliffside camp with no
                  distinct objects visible."          ← no forearms anywhere
Nothing narrates the attacker leaving. Shot 12's actingInstructions treats her as alone. In SEL 19 these two shots are adjacent with no shot 9 between them, which makes it worse.

Alternative reading, stated honestly: shot 9 also has her own hand at her throat with no attacker, so the supernatural attack may be intended to flicker in and out. But no sent field says so — spatialState is absent on all four shots and no beat note carries it. The fix is a narration field, not a geometry change.

2 · An unattributed second body — MEDIUM. Two forearms choke her in shot 11; charactersVisible = (none) on that shot; actingInstructions calls them "The attacker's forearms"; and a Drowned Man sheet (asset=4216bc1c) is sent that no shot references. Sending it is arguably right — someone must own those arms — but nothing links the sheet to them, and on the derived path this shot would get zero character sheets while containing two people.

3 · A sent location variant that no shot declares — MEDIUM, and newly precise. SEL 18 sends Cliffside Camp var=1d2731f5; shot 2 declares 9c6e1ad6. SEL 19, eight minutes earlier, sent the correct 9c6e1ad6. Every send in this scene from Aug 31 used the stale 1d2731f5, so it is a sticky selection, not a slip. This is a fully deterministic check: does any sent locations[].variantId match a declared shot.environment.variantId?

4 · A held prop silently disappears — SLIGHT. Shot 2 is entirely about Shuki's camera (glowing below frame, lighting her face). Shot 9 never mentions it and her right hand is on her throat. Downgraded to slight because shot 9 crops "hands below chest level" and says her left arm is "mostly out of frame" — the camera could still be in it. The blue-white glow lighting her face in shot 2 is also gone with no replacement light source named.

5 · Three of four shots ship with no image, an unanalysed stub sketch promoted to masterShot, and no validation (shots 9, 11, 12).

Not conflicts — two negatives: - props[] = NONE while Shuki's Camera is registered is correct here: every frame says the camera is below the frame edge or not visible. The N4-family check must be gated on visibility. - Shot 2's frames say "Close-up" while shotSize is MEDIUM_CLOSE_UP. Legitimate — its cameraMovementDetails says "Slow dolly from medium close-up to close-up". A frame-vs-enum shot-size detector must exempt dollies and zooms.


SEL 19 — The Countdown / Revelation and Countdown · shots [2,11,12]

b5e9fa49 · 2026-09-08 13:35 · 8 s for 6.80 s · 2 of 2 rendered

SEL 18 minus shot 9, sent 8 minutes earlier. Same shot-2 sketch analysis, same orphan stub (upload-34713e12), same unattributed Drowned Man sheet.

1 · The 11→12 attacker vanish is now a direct cut — BLOCKER. Removing shot 9 removes the only shot between them. Identical text to SEL 18, strictly worse placement.

2 · The location variant is correct in this send (9c6e1ad6) and wrong in SEL 18. Two sends of nearly the same selection, 8 minutes apart, different environment reference — the clearest possible evidence that the reference bundle drifts independently of the shots.


SEL 20 — Not Good, Really Not Good / Becca Meets Malcolm · shots [1,11]

fb33edb0 · 2026-09-08 12:49 · 14 s for 14.00 s (exact) · 3 of 3 rendered

1 · A prop that is the entire subject of the shot is never sent — BLOCKER for prop fidelity. Shot 1's actingInstructions: "Right thumb and index finger lift the one-frame eyewear at her right eye, then slide it toward her right temple." All three frames name it. It is registered (One-frame eyewear, id one-fram) and declared in the shot's props. props[] = NONE was sent. The model must invent what "one-frame eyewear" looks like. This is the cleanest instance of the class in the cohort.

2 · Competing analyses on the same frame, one of which hallucinates continuity — SLIGHT. Shot 1 has two connectedTo=start analyses: one applies a real change ("Update Becca's right-hand pose so her raised hand brings the rectangular one-frame eyewear directly in front of her right eye ... instead of touching it at the temple" — the start frame shows it applied ✓), the other says "No metadata changes." The first also instructs "Keep the tablet held against her torso with the left forearm" — no frame mentions a tablet, and all three say her left forearm "hangs to the side (off frame)". The writer ignored that part. Evidence that analysis summaries are not reliable as rewrite instructions.

3 · The same TEXT_FIELD_CONTRADICTION as SEL 15 on shared shot 11 — MEDIUM, live. "Start frame and End frame put the table behind Becca. Description and Middle frame put Becca behind the table." fieldPaths names four fields and three of them are sent, so this one is live: description says "behind a plain table" while start and end both say "in front of the sleek central table". A 1-vs-2 split among sent fields. status: pass.

4 · Shot 1 has no preGenValidation despite four sketches and an applied pose change. shotJob/beatEmotion empty on both shots. locations[] = NONE for a declared conference room.

5 · The reversed-order send. The earlier attempt at 11:28 sent [11,1] — the argument before the entrance. The 12:49 attempt sent [1,11]. Same pair, same day, two different narrative orders, no warning either way.

Taxonomy note this selection forces: the "conflict" at the 11→1 seam in the 11:28 send is an artifact of the send order, not of the shot text. A seam checker must run on the sent order, and an order check must be a separate, earlier gate — otherwise it reports geometry problems that vanish when you fix the ordering.


4. Cross-cutting counts (this cohort of 20)

Observation Count
Sent duration shorter than the shots sum to 9 / 20
Dialogue longer than the whole video 3 / 20 (SEL 11, 12, 16)
Sent out of story order (latest send) 1 / 20 (SEL 15); SEL 20 on an earlier attempt
locations[] = NONE while a shot declares an environment 8 / 20
props[] = NONE while a registered prop is described as visible 6 / 20
At least one masterShot slot filled with a sketch 7 / 20
Two reference sheets sharing one label (variants or duplicates) 5 / 20
At least one shot with a selected sketch and no analysis 11 / 20
At least one orphan analysis (sketch not in sketches[]) 7 / 20
At least one stub analysis (outcome=undefined) 9 / 20
status: pass coexisting with risky conflicts 8 shots
A shot with no preGenValidation at all 14 / 20 selections
Shots where a *Details field contradicts the frames SEL 12 (×2), 13, 14 (×2)
Shots where the sketch rewrote only middleFrameInstructions SEL 1, 4, 5, 6, 11, 12, 15, 16, 20
Blank imageURL in a sent slot 6 / 20

Generation failures in this cohort: one — SEL 9's Byteplus API-key error. Zero continuity-related render failures. Continuity defects do not fail the job; they ship.


5. What this does to the taxonomy

5.1 The structural problem with the current taxonomy

The existing codes (N1a, N1b, N2, N4b, N7a/b/c, N8a, N8b, REF-1…5, STR-1…3, TXT-1) are a flat list that mixes four different kinds of thing:

  • whether an image was attached (REF-*)
  • whether two sentences disagree (N*)
  • whether the bundle was assembled correctly (STR-*)
  • who introduced the disagreement (TXT-1)

That flatness has two concrete costs. First, severity is unassignable: N8a "variant drift" at 39.4% lumps together a stale sheet in the request (deterministic, cheap, real) with two shots disagreeing in prose (needs an LLM, often intentional). Second, the layer that decides whether a conflict can even matter — the send path — is missing entirely, so a contradiction in middleFrameInstructions and a contradiction in shotSizeDetails get the same code and the same risky label, when one is unreachable and the other is the worst live defect in the corpus.

5.2 The proposed shape: four families plus a send-verdict

                      ┌──────────────────────────────────────┐
   every finding ────▶│  SEND VERDICT   (a modifier, not a   │
                      │  class)  LIVE / STORED-ONLY / REF    │
                      └──────────────────┬───────────────────┘
                                         │
      ┌──────────────┬───────────────────┼───────────────────┬──────────────┐
      ▼              ▼                   ▼                   ▼              
   B-*  BUNDLE    S-*  SHOT          X-*  SEAM          P-*  PROVENANCE
   what shipped   inside one shot    between two        why the shot
   alongside      (fields + its 3    consecutive SENT   disagrees with
   the text       frames)            shots              itself
   ─────────────  ─────────────────  ─────────────────  ─────────────────
   deterministic  mostly LLM         LLM + mitigators   deterministic
   cheap, gateable                   most false-positive-prone

The send verdict is computed first and mechanically, from the field name alone. It is what makes the severities in §3 defensible, and it splits one bad risky bucket into two actionable ones:

Verdict Meaning What the user should be told
LIVE the contradicting fields are in toShotBreakdown()'s output "this will affect your video"
STORED-ONLY confined to middleFrameInstructions / spatialState / shot props "your sketch edit was not applied to the video"
REF in the reference bundle, not the text "the wrong image was attached"

5.3 Family B — BUNDLE (all deterministic, all cheap, all gateable)

Code What it detects Old code Severity Evidence
B-DUR-DIALOGUE Σ dialogue duration > sent duration — new BLOCKER SEL 11 (35.4→10), 12 (29.5→8), 16 (18.6→10)
B-DUR-SHORT sent duration < Σ shot timing — new MEDIUM 9 / 20
B-DUR-LONG sent duration > Σ shot timing — new SLIGHT 8 / 20
B-ORDER sent shot order is not ascending by shotIndex — new BLOCKER SEL 15 [11,4,7,12], SEL 20 [11,1]
B-CHAR-WRONG-ASSET a sent sheet's assetId matches no charactersVisible entry in any shot — new BLOCKER SEL 7 Old Bot 1fb52572 vs Data Bot a3b73b92
B-CHAR-MISSING a charactersVisible entry has no sheet REF-1 MEDIUM SEL 7, 10
B-CHAR-ZERO a populated shot yields zero character sheets REF-1b BLOCKER SEL 4 sh15, SEL 18 sh11
B-CHAR-SPEAKER a dialogues[].speaker has no sheet REF-1c MEDIUM SEL 13 (Mother)
B-CHAR-COUNT frame text says "three X", one X sheet sent — new (PEA-2982) MEDIUM SEL 10 sh1, SEL 17
B-ENV-MISSING shots declare an environment, locations[] = NONE REF-2 MEDIUM 8 / 20
B-ENV-VAR-STALE sent locations[].variantId matches no declared shot variant half of N8a MEDIUM SEL 18 1d2731f5 vs 9c6e1ad6
B-LABEL-COLLISION two sheets share a label (different variants or assets) reframes REF-3 MEDIUM SEL 17 ×3, SEL 10, 11, 7
B-LABEL-JUNK label is a UI string or an authoring note REF-4 SLIGHT "Upload from device", "No diamond blobs in the dome", "…cel-shaded style."
B-PROP-MISSING a registered prop is described as visible and no sheet is sent N4b, re-layered MEDIUM SEL 20 eyewear, SEL 14 camera, SEL 16 log
B-PROP-UNREGISTERED frame text names a prop absent from the registry — new SLIGHT SEL 12 "dessert plate"
B-MASTER-IS-SKETCH masterShot slot holds a line drawing — new MEDIUM 7 / 20
B-MASTER-DOUBLE-ROLE one image in two reference roles — new MEDIUM SEL 15 upload-34ed8bba
B-SLOT-EMPTY a sent reference slot has a blank imageURL — new MEDIUM 6 / 20

B-PROP-MISSING moving out of the text family is the important re-layering. It was N4b at 8.3%, filed next to prose conflicts. It is a request-assembly bug, it needs no LLM, and it is gateable before the call.

5.4 Family S — SHOT (inside one shot)

Code What it detects Old code Severity Evidence
S-DETAILS-STALE camera*Details/shotSizeDetails contradict the frames — new BLOCKER (LIVE) SEL 14 sh20, SEL 12 sh9, SEL 13 sh3
S-EMPTY-BLOCKING acting + all three frames blank — new BLOCKER SEL 12 sh10
S-SIDE-INTRA one character on both screen sides across the 3 frames N1a per verdict SEL 1/4 sh14 (STORED-ONLY), SEL 16 sh14 (STORED-ONLY)
S-CAST-UNDECLARED described in frames, missing from charactersVisible N7a MEDIUM SEL 4 sh15, SEL 17 sh2, SEL 18 sh11
S-CAST-BODYPART only a body part is present N7b SLIGHT SEL 18 sh11 forearms
S-CAST-DUPLICATE the same character listed twice — new SLIGHT SEL 2 "James\|James"
S-REMAINS a frame says remains / still / stays about a state no earlier frame established — new MEDIUM SEL 2 sh0, SEL 17 sh1
S-DAYNIGHT-INTRA description names a time of day its own frames contradict — new MEDIUM SEL 14 sh14 "night scene" vs "grey sky"
S-DLG-EMPTY a portion strips to "" after stripVoiceParentheticals() — new MEDIUM SEL 13 sh3 Father: "[matter of fact]"
S-DLG-FRAGMENT a portion < 5 chars, or ends mid-clause — new SLIGHT 25 / 69 portions don't end on a sentence boundary; Shuki [0-2] "[r"
S-DLG-UNANCHORED actingInstructions quotes speech absent from the shot's dialogue — new MEDIUM SEL 11 sh14, SEL 12 sh9
S-DLG-PILEUP many lines at offset 0, or ≥3 speakers in a tight close-up — new BLOCKER SEL 11 sh14 (16 lines), SEL 12 sh10 (4 speakers, 2 s ECU)

S-DETAILS-STALE is the single highest-value new code in the document: it is LIVE by construction, three independent instances appeared in 20 selections, two of them invert left and right, and none of the three shots involved had any validation at all.

5.5 Family X — SEAM (between consecutive sent shots)

Code What it detects Old code Severity Evidence
X-BODY-VANISH a second body present in shot N, absent in N+1 — new BLOCKER SEL 18/19 sh 11→12
X-SIDE true 180° break across a seam N1b, X1 BLOCKER→SLIGHT by mitigators SEL 13 1→2→3 (blocker), SEL 16 14→17 (slight)
X-REWIND the action moves backwards across the cut — new MEDIUM SEL 9 0→1
X-ARRIVAL a character is present in N+1 with no entrance anywhere N2 half MEDIUM SEL 12 7→8 (Mother)
X-POSTURE unnarrated posture change across a seam N2 MEDIUM SEL 9 1→3
X-PROP-DROP a held prop is gone with no narration — new SLIGHT SEL 18 2→9 (camera)
X-LIGHT lighting / time of day breaks across a seam previously retired MEDIUM SEL 3 sh1→sh10
X-PLACE consecutive shots are in different places N8b MEDIUM — none in this cohort
X-ENV-VAR consecutive shots declare different variants of one place half of N8a SLIGHT SEL 17 (correct here)

5.6 Family P — PROVENANCE (why the shot disagrees with itself)

This family does not exist in the current taxonomy, and it is where the dominant mechanism in this corpus lives. All four codes are deterministic.

Code What it detects Severity Evidence
P-SKETCH-ONEFRAME an analysis with resolvedConnectedTo = middle rewrote one frame; its siblings still describe the old blocking STORED-ONLY but always report 9 / 20 selections
P-SKETCH-COMPETING ≥2 analyses target the same frame with different instructions MEDIUM SEL 6 sh1, SEL 15 sh7 & sh11, SEL 20 sh1
P-SKETCH-ORPHAN an analysis references a sketch absent from the shot's sketches[] SLIGHT 7 / 20
P-SKETCH-STUB a selected sketch has analysisOutcome = undefined — and is still promoted to masterShot MEDIUM 11 / 20
P-PLACEMENT-CONTRADICTS the annotated centred N% disagrees with the screen-side word in the named frame MEDIUM check confirmed consistent in SEL 13 sh2, SEL 16 sh14 — so report only on real mismatch

Why P-SKETCH-ONEFRAME deserves its own code even though it is STORED-ONLY. The mechanism is:

   user draws a sketch on ONE moment
            │
            ▼
   sketchAnalysis: resolvedConnectedTo = middle       ← 3 of 4 analyses in this cohort pick middle
            │
            ├──▶ middleFrameInstructions   REWRITTEN, declares itself authoritative
            ├──▶ initialFrameInstructions  untouched  ─┐
            ├──▶ finalFrameInstructions    untouched   ├─ still describe the OLD blocking
            ├──▶ spatialState              untouched  ─┘
            └──▶ camera*/shotSizeDetails   untouched
            │
            ▼
   preGenValidation correctly reports TEXT_FIELD_CONTRADICTION, severity risky, status pass
            │
            ▼
   toShotBreakdown() drops middleFrameInstructions      ← ✖ the rewrite never ships
            │
            ▼
   Seedance renders the OLD blocking. The user's edit had no effect and nobody said so.

SEL 5 is the case that makes this urgent: the shot is isKeyShot: true, the sketch was about the emotional peak ("mouth open"), and preGenValidation recorded pass, 0 conflicts. The user got silence and an unchanged video.

Two possible fixes, and they are genuinely different products — this is a decision for Miki/Disha, not one to make in a detector: 1. Send the middle frame. Add middleFrameInstructions to Seedance2ShotBreakdown. Makes the user's edit real, and instantly promotes every STORED-ONLY finding in §3 to LIVE — including the left→right→left flips. Would need the sibling frames reconciled first or the renders get worse, not better. 2. Stop writing to a field that isn't sent. Force resolvedConnectedTo to start or end, or have the rewrite propagate to the siblings.

Until one is chosen, the honest user-facing message is "your sketch edit was stored but will not appear in the video."

5.7 Severity calibration — the eight mitigators

The brief asked for calibration, and this is the part that decides whether the system is usable. Every rule below is grounded in a specific selection where the naive check fires and is wrong.

# Mitigator Applies to Evidence
1 The transition is narrated in actingInstructions → downgrade or drop X-* SEL 7 3→4 ("as both turn and exit frame-right"), SEL 17 1→2
2 The camera setup changed materially between the shots → screen-side comparison is invalid X-SIDE SEL 17 1→2: WIDE profile → MCU frontal explains both apparent flips
3 A cutaway sits between the two shots → a side swap is standard grammar X-SIDE SEL 16 14→17 (slight) vs SEL 13 1→2 (blocker) — geometrically identical
4 The frames say the element is off-screen / cropped out → not missing B-PROP-MISSING, S-CAST-* SEL 18 rope coil, SEL 14 rope coil (correct) vs Shuki's camera (real)
5 beatEmotion is a POV / hallucination / dream state → lighting and geography breaks downgrade X-LIGHT, X-PLACE SEL 3 sh10 panic_hallucination
6 The three frames are near-identical → a deliberate hold, not a missing-progression bug any "frames don't differ" check SEL 17 sh0, SEL 10 sh0 ("sits" → "remains")
7 Frame text may name a different shot size than the shotSize enum under a DOLLY/ZOOM frame-vs-enum checks SEL 18 sh2 (MEDIUM_CLOSE_UP enum, "Close-up" text, dolly declared)
8 Dialogue split across shots via portion.start/end is the designed mechanism S-DLG-* only flag when it strips to empty, is < 5 chars, or the shots are non-adjacent in the sent order

Rules 2 and 3 matter most. They are the difference between a 180°-break detector that finds SEL 13 and one that also reports SEL 16 and SEL 17 and gets switched off.

5.8 Order of operations

Because SEL 20 shows that a seam conflict can be an artifact of the send order, the gates have to run in this order:

   1. B-ORDER, B-DUR-*          deterministic, no LLM, fix before anything else
   2. B-* references            deterministic, no LLM, gateable pre-call
   3. P-* provenance            deterministic; produces the "your sketch was ignored" message
   4. S-* intra-shot            LLM, per shot, cacheable by shot hash
   5. X-* seams                 LLM, on the SENT order, with §5.7 mitigators applied

Steps 1–3 need no model at all and cover the three BLOCKERs with the highest counts in this cohort (B-DUR-DIALOGUE 3/20, B-ORDER 1/20, B-CHAR-WRONG-ASSET 1/20) plus the whole P-SKETCH-* family.

5.9 Retired and re-mapped

Old Fate
C1, C6, C7, C8 stay retired
X1 → X-SIDE
C5 useful half → X-POSTURE; rest dropped
C4 → split: B-ENV-VAR-STALE (request) vs X-ENV-VAR (text)
C2 → S-CAST-UNDECLARED + B-CHAR-MISSING
C3 → B-PROP-MISSING, re-layered into the bundle family
N2n, N7c not codes — they become mitigators 1 and 4
TXT-1 absorbed into family P-*
REF-3 reframed from "places flattened" to B-LABEL-COLLISION
N8a (39.4%) split; the request half is deterministic and gateable, the text half is not

5.10 What not to build

  • A "frames must differ" detector. Two selections hold deliberately still (mitigator 6).
  • A blanket screen-side comparator. It fires on SEL 17's camera change and SEL 16's cutaway.
  • A dialogue-boundary checker on portion offsets alone. Splitting is the designed mechanism.
  • A second copy of ENVIRONMENT_VARIANT_MISMATCH. It already duplicates SKETCH_ENVIRONMENT_MISMATCH (SEL 10, SEL 17). Dedupe by physical claim, not by stage.
  • Anything that reads stored preGenValidation as a gate. Its results can post-date the send by days (§1d).

6. Corrections to I2V_SEQUENCE_CONFLICTS_IN_REAL_DATA.md

  1. "Day/night inside a sequence: 0 of 212 → do not build this gate" is wrong. SEL 3 is a genuine cross-shot lighting break in sent fields ("Soft diffused overcast light" → "Background falls to near-black"). Build it, with mitigator 5. SEL 14 shot 14 adds an intra-shot case ("night scene" vs "grey sky").
  2. N4b "registered prop named never sent" (8.3%) is misfiled. It is a request-assembly defect (B-PROP-MISSING), deterministic and gateable, not a prose conflict — and it must be gated on visibility (mitigator 4), which the 8.3% figure did not do.
  3. REF-3 PLACES_FLATTENED is the wrong description of the mechanism. Places are not collapsed into one sheet; multiple sheets are sent and their variantId is dropped before the prompt, so distinct variants arrive with one identical label (§1b, SEL 17).
  4. N8a at 39.4% conflates two different bugs with different fixes and different detectors (§5.9).
  5. VARIANT_CHOICE_MISMATCH is unfixable at the text layer. It flags a character variant. There is no character-variant field in Seedance2ShotBreakdown, and characters[].variantId is undefined in the request for every row of the Countdown scene while it is populated for SEL 7. The fix belongs at reference-selection time.
  6. Retained from the previous document: isSelected is not a quality label; no detector has been validated against an outcome; the baseline of 1.87 renders per selection ±0.6 still stands as the only available proxy and it is weak.

7. Open questions

  • Not verified yet: whether the 15 s duration ceiling and the -1 sentinel are enforced client-side or by Byteplus. Confirmed: there is no server-side clamp — grep -rn "duration" src/workbench/ src/models/storyVideos.model.ts | grep -i "max\|cap\|clamp\|15\|-1\|limit" returns nothing.
  • Not verified yet: what produces base64-…png character sheets (SEL 14 James, SEL 18/19 Drowned Man) rather than uploaded assets.
  • Not verified yet: whether the frontend surfaces status: pass + risky differently from review_required. If it does not, the 8 shots in §4 shipped with no visible warning.
  • Needs checking: whether SEL 14's location reference was lost by a code change or a user action — the same shot list carried Cliffside Camp var=a308f4f0 on 2026-09-01 and no location at all on 09-08 and 09-09.
  • Tooling note: /tmp/i2v/diss.js prints each selection's shot order from the first attempt it sees while printing metadata from the latest. Its header shot order is unreliable; §3's orders were re-derived in /tmp/i2v/dur_pinned.js. It also reads d.characterName/d.text for dialogues (real keys: d.speaker.title, d.portion.text), so every dialogues[]: ?: "" line in the dump must be ignored.