阶段二失败(或阶段 1.5 引擎失败)后,仅凭 Core 侧数据把「详情 + 预警」两件事补回来
(PRD §7.1 / 架构 §5.4)。
落地(改 3 + 新增 2 脚本 + 测试 2 文件)
- convert_service:新增公开 compensate_convert(group_id, ...) —— 补偿的服务端单点入口
· 锁键 convert:rerun:{gid},与 convert_fund 幂等重试路径同一个键
· 详情侧:非 completed 才补写,复用 _finalize_from_core(不另写第二份阶段二)
· 预警侧:幂等锚点 = 转出端 out_trade_id,复用 find_alerts_by_trade;
命中即 skipped,否则跑 process_convert_event
- risk_repository:has_engine_error_audit 加 decision 参数(默认值不变)
· convert 线阶段 1.5 失败审计用 engine_error,普通交易用 risk_engine_error,不是同一个码
- rebuild_alerts.py:新增 --convert-group(与 location 参数 trade_ids 互斥),薄封装
- 新增 scripts/agent/cleanup_pending_convert.py(架构 §2 与开发计划 §9 指定路径):
超 convert_compensate_sla_hours 的 pending 占位 → status='expired'(标记不硬删,S2)
- 新增 scripts/dev/verify_convert_compensate.py:真库验证脚本(MySQL 8.0.46)
- 测试 +12:test_convert_service +4(补写 / 幂等 / missing / locked)、
test_demo_scripts +8(--convert-group 分派与接线 + cleanup 脚本)
state 四态与 CLI 退出码
- rebuilt(0) / skipped(0 幂等) / missing(1 零写入) / locked(3)
- 退出码 2 保留给 argparse 用法错误,故 locked 取 3
真库专属证据(sqlite 单测给不了的,本任务核心增量)
- status='expired' 在 MySQL ENUM 上被接受(sqlite 该列是 VARCHAR,写什么都收)
- created_at < cutoff 在 DATETIME(3) 上的时间边界正确(超时进候选 / 未超时不进 / 复跑幂等)
- input_summary 是真 JSON 列,而 has_engine_error_audit 用 LIKE 判定:脚本先断言
information_schema 的 DATA_TYPE='json' 再验命中,并反向断言决策码不匹配则不命中
顺带收口(用户指示)
- core_ro.concentration_profile 补 h.qty > 0,与 list_holdings 真正同口径
· ratio 不变(归零行市值为 0),但 rows 不再多出已清仓产品、不虚占截断判定位
· 新用例含跨出口一致性断言;突变验证:去掉 qty > 0 → 精准 1 条红
验证
- pytest -q → 731 passed / 3 skipped(基线 719 加 12,零回归)
- 突变验证 3 组精准命中:去掉幂等锚点(1 红)/ 去掉 status 过滤(2 红)/ 补偿无视锁(1 红)
- 真库 verify_convert_compensate.py 34/34,隔离数据零残留
- 全套 7 个真库脚本复跑零回归:seed 全 PASS / apply 24 / service 35 / engine 31 / lots 20 / tools 14 / compensate 34
27 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)(2026-09-10):设计 + 开发计划均已闭环 —— PRD v0.9.2 + 架构 v1.0.1 + 独立评审 13 条 0 悬空(接受 10 / 修正性接受 3 / 驳回 0),门控 M-7 已满足;第 4 步开发计划 v1.0 已产出并经独立审核(4 条意见全接受、驳回 0,含新增 2 条回归面 R15/R16 + R-c 双条修订);第 5 步进行中:T-0 ~ T-12 均已于 2026-09-10 完成(731 passed / 3 skipped;T-1 断言 8/8 PASS、T-2 纯函数 93 用例、T-2b 实算 15/15 一致、T-6 真库 24/24、T-7 真库 35/35、T-8 真库 31/31、T-9 真 MySQL 集成 8 条 + 4 组突变验证 + 展示位数修复、T-10 新增 17 用例 + 真库 20/20 + 2 组突变验证、T-11 新增 4 用例 + 真库 14/14 + 3 组突变验证 · amount_view 提升为公开、T-12 新增 12 用例 + 真库 34/34 + 3 组突变验证 · 补偿逻辑收敛到 compensate_convert 单点),下一步 = T-13(全量回归 + 50 并发压测 + 性能补录 · 本线最后一个任务)。两个阻断前置(T-0 sqlite/MySQL 列名统一 + 建库自校验 · T-0b DB 账号分离 D20:xh_core_ro/xh_core_rw/xh_agent_rw)均已落地。入口:项目根 交接文档.md §B(三线合并版唯一入口,读这一节即可开工);开工前必读开发计划 §1.4(15 条代码事实)+ §1.5(8 条实现级裁定 R-a~R-h)+ §12(16 条回归面)。
基金转换线待办(推荐顺序)
- 【第 4 步】产出开发计划 —— 完成(2026-09-10):
docs/项目框架设计/开发计划-基金转换交易.md(1,047 行,含 T-0~T-13 任务拆解 + 逐条改法 + DoD + 四轮审核记录)。四轮独立子代理审核已收敛:12 条意见 → 接受 11 / 驳回 1(附实测证据)/ 0 悬空(第一轮:补 R15 真 MySQL 集成用例test_integration_risk.py:426-437+ 补 R16 redeem 用例 + R-c 拆「降级规则 + 覆盖率补偿」双条 + F-11 计数 11→13 更正;第二轮:发现执行权锁是请求粒度致并发首次建行撞 UNIQUE → R-a 增第 ③ 步IntegrityError回退 UPDATE,并实测排除WHERE NOT EXISTS/FROM DUAL两个不可移植写法;第三轮:修 §14「四道→五道」口径不一致 + 驳回「SQLAlchemy 会抛 PendingRollbackError」的推测;第四轮:终验通过、无「声明已改实际未改」残留)。本计划新增的增量资产:§1.3 两处 PRD-架构口径裁定(W-1/W-2)· §1.4 十五条代码事实核对表 · §1.5 七条实现级裁定(R-a「条件 UPDATE → 首次 INSERT →IntegrityError回退 UPDATE」三步、R-b 流水写 redeem/subscribe 不写 convert、R-c 批次降级+覆盖、R-dsum_trades_on_date去重、R-e conftest 用 admin 角色、R-fcore_product_nav并入 T-0、R-g 自校验落_ddl.py)· §12 十六条回归面 · §13 PRD 19 条验收映射 · §14 新增实现级风险表 - 【第 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】(最后一个):全量回归 → 50 并发压测 → 性能实测补录 → PRD §5.3 / §9 第 18 条数字回填。T-13 内部顺序:先 50 并发压测 → 再性能实测补录 → 最后 PRD 数字回填(详见架构 §15 + 开发计划 §2~§10)。DoD:① 性能实测值回填 PRD §9 第 18 条(替换「预估 < 100ms」);② 50 并发结论(是否超卖 /
100/200/400ms退避间隔够不够)写入交接文档.md§B;③ 实测超阈值 → 优化索引/锁策略后重定阈值,不得反向修改实测数据迁就指标 - 【待用户裁定】幂等重放响应的数值位数偏差(T-9 执行期发现,未顺手改):首次响应 2 位(
calc量化)vs 重放响应 4 位(core_tradeDECIMAL(18,4)直读)→"53456.95"vs"53456.9500",数值相等,违反 PRD「对外一律 2 位」展示契约,属 T-7_rebuild_quote范畴。集成测试已「比数值不比字符串」并钉住偏差
第 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-13(全量回归 + 50 并发压测 + 性能补录 · 本线最后一个任务)。基线 731 passed / 3 skipped(T-10 后 714 → T-11 后 718 → T-12 后 731,+13)。 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 交接清单)