KMC ⇄ KAP 无限画布管线状态机对齐审计

审计日期:2026-08-06 · 方法:7 个并行 extraction agent 深读两仓全部指定文件 + 4 处关键源码核验
KMC:canvas_sync.py (4408行) · KAP:canvasAssetSchema.ts / flowgraph-v2-schema.ts / canvasRelationalStore.ts / save-v2.ts
4
🚨 CRITICAL 断裂
6
⚠️ WARNING
6
ℹ️ INFO
17
Phase 总数 (Registry)
13
KAP NodeType 枚举
11
KMC ref_type 种类
§0 前置关键发现:KAP 存在三套类型定义,canvas.ts 不是存储契约。 关系存储层 (canvasRelationalStore.ts) 和 save-v2 校验门引用的是 flowgraph-v2.ts / flowgraph-v2-schema.ts, 其 NodeType 有 13 个(vs canvas.ts 6 个),NodeState 末位是 skipped(vs canvas.ts cached)。
目录

§1 资产节点类型对齐表

1.1 节点 type(canvas_type)对齐

KMC 产出 {script, asset, storyboard, video, audio}(5个),全部落在 KAP Gate A 13 枚举内 → 不 reject

PhaseKMC canvas_typeKMC asset_typeKAP NodeType ∈ 枚举对齐
p01scripttopic✅✅
p02scriptoutline✅✅
p03scriptscript_phase✅✅
p04assetcharacter✅✅
p05scriptscript_phase✅⚠️ 死映射
p06scriptscript_phase✅✅
p07assetscene✅✅
p08assetscene✅✅
p09storyboardstoryboard✅✅
p09bscriptscript_phase✅✅
p10audiovoice✅✅
p10bvideoclip✅✅
p10caudiovoice✅✅
p11videovideo✅✅
p12videoclip✅✅
p13scriptdelivery✅✅
p14scriptscript_phase✅✅
p15未定义 (fallback: asset/scene)——🚨 不可见

1.3 Phase 漂移

p15_feedback:runner 会执行(PHASE_REGISTRY 含 p15),但 canvas_sync 三张表(_PHASE_TYPE_MAP / _LABELS / _INDEX_MAP)和 _PHASE_OUTPUT_MAP 都无 p15 条目 → 若触发 on_phase_complete,phaseIndex=0、label 走 fallback、type 走 asset/scene fallback → 整个 P15 反思产出被丢弃

p05:已从 PHASE_REGISTRY 链中移出(DIALOGUE-REFORM),但 canvas_sync 三张表仍保留 p05 条目 → 死映射(不影响功能,建议清理)

§2 资产输出 Key 对齐表

2.1 字段映射机制

KMC 有完整的适配层主动满足 save-v2 Gate B(缺必填参 → HTTP 400):

2.2 Gate B 必填字段 vs KMC 实际产出

KAP 节点类型Gate B 必填KMC 对应产出风险
audiofilePath, shot_id, engine, duration_secvoice_clips 透传🚨 源缺则 400
videofilePath, shot_id, engine, duration_sec, resolutionvideo_clips 透传🚨 源缺则 400
assetfilePath, label, assetTypep04/p07/p08 全带✅
storyboardlabel, shot_id, shot_type, duration_secKMC 用 shot_intent 而非 shot_type🚨 字段名风险
scriptlabel, descriptionlabel 必有 + description 兜底✅
关键风险:媒体守卫只救"缺 filePath"(降级 script),救不了"有 filePath 但缺 engine/duration_sec/resolution/shot_type"。一旦某个节点带 filePath 缺必填参,Gate B 仍 400 reject 整张图。

2.3 Phantom(声明但不产出)& Orphan(产出但未声明)

6 个 phantom(全部有意占位,Notion forward-declaration):p07.scene_blueprint、p07.scene_temporal_variants、p11.midframes、p12.foley_stems、p12.bgm_tracks

Orphan产出处后果严重度
p15.feedback-logp15_feedback.py:300整个跨集反思产出对画布不可见🚨
p07.imagesfilesystem-fallback 别名与 scene_images 生成重复节点⚠️
p09.continuity_reportp09_shot_breakdown.py:1534dict 型,静默丢弃⚠️
p03.auditp03_script_audit.py:637dict 型别名,丢弃ℹ️
p10b.errorp10b 异常路径string 型,丢弃ℹ️

§3 参考关系(画布拓扑边)对应表

3.1 KMC 实际产出的边模型

KMC 持久化的 link dict 极简:{id, source, target, branchId, dataType}

3.2 KAP 的边模型 vs KMC

维度KAP 侧事实与 KMC 对齐?
canvas_links 表列无 link_type / ref_type / semantic 列⚠️ 巧合"对齐"(都丢)
LinkSemanticType仅 canvas.ts 有;FlowLinkV2 无此字段 → save 即丢🚨 双向无持久化
LinkRefType同上,仅 canvas.ts;FlowLinkV2 无 → 丢弃🚨
LinkDataTypeFlowLinkV2Schema.dataType 为自由 string,不校验🚨 词表零交集
§3.3 边层面断裂结论:

§4 状态机对齐

4.1 节点 state 执行态

KMC 实际写入 {success, pending, error, idle}(4值),全在 KAP Gate A 6 枚举内 → 不 reject

KMC 写入的 state条件依据
success无 error 且非 gate-awaitingL1628
pendinggate awaiting_reviewL1626
errorresult["error"] 存在(优先于 pending)L1623-1624
idle未选中的候选 scene/shot 子节点L3649,3732

KMC 从不写 running(无瞬态);KAP 的 cached(canvas.ts) vs skipped(flowgraph-v2) 自相矛盾

4.3 Gate / ReviewStatus 映射

🚨 CRITICAL 错位:KMC 把 reviewStatus 写在 node_data["data"]["reviewStatus"](嵌套,L1684), 而 KAP 契约/存储读顶层 reviewStatus(flowgraph-v2-schema.ts:42)→ canvas_nodes.review_status 列恒 NULL → 审核徽章/过滤完全失效。 值本身没丢(活在 data JSON blob 里),但任何按顶层 reviewStatus 过滤的前端都看不到。

4.2 error / timeout 反映到画布

✅ runner 异常处理器在 re-raise 之前先 sync error stub(runner.py:2524,2587,2813),canvas_sync 见 error → state=error + 错误 tag 拼进 description → error/timeout 能正确反映为画布 error 节点

§5 已知断裂点 & 风险清单

🚨 CRITICAL(数据丢失 / 用户看到错误或缺失信息)

C1. P15_feedback 整相产出对画布不可见

runner 会跑 p15,但 canvas_sync 四张表无 p15 → feedback-log(含 rejected_phases/rejection_events/lesson_count)完全不落画布。

建议:三张表补 p15 条目;_PHASE_OUTPUT_MAP 增 "p15": [("feedback-log","跨集反思","script",True)]

C2. Link 的 ref/semantic 粒度全链路丢失

KMC 11 种 ref_type + KAP LinkSemanticType/LinkRefType 双向都无持久化。canvas_links 无列、FlowLinkV2 无字段、save 即丢。

建议:(a) KAP 加 link_type/ref_type 列并在 FlowLinkV2 建模;或 (b) 约定前端解析 id 前缀 ref-{type}-

C3. ReviewStatus 字段错位(嵌套 vs 顶层)

KMC 写 data.reviewStatus(嵌套 L1684),KAP 读顶层 reviewStatus → review_status 列恒 NULL。

建议:KMC 在 _build_phase_node / _build_gate_node 额外写顶层 node_data["reviewStatus"]

C4. Gate B 整批 400 风险

任一 audio/video/storyboard 节点缺必填即整张图 400。媒体守卫只救"缺 filePath",救不了"有 filePath 缺 engine/duration_sec/resolution/shot_type"。

建议:_build_artifact_node 增字段名归一化(shot_intent→shot_type 等)+ 缺关键字段的媒体节点统一降级为 script

⚠️ WARNING

#问题建议
W1KAP 三套类型定义不同步,canvas.ts 过期(6 NodeType vs 13;cached vs skipped)统一以 flowgraph-v2 为唯一源,对齐/删除 canvas.ts
W2dataType 词表不交(output/reference vs text/image/video/audio/data)明确 output/reference 的前端处理,或 KMC 改用 KAP 词表
W3p07.images orphan 产生重复节点把 images 纳入 p07 声明集或在 fallback 抑制别名
W4p09.continuity_report 静默丢弃补 _PHASE_OUTPUT_MAP 声明
W5FlowGraphNode 多字段持久化丢失(progress/groupId/routingDecision/variantIndex)确认是否仍需,否则从 canvas.ts 移除
W6微门 phaseIndex 共享致排序歧义(p10b/p10c 都=10)微门给唯一 phaseIndex 或显式 sort key

ℹ️ INFO

附:两套系统契约速查

项KMC(产出方)KAP(消费/校验方)
phase 列表PHASE_REGISTRY 17 项(含 p15、不含 p05)无独立枚举;靠 node.phaseIndex/phaseName
节点 type{script, asset, storyboard, video, audio}Gate A 枚举 13 个
节点 state{success, pending, error, idle}Gate A 枚举 6 个;canvas.ts 末位 cached(矛盾)
reviewStatus写在 data.reviewStatus(嵌套)读顶层 reviewStatus → review_status 列
边 dataType{output, reference}LinkDataType {text,image,video,audio,data}(不校验)
边 ref/semantic11 种 ref_type,仅编码在 link id 串LinkSemanticType/LinkRefType 仅在 canvas.ts,无列、无字段、save 即丢
必填参校验主动适配(normalize/passthrough/降级/description 兜底)Gate B:缺必填 → 整图 400
报告由 GLM-5.2[1m] 老司机 7-agent 并行审计产出 · 完整 Markdown 版:/tmp/canvas-state-compare-report.md