edit | blame | history | raw

股票估值端到端协调层 V2 编码方案 V007

创建人员:dev.developer.project.secondary / infodev-2

事项:DEV-ANA-STOCK-VALUATION-PIPELINE-V2-20260801-001

性质:仅关闭实现复审 F5-R1 的 receipt 自指时序阻断;V003+V004+V005+V006 与已关闭 F1、其余实现修复合同全部继承。

当前状态:PENDING_RECEIPT_TIMING_DELTA_REVIEW;本文件 PASS 前不修改 F5 receipt/force 实现。

1. 阻断与不可满足点

V004 要求同一 OUT.commit-receipt.json 同时包含 commit_finished_at/task_wall_seconds/process_wall_seconds,且这些值代表该 receipt 自身最终原子写入与持久化完成之后的时刻。任何有限次实现都无法满足:先取时刻再写入,时刻早于这次写;写完再取时刻并回写,又产生一次更晚的最终写。当前实现以第二次写入前的时刻冒充写入完成,reviewer 对最终写单独延迟 0.25 秒后复现:实际成功返回 0.617s,receipt/stdout process_wall_seconds=0.359s,遗漏 0.258s

因此本修订不再让 receipt 自报其自身写后时刻。receipt 负责不可变地绑定 manifest 和提交身份;stdout 在 receipt 已原子写入、重新读取并复算 hash/bytes、完成 backup cleanup 尝试后记录最终墙钟。这样不存在自指,并能证明最终墙钟不早于 receipt 写入。

2. V004 receipt 合同的限定替换

本节仅替换 V004 第 3.3 节及第 4 节中“receipt 包含最终双墙钟、stdout 双墙钟逐值匹配 receipt”的条款。正式文件集合、receipt 路径、ticker stdout 精确字段、失败包和全部其他状态矩阵不变。

OUT.commit-receipt.json 升级为 schema 2,精确字段固定为:

{
  "schema_version": 2,
  "run_id": "string",
  "status": "COMPLETE|COMPLETE_WITH_GAPS|DATA_READY_NEEDS_JUDGMENT",
  "output_path": "absolute-string",
  "manifest_path": "absolute-string",
  "manifest_sha256": "64-lowercase-hex",
  "manifest_bytes": 0,
  "commit_ready_at": "timezone-aware ISO-8601",
  "receipt_write_started_at": "timezone-aware ISO-8601",
  "task_start": "timezone-aware ISO-8601",
  "task_start_source": "arg|process_start",
  "process_start": "timezone-aware ISO-8601",
  "wall_scope": "through_receipt_write_started"
}

schema 2 receipt 不含 commit_finished_at/task_wall_seconds/process_wall_seconds,也不增加会再次自引用的 receipt hash。receipt_write_started_at 只是写入开始下界,不得被文档或调用者解释为提交完成时刻。

ticker stdout 继续逐字遵循 V004 第 3.2 节的 schema 1 和 null 规则;成功 stdout 的 receipt_path/receipt_sha256/receipt_bytes 必须与最终 schema 2 receipt 实物一致。成功 stdout 的 terminal_at/task_wall_seconds/process_wall_seconds 改为唯一权威最终墙钟,terminal_at 必须在 receipt 原子写入返回、最终实物 hash/bytes 复算和 backup cleanup 尝试之后捕获。包内 runtime_metrics.json 继续是 through_commit_ready,其双墙钟不得大于 stdout 最终双墙钟。

3. 成功提交的确定状态机

成功路径顺序固定如下,不得调整:

  1. 完成 staging、QA、manifest-last,并记录 commit_ready_at
  2. force 时把旧 receipt 和旧 output 分别移入本次唯一 backup;
  3. 把 staging 原子 rename 为正式 output;
  4. 捕获 receipt_write_started_at,构造一次且仅一次的 schema 2 receipt canonical bytes;
  5. receipt 原子写:同目录临时文件 write -> flush -> fsync -> os.replace,临时文件/replace 任一点失败都算真正提交失败;
  6. 从正式 receipt 路径重新读取,复算 receipt_sha256/receipt_bytes,并逐值确认 run/status/output/manifest 指纹;读取、解析或复算失败仍算真正提交失败;
  7. 新 output+receipt 已验证后尝试清理旧 output/receipt backup;cleanup 失败只保留新真值、backup 和 warning,不回滚;
  8. cleanup 尝试返回后立即捕获 monotonic/wall terminal_at,计算 stdout 的最终 task/process wall,随后序列化并输出唯一一行 JSON;成功路径此后不得再写 output、receipt、cache 或 baseline。

不存在第二次“补写最终墙钟”的 receipt 写入。正式 receipt bytes 一旦第 5 步成功便不可变;stdout 只引用第 6 步复算的最终 hash/bytes。

4. 失败和 force 恢复

在第 5 或第 6 步发生 BaseException,均属于 receipt 未完成验证:

  • absent 模式:新 output 移到唯一 failed-<run_id> 归属,删除本次不完整 receipt/临时文件,生成 FAILED/BLOCKED 失败包,禁止成功 stdout;
  • force 模式:新 output 移入 failed 归属,恢复旧 output 和旧 receipt;恢复/清理的次生异常进入 rollback_errors,不得替换原 KeyboardInterrupt/SystemExit;旧正式树和旧 receipt hash 必须与提交前完全一致;
  • 第 7 步 cleanup 失败不属于提交失败,不移除新 output/receipt,不恢复旧版本;warning 必须进入 stderr/runtime 证据,stdout 最终墙钟在 warning 形成后捕获。

receipt 临时文件、正式 replace、最终重新读取/hash/stat、restore、cleanup 都是独立 fault point。路径词法预检和 reparse 规则继续继承 V003 与已完成 F5 修复,不在本修订重开。

5. 限定离线验收

新增实际入口测试,不以局部函数或静态字段断言替代:

  1. 最终 receipt 原子写仅延迟 0.25s:成功实际返回、stdout process_wall_seconds 均包含该延迟,允许计时器 50ms 容差;schema 2 receipt 不出现三个被废止的自指字段;
  2. receipt temp write、flush/fsync、replace、最终 read/hash/stat 各注入普通异常、KeyboardInterruptSystemExit;absent 不留伪成功,force 恢复旧 output/receipt 全树 hash;
  3. cleanup 延迟 0.25s 和 cleanup 失败:stdout 最终墙钟包含 cleanup 尝试;失败时新 output/receipt 仍为权威、backup 保留、warning 可消费;
  4. 复算 manifest/receipt hash/bytes,断言 stdout 路径和指纹精确一致;task_start<=process_start<=commit_ready_at<=receipt_write_started_at<=terminal_attask_wall>=process_wall>=0,runtime 双墙钟不大于 stdout;
  5. 三个成功终态和 force 替换都覆盖 schema 2;BLOCKED/FAILED/INPUT_ERROR 继续没有 receipt,V1 --input 0/2/3 完全不受影响。

本限定修订不要求真实网络 smoke;通过 fixture 和受控延迟/故障桩即可复验。实现后应同步工具说明、实现证据和执行日志,明确“receipt 绑定提交身份,stdout 是最终墙钟权威”,不得继续声称 receipt 自报写后时刻。

6. 不变边界与门禁

  • 不修改 ana-dev、V1 公式、provider、缓存 freshness、A1、报告、QA 或交易边界;
  • 不新增 GUI/API/数据库/服务/批处理/付费登录来源;
  • 操作手册仍处于 NOT_AUTHORIZED_WHILE_HOLD
  • dev.reviewer.project 对本 V007 PASS 后才实施第 2—5 节;F2-R1/F3-R1/F4-R1/F6-R1 继续按既有组合方案离线闭环,无需借本修订扩范围。