# 股票估值端到端协调层 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,精确字段固定为: ```json { "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-` 归属,删除本次不完整 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 各注入普通异常、`KeyboardInterrupt` 和 `SystemExit`;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_at`,`task_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 继续按既有组合方案离线闭环,无需借本修订扩范围。