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:
middleFrameInstructionsis 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 fromSeedance2ShotBreakdown(sequenceFlow.types.ts:14-15). The prompt's own "Acting synthesis note" (generateSequenceSeedancePrompt.template.ts:54) names exactly three lenses:actingInstructions,initialFrameInstructions,finalFrameInstructions.- A contradiction confined to
middleFrameInstructionsorspatialStatecannot 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. - A contradiction in
cameraAngleDetails/cameraMovementDetails/shotSizeDetailsIS 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
@imageNonly when that location is listed inbundle.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 0image[22] *SELECTED*;asset-0bdf56b9= shot 1image[8];asset-ae8c5f8b= shot 2image[5]. - Shot has no image → its selected sketch is sent in the masterShot slot. SEL 8:
asset-246d767b= shot 2sketch[3] *SELECTED*,asset-f544f359= shot 3sketch[3], both shotsimages: 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 ✓
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"
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%)
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."
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 ✓
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
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
portionoffsets alone. Splitting is the designed mechanism. - A second copy of
ENVIRONMENT_VARIANT_MISMATCH. It already duplicatesSKETCH_ENVIRONMENT_MISMATCH(SEL 10, SEL 17). Dedupe by physical claim, not by stage. - Anything that reads stored
preGenValidationas a gate. Its results can post-date the send by days (§1d).
6. Corrections to I2V_SEQUENCE_CONFLICTS_IN_REAL_DATA.md¶
- "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").
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.REF-3 PLACES_FLATTENEDis the wrong description of the mechanism. Places are not collapsed into one sheet; multiple sheets are sent and theirvariantIdis dropped before the prompt, so distinct variants arrive with one identical label (§1b, SEL 17).N8aat 39.4% conflates two different bugs with different fixes and different detectors (§5.9).VARIANT_CHOICE_MISMATCHis unfixable at the text layer. It flags a character variant. There is no character-variant field inSeedance2ShotBreakdown, andcharacters[].variantIdisundefinedin the request for every row of the Countdown scene while it is populated for SEL 7. The fix belongs at reference-selection time.- Retained from the previous document:
isSelectedis 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 sdurationceiling and the-1sentinel 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 producesbase64-…pngcharacter sheets (SEL 14 James, SEL 18/19 Drowned Man) rather than uploaded assets.Not verified yet:whether the frontend surfacesstatus: pass+riskydifferently fromreview_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 carriedCliffside Camp var=a308f4f0on 2026-09-01 and no location at all on 09-08 and 09-09.- Tooling note:
/tmp/i2v/diss.jsprints 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 readsd.characterName/d.textfor dialogues (real keys:d.speaker.title,d.portion.text), so everydialogues[]: ?: ""line in the dump must be ignored.