# KMC 图片生成本地引擎化实施批 — 架构司机批次

## 背景事实（operator 已实证，直接采用勿重新推导）

1. **定案（operator 0910 拍板）**：KMC 图片生成本地引擎化——**Z-Image 做主力引擎，Ideogram 只留「招牌文字」特殊档**。翻默认，但 **dreamina 路径零删除**（保留为可手动切档），**禁止自动 fallback 到 dreamina**（本地失败就显式失败，不静默落云）。
2. **dreamina 触点全量普查（operator 实测，本批范围就这 4 处）**：
   - ① P04 角色设计（turnaround L1/L2 batch + costume_swap）：**zimage 分支已存在**——`p04_character_design.py` L1276-1302（zimage 档时给子代理的确定性指令：dreamina_gen_image.py 命令全部作废换 zimage 等价命令）、L988 引擎分支。resolver = `p04._resolve_image_engine`（L563）。
   - ② P07 场景图：`p07_scene_generation.py`——主路径走 dreamina_manager 批量（delegate goal 契约 L427 附近）；two_step 重建分支已合入（L1479：`engine=="two_step"` 时 `_run_scene_two_step` 重建合格场景 front view；合格判定 `_scene_two_step_qualifies` L950 四信号；resolver `_resolve_image_engine` L850 / `_resolve_two_step_cfg` L879）。**zimage 主路径现状未探明**——见 C2 实探。
   - ③ P09c 白模分镜板：`p09c_storyboard_board.py` L482 subprocess 调 `templates/dreamina_gen_image.py`（text2image 网格板）。
   - ④ P11 条件帧：`templates/gen_iframes.py` L72 `_DREAMINA_HELPER = dreamina_gen_image.py`；chained 模式=copy(prev last_frame) 不生成（保留），非 chained=dreamina 生成 first_frame。
3. **引擎能力定谳（实测背书，写进注释即可勿再验证）**：Z-Image Turbo——中文渲染盲测 R1 第一、t2i 9步10-20s、i2i d0.75 生产档（人物入景 corr 0.56-0.80、中文招牌 d0.35-0.75 全保 OCR≥0.98）。Ideogram4——t2i-only、慢（20步28-32s）、双底模驻留 ~21G，**唯一不可替代项=中英文招牌文字渲染（OCR 0.98+ 四字笔画全对）**。
4. **two_step 拓扑已复核定谳**（416f58aa，TOPOLOGY_STATUS=verified）+ P07 消费接线已合入（57af8271）。
5. **已知未闭环 bug（C5 负责）**：two_step 臂间显存接力（4c53979c）真机复跑失败——臂A Ideogram 渲染后驻留 ~21G，臂B Z 守卫 EngineBusy（20915MiB>18432）→ 链耗尽。修复代码已提交但未生效，根因未定谳。
6. **API 面**：`two_step_generate(design_prompt, refine_prompt, *, width,height,seed,denoise=0.75, init_image=None, ..., final_fallback=None)`；`ZImageEngine.generate(prompt, *, width,height,seed, filename_prefix, output_dir, negative_prompt, init_image=None, denoise=0.65缺省)`；`Ideogram4Engine.generate(t2i only)`。编排器 `resolve_fallback_chain` 链尾 dreamina 是**占位**（final_fallback 缺省 None，phase 不注入就不发生）。

## 设计定案（operator 拍板，实现照此）

**引擎选择规则（新）**：`engine` 值域扩展为 `"auto" | "zimage" | "two_step" | "dreamina"`：
- **`auto` = 新缺省**（P04 全部子资产 + P07 scene_image）：场景命中 text_spec/文字载体信号（复用 `p07._scene_two_step_qualifies` 的文字信号，P04 侧=turnaround 的 textguard text_spec 语义）→ two_step；否则 → zimage。
- 显式 `"zimage"` / `"two_step"` / `"dreamina"` = 手动锁档（dreamina 保留=operator 手动切回云端的开关，**永远可用**）。
- **禁自动 fallback**：auto/zimage/two_step 模式下本地引擎失败 → 场景/资产标 `engine_error` 显式失败（fail-visible，下游选择层可见缺失），**禁止**静默补跑 dreamina；编排器链内 two_step→zimage 的**本地**降级保留（都是本地引擎），dreamina 链尾不接（final_fallback 维持 None，p07 侧不注入）。

## 任务

### C1. 翻默认 + auto 档（P04 + P07）
- runner `_DEFAULT_GENERATION_CONFIG`（~L2471）：p04_character 三子资产 engine `"dreamina"→"auto"`；p07_scene（含 scene_image 子键，若无则建）engine `"auto"`。**dreamina/zimage/two_step 值域注释保留**（手动切档文档就在注释里）。治理注释更新：本批翻默认是 operator 0910 定案（本地引擎化），dreamina 手动档保留。
- `p04._resolve_image_engine` / `p07._resolve_image_engine`：值域 + auto 解析（auto 不是最终引擎——消费侧展开，resolver 原样返回 "auto"）。
- P04 消费侧（~L990 分支）：auto 时按资产类型展开——costume_swap 的 zimage 分支照走；turnaround/bible batch 分支按「有无 text_spec」选 zimage batch 或 two_step（P04 的 two_step 仅在有文字信号时；**P04 turnaround 网格板是否适合 two_step 存疑，宁可保守：P04 auto 一律展开为 zimage，two_step 仅 p07 scene_image 生效**——把这条写成注释）。
- P07 消费侧：**实探 zimage 主路径是否存在**（grep p07 的 zimage 触点）。若 scene_image 主路径只有 dreamina_manager：把 delegate goal 契约按 engine 分档（auto/zimage → 指令子代理用 zimage batch（参照 p04 L1276 确定性指令模式）；dreamina → 原 goal 原样）。two_step 重建分支保持（L1479），触发条件从 `=="two_step"` 改为 `in ("two_step","auto")`（auto 时仅文字合格场景重建，`_scene_two_step_qualifies` 已实现）。

### C2. P09c 白模分镜板 → zimage t2i
- `_GEN` subprocess 处（L482）加引擎分支：默认 zimage（batch JSON 逐条 → ZImageEngine t2i，并发参照原 --workers 语义，本地守卫 EngineBusy 串行等待）；`--engine dreamina` 选项保留原路径零改动。网格板 prompt 直传（Z 无 dreamina 3100 字节限）。
- 注意：Z t2i 出网格板（clay maquette 多格布局）是**未验证面**——代码照做，注释标「板式保真待 operator 冒烟验收」，不做过设计。

### C3. P11 条件帧 → zimage i2i
- `templates/gen_iframes.py`：`_DREAMINA_HELPER` 旁加 zimage 通道（非 chained 场景 → ZImageEngine i2i，init=上游锚帧/ref 图按现有 ref 解析语义，denoise 缺省 0.75；chained 模式 copy 逻辑零改动）；引擎选择参数化（缺省 zimage，`--engine dreamina` 保留）。
- **实探消费链**：grep P11 编排层（p11b/p11 视觉执行）怎么调 gen_iframes，参数怎么透传，确保缺省翻档后 P11 跑批自动走 zimage、dreamina 选项仍可手动传。

### C4. 禁 fallback 纪律硬化
- p07 `_run_scene_two_step`：TwoStepChainError 现语义「维持 dreamina 产物」在 auto/zimage 模式下改为「scene 标 engine_error + 无产物」（dreamina 锁档时原语义保留——那时 dreamina 产物是主产物）。WARN 日志写明「本地引擎失败，按 operator 0910 禁-fallback 纪律不落 dreamina」。
- 全局 grep 确认无其他「本地失败→dreamina」自动路径被本批引入。

### C5. two_step 臂间显存接力 bug 定谳（代码面诊断+修复）
- 症状：4c53979c（臂A 成功后 `_release_vram(design)`→`Ideogram4Engine.free_vram()` POST /free）真机复跑臂B 仍 EngineBusy 20915MiB。
- 诊断方向（只读+代码修复，GPU 真机复验归 operator）：① `_release_vram` 是否真被调（编排器臂A 成功分支路径核对）；② /free 返回后 ComfyUI 卸载是否异步滞后（ZImageEngine `_check_gpu` 在 submit 前查询——需不需要 free 后短暂 wait-and-recheck）；③ Ideogram 双底模 21G 驻留是否真是 /free 可释放面（vs 模型常驻 pinned）。修复+单测（mock 时序断言），修复结论写交付文档。

### C6. 测试 + 交付文档
- 测试（全 mock）：auto 展开逻辑（P07 文字信号→two_step/否则 zimage；P04 auto→zimage）；翻默认后缺省行为断言；dreamina 手动档仍可达（配置 dreamina → 走原路径断言）；禁 fallback 断言（two_step 链耗尽 → engine_error 且零 dreamina 补跑）；P09c/P11 引擎分支。
- `docs/image-engine-localization.md`：改动锚点 + auto 语义 + 手动切档表（requirement.json 样例：锁 dreamina / 锁 zimage / 锁 two_step）+ 验证命令 + 回滚（git revert）。
- **无部署面**（管线 Python 侧随进程生效）。

## 验证命令（operator 验收独立复跑）
1. `cd <worktree>/skills/kais-movie-pipeline && python3 -m pytest tests/ -q --no-header -k "p04 or p07 or p09c or two_step or ideogram or zimage or iframe" 2>&1 | tail -3` 全绿
2. `python3 -m py_compile pipeline/phases/p04_character_design.py pipeline/phases/p07_scene_generation.py pipeline/phases/p09c_storyboard_board.py pipeline/runner.py templates/gen_iframes.py`
3. `git diff <baseline>..HEAD --stat` 范围审查 + **dreamina 路径零删除断言**（`git diff | grep -c "^-.*dreamina"` 中删除行仅限注释/默认值翻改，禁删分支/函数）

## 基线与红线

- 仓：/data/workspace/kais-hermes-skills，发车前 `git log --oneline -1` 认环境（预期 HEAD=57af8271，若已前进以内容为准）。
- worktree：`git worktree add -b wt/image-engine-localize /data/workspace/kais-hermes-skills-wt/imgeng 57af8271`
- 红线：①**dreamina 代码路径/分支/函数零删除**——只翻默认值+加 auto 档，dreamina 永远是合法手动档；②**禁自动 fallback 到 dreamina**；③禁改 engine_adapters/{zimage,ideogram,two_step}.py 的既有对外语义（C5 修复除外）；④禁 GPU 真机渲染（测试全 mock，真机归 operator）；⑤禁 push，提交只进你的 worktree 分支；⑥ kais-hermes-skills 多会话共享仓，动手前 git log 认环境。
