文档:T-8 回写 + 全仓进度一致性复核(订正 5 处漏同步)
本轮在 T-8 提交(57f16a5)后做文档回写,并对全仓「同一事实的副本」做一致性扫描,
发现并当场订正 5 处漏同步(均属上次改了主状态位、漏改副本):
- AGENTS.md 入口引用(最重要,属项目记忆已强调的「全仓同步入口引用」漏项):
T-1~T-6 ✅/797 基线/下一步 T-7 → T-1~T-8 ✅/829 基线/下一步 T-9;
T-6 真库 verify_convert_accept.py 36/36 → 37/37,并并列 83/83、39/39。
- docs/memory/TODO.md:汇总待办行「T-8 ~ T-17(含已完成之引擎时机)」→「T-9 ~ T-17」;
为 v0.x 线引用块加编号歧义提示(其 T-11/T-12 与新线同号且均涉 amount_view,易混)。
- docs/memory/MEMORY.md:自检问答第 6 问进度 T-1~T-7 ✅/827 → T-1~T-8 ✅/829。
- 开发计划(T-8 执行期订正,承 57f16a5 代码提交):
就地订正 T-7 执行记录第 2 条「T-8 剩余仅为 rules.amount_view」之误(F-10 明确 T-8 不动去重口径,属 T-11);
新增 T-8「执行记录」5 条差异裁定;DoD 全勾。
不入库但同批完成(交接文档.md 受 .gitignore 忽略):
- 顶部版本 v3.7 → v3.8;§③ 表格行;§B.11 状态块(T-8 完成 + 两处订正);
- 开工纪律行 T-1~T-6 → T-1~T-8;
- §B.11「未落地(T-1 起执行)」立项期清单 → 「已落地」并附实测行号
(01-ddl.sql 272/297/305 行;已进 reset.ps1 与 verify_convert_seed.py 清单),原文折叠留痕。
复核:全量 pytest -q → 829 passed / 10 skipped(16.37s,零失败)。
This commit is contained in:
@@ -24,7 +24,7 @@
|
||||
- 技术选型 / JWT:`docs/项目框架设计/技术选型和版本/`
|
||||
- Core 模拟底座:`docs/项目框架设计/Core模拟底座/`
|
||||
- 业务记忆分层:`docs/业务记忆管理/业务记忆管理手册.md`
|
||||
- **基金转换线(第 5 步 todo 开发进行中 · T+1 受理/确认分离模型)**:**T-1 ~ T-6 ✅ / T-7 ~ T-17 ⬜**(当前基线 **797 passed / 10 skipped** 实测;T-6 真库 `verify_convert_accept.py` **36/36**;下一步 **T-7** = 三段编排 + 新增 `confirm_service`,核心重写);开工入口 **`交接文档.md` §B**(§B.11 下一条立项指引 = 最新状态)· `docs/PRD/PRD-基金转换交易.md`(**v1.1**)· `docs/项目框架设计/架构设计-基金转换交易.md`(**v2.1**)· `docs/项目框架设计/开发计划-基金转换交易.md`(**v2.0** · T-1~T-17 逐任务改法 + DoD)
|
||||
- **基金转换线(第 5 步 todo 开发进行中 · T+1 受理/确认分离模型)**:**T-1 ~ T-8 ✅ / T-9 ~ T-17 ⬜**(当前基线 **829 passed / 10 skipped** 实测;真库 T-6 `verify_convert_accept.py` **37/37**、T-7 `verify_convert_confirm.py` **83/83**、T-8 `verify_convert_engine.py` **39/39**,退出码均 0;下一步 **T-9** = api 层:redeem 份额申报 + 撤单/确认/查询接口 + 网关分派);开工入口 **`交接文档.md` §B**(§B.11 下一条立项指引 = 最新状态)· `docs/PRD/PRD-基金转换交易.md`(**v1.1**)· `docs/项目框架设计/架构设计-基金转换交易.md`(**v2.1**)· `docs/项目框架设计/开发计划-基金转换交易.md`(**v2.0** · T-1~T-17 逐任务改法 + DoD)
|
||||
- **架构改进线(✅ 2026-09-10 已结项,无待办)**:开工入口 **`交接文档.md` §C**
|
||||
- **风控模块主线**:**`交接文档.md` §A**
|
||||
|
||||
|
||||
@@ -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-7 ✅,**827 passed / 10 skipped** 零失败;T-6 真库 verify **37/37**、T-7 真库 verify **83/83**,退出码均 0;下一步 T-8 `rules.amount_view` / T-9 api 层 —— 注意引擎「时机」部分已在 T-7 由 `engine_call.py` 完成,全仓 `process_convert_event(` 恰 1 处调用)**。**T-7 关键裁定:强制全转属受理段决策** —— 受理由 `plan_lots` 判定并把 `qty` 收敛为实际全转量 + 受理单 `remark='full_transfer'`,确认段**只继承不重判**(`plan_lots` 不传 `min_hold_qty`);重判会因 T→T+1 可用份额变化(部分成交/他人申赎/产品参数改)得出与受理承诺不一致的结论(擅自扩大客户指令)。撤单范围: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-8 ✅,**829 passed / 10 skipped** 零失败;T-6 真库 verify **37/37**、T-7 真库 verify **83/83**、T-8 真库 verify **39/39**,退出码均 0;下一步 T-9 api 层)**。**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 交易日)。
|
||||
**仓库地图:**
|
||||
|
||||
| 路径 | 状态 | 说明 |
|
||||
@@ -201,7 +201,7 @@ RBAC 联调账号:scripts/dev/rbac-seed-reference.md
|
||||
3. 是否需 customer_id 归属与 JWT RBAC?
|
||||
4. Core 是模拟库只读还是 agent 库读写?
|
||||
5. 如何验证?(`python -m pytest` 全量(当前 **739 passed / 10 skipped**,基线 510)· 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-7 ✅,827 绿**))——动代码前先确认自己属于哪条线,别混淆前置条件。
|
||||
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-8 ✅,829 绿**))——动代码前先确认自己属于哪条线,别混淆前置条件。
|
||||
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/` 目录被删**
|
||||
|
||||
+5
-3
@@ -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-7 完成(全量 pytest 827 passed / 10 skipped 零失败;T-6 真库 verify 37/37、T-7 真库 verify 83/83,退出码均 0),下一步 T-8(`rules.amount_view`;引擎时机部分已在 T-7 完成)/ T-9(api 层)**。撤单范围: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-8 完成(全量 pytest 829 passed / 10 skipped 零失败;T-6 真库 verify 37/37、T-7 真库 verify 83/83、T-8 真库 verify 39/39,退出码均 0),下一步 T-9(api 层:redeem 份额申报 + 撤单/确认/查询接口 + 网关分派)**。撤单范围:PRD §5.5 原表述与实现(仅 `accepted`)不矛盾、无需回填(第三轮 C1 订正)。
|
||||
|
||||
### 基金转换线待办(推荐顺序)
|
||||
|
||||
@@ -34,10 +34,12 @@
|
||||
- [x] **T-5 锁原语 ✅**:新增 `app/service/convert/trading_calendar.py`(纯函数包,`is_open` 谓词注入,不查库)+ 单测;`locks.py` 补锁键单一事实源;受理接入 `run_locked`
|
||||
- [x] **T-6 受理事务 ✅**:`accept_convert` 八步落地(幂等前置 → 产品/份额/适当性 → 受理日顺延 R-5 → 可用份额 R-3 → 落 `core_convert_request(accepted)` → 镜像 + 审计 → 202 回执);新增 `tests/test_convert_accept.py`;**真库 `verify_convert_accept.py` 37/37 一致(退出码 0)**
|
||||
- [x] **T-7 三段编排 + `confirm_service`(核心重写)✅(2026-09-11,提交 `048f1a9`)**:新增 `confirm_service.py`(`confirm_one` 8 步:读单+状态闸门 → T 日净值精确匹配(缺→`nav_pending`)→ 产品复核 + T+1 适当性复核 → 部分成交 R-10 → FIFO 扣批 + 折算 → 确认事务(扣批次 + 2 流水 + 转入批次 + 两端持仓 + 明细 + 受理单置 `confirmed`,同事务,`rowcount!=1` → `ConfirmConflict` 整体回滚)→ 引擎恰好一次(commit 后,异常不阻断)→ 镜像 + 审计;`confirm_batch`:整批锁 + 业务日捞单窗口 + 串行 + 单笔容错);抽出 `format.py`/`audit.py`/`engine_call.py` 三个共用出口;`convert_service` 加 `cancel_convert`(T 日撤单两道闸门)+ `_t1_t2_dates`,受理响应改 PRD §5.3.1 字段;`convert_core_repository.ConvertApplyInput` 加 `convert_request_id`/`diff_fee`/`request_remark` 并内置 `_confirm_request` 状态守卫;`convert_request_repository` 加 `_end_of_day` 闭区间 + `reject()`。**单测 `tests/test_convert_confirm.py`(24 例)+ 真库 `verify_convert_confirm.py` 83/83 一致(含 PRD §5.3.2 示例真库逐字节重放)**;全量 **827 passed / 10 skipped**。**关键裁定(计划缺口,已回写开发计划)**:强制全转是受理段决策,受理单 `remark='full_transfer'` 传承,确认段**只继承不重判**(`plan_lots` 不传 `min_hold_qty`)—— 重判会因 T→T+1 可用份额变化擅自扩大客户指令。
|
||||
- [ ] T-8 ~ T-17(引擎时机 / API 受理接口 / 撤单 / 调换 / 工具 / 补偿 / 回归 / D27 产品级舍入 / D28 巨额赎回 / D29 资金流中转 / D30 A/C 互转)
|
||||
- [x] **T-8 引擎时机收口 ✅(2026-09-11,提交 `57f16a5`)**:**R-7 的实现部分在 T-7 已完成**(`engine_call.run_convert_engine` 是引擎唯一出口、位于确认事务 commit 之后;`accept_convert` 自实现起不含引擎调用)。本轮补**守护与端到端验证**:① `test_process_convert_event_has_single_call_site` —— 用 **AST** 统计 `app/` 下 `process_convert_event(` 的 Call 节点**恰 1 处**且宿主为 `run_convert_engine`(字符串匹配会被 `engine_call.py` 说明段误判);② 受理无副作用用例补「不触引擎」断言(受理后 `risk_alert` 0 行、无 `pass`/`engine_error` 审计,验收 29 前半);③ `test_real_engine_on_confirm_dedupes_daily_total` —— 确认链路接**真引擎**(不注入 hook)的正证 + 反证(阈值夹逼 → RISK-002 不命中 / 阈值下调 → 命中),并断言一张单 + `payload.events` 两条 + 去重不删行(验收 5/6/7)。两条新用例**均做突变验证**(加第二处调用 / 禁用引擎调用 → 变红 → 还原)。真库 `verify_convert_engine.py` **整体切换 T+1 链路**(此前走 v1.0 `convert_fund`):受理 → 确认,新增 A0 组「受理不触引擎」,折算期望改用 T 日净值,**真库 39/39 一致**。**订正**:原记「T-8 剩余工作仅为 `rules.amount_view`」有误 —— F-10 明确 T-8 **不动**去重口径(属 T-11 范围),T-8 剩余的是**验证面**。
|
||||
- [ ] T-9 ~ T-17(API 受理接口 / 撤单 / 调换 / 工具 / 补偿 / 回归 / 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)。
|
||||
> **本线已全部闭环(T-0 ~ T-13)**。基线 **736 passed / 10 skipped**(T-10 后 714 → T-11 后 718 → T-12 后 731 → **T-13 后 736**,+5);`CONVERT_STRESS=1` 另跑 9 条并发用例全绿。
|
||||
> ⚠️ **以下四条引用块均为 v0.x 两阶段实时线记录,其 T 编号与新线(T-1~T-17)无关、勿混**:新线 T-11 亦涉 `amount_view`,与 v0.x T-11「提升为公开函数」是两回事。
|
||||
> **本线(v0.x)已全部闭环(T-0 ~ T-13)**。基线 **736 passed / 10 skipped**(T-10 后 714 → T-11 后 718 → T-12 后 731 → **T-13 后 736**,+5);`CONVERT_STRESS=1` 另跑 9 条并发用例全绿。
|
||||
> **T-11 执行期两条裁定**:① `_amount_view` **提升为公开 `amount_view`**(跨层复用,全仓唯一金额聚合口径);
|
||||
> ② SQL 去重条件从计划的 `IS NULL` 扩为 **`IS NULL OR convert_group_id = ''`** —— 真库实证「只写 `IS NULL` 会漏掉空串那笔」(400000 vs 450000,差 50000)。
|
||||
> **T-12 执行期三条裁定**:① 补偿逻辑收敛到 **`convert_service.compensate_convert` 单点**,`rebuild_alerts --convert-group` 只是薄封装;
|
||||
|
||||
@@ -487,9 +487,12 @@
|
||||
2. **新增三个共用模块**(计划未列):`format.py`(`D2/D4/new_id/q` 展示规格唯一出口)、
|
||||
`audit.py`(`write_convert_audit` 唯一审计写入点)、`engine_call.py`
|
||||
(`run_convert_engine` 引擎唯一调用点)。理由:受理段与确认段共用同一套量化 / 审计 /
|
||||
引擎口径,若两段各写一份必然漂移。`engine_call.py` 的引入**同时完成了 T-8 的「引擎时机改」**
|
||||
(调用点已迁到确认事务 commit 之后,且全仓恰 1 处调用)—— T-8 剩余工作仅为
|
||||
`rules.amount_view` 与三处消费方同步。
|
||||
引擎口径,若两段各写一份必然漂移。`engine_call.py` 的引入完成了 T-8「引擎时机」的
|
||||
**实现部分**(调用点已迁到确认事务 commit 之后,且全仓恰 1 处调用)。
|
||||
⚠️ **订正(2026-09-11,T-8 执行期发现)**:本行原写「T-8 剩余工作仅为 `rules.amount_view`
|
||||
与三处消费方同步」——**错**。F-10 已明确 T-8 **不动**去重口径(`amount_view` 三处消费方
|
||||
**原样不动**,属 T-11 的范围)。T-8 剩余的是**验证面**:调用点唯一性守护 + 受理不触引擎用例
|
||||
+ 确认链路真引擎出单 / RISK-002 不翻倍的真库断言。详见下方 T-8「执行记录」。
|
||||
3. **`nav.py` 未改**:确认段直接调 `core_ro.get_nav_on(product, T)`(T-3 已新增的精确匹配口径),
|
||||
无需经 `nav.py`。计划第 4 条要删的「取 T−1 路径」(`_nav_as_of`)属 v1.0 `convert_fund`,
|
||||
该函数已标 `⛔ Deprecated`,随 T-9 一并删除。
|
||||
@@ -522,15 +525,43 @@
|
||||
**依赖**:无(引擎时机改动不与 T-7 强绑定前置,但联调在 T-7 DoD 覆盖)
|
||||
|
||||
**DoD**:
|
||||
- [ ] grep:`process_convert_event(` 全仓恰 1 处调用(确认段)
|
||||
- [ ] 受理路径用例:受理后 `risk_alert` 0 新增(验收 29 前半)
|
||||
- [ ] 确认路径用例:引擎跑一次、RISK-002 计一次(验收 5/7)
|
||||
- [ ] RISK-001/003 仍见两条(去重未删行,验收 6)
|
||||
- [ ] pytest 全绿
|
||||
- [x] grep:`process_convert_event(` 全仓恰 1 处调用(确认段)
|
||||
- [x] 受理路径用例:受理后 `risk_alert` 0 新增(验收 29 前半)
|
||||
- [x] 确认路径用例:引擎跑一次、RISK-002 计一次(验收 5/7)
|
||||
- [x] RISK-001/003 仍见两条(去重未删行,验收 6)
|
||||
- [x] pytest 全绿
|
||||
|
||||
**风险**:调用点漏清(旧受理段残留)→ DoD 1 守护
|
||||
**回滚点**:单点改动,git 回退即还原
|
||||
|
||||
**执行记录(2026-09-11 · 提交 `57f16a5`)**
|
||||
|
||||
真库 `verify_convert_engine.py` **39 项一致 / 0 不一致**(A0/A/B/C/D/E/F 七组);
|
||||
全量 pytest **829 passed / 10 skipped**(T-7 基线 827,+2);复跑 T-6 `verify_convert_accept.py`
|
||||
**37/37**、T-7 `verify_convert_confirm.py` **83/83**、v1.0 链路 `verify_convert_service.py` **35/35**,均零失败。
|
||||
|
||||
**本轮实际范围(与任务书字面的差异,已留痕)**:
|
||||
|
||||
1. **引擎时机的「实现」在 T-7 已完成,本轮只做「守护 + 端到端验证」**。T-7 抽出
|
||||
`engine_call.run_convert_engine` 时即把调用点放在确认事务 commit 之后,且全仓仅此一处;
|
||||
`accept_convert` 自 T-6 实现起就不含引擎调用(阶段 1.5 属 v1.0 `convert_fund`,不在受理段内)。
|
||||
故 R-7 的两条要求(受理不触引擎 / 确认后唯一调用点)在 T-7 已成立,本轮补的是**可回归的守护**。
|
||||
2. **DoD 1 的 grep 改用 AST 实现**。字符串匹配会被 `engine_call.py` 的说明段
|
||||
(「`process_convert_event(` 全仓应恰 1 处调用」)误判为第二处调用 —— 该守护若用 grep 写,
|
||||
会恒红或被迫加脆弱的排除规则。改用 AST 统计 `Call` 节点,并同时断言宿主函数为
|
||||
`run_convert_engine`(防「文件对但函数被搬走」)。**已做突变验证**:
|
||||
临时追加第二处调用 → 断言变红 → 还原。
|
||||
3. **`convert_fund` 的阶段 1.5 调用点本轮不动**。该函数是 v1.0 实时模型的全流程入口
|
||||
(已被 4 个测试文件 + gateway 依赖),T-9 切换 API 后整体删除。本轮若只摘掉它的引擎调用,
|
||||
会让过渡函数变成「扣了份额但不出预警单」——**风控缺失比时机错更危险**,故保留,
|
||||
由 T-9 随函数一并清除。
|
||||
4. **确认链路的真引擎断言采用「正证 + 反证」双断言**。仅断言「RISK-002 不命中」无法区分
|
||||
「去重生效」与「引擎根本没跑」;故正证(阈值夹逼 → 不命中)之外补反证
|
||||
(阈值下调 → 命中),并做突变验证(禁用引擎调用 → 变红)。
|
||||
5. **真库脚本踩坑(已钉进脚本注释)**:`confirm_one(thresholds=...)` 必须**显式传阈值**,
|
||||
缺省退回 `RiskThresholds.from_settings()`;settings 的 `daily_total` 一旦低于单条金额,
|
||||
RISK-002 就会「命中」,**症状看着像去重失效,实为阈值口径没传**(首轮实跑被 B 组断言捕获)。
|
||||
|
||||
---
|
||||
|
||||
### T-9 · api 层(redeem 份额申报 + 撤单/确认/查询接口 + 网关分派)
|
||||
|
||||
Reference in New Issue
Block a user