## 修复记录

- 21:56：记录 bug 修复：非成功 Agent 工具调用可能被商业账本误计量。
  - Git 提交检查：已执行 `git fetch --all --prune`；`HEAD..origin/main` 无新增提交；本地 `main` ahead 17 个既有提交，分别为 `242d68c3` 审批任务流、`28b834ed` 不可变动作回放、`4940ebc4` 风险处置、`ee88a36b` 分层费用学习、`6bdf65bc` 权威预审、`ae3f02c3` 零录入票据关联、`54754b55` 个人申请记忆、`211f85d9` 统一申请流、`5b246307` 申请预览决策、`a662cfe6` 申请反馈台账、`5ed34c2b` 历史申请回填、`11275e4b` 迁移归属校验、`1347366b` 费用时间线与草稿事件、`22669a90` 统一费用事件时间线、`a616b30c` AI 申请事务、`653eda05` bearer 会话和 `661990b2` 费用案例事件；均非本次修复产生。
  - 修改：`commercial_runtime_policy.py` 把工具调用状态明确分为可计量、采集中和不可计量；`commercial_runtime_metering.py` 只允许 `succeeded/success/ok/completed` 的真实终态调用进入用量与成本账本，`running/pending/queued` 保留待终态补偿语义，`blocked/failed/skipped/cancelled` 不再产生商业事实。同步用 `commercial_runtime_bridge.py` 将未配置租户兼容放行、显式配置后的执行前配额门禁、成功调用后的幂等追加和故障补偿接入真实 `AgentToolCall` 生命周期。
  - 操作：在 `AgentRunService` 的创建与终态更新后触发桥接计量；在中央工具执行器调用真实 executor 前执行权益预检；将工具执行职责拆到 `orchestrator_tool_execution.py`，让核心编排文件回落到 762 行；所有命令均在 `local-x-financial-linux` 容器内运行并设置 60 秒超时。
  - 验证：商业运行计量 17 项通过，商业模型/服务/接口/运行计量合计 28 项通过，AgentRun 与 Orchestrator 鉴权相关回归合计 34 项通过；范围内 Ruff、`compileall`、diff 检查和类级 800 行检查通过。全库 code-size 门禁仍被本次范围外的 `RiskRuleGenerationService` 817 行阻断，未在本修复中改动该类。
  - 影响：未成功完成的工具调用不会再消耗客户配额或形成内部成本；未配置商业计量的既有租户继续执行；已配置租户在执行前受配额约束。计量系统故障时真实工具调用记录保持不变，返回 `requires_reconciliation` 并可按同一工具调用 ID 幂等重试，避免把计量失败伪装成已入账。

- 22:31：修复执行前只读配额在并发下可超卖、直接调用绕过预占及补偿误判问题。
  - Git 提交检查：再次执行 `git fetch --all --prune`、`git status -sb`、`git log HEAD..@{u}` 和 `git log @{u}..HEAD`；上游无新增提交，本地仍 ahead 17 个既有提交：`242d68c3`、`28b834ed`、`4940ebc4`、`ee88a36b`、`6bdf65bc`、`ae3f02c3`、`54754b55`、`211f85d9`、`5b246307`、`a662cfe6`、`5ed34c2b`、`11275e4b`、`1347366b`、`22669a90`、`a616b30c`、`653eda05`、`661990b2`，均非本次修复产生。
  - 修改：新增 `commercial_runtime_reservations` 运营占位及 `0019` 迁移；在订阅、权益行锁内按“已用量 + 有效预占 + 本次预占”原子校验硬配额。中央 Orchestrator 先生成稳定 tool call ID 并预占，再执行真实工具；成功且真实量不超过预占才追加用量/成本并提交，失败或阻断释放，变量基准没有执行器 hard max 时失败关闭。
  - 修改：新增持久 `reconciliation_required` 和过期补偿器。缺少执行前预占的旧直接调用不再静默补写正常用量，而是冻结对应容量；补偿器仅在真实工具成功、失败或运行已终止且无调用时结算/释放，运行中或来源不确定继续保留。修复历史过期订阅/权益错误启用门禁、无租户旧运行错误进入补偿、相同预占重试被自身占位判定为额度耗尽三个边界。
  - 操作：拆出运行时成本解析、周期键、标量校验、预占和补偿模块，相关核心类均低于 800 行；更新模型注册、迁移所有权、前置检查、商业配额投影、AgentRun/中央工具调用点和迁移/并发/补偿测试。所有 Python、Alembic 和 PostgreSQL 验证均在 `local-x-financial-linux` 容器内以 60 秒超时执行。
  - 验证：运行时定向 25 项通过；商业、Agent、权限、迁移组合 140 项通过；一次性 PostgreSQL 17 商业并发 4 项通过，两个线程竞争一份硬配额时只有一个预占成功；全新 PostgreSQL 0019→0020 完整 Alembic 升降级循环 1 项通过；范围内 Ruff、`compileall`、`git diff --check` 和相关类 800 行检查通过。Orchestrator review 套件保持既有 5 项本体/申请流失败、11 项通过；全库 code-size 仍仅被范围外 `RiskRuleGenerationService` 817 行阻断。
  - 影响：商业硬配额从“执行前提示”升级为数据库原子 permit，真实工具并发不能再穿透上限；成功事实可幂等结算，计量或成本故障保留可补偿状态且不伪造成功；未配置 runtime meter 的路径继续兼容，历史失效配置不会误拦截用户。

- 22:39：修复“用量已提交、成本写入失败”缺少持久补偿身份的问题。
  - Git 提交检查：再次执行 `git fetch --all --prune`、`git status -sb`、`git log HEAD..@{u}` 和 `git log @{u}..HEAD`；上游仍无新增提交，本地仍 ahead 17 个既有提交：`242d68c3`、`28b834ed`、`4940ebc4`、`ee88a36b`、`6bdf65bc`、`ae3f02c3`、`54754b55`、`211f85d9`、`5b246307`、`a662cfe6`、`5ed34c2b`、`11275e4b`、`1347366b`、`22669a90`、`a616b30c`、`653eda05`、`661990b2`，均非本次修复产生。
  - 修改：为运行时预占增加 `committed_reconciliation_required` 状态。真实用量已经追加但内部成本失败时，保留真实数量、结算时间和失败原因并进入补偿队列；按同一 tool call 重试只幂等补写成本，成功后恢复 committed。该状态不再计入有效预占，避免真实用量和冻结量重复消耗配额。
  - 修改：直连调用发生后若当前唯一匹配合同已暂停，允许补偿记录绑定原订阅/权益快照并进入 `reconciliation_required`；正常执行前 reserve 仍严格要求 active/trialing 订阅和 active 权益，不放宽真实执行许可。
  - 验证：容器内运行时定向 27 项、商业/Agent/权限/迁移组合 183 项通过，另 1 项因未显式配置外部迁移库跳过；全新 PostgreSQL 完整迁移循环 1 项、商业并发 4 项通过。成本故障用例验证 `used=1`、`reserved=0`，重试后用量仍为 1 且只新增 1 条成本；范围内 Ruff 通过。
  - 影响：成本账本短暂故障不再只依赖日志发现，也不会让客户额度被重复扣减；暂停发生与工具终态竞态时，已发生业务仍有持久、租户隔离的补偿证据。
