补充 run-workflow 的轮次、漂移与写回幂等口径

- 检查点行补充 outdated 与起始 revision,明确 write-back / outdated 都是轮次结束行
- 追加前截断半行,避免崩溃留下的半行夹在日志中间
- 文档中途漂移时追加 outdated 并返回错误,由下一次调用显式开新一轮,不在同一次调用内自动重启
- 写回按「目标 State 与文档当前 State 相等」判幂等,并记录该判据成立的前提
- 切图资源失败不回滚,NeedReview 由 separation DTO 的 problematic_nodes 在编排阶段统一回写
This commit is contained in:
2026-09-23 19:12:19 +08:00
parent 648ead2150
commit 8ac8f2ff5d
@@ -39,15 +39,24 @@
不再有合并、组件绑定与页面级 profile/finalize 阶段;`recognize` 之前不做任何前置发现。
`NeedReview``component_status` 的清理是 `separation` DTO 的一部分:问题节点由 DTO 的
`problematic_nodes` 给出,编排阶段统一回写,重放时不需要模型再判一次;文案与判据镜像
前端 `features/ui-editor/separationStatus.ts`
## 崩溃恢复
检查点是文档旁一条追加式 JSONL 日志,方案与被否方案见 [ADR:UI 工作流检查点用追加式 JSONL 日志](../adr/【ADR】UI工作流检查点用追加式JSONL日志-2026-09-23.md)。
- 位置:`ui/.<文档文件名去扩展名>-workflow.jsonl`,与文档同级,不进 manifest、不推进项目 revision。
- 行格式:`run`(原始 State 快照)、`recognize`DTO)、`separate`DTO)、`write-back`(新 revision);行内另带 `at` 时间戳。
- 行格式:`run`(原始 State 快照 + 起始 revision)、`recognize`DTO)、`separate`DTO)、`write-back`(新 revision`outdated`(本轮作废原因);行内另带 `at` 时间戳。
- 判据只有一条:「本步有没有对应的行」。每行必须一次性原子追加,崩溃留下的半行一律视为该步未完成。
- 轮次:一轮以 `run` 行开头,以该轮第一行 `write-back` 结束;恢复只针对最后一没有 `write-back` 的轮次
- 轮次:一轮以 `run` 行开头,以该轮第一行 `write-back` `outdated` 结束;只有最后一没有结束行时才需要恢复。`outdated` 只作废未完成的那一轮,不删除既有行
- 半行:追加前先把日志截断到最后一个换行,丢掉崩溃留下的半行,避免它夹在日志中间。
- 漂移:文档在轮次中途被改动(当前 State 与 `run` 行快照不一致)时,追加一行 `outdated` 并**返回错误**,不在同一次调用里自动重开新一轮;下一次调用看到 `outdated` 才从头开新一轮,且以当前文档为基准。
- 写回幂等:`save` 成功但 `write-back` 行没追加时,重放会重建出同一份目标 State,此时按「目标 State 与文档当前 State 相等」判定为已写完,直接补 `write-back` 行并返回成功。这条判据成立的前提是工作流这条路不产生随机身份:识别树的根节点 id 来自 DTO,切图资源 id 走 manifest 的 by-path 复用。
- 切图资源不回滚:切分产出的图片与已登记资源在失败后保留,重放靠 by-path 复用接上,不做回滚清理。
- 切分 op 内部的细粒度恢复仍由 `SeparationState` 承担(`ui-editor-separation-state.v2` sidecar),日志只记录工作流层面的步骤完成,不复制它的进度。
- 不引入跨语言 fixture 比对:镜像的四个 seam 都是简单变换,靠同语义实现与各自单测覆盖,不为它们额外维护一套 golden。
## 模块布局