Files
group_xinghuo_jinrong/docs/memory/TODO.md
T
GaoYiYuan_0626 5a784dc185 文档:T-10 回写 + 全仓进度一致性(开发计划 DoD 全勾 + 执行记录)
- 开发计划 v2.0:T-10 六项 DoD 全勾(申购落批次 / 哨兵不超扣 / T+2 半开区间
  双向 / 金额公式 D26 / 转换后不超扣验收 9 / rebuild 无漂移)+ 新增执行记录
  (改法、验证证据 844 passed、真库 89/89、突防验证、3 处断点与口径)
- 交接文档 v4.0(gitignore 不入库,本轮未提交)
- AGENTS.md 入口引用 → T-1~T-10 ✅ / 844 / 89/89 / 下一步 T-11
- docs/memory/TODO.md:T-10 完成条目 + 待办行 T-11~T-17
- docs/memory/MEMORY.md:进度 + 自检第 5/6 问 → 844 / T-1~T-10
2026-09-11 21:24:40 +08:00

36 KiB
Raw Blame History

TODO

大任务开始时更新;完成一步打钩并验证后再往下。
新 Agent: 先看 MEMORY.md §0 交接清单,再从此处取下一项。

进行中

阶段一 AL-01AL-08 与阶段二 C4C6 均已完成(2026-09-07):全量 pytest 482 passed 0 failed 0 skipped(真库集成)✓ · uvicorn 冒烟三端点 ✓ · 接口实调验收 ✓(2026-09-07:suitability/check 阻断+放行、simulate/trade 阻断、三条鉴权边界 401/403/403,契约零偏差)· risk-m1~m4 tag 齐。合并 main 已移交合并执行人(操作手册:《docs/项目框架设计/合并注意事项-风控模块并入main.md》,随分支上传),后续模块侧待办见下方。

⚡ 并行新线 · 基金转换(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-1T-17 按架构 §15 重排 + 代码事实 F-1F-25 + 裁定 R-1~R-15 + 16 条回归面 + 验收 31 条 + FR-C29/C30 全映射),经三轮独立审核闭环(挑毛病 / 验证型 / 白纸重审 + 验证型复核 22/22 落位),已定稿(2026-09-11 用户批准)。第 5 步 todo 开发已开工(2026-09-11):T-1 ~ T-10 完成(全量 pytest 844 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,退出码均 0),下一步 T-11(汇总去重)。撤单范围:PRD §5.5 原表述与实现(仅 accepted)不矛盾、无需回填(第三轮 C1 订正)。

基金转换线待办(推荐顺序)

  • 【第 4 步重做】产出开发计划 v2.0(T+1 模型) —— 完成(2026-09-11):docs/项目框架设计/开发计划-基金转换交易.md 整体重做为 v2.0(797 行)——T-0/T-0b 沿用(✅ 已完成),T-1T-17 按架构 v2.1 §15 重排 + §1.4 **代码事实核对表 F-1F-25**(实测文件:行号)+ §1.5 实现级裁定 R-1~R-15 + §5 十六条回归面 + §6 验收 31 条全映射(+FR-C29/C30)+ §7 风险 14 条。经三轮独立审核闭环:第一轮 2 阻断(B1 convert_cutoff_time 配置缺失违反 PRD §2.6.1 不得硬编码 → 已加 settings 全链读;B2 core_ro.get_nav_as_of 实为 nav_date <= :d LIMIT 1 回退查询,缺 T 日净值会静默取 T−1 致 nav_pending 永不触发 → 已改新增 get_nav_on 精确匹配)+ 5 重要 + 3 可选全闭环;第二轮验证型逐条核实 12 项零残留;第三轮白纸重审抓出 5 重要(C1 撤单引述订正 / C2 §6 补 C29·C30 / C3 回归面补 redeem 6 处 / C4 删 0 命中误引 / C5 cash_flow 归属厘清)+ 4 可选,验证型复核 22/22 落位 + D-1 残留修复。状态:已定稿(2026-09-11 用户批准)(批准后进第 5 步 todo 开发)。⚠️ 开发计划 v2.0 语义与旧 v1.0 完全不同(v1.0 是 v0.x 实时模型,作废)
  • 【第 4 步】产出开发计划 v1.0(v0.x 模型 · 历史) —— 完成(2026-09-10,已被 v2.0 取代):docs/项目框架设计/开发计划-基金转换交易.md(原 1,047 行,含 T-0~T-13 任务拆解 + 逐条改法 + DoD + 四轮审核记录)。四轮独立子代理审核已收敛:12 条意见 → 接受 11 / 驳回 1(附实测证据)/ 0 悬空。本计划新增的增量资产:§1.3 两处 PRD-架构口径裁定(W-1/W-2)· §1.4 十五条代码事实核对表 · §1.5 七条实现级裁定 · §12 十六条回归面 · §13 PRD 19 条验收映射 · §14 新增实现级风险表。注:该版本属 v0.x 两阶段实时模型,2026-09-11 已随模型切换整体作废(v2.0 重做,见上条)
  • 【第 5 步 · T-0 · 阻断前置】sqlite/MySQL 结构对齐 + 建库自校验 —— 完成(2026-09-10):tests/_ddl.py 重写 core_holding(qty/cost_amount/as_of/pnl_pct + PK + uk_cust_product)+ 补 core_product_nav(R-f)+ _assert_ddl_aligned() 建库自校验(R-g);2 处测试 INSERT(test_chat_tools.py:81、test_concentration_c4.py:74)改 qty 并补 3 个 NOT NULL 列(原计划漏项);test_db.py 新增 test_core_holding_columns / test_core_product_nav_columns / test_ddl_alignment_guard_fails_when_column_missing(反向验证门禁,无需手工改删)
  • 【T-0b · 阻断前置】DB 账号分离(D20) —— 完成(2026-09-10):scripts/core/00-grant.sql 新建(3 账号逐表授权,不进 reset.ps1);settings.py +6 项;db.py 改 get_engine(db, role) + _resolve_credentials(缓存键 (db, role),未配置回退 mysql_user);core_ro→ro · gateway_repository→rw · risk_repository/session_repository→rw 显式;conftest.py 4 处→admin(R-e)。两处口径修正:① audit_log 实授 SELECT, INSERT(字面「只授 INSERT」会剥夺读,致 has_engine_error_audit/list_audit_events 失权)② conftest 必须 admin。遗留环境操作:00-grant.sql 需管理员执行 + 写 .env,未执行时 3 条权限断言自动 skip
  • 【T-1 · 第 1 批】DDL + 种子 + sqlite 同步 —— 完成(2026-09-10):scripts/core/01-ddl.sql 新建 core_fee_rule/core_share_lot/core_convert_lot_detail + core_trade 加 convert_group_id+索引 + core_product 加 8 列(subscribe_fee_rate 等)+ fee_rate 补 COMMENT;新增 07-seed-fee-rule.sql(14 产品 × 5 档,按 22 号文 §10)/ 08-seed-share-lot.sql(58 行持仓 → 61 行批次,Σ remain_qty 恒等于 qty,CUST-9527 跨批次)/ 09-seed-org.sql(管理人 + TA + 申购费率 + 最低持有余额);reset.ps1 追加 07/08/09;02-mysql-agent专用.sql 追加 risk_convert_detail(status ENUM 建表即 5 值);tests/_ddl.py 同步 4 表 + REQUIRED_CONVERT_TABLES 门禁。验证:新增 scripts/dev/verify_convert_seed.py(pymysql 等价 reset 流程 + 8 条断言)→ 8/8 PASS;pytest -q → 516 passed / 3 skipped(零回归)。3 点需注意:① mysql 不在 PATH → 用该脚本替代 reset.ps1;② core_fee_rule 读取走只读账号(T-6 遵守);③ PROD-005827 费率分类口径差异(mixed vs 主动偏股)待裁定 → 已裁定并修正(PRD v0.9.1):mixed 归位 0.0050(其他混合型),主示例转入方改真主动偏股 PROD-003095,09-seed-org.sql 升 v1.1 按「管理人全产品线」重排,并新增断言 ⑧ 机器化卡口
  • 【T-2 · 第 2 批】service/convert/ 纯函数包 —— 完成(2026-09-10):新建 app/service/convert/ 7 文件(__init__ / types(Lot/FeeRule/LotAllocation/PlanResult frozen dataclass + 3 个归一工具)/ calc(plan_lots/lot_amount/lot_fee/convert_amount/in_qty/rounding_diff/diff_fee/hold_days/ensure_batch_limit)/ fee(pick_fee_rate 左闭右开)/ nav(ensure_nav_ready→503 / is_stale)/ lot_bootstrap(D18 单点,crc32 确定性偏移)/ errors(ConvertError + 11 子类))。新增 tests/test_convert_calc.py 93 用例(12 类:精度 HALF_UP 反向自证 / 分档边界 6-7-29-30-179-180-364-365 / FIFO 含同 confirmed_at tiebreak / 跨批计费 / 双口径 252.40 vs 253.91 / 强制全转与强制赎回 / 恰好等于阈值不触发 / 零剩余不触发(新裁定 R-h) / PRD §5.3 全链自证 / T+1 起算 / 净值 503 与 stale 分家 / D18 确定性 / §8.3 错误码 / 纯函数零 IO 依赖断言)。验证:pytest -q → 609 passed / 3 skipped(+93,零回归);calc_convert_demo.py → 15/15 与 PRD §5.3 一致(退出码 0)
  • 【T-3 ~ T-9 已完成】 仓储与锁(并行组 A:T-3 / T-4 / T-5 ✅)→ T-6 ✅(阶段一事务 · 真库 24/24)→ T-7 ✅(八步编排 · 真库 35/35)→ T-8 ✅(规则引擎改造 · 真库 31/31;⭐ 阶段 1.5 从「跳过」变「真跑」) → T-9 ✅(API 模型 + 网关分派 · HTTP 层 convert 已走通;新增真 MySQL 集成 7 条 + 11 条错误码映射 + 3 组突变验证)
  • 【T-10 ✅ · T-11 ✅ · T-12 ✅】均已结项(2026-09-10):T-10 普通申赎批次维护(改 trade_gateway 主流程 + D8 兜底补建 + rebuild_lots.py;+17 用例 · 真库 20/20 · 突变 2 组 · R16 零改动通过)→ T-11 工具与 SQL 汇总去重(_amount_view 提升为公开 amount_view + query_recent_trades 汇总去重 FR-C15 + list_holdings 过滤 qty > 0 + sum_trades_on_date 加 convert 去重 R-d;+4 用例 · 真库 14/14 · 突变 3 组)→ T-12 补偿脚本(公开 compensate_convert 单点入口 + rebuild_alerts --convert-group 薄封装 + 新增 scripts/agent/cleanup_pending_convert.py;+12 用例 · 真库 34/34 · 突变 3 组 · 全套 7 真库脚本复跑零回归;顺带收口 concentration_profile 的 qty > 0)
  • 【T-13 ✅】(最后一个 · 已完成 2026-09-10):全量回归 → 50 并发压测 → 性能实测补录 → PRD §9 第 18 条数字回填。DoD 三条:① 性能实测值已回填 PRD §9 第 18 条(v0.9.3,替换「预估 < 100ms」);② 50 并发结论(不超卖 / 100/200/400ms 退避不够用)已写入 交接文档.md §B.6.6;③ 实测未超阈值 → 无需重定阈值(未修改实测数据)。产出:tests/test_convert_concurrency.py(9 条 · CONVERT_STRESS 门禁)+ test_convert_service +3 + 修复 insert_placeholder 三步法 / 幂等判定 pending→202;736 passed / 10 skipped、CONVERT_STRESS=1 并发 9/9、重灌双库复跑零回归、4 组突变验证全命中。
  • 【待用户裁定】幂等重放响应的数值位数偏差(T-9 执行期发现,未顺手改):首次响应 2 位(calc 量化)vs 重放响应 4 位(core_trade DECIMAL(18,4) 直读)→ "53456.95" vs "53456.9500",数值相等,违反 PRD「对外一律 2 位」展示契约,属 T-7 _rebuild_quote 范畴。集成测试已「比数值不比字符串」并钉住偏差

第 5 步 · T+1 受理/确认分离模型(T-1 ~ T-17 · 进行中)

  • T-1 DDL + 种子 ✅(2026-09-11):01-ddl.sql 新建 core_convert_request(6 态 ENUM 权威状态机)/ core_trade_calendar / core_share_rule + core_product 补 4 列;11-seed-share-rule.sql(42 行);reset.ps1 追加 10/11;settings 加 convert_cutoff_time="15:00" / convert_confirm_sla_days=2;tests/_ddl.py 三表同步;verify_convert_seed.py 加 DoD ⑨⑩⑪(503 交易日 / 42 行 / 6 态 ENUM,真库全 PASS)
  • T-2 calc 扩展 ✅:calc.py 加 product_round / redeem_amount / partial_qty(__all__ 同步);test_convert_calc.py +10 用例
  • T-2b 示例实算回填 ✅:calc_convert_demo.py 改真实净值(T=2026-09-09 PROD-110022=1.3604 / PROD-003095=1.9194)+ 15 项 EXPECTED;test_convert_integration.py 净值常量与 5 处硬断言同步;demo 15 项逐字节一致
  • T-3 数据层 ✅:core_ro 加 6 方法(含 get_nav_on 精确匹配、sum_inflight_qty、is_open、get_share_rule);share_lot_repository 加 available_qty_with_inflight;新建 convert_request_repository.py(6 态条件 UPDATE);修 1 处生产 bug(sum_inflight_qty 列名 product_id→from_product_id)
  • T-4 语义收窄 ✅:convert_repository 新增唯一写入口 sync_mirror(三步法幂等重写;status 只允许 pending/completed/failed,写 cancelled/expired 直接 ValueError);v1.0 遗留 insert_placeholder/complete_convert/mark_failed 标 Deprecated(T-7 后删除);状态迁移职责归 convert_request_repository.transition_status
  • T-5 锁原语 ✅:新增 app/service/convert/trading_calendar.py(纯函数包,is_open 谓词注入,不查库)+ 单测;locks.py 补锁键单一事实源;受理接入 run_locked
  • 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)
  • 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 引擎时机收口 ✅(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 API |网关分派 ✅(2026-09-11):三接口路径以 PRD 为准(裁定 11/12)——convert_admin.py 撤单/确认批处理/查询 + simulate.py convert 分支 202 + 受理回执(两类 202)+ trade_gateway 分派改调 accept_convert(SUPPORTED_TRADE_TYPES 维持 2 类型)+ redeem 份额申报(D26/R-6 _redeem_quote = qty × D 净值 − 赎回费)+ 错误码 CANCEL_NOT_ALLOWED/CONCURRENT_CONFLICT(409)。验证:端到端 test_convert_integration 重写 T+1 两段链路 13 passed;全量 834 passed / 10 skipped;真库 verify_convert_api.py HTTP 全链路 88/88;3 组突变验证全命中;修 2 处口径缺陷(out_nav 反推漂移 → 直读明细、幂等字段面对齐)。执行缺口:convert_fund 退役并入 T-13
  • 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 用例变红 → 还原)
  • T-11 ~ T-17(汇总去重 / 补偿改写 / 全量回归 / D27 产品级舍入 / D28 巨额赎回 / D29 资金流中转 / D30 A/C 互转)。注(2026-09-11 用户裁定):convert_fund 退役并入 T-13(T-13 目标/改法 6/DoD/风险已加)

第 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「提升为公开函数」是两回事。 本线(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 只是薄封装; ② 锁键 convert:rerun:{gid} 与幂等锚点(转出端 out_trade_id)沿用既有口径不新造; ③ has_engine_error_audit 加 decision 参数而非另写一份查询(convert 线失败码是 engine_error,与 risk_engine_error 不同)。 T-12 真库三处 sqlite 给不了的证据:expired 的 ENUM 值域 · DATETIME(3) 时间边界 · 真 JSON 列 input_summary LIKE。

⚠️ 基金转换的 T-0b 与下方「架构改进第 3/4 批」的 core_ro 只读账号是同一件事 —— 已由本线定案为 D20,不再挂在架构改进线(该线原「不要做」清单已更新)。

待办(推荐顺序)

  • 【阶段一验收门】接口实调验收 —— 通过(2026-09-07 委托 AI 代验:三接口契约 + 三鉴权边界全部符合;前端 web/ 未 init,验收口径为后端接口验证)

  • 【阶段二】C4~C6 追加需求编码(实现方案已定稿)—— 全部完成(C4 RISK-006 fe4801b / C5 RISK-007 90d0660 / C6 RISK-008 66ec7eb,全量 pytest 482 passed 0 failed);收尾=演示 SOP 补代理人扮演步骤 + 02-redis-keys.md 增补 + tag risk-m4(见下条)

  • 【阶段二前置】python -m pytest 全量(系统 Python 3.13.14)确认基线绿 —— 482 passed 0 failed ✓(2026-09-07)

  • 【阶段二】C5 前置联动(挂账 #6):seed STAFF-31001/31002 + AGENT_ACCESS_MATRIX 增补 risk_manager + chat.py 显式 deny(对话线维持仅 risk_officer)+ risk.py 台账 manager 只读分支 + JWT 手册 §5.3 —— 完成(随 C5 落地,见挂账 #6 核对)

  • 【阶段二】C4 RISK-006 集中度(FR-8):rules(rule_concentration + RuleHit.alert_subtype)+ core_ro.concentration_profile + engine 接入 + alert_service(锚点排除 agent_behavior 单【评审 P0-1】+ subtype 合并 + alert_type 重算)+ customer_context 扩展 + settings 11 项配置;验收 A-10 —— 完成(commit fe4801b)

  • 【阶段二】C5 RISK-007 时效升级(FR-9):escalation_service + scripts/cron/escalation_scan.py + query_overdue_alerts Tool + conftest 回拨 fixture;验收 A-11 —— 完成(commit 90d0660)

  • 【阶段二】C6 RISK-008 代理人行为链(FR-10):trade_gateway actor_id 透传(前置)+ agent_behavior_service + scripts/cron/agent_behavior_scan.py + query_agent_behavior Tool;验收 A-12 —— 完成(commit 66ec7eb)

  • **【阶段二收尾】**演示 SOP 补代理人扮演步骤(A-12)+ 02-redis-keys.md 增补(C6 联动)+ 挂账 #1~#9 逐项核对 + 打 risk-m4 tag —— 全部完成(2026-09-07,risk-m4 指向 323d98b,仅本地未 push)

    挂账 #1~#9 核对结论(基于 C4~C6 三提交 fe4801b/90d0660/66ec7eb + 文档 323d98b 实查):

    挂账 内容 现状 判定
    #1 持仓汇总 收口进 core_ro.concentration_profile(持仓画像非流水),C4 rule_concentration 直接消费 ✓ 已收口
    #2 定时任务内嵌 lifespan app/main.py lifespan 无 cron 调用;scripts/cron/escalation_scan.py + agent_behavior_scan.py 仍独立 ✓ 未触碰
    #3 agent_profile_l3 建表 终态 entities 无 agent_profile_l3(仅有 customer_profile_l3,非同一表) ✓ 未建
    #4 escalated 状态改表 升级标记走 payload.escalation_level/escalated_at,无 status 列变更、无 ALTER ✓ 未改表
    #5 alert_type ENUM 扩展 alert_type 仍为 VARCHAR,靠 payload.alert_subtype 承载子类型 ✓ 未扩 ENUM
    #6 risk_manager 联动 随 C5 前置落地:seed STAFF-31001/31002 + AGENT_ACCESS_MATRIX 放行只读 + handle/aml/scan 端点保持 risk_officer only(manager 触碰即 403) ✓ 已收口(零处置权)
    #7 customer_query 事件类型补建 C6 复用既有 trade_request/authz forbidden 事件,无新建 customer_query 事件类型/枚举 ✓ 未建
    #8 core_trade actor 字段 终态 core_trade ORM 无 actor 列;actor 透传仅落在 audit_log/agent_*(trade_gateway.actor_id 写入审计,非 core_trade) ✓ 未加列
    #9 payload JSON 检索性能 risk_repository 仅改 append/merge/find 逻辑,无新增索引/查询计划优化 ✓ 未动

    红线复核:C4~C6 无 DDL/迁移脚本(scripts/core/02-seed-base.sql 仅补 seed 行,非改表);审计仅 INSERT;升级标记仅 cron 可写;manager 无处置权;四 Agent 不互调 LLM。挂账清单无一项退化为本期误做。

待办(模块侧开放项)

  • 【架构改进线 · 收尾】docs/开发计划-架构改进.md §7.2 七项手工冒烟 —— 2026-09-10 全部补跑,7/7 PASS:无 key 启动告警(清空/占位非空各一次)· 交易阻断+放行(SUIT_AGE_CONFIRM / RISK-001,002)· 预警聚合(CUST-9527 连发 4 笔,第 3/4 笔 alert_ids 同单、pending_review 计数 1、audit 呈 alert_created→alert_appended)· Redis 不可用→退回进程内锁(日志 2 次 退回进程内锁,交易仍 200)· Redis 恢复→退回进程内锁 命中 0 行 · 调换 main.py 装饰器→T-202 守卫变红(assert '' @ test_audit_middleware.py:221)→字节级还原后转绿。037ce7e 早已 push(远程 risk-control-agent = fffb78a = 本地 HEAD),原「未 push」表述作废;残留已按 SOP §2 重灌,全量 510 passed。入口:项目根 交接文档.md §C
  • chat 链路 risk_suitability_log.actor_id 暂落 SYSTEM(run_tool 统一透传需动 core_tools/kb_tools 冻结 func 契约,发起者留痕已由 agent_tool_call 覆盖)——AL-06 遗留,动 Tool 契约前先出方案
  • 【前端接入·方案 B】chat 拉侧三端点(commit 8328c24,2026-09-08):GET /api/chat/sessions(本人+本 Agent 线分页列表)、GET /api/chat/sessions/{id}/messages(历史消息升序分页,closed 仍可读)、POST /api/chat/sessions/{id}/close(active→closed,重复/非 active 409);chat.py 抽 _resolve_agent_type/_assert_chat_entry/_guard_session 三守卫供四端点共用,POST "" 行为零回归;risk_manager 在对话线数据面保持 403(PRD 4A.1)。测试 482→494 绿;独立评审 P0=0,P1(close 并发 rowcount 静默 200)已修复
  • 【前端接入·方案 C】SSE 流式对话(commit 01ec5fc,2026-09-08):新增 POST /api/chat/stream(OpenAI 兼容 chunk:首帧 meta → delta → finish_reason=stop → [DONE]);agent_service.stream_chat 生成器 + needs_disclaimer;_guard_request/_prepare_turn 与同步端点共用守卫;session_repository.insert_turn user+assistant 同事务落库(修评审 P0/P1)。测试 494→503 绿。遗留:无心跳帧、断连留空会话待清理
  • 前端 React 多 Agent 入口(HashRouter,web/ init)——是否归风控模块由用户拍板
  • 2026-09-05 memory 文件夹更新(新 Agent 交接清单)

合并 main 相关(AL-09 / AL-10 / AL-11)已移交合并执行人——模块侧交付完毕(482 绿 + 接口实调验收通过 2026-09-07),执行手册:《docs/项目框架设计/合并注意事项-风控模块并入main.md》(含基底锁定/20 冲突裁决/14 静默文件/三硬伤/合并后必测清单,实测数据编制)。

  • T-04 Core RO 封装为 Tool 节点;A-01 归属校验(chat Tool 接入 + agent_tool_call 落库)—— 完成(2026-09-07):app/tool/core_tools.py(L0/持仓/流水三只读 Tool + TOOL_REGISTRY 白名单)+ app/service/tool_service.py(关键词意图仅 customer/advisor;归属校验对齐 deps.assert_customer_access 口径——Tool 层拒绝不抛 403 而 blocked 留痕,纵深防御;run_tool 执行+落库,落库失败降级)+ agent_service 图 tool 节点(START→tool→llm→guard;结果注入 LLM 上下文,降级回复带摘要)+ session_repository.insert_tool_call(message_id 一期 NULL)。A-01 口径:本任务只做 Tool 层归属校验语义(customer 本人/advisor assigned/risk_officer 全量/其余拒),A-01 完整场景(代理人画像)仍归 T-20;risk 分支四 Tool 归 C1 复用 run_tool。评审闭环(2026-09-07):首评 P1×2+P2×3+P3×2 → 修复 40a9ee2 → 复审 P2×1+P3×4 → 修复 1216d26,pytest 321 绿;入参白名单+days 钳制、公共鉴权双写 utils/authz.py、list_holdings LIMIT 均落地
  • T-21 Milvus Lite + kb_product_rules 首批入库 —— 完成(2026-09-07,commits e34973f~535c8a0 共 6 个 + 评审闭环 9cc2e59):app/service/embedding.py(Ollama bge-m3 批量 /api/embed 1024 维,四类失败一律 EmbeddingError 不静默降级)+ app/service/milvus_service.py(kb_product_rules 幂等建集合+upsert+search_kb 溯源/effective_date 合规过滤)+ data/kb/ 6 只种子产品手册(prospectus/fee/rule/risk 四节 24 块)+ scripts/kb/build_kb.py(--dry-run/--kb-dir)+ app/service/rag_service.py 落地(search_knowledge→chunks+source_refs,异常上抛防 LLM 编造)+ app/tool/kb_tools.py 挂注册表第三层(ToolSpec 新增 skip_access_check:公开知识无归属语义,advisor 无绑定客户可查;意图层限定 customer/advisor,risk 不开放——用户拍板)+ tool_node 按 spec 白名单注入 query + summarize 溯源口径。真库验收:24 块入库,search_knowledge("基金申购") Top3 命中申赎规则(score 0.73+),溯源完整。三坑收口:Milvus Lite 跨进程重开须显式 load / faiss 不支持中文路径(本机 .env 改 C:/Users/YUAN/.jinrong/milvus/)/ build_kb sys.path 引导。知识库 API(上传/重建端点)一期不做(knowledge.py 仍空壳,用户拍板),425 绿
  • T-03 输入防护规则(F-03:prompt_injection/oversize/限流)—— 完成(2026-09-07,commits 497554d/65b45aa/cc6f34f/207fc79):app/service/input_guard.py(注入短语词表 42 条四类纯函数检测 + inspect_message oversize 4000 先于 injection + check_rate_limit Redis INCR 固定窗口 actor 级 30 次/分 fail-open)+ chat 路由接入(顺序:鉴权→准入→空白→限流 429→注入/超长 400→归属→会话;被拒 fail-fast 不建会话不落消息,blocked 落 input_guard_log,留痕降级不改拒绝语义;Pydantic 硬顶 20000,业务限 4000 移 guard 层换留痕)+ redis_gateway.incr + settings.guard_rate_limit_*;拍板:命中即拒不清洗、仅 blocked 留痕、词表代码常量可审计。独立 AI 评审 PASS with findings(P0=0;P2×3 已收口:词表断言修正/补 7 条同构变体/窗口 TTL 断言+EXPIRE 失败取舍锁定;P3 已收 session_id 截断,挂账对抗变体扩表),378 绿
  • 风控阶段 C(C0 pytest-asyncio / C1 chat_tools / C2 risk 分支 StateGraph / C3 A-6 验收)—— 完成(2026-09-07):app/service/risk/chat_tools.py 四只读 Tool(alert_query/customer_context/suitability_check/aml_lookup)挂 RISK_TOOL_REGISTRY;tool_service.run_tool 改查 core+risk 统一注册表 get_registered_tool 且恒传 risk_repo;_normalize_params 读 spec 白名单;match_intent 按 agent 分组扩 risk 关键词;agent_service.tool_node 守卫放宽(requires_customer=False 允许无绑定客户,支撑 A-6 全量待审);A-6 验收+诱导处置边界(无处置 Tool、系统提示禁自动处置、诱导只触发只读且预警状态不变);独立 AI 评审 PASS(P0=0,P2 补 advisor 归属/空 product_id 单测已收口),345 绿,tag risk-m3

风控模块(PRD v1.0 已冻结 · docs/PRD/PRD-风控监测Agent.md,事件驱动线不依赖 T-07 可先行)

  • T-30 风控事件线 —— 全部完成(B1~B9b,M2 tag risk-m2):规则引擎/预警聚合/L3/AML/交易网关/4 API/演示走查 11/11 PASS + 核查单①~⑥收口,均经独立 AI 评审闭环;scan_all 幂等读后写无锁留痕(接批量时 run_locked)
  • T-31 service/suitability.py 公共校验(SUIT-001008)+ POST /api/risk/suitability/check —— **交付=suitability 服务函数+单测(77 例;check API 随 B6 带鉴权+直调审计);MySQL 手工 SQL 对照(阶段 A 评审 P2-8)2026-09-07 收口:4 组演示组合真库 SQL 推导与函数判定逐项一致(演示 SOP 核查单附行)。【2026-09-07 阶段一退役】SUIT-001008 编号体系已随 AL-05 换核退役,判定内核改为 main 的 core_ro.check_suitability(C×R 矩阵 + JR-AST/FM 契约),测试按 main 契约重写(原 77 例作废,全量基线 425→406)**
  • T-32 预警台账与人工处置 API + 对话线 —— 台账/处置 API 已由 B6 覆盖并复审通过(A-7/A-9 用例绿);交付=对话线,归阶段 C(C1~C3,T-07 已就绪)

已完成

  • 2026-09-07 风控 M2 收尾(M4 复核):MEMORY/TODO 状态与边界文字对齐(任务映射 T-30/T-31/T-32 口径确认;B7 复审留痕「成功响应不包裹外壳」演进口径维持并登记开发计划 M4 节)——风控阶段 B 正式完结
  • 2026-09-09 架构改进与稳定性加固 T-101~T-202(分支 risk-control-agent 本地完成、待用户目视验收后 push):明细见 docs/项目框架设计/TODO-架构改进.md(全勾 ✓);pytest 510 绿(503+7:T-201.3 双层锁 6 + T-202 trace 顺序守卫 1)。含 Redis 双层分布式锁 T-201(acquire_lock/release_lock + run_locked 三降级,多实例安全)/ 审计中间件 trace 顺序守卫 T-202 / 注入词表 42→45 / 风控只读 Tool 加 query_overdue_alerts 共 5 个 / 架构设计补 §5.8 三项设计遗留(G1 X-Trace-Id 白名单 / G2 uuid4 概率唯一 / G3 admin·knowledge 空壳非 RAG 缺失)。全部为文档·告警·锁原语修正,接口契约与表结构零变更,合并 main 无新增冲突面。
  • 2026-09-07 T-01 JWT 鉴权(commit 36f476f + 评审闭环 61711cb):app/service/auth_service.py Auth SDK(HS256 dev/RS256 生产、必填 claims 显式校验、jti 吊销 fail-open、RS256/HS256 算法白名单互斥)+ deps.get_auth_context 工厂替换(Bearer 全环境优先;debug 头降级 dev 兜底,双闸门=APP_ENV+无 RS256 公钥)+ X-Agent-Type 交叉校验(手册 §4.6/§5.4 AGENT_ACCESS_MATRIX)+ scripts/dev/issue_dev_token.py 签发 CLI + lifespan 改验 jwt_ready
  • 2026-09-07 T-02 审计中间件(commit 3cec034):app/api/audit_middleware.py http_access 全量访问审计(actor 经 request.state.auth,排障路径/OPTIONS 跳过,写库失败降级)+ 独立 request_id(X-Request-Id 贯通,B7 复审 P3-4)+ 422/404/405/500 统一错误体(500 由 trace 中间件兜底回写 trace 头,B7 复审 P2-2)+ input_guard_log 双写(挂账⑧收口;401 归 platform、四 Agent 入口写 guard)
  • 2026-09-07 T-07 LangGraph 骨架(commit fb18c04):agent_service StateGraph(llm→guard)+ DeepSeek/langchain-openai(无 key 降级明确标注)+ 四 Agent 边界 system prompt + customer/risk 免责声明(has_disclaimer)+ 单测 mock LLM 不依赖外网
  • 2026-09-07 T-06 chat 最小闭环(commit ee5c78a):api/chat.py POST /api/chat(X-Agent-Type 分流+准入+归属校验+SessionGuard AUTH_403_SESSION_AGENT+closed 409)+ session_repository(agent_session/agent_message)+ memory_service(Redis 窗口 sess:{agent}:{id}:msgs TTL2h N≤20,miss/异常回源 MySQL)+ main 挂载
  • 2026-09-07 Wave 0 独立 AI 评审有条件通过→闭环(commit 61711cb):P2×5(python-jose>=3.5.0 防 CVE / audit 降级测试 / JWT 通道 chat 用例 / debug 兜底纵深防御 / 留痕失败降级显式化)+ P3×11 顺手,273 测试绿
  • 2026-09-05 init 项目记忆目录 + app/ 脚手架(api/service/tool/model/config/utils)
  • 2026-09-05 需求拆解文档(业务场景/矩阵/合规)
  • 2026-09-05 表设计 + 技术选型 + JWT 手册
  • 2026-09-05 Core 模拟库 scripts/core/* + reset.ps1 + 文档
  • 2026-09-05 core_ro.py + settings.mysql_core_database + sync 脚本
  • 2026-09-05 Agent 编排依赖改为 LangGraph(requirements.txt)
  • 2026-09-05 memory 文件夹更新(新 Agent 交接清单)