# Engine Learnings

Append new entries at the top (reverse chronological). Each entry must pass
the write discipline test: "Would a new session make a better decision knowing this?"

Populated automatically by `/analyze-production`. Do not edit manually unless
correcting an error.

## Entries

### 2026-03-25 [script]
**ID:** L005
**Learning:** Separation handling is the sole transition gate concern — when characters separate between episodes, the next hook fails to acknowledge it.
**Evidence:** transition_gate_report.json: 9/9 reviews are type "separation_handling" (transitions 5→6, 14→15, 17→18, 34→35, 39→40, 43→44, 48→49, 49→50, 56→57). 0 hard fails.
**Implication:** When generating an episode where the previous episode ended with characters separating, the hook must explicitly acknowledge the separation — show what one character is doing alone, then bring them back together or show the other's parallel action.
**Confirmed by:** tartarus-r1
**Status:** provisional

### 2026-03-25 [script]
**ID:** L004
**Learning:** Cliffhanger type distribution violates format spec — 100% mid-action, 0% aftermath across 60 episodes (spec requires 70-85%/15-30%).
**Evidence:** Batch summaries: 60/60 episodes use mid-action cliffhangers. CONSTANTS.md requires 70-85% mid-action / 15-30% aftermath. Max 3 consecutive same type. Tartarus has 60 consecutive.
**Implication:** During generation, enforce cliffhanger type distribution per CONSTANTS.md. Target 9-18 of 60 episodes with aftermath cliffhangers. Orchestrator should track running cliffhanger type and force variety after 3 consecutive same type.
**Confirmed by:** tartarus-r1
**Status:** provisional
**Root cause fix applied (2026-03-25):** Made cliffhanger_constraint HARD (not optional) in batch_agent.md. Added mandatory cumulative ratio computation to orchestrator_agent.md for batches 3+. Added "MUST break streak" instruction. Next project should show 70-85% mid-action distribution.

### 2026-03-25 [script]
**ID:** L003
**Learning:** Character tic repetition compounds across batches — repeated physical descriptors for characters dilute impact through sheer repetition.
**Evidence:** script_doctor_brief.json: 5 pattern_fatigue + 2 tic_audit findings. Summary: "visual adjective fatigue — Wren's eyes, Jade's physical tics." revision_log.json: 50/58 annotations were REWRITE actions fixing repeated textures.
**Implication:** Track character-specific physical tics in a running inventory per batch. Maximum 3 uses of any single tic per 10 episodes. After 3 uses, the tic must evolve or be replaced with a new behavioral anchor.
**Confirmed by:** tartarus-r1
**Status:** provisional

### 2026-03-25 [script]
**ID:** L002
**Learning:** Unfilmable interiority is the dominant filmability failure — action lines describe internal states, backstory knowledge, or authorial commentary instead of camera-visible behavior.
**Evidence:** script_doctor_brief.json: 9/60 findings are close_read/filmability. Pattern: lines like "Recognition flooding systems not built for guilt" or "She means the opposite." All rewritable to visual cues.
**Implication:** Every action line must pass the camera test: could a cinematographer frame this as a shot? If the line describes what a character thinks/knows/remembers, rewrite as what the camera SEES: eye movement, hand gesture, posture shift, vocal quality change.
**Confirmed by:** tartarus-r1
**Status:** provisional

### 2026-03-25 [script]
**ID:** L001
**Learning:** Spatial logic breaks are the dominant failure mode — CONTINUOUS transitions across level changes cause characters to teleport between locations.
**Evidence:** script_doctor_brief.json: 11/60 findings are close_read/spatial_logic (C001 ep 3-4, C002 ep 9-10, C016 ep 27-28, C020 ep 33-34, C021 ep 34-35, C022 ep 37-38, C023 ep 41). All involve CONTINUOUS sluglines across level changes.
**Implication:** When generating episodes with location changes, never use CONTINUOUS across level changes. The final line of the outgoing episode must establish the physical vector toward the next location. Match slugline levels to the previous episode's exit point.
**Confirmed by:** tartarus-r1
**Status:** provisional
**Root cause fix applied (2026-03-25):** Added CONTINUOUS spatial adjacency rule to format_v12/SKILL.md. Added `last_slugline` to orchestrator continuity_notes and batch_agent instructions. Next project should show reduced spatial logic violations.

<!-- Entry format:
### [YYYY-MM-DD] [Category: script | visual | production | development]
**ID:** L001
**Learning:** [One clear sentence stating what was discovered]
**Evidence:** [File path + specific values from exhaust data]
**Implication:** [What the engine should do differently — must name a specific pipeline step]
**Confirmed by:** [project-rN, project-rN, ...]
**Status:** active | provisional | needs-condition | stale
-->

## Meta
proposed_shown: 2
proposed_promoted: 0
runs_since_last_promotion: 0
last_run_project: tartarus
last_run_date: 2026-03-25
total_runs: 1

---

## krea2-flora image pipeline (2026-06-02, harness build)

**Flora image ref-input contract (EMPIRICALLY UNCONFIRMED — confirm before live use):**
- `flora.py` image i2i/is2i emits reference images via a single constant `_IMAGE_REF_PARAM = "image_urls"` (a list), assumed by analogy to the working video r2v path. The actual Flora image ref-field is UNDOCUMENTED in `GET /models` (image params are tuning-only: creativity/seed/aspect_ratio/resolution). **A supervised paid probe on `is2i-seedream-v4.5` must confirm the field** (try `image_urls` then `image_url`; fallback: attach-asset-to-canvas, then a Technique with typed `imageUrl` inputs). To switch fields after the probe, change only `_IMAGE_REF_PARAM`. See research/06-flora-worksurface.md.

**LIVE-PATH BLOCKER — Flora image generation does NOT dispatch yet:**
- `execute_keyframe` dispatches image gen via `adapter.direct_submit_image(unified)`; `FloraAdapter.direct_submit_image` is `NotImplementedError` (loud + self-documenting). The structural pipeline (payload assembly, Look/Identity ref injection + budgeting, binding, edit-pass/concept CLIs, apply_look prompt fragments, creativity/seed hints) is COMPLETE + validated (dispatch audit 202/202). To go live, a supervised session must: (1) confirm the ref-field; (2) implement `FloraAdapter.direct_submit_image` (build_submit → POST /generate → poll GET /runs/{id} → download bytes). `build_submit` already uploads local `payload.image` + `reference_images`, and `_build_params` whitelists image hints to creativity/seed (no Google-shape key leak).

**Look/Identity SSOT model:** Looks (`recoil/config/looks/*.yaml`) are additive extensions of a cinema mode (`extends_cinema_mode` FK); Identities (`recoil/config/identities/*.yaml`) carry ref sets. `look_loader.build_look_bundle` budgets refs by model caps (`max_reference_images` total; `max_character_refs` is an identity SUB-cap where `null` = "no sub-cap, use full budget", `0` = "no identity refs"). A project binds `look` XOR project-level `cinema_mode`. Example ref images are dev placeholders regenerated by `tests/conftest.py` (repo policy: no binaries in git).

**Style-hold experiment verdict: PENDING.** The v2 style-LoRA gate (STYLE_HOLD_RESULT.md) is a PRE-REGISTERED protocol — the 20-frame paid corpus + human on-look scoring are DEFERRED. `style_hold_eval.py` computes palette ΔE2000 + style-centroid drift + face-embedding (lazy heavy deps). v2 LoRA work is funded ONLY on a real FAIL (BOTH human <3.5/5-or-≥30%≤2 AND objective drift/ΔE>10).
