What · 是什么
ocr.run-manifest/v1:注册/封印/完成/失败四态跟踪每文件审查状态,8 类失败分类,预算截断≠运行失败
Run Manifest 是审查运行的覆盖度契约,声明本次审查覆盖了哪些项、每项什么状态、哪些失败,schema 标识为 'ocr.run-manifest/v1'
提供 RegisterSelected/SealSelected/MarkCompleted/Reused/Failed 等操作登记任务生命周期
FailureClass 分 8 类,实现精细化失败归因
SetRunFailure 与 SetPendingFailureCause 语义分离:预算截断(pending)≠ 运行失败(failure)
Finalize 冻结 input/repository/coverage,形成不可变快照
scan 模式无 manifest 属设计行为,非缺陷
Why · 为什么
原理 · Principle
审查工具必须能回答『这次审查到底完整吗』,manifest 是覆盖度的单一事实源
8 类 FailureClass 让失败可机器归因(超时/上下文溢出/LLM 错误等),支撑自动重试与审计
pending(预算截断)与 failure 分离,避免把『没审完』误判为『审坏了』
Finalize 冻结快照保证审计时引用的输入与产出严格一致
How · 怎么做
运行开始时通过 RegisterSelected 登记被选中的评审项,SealSelected 封存选定集合
每项完成后调用 MarkCompleted/Reused/Failed 更新状态,形成逐项覆盖度台账
失败按 FailureClass 8 类归因,如 LLM 调用失败、上下文截断、定位失败、超时等
预算截断类情况用 SetPendingFailureCause 记录未决原因,区别于 SetRunFailure 的整体运行失败
全部任务结束后 Finalize 冻结 input/repository/coverage 三元快照,落盘为不可变记录
scan 模式因无逐项评审任务,按设计不产出 manifest
案例 · Cases
| 代表性案例 |
|---|
| 运行中 3 项因上下文溢出失败,manifest 记为 failed(类:上下文溢出),重试时精确重跑这 3 项 |
| 预算只够审 80 项中的 60 项,剩余 20 项记为 pending(SetPendingFailureCause),不污染失败统计 |
| 审计时读取 Finalize 快照,确认 coverage 与 input 严格对应 |
| 复用评论的条目 MarkReused,覆盖度统计中明确区分『新审』与『复用』 |
反模式 · Anti-patterns
- 把预算截断的 pending 项标记为 failed,覆盖度报告失真,误导重试与统计
- 跳过 Finalize 不冻结快照,后续审计无法确认输入与产出的对应关系
- 失败不按 FailureClass 归因而只记布尔值,机器无法自动分类重试
- 在 scan 模式强造 manifest,破坏『scan 无 manifest』的设计契约
正反实例论证 · Evidence
正例 · Pro
预算截断用 SetPendingFailureCause,与 SetRunFailure 分离
RegisterSelected(items)SealSelected(items)# 预算耗尽,剩余项未审SetPendingFailureCause(items[60:], BudgetTruncated)# 而非 SetRunFailure() 整体判失败Finalize(input, repository, coverage) // 冻结快照pending(预算截断)与 failure 语义分离:剩余项记为未决而非失败,覆盖度报告不失真;Finalize 冻结 input/repository/coverage 供审计引用。
反例 · Con
把 pending 项标 failed,覆盖度报告失真
# 错误:预算截断当失败MarkFailed(items[60:])# 覆盖度统计:60/80 失败,实际是未审完把『没审完』误判为『审坏了』,误导重试策略与覆盖度统计,审计结论全面失真。
正例 · Pro
失败按 FailureClass 8 类归因,可机器分类重试
switch failure.Class {case ContextOverflow: retryWithLargerBudget(item)case LLMCallFailed: retryWithBackoff(item)case LocateFailed: fallbackToRelocate(item)case Timeout: requeue(item)}# 每项 MarkCompleted/Reused/Failed 更新台账逐项状态 + 8 类失败归因形成逐项覆盖度台账,重试逻辑可按类精确处理,而不是对整次运行一刀切。
反例 · Con
失败只记布尔值且跳过 Finalize
# 错误:失败不归因item.Failed = true // 无法自动分类重试# 错误:不冻结快照runDone() // 无 input/repository/coverage 快照布尔失败标记让机器无法自动分类重试;跳过 Finalize 后审计无法确认输入与产出的严格对应关系,覆盖度契约名存实亡。