文档:T-13 回写 + 全仓进度一致性(开发计划 DoD 6/6 全勾 + 执行记录 · PRD §9 第 18/31 条实测回填 · 交接文档 v4.3)

This commit is contained in:
2026-09-12 11:58:42 +08:00
parent 3bc84a093d
commit 5f7ad9180b
6 changed files with 109 additions and 14 deletions
+82 -1
View File
@@ -1,6 +1,6 @@
# 2026-09-12 工作日志
> 本日:基金转换线(T+1 受理/确认分离模型)**第 5 步 T-11、T-12 完成** —— T-11 core_tools 汇总去重 + 持仓过滤(确认段场景补用例,生产代码零改动);T-12 补偿 + SLA 清理切 T+1 链路 + **confirm_one 引擎异常留痕修复**(真库脚本暴露)。**用户新增铁律:不确定的外部真实业务事实必须联网核实,禁止凭训练记忆假设。**
> 本日:基金转换线(T+1 受理/确认分离模型)**第 5 步 T-11、T-12、T-13 完成** —— T-11 core_tools 汇总去重 + 持仓过滤(确认段场景补用例,生产代码零改动);T-12 补偿 + SLA 清理切 T+1 链路 + **confirm_one 引擎异常留痕修复**(真库脚本暴露)。**用户新增铁律:不确定的外部真实业务事实必须联网核实,禁止凭训练记忆假设。**
---
@@ -179,3 +179,84 @@ confirmed 审计与 return dict;**D17「不阻断」语义保留**(测试注
CONVERT_STRESS 并发 · 性能实测(端到端 < 2s 硬门禁)· 紧池成功率重测 ·
`convert_fund` / `rebuild_convert_response` 删除 + v1.0 依赖链
(约 25 处测试 + `verify_convert_service.py`)改写。
---
# T-13:全量门禁 + `convert_fund` 退役(2026-09-12 下午)
## 一、退役落地(convert_service.py 净删 468 行)
- 删除 `convert_fund`(v1.0 两阶段实时八步编排)+ v1.0 专属依赖:
`_plan_and_quote` / `_pick_rate`(死代码)/ `_finalize_from_core` / `_write_main_audit`
+ 17 个孤儿 import;模块 docstring 重写为 T+1 编排说明;
`__all__` 收敛为 6 个在役符号(accept_convert / cancel_convert / t1_t2_dates /
compensate_convert / rebuild_convert_response / PROCESSING)。
- **按实际修订**:开发计划原「`rebuild_convert_response` T-13 退役」**不成立** ——
它是 T-9 查询接口 confirmed 分支的在役读路径,**保留在役**
(`PROCESSING` 仅作 simulate 网关 202 判断常量,同样保留)。
- `verify_convert_service.py`(v1.0 链路真库脚本)`git rm`,git 历史留档。
## 二、测试面改写(约 25 处映射落地)
- `test_convert_service.py` 全量重写(805 → 约 440 行):v1.0 十组用例退役,
替代断言分布 = T-6/T-7/T-8 既有用例 + 补偿组 6 用例保留 + 新增 2
(`confirm_mirror_write_failure_keeps_core_confirmed` 镜像失败不回滚 Core /
`confirm_rejects_too_many_lots` 批次上限 rejected 零流水 remain==200)。
- **显式依赖注入踩坑(留痕)**:`confirm_one` 的 `core_writer` / `request_repo`
缺省构造会**连真 MySQL** —— 症状一:写侧 FK 1452(事务整体回滚,真库零污染);
症状二:`rrepo.reject` 条件 UPDATE 在真库 rowcount=0 → rejected 被误判 skipped。
测试 helper `_services` 必须把五个仓储全部钉在同一 sqlite 引擎。
- `test_convert_concurrency.py` 全量重写为 T+1 并发面(v1.0 九用例 → 六用例):
- 50 并发扣减争抢 → **并发 confirm_one 不超卖**(受理段允许 R-3 TOCTOU 超授、
确认段 FIFO 哨兵兜底,硬不变量钉在确认后);
- 紧池 80% → **紧池 100%**(受理全 accepted + `confirm_batch` 串行);
- 同键并发单次转换 → **同键并发受理单唯一**(uk_idem + 客户级锁;
3b/3c 占位竞态确定性交错用例随 v1.0 占位语义退役,无 T+1 对应物);
- 死锁重试 → 多客户并发 confirm_one(本轮实测内部重试吸收,外部退避 0 次);
- 性能探针 → 受理/确认/端到端三段计量。
- **monkeypatch 边界(留痕)**:`confirm_one` 的 trade_id 走 `format.new_id`
(与 `convert_service._new_id` 是两个符号),patch 罩不到 → `_confirm` /
`confirm_batch` 显式传 `id_factory=_new_id`。
- **并发语义裁定(S2)**:`LotConflict`(退避耗尽)= 并发 confirm_one(超纲场景,
生产由批处理锁保证串行 FR-C23)下的**零扣减让路终态**,受理单保持 accepted
占用保持、下轮批处理可再确认 —— 与 v1.0 用例 1 允许 LotConflict 同口径,
资金安全不变量独立成立。
## 三、门禁结果(六条 DoD 全勾)
| DoD | 结果 |
|---|---|
| 全量 pytest | **830 passed / 7 skipped** 退出码 0(849 → 830 = v1.0 用例组退役净减;skip 10 → 7 = 并发 stress 标记 7 → 4) |
| 真库 verify 套件 | **9/9 退出码 0**:accept 37 / confirm 83 / engine 39 / api 89 / compensate 56 / apply 24 / lots 20 / seed 全 PASS / tools 14 |
| CONVERT_STRESS=1 | **6/6** 退出码 0 |
| 性能(< 2s 硬门禁) | **端到端 P50 79.2 / P95 110.3 / max 114.7 / mean 83.0 ms**,余量约 17 倍(回填 PRD §9 第 18 条) |
| 紧池(验收 31) | **受理 50/50 + 串行确认 50/50 = 100%**、扣减恰=池守恒(v1.0 同场景 80%;回填 PRD §9 第 31 条) |
| convert_fund 残留 | grep 仅 4 处注释性历史说明、**零调用**;redeem 传 `amount=` 过期调用全仓零残留 |
## 四、计划外产出:全量复跑抓出过期脚本 1 处
`verify_convert_lots.py`(T-10 产物)B/C/D 组仍按 v1.0「金额赎回」传 `amount=` ——
T-9 已按 D26/R-6 改**份额申报**(`qty=`),`_maintain_lots` redeem 分支
`qty is None` 时**静默跳过**(尽力而为语义)→ B/C FIFO 扣减失效、D 组兜底补建红
(A 组申购不受影响,故首轮仅此脚本红)。修正为 `qty=` 后 **20/20**。
「金额申购、份额赎回」行业铁律(2026-09-10 联网查证)的又一处落地。
## 五、性能实测口径(载体 `test_performance_probe_accept_confirm_end_to_end`)
n=59(n=60 剔除首个连接池冷启动样本)· 本机 MySQL 8.0.46 / 模拟库 / 单线程顺序 /
每笔 1 份 / 空引擎 hook:受理段 P50 37.9 / P95 53.8 / max 57.9;
确认事务(`apply_convert`)P50 10.0 / P95 25.3 / max 25.5;
确认全程 P50 41.4 / P95 61.3 / max 74.4;端到端 = 受理 + 确认两段之和。
## 六、文档回写
开发计划 v2.0(文件头基线 830/7 + T-13 节 DoD 6/6 全勾 + 执行记录 ①~⑧)·
PRD v1.1(§9 第 18 条性能实测 + 第 31 条紧池 100% 回填)· `交接文档.md`(v4.2 → **v4.3**,
§B.11 状态段 + T-13 完成段 + 基线行)· `docs/memory/TODO.md`(进度行 + T-13 勾选,
T-14~T-17 待办拆出)· `docs/memory/MEMORY.md`(3 处进度)· `AGENTS.md`(进度行)· 本日志。
## 七、下一步
**T-14**(D27 产品舍入真正接入):`calc.py` `product_round` 接入 +
`core_share_rule` 种子 + 4 位产品用例(覆盖率不得让降级路径当覆盖)。
其后 T-15~T-17。提交:代码 `3bc84a0` + 文档(本次),均**不 push**(由用户定)。
+3 -3
View File
@@ -13,7 +13,7 @@
**⚡ 基金转换(convert)线 — 两条子线**:
- **(一)v0.x 两阶段实时模型(已结项 2026-09-10)**:PRD **v0.9.3** + 架构 **v1.0.1** + 开发计划 **v1.0**,T-0 ~ T-13 全部完成(第 5+6 步闭环,最终 **739 passed / 10 skipped**,`CONVERT_STRESS=1` 并发 9/9,含死锁重试补丁 `43cf2a1`);**该模型已被下一线取代,其 PRD/架构/开发计划作废,代码保留作过渡基线**。
- **(二)下一线 · T+1 受理/确认分离模型(进行中 · 2026-09-11)**:入口 **交接文档.md §B.11**(10 项真实业务拍板)· PRD **v1.1** + 架构 **v2.1** 已整体重写并经独立 AI 联网审查通过(0 阻断级),**已定稿**(2026-09-11 用户批准);**第 4 步开发计划 v2.0 已整体重做**(`docs/项目框架设计/开发计划-基金转换交易.md`,797 行:T-0~T-17 按架构 §15 重排 + §1.4 代码事实核对表 F-1~F-25 + §1.5 实现级裁定 R-1~R-15 + §5 十六条回归面 + §6 验收 31 条 + FR-C29/C30 全映射),**经三轮独立审核闭环(第一轮挑毛病 2 阻断+5 重要+3 可选 / 第二轮验证型 12 项零残留 / 第三轮白纸重审 C1~C5+O1~O4 + 验证型复核 22/22 落位),已定稿(2026-09-11 用户批准)**。**核心认知:不新增冻结列,在途占用由受理单推导;紧池 80% 病根在 T+1 串行确认下自动消失。** 下一步:**第 5 步 todo 开发进行中(T-1~T-12 ✅,**849 passed / 10 skipped** 零失败;T-6 真库 verify **37/37**、T-7 真库 verify **83/83**、T-8 真库 verify **39/39**、T-9/T-10 真库 verify_convert_api **89/89**、T-11 复跑 verify_convert_tools **14/14**、T-12 重写 verify_convert_compensate **56/56**,退出码均 0;下一步 T-13 全量回归 + convert_fund 退役)**。**T-7 关键裁定:强制全转属受理段决策** —— 受理由 `plan_lots` 判定并把 `qty` 收敛为实际全转量 + 受理单 `remark='full_transfer'`,确认段**只继承不重判**(`plan_lots` 不传 `min_hold_qty`);重判会因 T→T+1 可用份额变化(部分成交/他人申赎/产品参数改)得出与受理承诺不一致的结论(擅自扩大客户指令)。**T-8 关键裁定**:引擎时机(R-7)的实现部分在 T-7 已完成,T-8 补的是**守护与验证**(AST 守护唯一调用点 / 受理不触引擎 / 确认链路真引擎正证+反证);⚠️ **T-8 不动去重口径** —— `amount_view` 三处消费方原样不动(属 T-11);`convert_fund` 的阶段 1.5 调用点随 T-9 删函数一并清除(只摘调用会让 v1.0 过渡函数「扣份额但不出预警单」,风控缺失比时机错更危险)。撤单范围:PRD §5.5 原表述与实现(仅 `accepted`)不矛盾、无需回填(第三轮 C1 订正)。已就绪:`fetch_nav.py` / `06-seed-nav.sql`(60 个真实净值日)/ `gen_trade_calendar.py` / `10-seed-trade-calendar.sql`(503 交易日)。
- **(二)下一线 · T+1 受理/确认分离模型(进行中 · 2026-09-11)**:入口 **交接文档.md §B.11**(10 项真实业务拍板)· PRD **v1.1** + 架构 **v2.1** 已整体重写并经独立 AI 联网审查通过(0 阻断级),**已定稿**(2026-09-11 用户批准);**第 4 步开发计划 v2.0 已整体重做**(`docs/项目框架设计/开发计划-基金转换交易.md`,797 行:T-0~T-17 按架构 §15 重排 + §1.4 代码事实核对表 F-1~F-25 + §1.5 实现级裁定 R-1~R-15 + §5 十六条回归面 + §6 验收 31 条 + FR-C29/C30 全映射),**经三轮独立审核闭环(第一轮挑毛病 2 阻断+5 重要+3 可选 / 第二轮验证型 12 项零残留 / 第三轮白纸重审 C1~C5+O1~O4 + 验证型复核 22/22 落位),已定稿(2026-09-11 用户批准)**。**核心认知:不新增冻结列,在途占用由受理单推导;紧池 80% 病根在 T+1 串行确认下自动消失。** 下一步:**第 5 步 todo 开发进行中(T-1~T-13 ✅,**830 passed / 7 skipped** 零失败;真库 verify 套件 **9/9 退出码 0**:accept 37 / confirm 83 / engine 39 / api 89 / compensate 56 / apply 24 / lots 20 / seed 全 PASS / tools 14;T-13 = 全量门禁 + convert_fund 退役——v1.0 入口净删 468 行、端到端性能实测 P95 110.3ms(<2s)、紧池 100%(v1.0 为 80%);下一步 T-14 D27 产品舍入接入)**。**T-7 关键裁定:强制全转属受理段决策** —— 受理由 `plan_lots` 判定并把 `qty` 收敛为实际全转量 + 受理单 `remark='full_transfer'`,确认段**只继承不重判**(`plan_lots` 不传 `min_hold_qty`);重判会因 T→T+1 可用份额变化(部分成交/他人申赎/产品参数改)得出与受理承诺不一致的结论(擅自扩大客户指令)。**T-8 关键裁定**:引擎时机(R-7)的实现部分在 T-7 已完成,T-8 补的是**守护与验证**(AST 守护唯一调用点 / 受理不触引擎 / 确认链路真引擎正证+反证);⚠️ **T-8 不动去重口径** —— `amount_view` 三处消费方原样不动(属 T-11);`convert_fund` 的阶段 1.5 调用点随 T-9 删函数一并清除(只摘调用会让 v1.0 过渡函数「扣份额但不出预警单」,风控缺失比时机错更危险)。撤单范围:PRD §5.5 原表述与实现(仅 `accepted`)不矛盾、无需回填(第三轮 C1 订正)。已就绪:`fetch_nav.py` / `06-seed-nav.sql`(60 个真实净值日)/ `gen_trade_calendar.py` / `10-seed-trade-calendar.sql`(503 交易日)。
**仓库地图:**
| 路径 | 状态 | 说明 |
@@ -200,8 +200,8 @@ RBAC 联调账号:scripts/dev/rbac-seed-reference.md
2. 改动属于 api / service / tool / repository 哪一层?
3. 是否需 customer_id 归属与 JWT RBAC?
4. Core 是模拟库只读还是 agent 库读写?
5. 如何验证?(`python -m pytest` 全量(当前 **849 passed / 10 skipped**,风控基线 510 / v0.x convert 完结 739)· uvicorn 启动 + /health · SQL / sync 脚本 · 对照 REQUIREMENTS 验收列)
6. **当前有哪两条并行线?**(① 风控/架构改进线:**已结项**(510 基线绿、§7.2 七项冒烟 7/7 PASS、`037ce7e` 已核实早已推送);② **基金转换线**:v0.x 实时模型已结项(739 绿,**已被 T+1 模型取代**);**下一线 T+1 受理/确认分离模型进行中(2026-09-11)**:PRD v1.1 / 架构 v2.1 / 开发计划 v2.0 重写完毕并经独立审查收敛,**已定稿**(2026-09-11 用户批准),第 5 步 todo 开发进行中(T-1~T-17;**当前进度 T-1~T-12 ✅,849 绿**))——动代码前先确认自己属于哪条线,别混淆前置条件。
5. 如何验证?(`python -m pytest` 全量(当前 **830 passed / 7 skipped**,风控基线 510 / v0.x convert 完结 739)· uvicorn 启动 + /health · SQL / sync 脚本 · 对照 REQUIREMENTS 验收列)
6. **当前有哪两条并行线?**(① 风控/架构改进线:**已结项**(510 基线绿、§7.2 七项冒烟 7/7 PASS、`037ce7e` 已核实早已推送);② **基金转换线**:v0.x 实时模型已结项(739 绿,**已被 T+1 模型取代**);**下一线 T+1 受理/确认分离模型进行中(2026-09-11)**:PRD v1.1 / 架构 v2.1 / 开发计划 v2.0 重写完毕并经独立审查收敛,**已定稿**(2026-09-11 用户批准),第 5 步 todo 开发进行中(T-1~T-17;**当前进度 T-1~T-13 ✅,830 绿**))——动代码前先确认自己属于哪条线,别混淆前置条件。
7. **远程分支到底还在不在?**(**在**。`git ls-remote --heads origin` 实测 `refs/heads/risk-control-agent` = `fffb78a`。⚠️ **判断远程存亡只能用 `git ls-remote`** —— 2026-09-10 **同日误报两次**,勿再踩。)
**本仓特有异常(2026-09-10 深挖确认,别误判为 stale ref)**:`.git/refs/remotes/**` **写入不落盘** ——
`git update-ref refs/remotes/origin/X <sha>` 返回 0,但松散引用消失,**且整个 `refs/remotes/origin/` 目录被删**
+3 -2
View File
@@ -9,7 +9,7 @@
**⚡ 并行新线 · 基金转换(convert)**—— **两条子线**:
- **(一)v0.x 两阶段实时模型(已结项 2026-09-10)**:PRD **v0.9.3** + 架构 **v1.0.1** + 开发计划 **v1.0**,**T-0 ~ T-13 全部完成**(第 5 步 + 第 6 步闭环,**736 passed / 10 skipped**;7 个 convert 真库脚本复跑零回归;压测修复 2 处并发缺陷 + 死锁重试后补 `43cf2a1` 最终 **739 passed / 10 skipped**)。**注:该模型已被下一线取代(按下述),其设计文档作废,代码仍保留作过渡基线**。
- **(二)下一线 · T+1 受理/确认分离模型(进行中 · 2026-09-11)**:入口 **交接文档.md §B.11** · PRD **v1.1** + 架构 **v2.1** 均已整体重写并经独立 AI 联网审查通过(0 阻断级),**已定稿**(2026-09-11 用户批准);**第 4 步开发计划 v2.0 已整体重做(`docs/项目框架设计/开发计划-基金转换交易.md`,T-1~T-17 按架构 §15 重排 + 代码事实 F-1~F-25 + 裁定 R-1~R-15 + 16 条回归面 + 验收 31 条 + FR-C29/C30 全映射),经三轮独立审核闭环(挑毛病 / 验证型 / 白纸重审 + 验证型复核 22/22 落位),已定稿(2026-09-11 用户批准)**。**第 5 步 todo 开发已开工(2026-09-11):T-1 ~ T-12 完成(全量 pytest 849 passed / 10 skipped 零失败;T-6 真库 verify 37/37、T-7 真库 verify 83/83、T-8 真库 verify 39/39、T-9/T-10 真库 verify_convert_api 89/89、T-11 复跑 verify_convert_tools 14/14、T-12 重写 verify_convert_compensate 56/56,退出码均 0),下一步 T-13(全量回归 + 并发/性能补录 + convert_fund 退役)**。撤单范围:PRD §5.5 原表述与实现(仅 `accepted`)不矛盾、无需回填(第三轮 C1 订正)。
- **(二)下一线 · T+1 受理/确认分离模型(进行中 · 2026-09-11)**:入口 **交接文档.md §B.11** · PRD **v1.1** + 架构 **v2.1** 均已整体重写并经独立 AI 联网审查通过(0 阻断级),**已定稿**(2026-09-11 用户批准);**第 4 步开发计划 v2.0 已整体重做(`docs/项目框架设计/开发计划-基金转换交易.md`,T-1~T-17 按架构 §15 重排 + 代码事实 F-1~F-25 + 裁定 R-1~R-15 + 16 条回归面 + 验收 31 条 + FR-C29/C30 全映射),经三轮独立审核闭环(挑毛病 / 验证型 / 白纸重审 + 验证型复核 22/22 落位),已定稿(2026-09-11 用户批准)**。**第 5 步 todo 开发已开工(2026-09-11):T-1 ~ T-13 完成(全量 pytest 830 passed / 7 skipped 零失败;真库 verify 套件 9/9 退出码 0:accept 37 / confirm 83 / engine 39 / api 89 / compensate 56 / apply 24 / lots 20 / seed 全 PASS / tools 14,v1.0 链路 verify_convert_service 已随 convert_fund 退役删除),下一步 T-14(D27 产品舍入真正接入)**。撤单范围:PRD §5.5 原表述与实现(仅 `accepted`)不矛盾、无需回填(第三轮 C1 订正)。
### 基金转换线待办(推荐顺序)
@@ -39,7 +39,8 @@
- [x] **T-10 普通申赎批次维护 + T+2 校验 + rebuild_lots ✅(2026-09-11)**:`trade_gateway` 主流程改 —— `_redeem_quote` 走 `available_qty_with_inflight` **硬校验**(R-3,申报超可赎抛 `InsufficientShares` 不静默裁剪);`_maintain_lots` redeem 三重裁剪(T+2 过滤 → D8 补建 → 在途占用 → 哨兵 FIFO 扣减),subscribe 落新批次;`core_ro.list_share_lots`/`share_lot_repository.select_for_convert` 加 `available_from` **T+2 半开区间过滤**(R-4,日历缺行降级不过滤同口径);`gateway_repository` 扣批次哨兵 `remain_qty >= :q`(防超扣)。**验证**:`test_share_lot` +10(半开区间双向/区分度/在途拦截与释放/哨兵回滚/转换后不超扣)+ `test_trade_gateway` +1(金额公式 995.00)→ 全量 **844 passed / 10 skipped**(834+11 零回归);真库 `verify_convert_api.py` **89/89**(H 节提前 + H2 在途占用拦截断言);`rebuild_lots.py --dry-run` 58 持仓 0 补建 0 写入;6 项 DoD 全闭环 + 突防验证(移除透传 → t2 用例变红 → 还原)
- [x] **T-11 core_tools 汇总去重 + 持仓过滤 ✅(2026-09-12,生产代码零改动)**:口径三处同调(F-10)与 `list_holdings` 的 `qty > 0` SQL 过滤均已就位(v0.x T-11 产物),本轮增量 = 把口径用例升级为 **T+1 真实链路场景**(R-回归 8「保留 + 补用例」/ R-回归 13「补确认段场景」—— T+1 下流水与持仓只在确认段产生):`tests/test_core_tools.py` +2 —— ① `test_confirm_then_sum_amount_counts_once`(受理→`confirm_one` 落两条同 gid 流水后 `sum_amount` = 转出端 40812.00 + 无组普通 100000 = 140812.00,明细仍 3 条全量,`sum_trades_on_date(T+1)` 跨口径一致)② `test_confirm_full_transfer_holding_zero_row_excluded`(先证归零行仍在库(台账留痕),再断言 `list_holdings`/`query_holdings` 只剩转入端)。**验证**:全量 **846 passed / 10 skipped**(844+2 零回归);突变 2 组均精准 3 红(去 `qty>0` / 绕开 `amount_view`)已还原;真库 `verify_convert_tools.py` 复跑 **14/14** 零残留。**执行期裁定 2 条**:① 转出端流水 `amount` = **费前**转出金额(与 PRD §5.3.2 的 68020.00 同语义,赎回费单列 `redeem_fee`)—— 初版锚点误按费后被真跑抓出;② `t1_env` 必须调 `seed_suitability_matrix`(缺 C×R 矩阵 → 受理全量 forbidden,与 conftest 同源)
- [x] **T-12 补偿 + SLA 清理切 T+1 链路 ✅(2026-09-12)**:① `cleanup_pending_convert.py` **整体重写**(扫描对象迁 Core:`list_inflight_before` 扫 `accepted/nav_pending` 且 `requested_at` 严格早于 cutoff → 条件 UPDATE 置 `expired`(S2 不硬删、天然幂等不加锁);SLA 边界 = 当前业务日上推 `convert_confirm_sla_days` 个交易日 00:00(`previous_biz_day` 链式,与 `_window_start` 同口径,日历缺失降级自然日并告警);`--days`/`--dry-run`;**不动镜像**(T-4 契约));② `compensate_convert` **从 v1.0 Deprecated 组救回在役**(详情侧 = Core 三件套前置校验(流水 ≥2 → `confirmed` → 明细非空,任一不满足 `missing` 零写入),补写与确认段第⑧步同口径 `sync_mirror` + `confirmed` 审计 `phase='confirm-compensate'`);③ `convert_request_repository` +`list_inflight_before`。**联网核实**(用户铁律):基金转换「无效申请」真实口径(多家基金公司业务规则:TA T+1 确认、无效资金退回 → `rejected` 映射成立)+ A 股连续休市最长 = 2020 春节 10 自然日(上交所通知,`_MAX_SCAN_DAYS=256` 依据成立)。**⚠️ 真库脚本暴露并修复**:`confirm_one` 第⑦步引擎异常只 log 不留痕(全仓唯一不落痕路径)→ except 补写 `decision='engine_error'` 审计 + `engine_error` 标志贯穿(D17 不阻断保留;test_convert_confirm 断言翻转 is True + 补审计断言)。**验证**:全量 **849 passed / 10 skipped**(846+3 零回归);真库 `verify_convert_compensate.py` **整体重写 T+1 链路 56/56 残留 0**(含幂等重跑;真库修正 1 条口径:`confirmed` 审计真链路恰 2 条 = 确认段 + 补偿各 1);**突变 4 组全被抓还原**(cleanup 窗口反转 5 红 / 前置守卫删除 1 红 / 真库 expired→cancelled 2 红 / 真库 nav_stale=True 1 红)。**勘误**:开发计划原写 `scripts/agent/rebuild_alerts.py` 实际在 `scripts/demo/`(零改动)
- [ ] T-13 ~ T-17(全量回归 + 并发/性能补录 + convert_fund 退役 / D27 产品级舍入 / D28 巨额赎回 / D29 资金流中转 / D30 A/C 互转)。**注(2026-09-11 用户裁定)**:`convert_fund` 退役并入 **T-13**(T-13 目标/改法 6/DoD/风险已加)
- [x] **T-13 全量门禁 + convert_fund 退役 ✅(2026-09-12,提交 `3bc84a0`)**:① `convert_fund` 及 v1.0 依赖链净删 468 行(`rebuild_convert_response` 按实际改判**保留在役**:T-9 查询接口读路径);`verify_convert_service.py` git rm;`test_convert_service.py`(805→约 440 行)与 `test_convert_concurrency.py`(v1.0 九用例 → T+1 六用例)全量重写;grep 仅余 4 处注释性历史说明、零调用。② **门禁**:全量 **830 passed / 7 skipped**(849 → 830 为 v1.0 用例组退役净减);CONVERT_STRESS=1 **6/6**;真库 **9/9 退出码 0**。③ **性能实测(PRD §9 第 18 条已回填)**:端到端 P50 79.2 / P95 110.3 / max 114.7 ms —— < 2s 硬门禁余量 17 倍。④ **紧池 100%(验收 31 已回填 PRD)**:50/50 受理 + 50/50 串行确认(v1.0 同场景 80% → 病根结构性消除)。⑤ **计划外产出**:`verify_convert_lots.py` B/C/D 组仍按 v1.0 金额赎回传 `amount=`(T-9 已改份额申报,redeem 分支 `qty is None` 静默跳过)→ 修正为 `qty=` 后 20/20。
- [ ] T-14 ~ T-17(D27 产品级舍入 / D28 巨额赎回 / D29 资金流中转 / D30 A/C 互转)
> **第 0~2 批结果(2026-09-10)**:基线 **510 passed** → 批 0 后 **516 passed / 3 skipped**(+3 T-0 用例 +3 T-0b 引擎用例)→ 批 1(T-1)后**仍 516 passed / 3 skipped**(只加表与种子,未加用例 → **零回归**);**T-1 数据层断言 8/8 PASS**(含新增断言 ⑧:费率档 ↔ `product_type` 匹配,越档即 FAIL)→ 批 2(T-2 + T-2b)后 **609 passed / 3 skipped**(**+93 纯函数用例**,零回归);T-2b 实算脚本 15/15 与 PRD §5.3 一致(退出码 0)。
> ⚠️ **以下四条引用块均为 v0.x 两阶段实时线记录,其 T 编号与新线(T-1~T-17)无关、勿混**:新线 T-11 亦涉 `amount_view`,与 v0.x T-11「提升为公开函数」是两回事。