## 修复记录

- 2026-07-16 15:10:42 CST：修复审批、退回和付款动作缺少稳定请求标识、预期状态与预期审批节点校验的问题。新增租户 + 操作人 + 请求 ID 唯一账本、请求指纹、PostgreSQL advisory lock 与 Claim 行锁；完全相同的重试返回原结果，请求内容变化或状态已过期返回 409，不重复扣减预算、写审批记录、生成业务事件或付款结果。
- 2026-07-16 15:10:42 CST：修复高风险观察仅展示但不阻止审批的问题。审批流程在任何路由、预算和业务状态变更之前检查同租户高危/严重风险；只有已判定误报或完成处置的观察允许继续，阻断响应返回稳定错误码和观察状态，整笔动作账本随事务回滚。
- 2026-07-16 15:10:42 CST：前端确认弹窗冻结请求 ID、预期单据状态和审批节点，网络结果不确定时复用同一请求，避免用户重试造成重复业务副作用。
- 2026-07-16 15:10:42 CST：验证在 `local-x-financial-linux` 容器完成：费用服务 116 项、审批动作/风险门禁/风险处置组合 26 项、报销接口回归 22 项；一次性 tmpfs PostgreSQL 17 迁移循环 13 项通过。变更 Python 文件 Ruff F/I 与格式检查通过。
- 2026-07-16 15:10:42 CST：Git 拉取检查已执行；上游没有本地尚未包含的新提交，当前分支相对上游 ahead 14。已有本地提交包括 `ee88a36b` 分层费用学习、`6bdf65bc` 权威预审、`ae3f02c3` 零录入票据闭环等，本次修复在这些能力之上继续演进。
- 2026-07-16 15:33:03 CST：交叉审查后修复三项并发绕过：审批动作不再调用会隐式提交的读取修复逻辑，列表/分页 GET 也不再修改审批节点；审批中心保留服务端原始状态并单独生成展示标签；门禁将持久化风险观察与未匹配原始高风险合并，重大观察持久化失败时 fail-closed。
- 2026-07-16 15:33:03 CST：审批、风险处置和 Hermes 扫描统一以 Claim 行锁为公共协调点，锁顺序固定为 Claim → Observation → Disposition；Hermes 锁外计算、锁内刷新并核对状态和更新时间，旧快照被丢弃。一次性 PostgreSQL 并发用例证明风险重新打开与审批竞争时，审批等待后读取最新风险并阻断，Claim 节点和动作账本均保持无副作用。
- 2026-07-16 15:33:03 CST：最终容器回归为审批/风险/费用服务 174 项、迁移/所有权 54 项、前端审批/风险 73 项通过，Vite 生产构建通过；一次性 tmpfs PostgreSQL 17 上 13 项迁移和 1 项真实并发测试通过，临时数据库自动清理。再次执行 Git 拉取检查，上游仍无新增提交，本地 ahead 14。
- 2026-07-16 15:44:39 CST：提交后交叉审查发现“副作用幂等”不等于“响应幂等”：动作账本虽然已有 `response_json`，重放却重新读取当前 Claim，后续节点变化会返回新状态。现改为首次动作在同一事务保存完整 `ExpenseClaimRead`，首次和重放均从该快照构造响应；快照缺失、单据/状态/节点身份不一致时 fail-closed 返回冲突，不再退回当前投影。
- 2026-07-16 15:44:39 CST：新增“首次批准 → 单据继续推进并写入后续内部状态 → 旧 request_id 重放”服务和 HTTP 回归，确认响应逐字段等于首次结果、后续风险字段不泄露、数据库当前状态不被回退；审批动作与报销接口组合 29 项通过。
- 2026-07-16 15:44:39 CST：再次完成 Git 拉取检查，上游无新增提交，本地 ahead 15，新增 ahead 为 `4940ebc4` 审批风险安全底座；用户维护的财务规则工作簿和历史日志继续保持未暂存。
- 2026-07-16 15:48:38 CST：扩大回归范围后发现两个兼容边界：首次动作若直接返回 Pydantic 快照会破坏既有服务层 ORM 可变语义，因此首次执行继续返回已提交并刷新的 ORM，只有重放从不可变快照构造；HTTP 首次与重放仍逐字段一致。另为风险门禁增加申请/报销阶段匹配，显式错阶段风险不阻断当前流程，未知阶段重大风险仍 fail-closed。
- 2026-07-16 15:48:38 CST：路由型重大风险统一使用显式 `route_review`，它允许当前审批进入预算/财务复核，但不会被标记为已解决；普通无 actionability 的原始重大风险继续阻断。容器内费用服务、审批路由、租户/Case、动作协议、接口和风险处置组合 182 项通过。
