37 KiB
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-11 完成(全量 pytest 846 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,退出码均 0),下一步 T-12(补偿脚本改写)。撤单范围: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 阻断(B1convert_cutoff_time配置缺失违反 PRD §2.6.1 不得硬编码 → 已加 settings 全链读;B2core_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.py4 处→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 遵守);③→ 已裁定并修正(PRD v0.9.1):PROD-005827费率分类口径差异(mixedvs 主动偏股)待裁定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/PlanResultfrozen 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.py93 用例(12 类:精度 HALF_UP 反向自证 / 分档边界 6-7-29-30-179-180-364-365 / FIFO 含同confirmed_attiebreak / 跨批计费 / 双口径 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_tradeDECIMAL(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-09PROD-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.py37/37 一致(退出码 0) - T-7 三段编排 +
confirm_service(核心重写)✅(2026-09-11,提交048f1a9):新增confirm_service.py(confirm_one8 步:读单+状态闸门 → 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.py83/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_alert0 行、无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.0convert_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.pyconvert 分支 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.pyHTTP 全链路 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_lotsredeem 三重裁剪(T+2 过滤 → D8 补建 → 在途占用 → 哨兵 FIFO 扣减),subscribe 落新批次;core_ro.list_share_lots/share_lot_repository.select_for_convert加available_fromT+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.py89/89(H 节提前 + H2 在途占用拦截断言);rebuild_lots.py --dry-run58 持仓 0 补建 0 写入;6 项 DoD 全闭环 + 突防验证(移除透传 → t2 用例变红 → 还原) - T-11 core_tools 汇总去重 + 持仓过滤 ✅(2026-09-12,生产代码零改动):口径三处同调(F-10)与
list_holdings的qty > 0SQL 过滤均已就位(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 同源) - T-12 ~ 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-00790d0660/ C6 RISK-00866ec7eb,全量 pytest 482 passed 0 failed);收尾=演示 SOP 补代理人扮演步骤 + 02-redis-keys.md 增补 + tagrisk-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-m4tag —— 全部完成(2026-09-07,risk-m4指向323d98b,仅本地未 push)挂账 #1~#9 核对结论(基于 C4~C6 三提交
fe4801b/90d0660/66ec7eb+ 文档323d98b实查):挂账 内容 现状 判定 #1 持仓汇总 收口进 core_ro.concentration_profile(持仓画像非流水),C4rule_concentration直接消费✓ 已收口 #2 定时任务内嵌 lifespan app/main.pylifespan 无 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_tradeORM 无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_turnuser+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_messageoversize 4000 先于 injection +check_rate_limitRedis 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 绿,tagrisk-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)+008 编号体系已随 AL-05 换核退役,判定内核改为 main 的 core_ro.check_suitability(C×R 矩阵 + JR-AST/FM 契约),测试按 main 契约重写(原 77 例作废,全量基线 425→406)**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-001 - 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.pyAuth 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.pyhttp_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_serviceStateGraph(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.pyPOST /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 交接清单)