 GaoYiYuan_0626andWorkBuddy
|
3244922a55
|
基金转换 T-3:core_ro 新增 5 个只读方法 + share_lot_repository 读侧
- core_ro 新增 get_nav_as_of(D10) / get_redeem_fee_rules / list_share_lots(S1 确定性排序)
/ sum_remain_qty(仅 >0) / get_holding;不动 get_latest_nav 与 list_trades_range 白名单
- 新增 share_lot_repository:core_share_lot 读侧 FIFO 贪心选批 + 汇总,排序复用 core_ro 的 ORDER BY(D18 单一副本)
- 新增 tests/test_share_lot.py 15 用例;pytest 全量 624 passed / 3 skipped(基线 609,零回归)
- 同步开发计划 §5.1 执行记录与交接文档 §B 状态(v1.5 / T-3 ✅ / 基线 624)
Co-Authored-By: WorkBuddy <workbuddy@tencent.com>
|
2026-09-10 15:42:55 +08:00 |
|
GaoYiYuan_0626
|
c5182f1910
|
feat(convert): 基金转换 T-0/T-0b 门禁 + T-1 数据层 + T-2/T-2b 纯函数与实算回填
T-0 / T-0b(门禁 · 2026-09-10)
- T-0:sqlite 与 MySQL 结构对齐 —— core_holding 统一为 qty/cost_amount/as_of/pnl_pct
+ PK + UNIQUE(customer_id, product_id);补 core_product_nav;新增建库自校验
_assert_ddl_aligned()(R-g);test_db.py 增 3 条门禁用例(含反向验证门禁失效)
- T-0b:DB 账号分离(D20)—— 新增 scripts/core/00-grant.sql(三账号逐表授权);
settings.py 增 3 组账号;db.py 改 get_engine(db, role),缓存键改为 (库名, 角色),
账号未配置回退单账号;core_ro→ro / gateway_repository→rw / risk·session_repository→rw;
tests/conftest.py 四处显式 role="admin"(R-e)
T-1(数据层)
- scripts/core/01-ddl.sql:新建 core_fee_rule / core_share_lot / core_convert_lot_detail;
core_trade 加 convert_group_id + idx_convert_group;core_product 加 8 列 + fee_rate 补 COMMENT
- 新增 07-seed-fee-rule.sql(赎回费 5 档 × 14 产品,按 22 号文 §10)/ 08-seed-share-lot.sql
(58 行持仓 → 61 行批次,Σ remain_qty 恒等于 qty)/ 09-seed-org.sql(管理人 + TA +
申购费率 + 最低持有余额,v1.1 按「管理人全产品线」重排)
- reset.ps1 追加 07/08/09;02-mysql-agent专用.sql 追加 risk_convert_detail
- tests/_ddl.py 同步 4 表 + 新增 REQUIRED_CONVERT_TABLES 建库门禁
- 新增 scripts/dev/verify_convert_seed.py(pymysql 等价 reset 流程 + 8 条 DoD 断言,
含断言 ⑧「费率档 ↔ product_type 匹配」,越档即 FAIL)
T-2 / T-2b(纯函数包 + 示例实算回填)
- 新增 app/service/convert/ 7 文件:__init__ / types / calc / fee / nav / lot_bootstrap / errors
(纯函数,不查库、不碰 SQL;所有量化显式 ROUND_HALF_UP;lot_bootstrap 用 zlib.crc32
保证 D18 跨进程同源)
- 新增 tests/test_convert_calc.py 93 用例(12 类:HALF_UP 反向自证 / 分档边界 /
FIFO 含同 confirmed_at 兜底 / 双口径 / 强制全转与强制赎回 / PRD §5.3 全链自证 /
纯函数零 IO 依赖断言)
- 重写 scripts/dev/calc_convert_demo.py:去掉脚本内公式副本,改为调用生产 calc.py,
末尾与 PRD §5.3 逐项比对(不一致即退出码 1),兼作一致性门禁
验证
- pytest 609 passed / 3 skipped(516 → +93,零回归)
- verify_convert_seed.py 8/8 PASS;calc_convert_demo.py 15/15 与 PRD §5.3 一致
文档:PRD v0.9.1(费率分类修正)· 架构 §7 签名回填 / §8.3 错误码注 / §15 T-2 完成 ·
开发计划 §1.5 新增 R-h + §4.2·§4.3 执行记录 · AGENTS.md · docs/memory
|
2026-09-10 14:45:55 +08:00 |
|
GaoYiYuan_0626
|
037ce7edca
|
docs(架构改进): 补齐 PRD/开发计划/TODO/交接文档,落地无密钥告警与 Redis 分布式锁
一、流程文档(按 AIcoding 六步落地,供新会话从交接文档开工)
- 新增 docs/PRD/PRD-架构改进与稳定性加固.md:6 条 FR(文档勘误、非缺陷说明、
无密钥启动告警、审计失败告警、Redis 分布式锁、中间件顺序测试)
- 新增 docs/项目框架设计/改进方案评审-问题清单与对比.md:24 项问题分档 A~G,
经两轮独立 AI 评审,无阻断级错误
- 新增 docs/项目框架设计/开发计划-架构改进.md:HOW 层设计,含合并前只做低风险
11 项的批次策略
- 新增 docs/项目框架设计/TODO-架构改进.md:T-101~T-109、T-201~T-202 可勾选项
- 新增 docs/交接文档-架构改进.md:自包含交接入口,hy3 新会话可直接开工
- 新增 docs/项目框架设计/架构设计说明书.md:按模块/分层逐一讲解的全量架构说明
二、代码改动(T-107/108/109、T-201.1、T-201.2)
- app/main.py:启动时 DEEPSEEK_API_KEY 缺失告警,明确告知将走降级回复
- app/utils/authz.py:越权审计失败日志补 trace_id,便于串联全链路
- app/api/audit_middleware.py:审计失败日志补 status/path/request_id
- app/service/risk/redis_gateway.py:新增 acquire_lock(SET NX EX)与
release_lock(Lua 原子释放,只删自己的锁)
- app/service/risk/locks.py:run_locked 改为双层锁,Redis 为主、进程内锁为备;
Redis 超时沿用 fn(locked=False) 降级语义,Redis 不可用(含测试 Fake 缺方法的
AttributeError)安全退回进程内锁,绝不抛异常
三、文档勘误(A1/A2/A3)
- MEMORY.md:文件数 42→45、Tools 4→5
- 02-mysql-agent专用.sql:会话表 5→6
- 架构设计-风控模块.md:同步更正
四、测试
- 新增 tests/test_locks_redis.py:覆盖抢锁成功、占用超时、Redis 故障降级、
Fake 缺方法降级、只删自己锁、三处调用点 key 前缀
- tests/test_audit_middleware.py:补充告警字段断言
- 全量 pytest 510 passed(原基线 503)
|
2026-09-09 18:10:03 +08:00 |
|
GaoYiYuan_0626
|
01ec5fce32
|
feat(chat): 新增 SSE 流式对话端点 POST /api/chat/stream(方案 C)
契约(OpenAI 兼容 chunk,AI SDK / fetch-event-source 可直接接):
首帧 meta(session_id/trace_id/disclaimer)→ delta → finish_reason=stop → [DONE]。
前端侧:免责声明由首帧下发、前端常驻渲染;落库文本仍按原口径拼尾部。
设计拍板:
1. 新增独立端点,原 POST /api/chat 契约与既有测试零影响;
2. 鉴权/限流/输入防护全部在返回 StreamingResponse 之前完成(SSE 一开就改不了
状态码),401/403/404/409/429/400 仍是普通 JSON;
3. 整轮一次性落库:中途异常/断连不落消息(Tool 留痕已落可审计),不产生
半截内容污染历史窗口。
实现:
- agent_service:抽 needs_disclaimer/_degraded_reply/_base_state;新增 stream_chat
生成器(Tool 节点同步跑完再推 LLM 文本,无 key 走降级整块);
- api/chat:抽 _guard_request(准入→空白→限流→注入拦截)与 _prepare_turn
(归属+会话解析/创建),同步与流式共用,守卫零偏差;
- session_repository:新增 insert_turn——user+assistant 同事务落库 + 事务内
取 seq,修掉评审 P0(落库失败会半截落且前端收不到 [DONE] 挂起)与 P1
(两次写非原子);同步端点一并改用。
测试:新增 9 例(契约/免责/降级/异常不落库/落库失败/鉴权边界/超长/closed/Tool
留痕),全量 pytest 494→503 绿。遗留:无心跳帧(长生成空隙靠反代 timeout 配置),
断连留空会话待清理策略。
|
2026-09-08 14:23:33 +08:00 |
|
GaoYiYuan_0626
|
8328c2403e
|
feat(chat): 新增前端拉侧三端点(会话列表/历史消息/关闭会话)
方案 B:补前端对话页「拉」侧能力(chat 此前只有 POST 发消息):
- GET /api/chat/sessions:本人 + 本 Agent 线会话分页列表(created_at 倒序,total 供分页器)
- GET /api/chat/sessions/{id}/messages:历史消息 seq_no 升序分页(closed 会话仍可读)
- POST /api/chat/sessions/{id}/close:active→closed + closed_at;重复/非 active 409
守卫复用:抽取 _resolve_agent_type / _assert_chat_entry / _guard_session,
POST "" 改为复用同套守卫(行为零回归);risk_manager 在对话线数据面保持
同口径 403(PRD 4A.1 冻结);会话仓储新增 list_sessions / list_messages_page /
close_session(条件更新防并发静默写)。
测试:新增 12 例(分页、越权 403+留痕、404、409、manager 拒绝、limit 钳制、
JWT 通道),路由挂载清单同步;全量 pytest 482→494 绿。独立 AI 评审 P0=0,
P1(close 并发 rowcount 静默 200)已修复。
|
2026-09-08 14:07:38 +08:00 |
|
GaoYiYuan_0626
|
66ec7eba08
|
feat: C6 FR-10 代理人行为链 RISK-008
代理人异常行为链识别(RISK-008)落地:
- 新增 agent_behavior_service:三条件证据聚合(A 诱导调仓/B AUTH_403_SCOPE 越权试探/C AUTH_403_NOT_OWNER|NOT_ASSIGNED 越权查询),按代理人维度独立出 pattern 单,payload.actor_id 指向代理人,审计仅 INSERT event_type=agent_behavior_detected。
- risk_repository 新增 list_audit_events / find_agent_behavior_alert / merge_agent_behavior_payload(同日同代理人一张单,证据并集)。
- trade_gateway.submit_trade 补 actor_id 透传(代理人发起交易归属发起人,缺省 SYSTEM);simulate 路由传入 auth.actor_id。
- chat_tools 新增 query_agent_behavior 只读 Tool(agent_id 过滤 + 客户脱敏),tool_service 补意图词与摘要。
- scripts/cron/agent_behavior_scan.py 定时扫描脚本。
- 修复 append_alert_event 序列化缺 default=str(C6 evidence 含 datetime 字段)。
- 单测 12 例(_count_induce 边界 / 三条件 / 出单去重 / payload 归属 / Tool 过滤脱敏)。
全量 pytest 482 passed 0 failed(470 基线 + 12 C6)。
|
2026-09-07 19:53:39 +08:00 |
|
GaoYiYuan_0626
|
90d0660b44
|
feat: C5 FR-9 预警处置时效升级(RISK-007,P0)
- 仓储:新增 list_pending_alerts_all / update_alert_escalation(统一读改写 payload,
升级标记独占写入,status/handler_* 列不碰;_parse_alert 补 created_at/handled_at
字符串→datetime 解析,兼容 sqlite 原生 DDL)
- escalation_service.scan_and_escalate:扫描判级(普通 4h/24h、AML 1h/4h 短通道)、
幂等闸门(仅升不降)、先持久化再推送、按 (customer_id,level) 降噪合并一次推送、
通知链累积(L1 含 risk_manager / L2 含 compliance)、逐单+任务级审计
- scripts/cron/escalation_scan.py:15min 定时扫描壳(sys.path 引导 + new_trace + JSON 摘要)
- 对话线 query_overdue_alerts Tool + 注册表 + 意图词(置于 alert_query 之前)+ summarize 分支
- C5 前置:seed STAFF-31001/31002(risk_manager) + deps 矩阵放行 + chat.py 显式 deny +
risk.py 台账全量只读分支;JWT 手册 §5.3/§5.4/§6.1 增补 risk_manager
- 测试:conftest 回拨 fixture + test_escalation_service(9) + risk_api/manager(5) +
chat deny(1) + chat_tools overdue(2);全量 470 绿(453+17)
|
2026-09-07 19:28:04 +08:00 |
|
GaoYiYuan_0626
|
fe4801bc0a
|
feat: C4 FR-8 持仓集中度预警(RISK-006)
依据《实现方案-风控追加需求v1.1-C4C6.md》§2;不改表结构(alert_type/status
复用 payload 承载,audit_log.event_type 为 VARCHAR 可直接扩)。
1. settings.py + .env.example:一次性加齐风控追加 v1.1 共 11 项配置(C4~C6 共用)。
2. core_ro.concentration_profile(customer_id, limit=500):一次 SQL 取明细
(LIMIT limit+1 探测截断)+ Python 端按 min_risk_code in (R4,R5) 聚合;
收口挂账 #1(PRD 字面为 list_holdings,改聚合封装,docstring 注明偏离)。
3. rules.py:RULE_SCORES/RULE_ALERT_TYPES 加 RISK-006=60/pattern;RuleHit 加
alert_subtype;RiskThresholds 加 concentration_threshold 且 from_settings
必须补读(评审 P1-2:漏读会让 conftest monkeypatch 失效打穿现有断言);
新增纯函数 rule_concentration——空仓不触发、截断视同达标(保守告警)、
阈值边界 79.9% 不触发 / 80% 触发、R4+R5 为 0 不触发。
4. engine.process_trade_event:run_rules 之后、record_trade_alerts 之前并入
集中度命中(不动 run_rules 签名);命中后 L3 打 high_risk_concentration
标签 + 写 risk_concentration 审计(金额只落合计与前 5 条摘要)。
5. risk_repository:find_pending_event_alert 改候选 LIMIT 50 + Python 过滤掉
payload.alert_subtype 含 agent_behavior 的单(评审 P0-1:代理人维度行为链单
不得充当客户维度事件单的聚合锚点);append_alert_event 加 extra_subtypes
合并进 payload.alert_subtype(不传时行为与原先一致,向后兼容)。
6. alert_service:subtypes 集合维护(空集不注入 payload,评审 P2-3);
追加时 alert_type 按「老单规则 ∪ 本批规则」重算(评审 P1-3,修掉既有
large_amount 单被本批仅 RISK-006(60) 翻转为 pattern 的缺陷);
_publish_alert 加 notify_role/extra 可选参数(C5/C6 复用)。
7. 对话线:chat_tools.customer_context 加 profile(concentration_ratio/
r45_value/total_value/holdings_truncated),tool_service.summarize 加
「高风险持仓占比 X%(仅供参考)」;不新增意图词。
8. 02-redis-keys.md 增补 alert_subtype / escalation_level 附加推送字段。
测试:conftest 加 autouse _disable_concentration_rule(阈值推 1.01 做回归隔离,
现有用例断言零改动);test_risk_rules 加 RISK-006 纯函数 6 例;新建
tests/test_concentration_c4.py 11 例(与 RISK-001 同单聚合、score max=70、
L3 tag、risk_concentration 审计、仅集中度也出单、subtype 合并、P0-1 回归、
alert_type 不翻转、对话线 ratio)。全量 453 绿(436 + 17)。
|
2026-09-07 19:05:02 +08:00 |
|
GaoYiYuan_0626
|
8c226f0c6d
|
chore: 风控Agent模块自治边界标注 + AL-09 合并预处置
背景:远端 main 新提交 3995cb4(09-07 17:20,交接文档漏记)为 Wave 0 鉴权/
chat/防护平行实现,与已完工 T-01/T-02/T-03/T-06 同名不同路径;试合并实测
20 文件冲突(原记 9 个),另有 13 个 main 新增文件不报冲突会静默并入。
拍板:风控 Agent 按独立封装模块自治,与宿主耦合收敛到 4 个接缝。
1. 《风控Agent模块边界与合并接缝标注》入库存档:A~D 四类文件归属表;
4 接缝(S1 挂载点 main.py / S2 AuthContext / S3 settings / S4 引擎工厂);
20 冲突文件逐个裁决(core_ro、model/suitability、conftest、02-seed-base
以模块版为准;chat/main/settings/agent_service 等公共层以 main 为主);
三处硬伤处置:issuer 不一致改为适配器映射不统一、STAFF-90001 必保、
main infer_roles 未知 actor 默认 analyst(fail-open)记宿主侧 P1。
2. app/api/auth_adapter.py:S2 接缝适配器预制件(当前未接线,AL-09 接入)。
鸭子类型读宿主 ctx 故不依赖宿主文件;sub→actor_id、trace_id→contextvar、
perm_matches 兼容宿主 `前缀:*` 通配;缺主体即 HostAuthAdapterError,
fail-closed 不静默降级。
3. tests/test_module_boundary.py:边界防呆 4 类断言——模块私有文件存在、
禁止跨层 import 宿主私有实现(gateway.*/config.database/middleware.*/
utils.input_guard/model.schemas)、AuthContext 契约完整(actor_id 与
has_role 多参)、settings 私有字段与 AGENT_TYPES 四值不漂移。
4. tests/test_auth_adapter.py:适配器 11 例(映射/回退/fail-closed/trace 绑定/通配)。
基线:406 → 436 全绿(演示库已按演练 SOP §2 重灌:AML 8 条 / 演示 7 行 / sync 33 rows)。
|
2026-09-07 18:28:18 +08:00 |
|
GaoYiYuan_0626
|
b5fd52ef02
|
AL-08: 演示库重灌与种子核对对齐 main 基准——prepare_risk_demo.sql 改写 expires_at 口径(演示客户刷新为测评 90 天前/剩余 275 天,CUST-1004 保持过期演示 FM-03,替代 SUIT-008 evaluated_at+365 旧写法);演示 SOP 同步(§2 完成标志 33 客户口径+expires_at 剩余天数,A-1 预期改 SUIT_RISK_MISMATCH,A-2 改 FM-01 SUIT_AGE_CONFIRM 网点确认);网关阻断响应补全 main 契约字段(match_result/mismatch_type/requires_disclosure/needs_branch_confirm/rule_refs)+audit detail 加 block_response_code;集成测试 4 例旧口径断言更新(A-1 trace 一致性断机器码/A-1 audit JSON 断机器码/A-2 重写为 FM-01 语义/settings 退役断言)。SOP §2 脚本化全量重灌双库验证通过(AML 8 条/演示 7 行/sync 33 rows);全量 406 passed 0 failed 0 skipped(集成测试真库走 21 列新表+expires_at 数据恢复执行)
|
2026-09-07 17:49:39 +08:00 |
|
GaoYiYuan_0626
|
ec11ec42c0
|
AL-07: test_suitability 按 main 契约重写——七判定路径正反例(not_found 客户/产品两向/FM-03 过期/JR-AST-PRO 专业豁免优先于矩阵 forbidden/JR-AST-012 矩阵 forbidden/矩阵缺行 fail-closed/allowed/矩阵披露与产品 requires_disclosure 两源/FM-01 age70+R5 阻断+69岁与R2 两边界);compute_rule_refs 四类组合(含报告样例 过期+不匹配→['JR-AST-012','FM-03']);build_suitability_log_row 逐字段 21 列映射断言+bool→int 转换;服务集成端到端(21 列落库/check_source r02_trade 与 r02_chat/actor_id/request_ref 透传/兼容字段 rule_id=机器码 映射/NotFound 结构化不抛);MySQL 方言冒烟(真库连通时验 SQL 可执行性,未灌库自动 skip)。可控日期用远未来/远过去 expires_at 种子。全量 395 passed 0 failed;1 skip=集成模块待 AL-08 重灌演示 SQL expires_at
|
2026-09-07 17:42:55 +08:00 |
|
GaoYiYuan_0626
|
38da477be4
|
AL-06: 对话 Tool 与 API 响应对齐 main 基准——chat_tools.suitability_check 返回体扩展 match_result/mismatch_type/requires_disclosure/needs_branch_confirm/block_response_code/rule_refs(替代 rule_id/reasons/effective_level 展示),check_source='r02_chat',not_found 转结构化 found=False(NotFoundError except 死代码清除);tool_service.summarize suitability 分支按新枚举重写文案(网点当面确认 FM-01/签署风险揭示书/测评过期 FM-03/专业豁免,附 rule_refs 依据);risk_api 断言改 block_response_code。全量 373 passed 0 failed(1 skip=test_suitability 占位待 AL-07)。遗留:chat 链路 risk_suitability_log.actor_id 暂落 SYSTEM(run_tool 统一透传需动 core_tools/kb_tools 冻结 func 契约,发起者留痕已由 agent_tool_call 覆盖)
|
2026-09-07 17:39:04 +08:00 |
|
GaoYiYuan_0626
|
adf5e8013a
|
AL-05: suitability 服务重构换核对齐 main 基准——判定内核由 SUIT-001~008 纯函数矩阵改为 core_ro.check_suitability(C×R 数据驱动);SuitabilityResult 扩 main 新字段(match_result 五值/mismatch_type 七值/requires_disclosure/needs_branch_confirm/block_response_code/rule_refs)并保留旧字段兼容层(rule_id=机器码别名/effective_level=customer_level/reasons=[reason]);check_core/cap_by_age/match_by_matrix/is_assessment_valid 删除(SUIT-006 被 FM-01 替换,SUIT-008 被 FM-03 expires_at 替换);settings.risk_assessment_valid_days 退役(.env/.env.example 注释);NotFoundError 不再抛(not_found 结构化,main 契约);写库走 build_suitability_log_row + insert_suitability_log 升级 21 列(rule_refs JSON 序列化);check_source 参数化(网关 r02_trade/risk.py manual)+actor_id 透传;网关阻断响应补 block_response_code;model 抽 compute_rule_refs 公共函数防两处漂移;测试配套:_ddl 加矩阵 25 行种子 helper、conftest fixture 灌种子+集成就位校验改 expires_at 口径、trade_gateway/risk_api fixture 补种子与 expires_at、404 两例改 200+blocked 新契约、repository 21 列断言、settings 退役断言、test_suitability 占位 skip 待 AL-07 重写。sqlite 端到端七语义+落库验证通过;剩 4 failed 均为 chat_tools/API 旧展示断言(AL-06 处理)
|
2026-09-07 17:34:32 +08:00 |
|
GaoYiYuan_0626
|
e99ec6775a
|
AL-02: risk_suitability_log 重建 21 列对齐 main 基准——底座 SQL 采纳 main 版(product_name/investor_category/match_result 五值/mismatch_type 七值/requires_disclosure/needs_branch_confirm/risk_was_expired/block_response_code/check_source 四值/actor_id/rule_refs JSON + 6 索引);07-说明.md 直接采用 main 版 P0 契约;tests/_ddl.py sqlite 同步(21 列 + core_suitability_rule 新表 + core_customer/core_customer_risk/core_product 扩列,VARCHAR 近似 ENUM 与现有风格一致);修 test_risk_api 位置式 INSERT 补列名。全列 INSERT 验收通过;剩余 15 failed 均为旧契约断言(报告预告作废集,AL-05/06/07 清零)
|
2026-09-07 17:05:15 +08:00 |
|
GaoYiYuan_0626
|
1c51149912
|
feat: T21-5 知识库 Tool 接入对话——kb_tools(search_knowledge)挂统一注册表第三层; ToolSpec 新增 skip_access_check(公开知识无归属语义, advisor 无绑定客户可查, 意图层限定 customer/advisor); 意图关键词 customer/advisor 组尾挂 kb 词(Core 词优先, risk 不开放); tool_node 按 spec 白名单注入 query; summarize 溯源口径; 单测 13 例, 425 绿
|
2026-09-07 12:05:36 +08:00 |
|
GaoYiYuan_0626
|
e2a444453e
|
feat: T21-4 RAG 检索编排——rag_service.search_knowledge(query→bge-m3 向量→Milvus 检索→chunks+source_refs 溯源去重), 异常原样上抛不吞(防 LLM 编造回答), 空白 query 短路, ensure_collection 幂等防御; 单测 8 例注入 mock, 412 绿
|
2026-09-07 12:01:45 +08:00 |
|
GaoYiYuan_0626
|
7edf522aff
|
feat: T21-3 知识库首批数据+入库脚本——data/kb 6 只种子产品手册(每只 prospectus/fee/rule/risk 四节 24 块, 费率与 core_product seed 对齐)+build_kb.py(front-matter+节标题切块/doc_type 白名单/Core 权威元数据缺省即中止/一次批量 embedding/upsert 幂等/--dry-run); 脚本单测 10 例, 404 绿
|
2026-09-07 11:55:24 +08:00 |
|
GaoYiYuan_0626
|
1056a95343
|
feat: T21-2 Milvus 接入层——kb_product_rules 幂等建集合(冻结 11 字段+AUTOINDEX COSINE)+upsert 入库+search_kb(溯源字段必带+effective_date 合规过滤+标量过滤); 规避 pymilvus 3.x import 阶段读 .env 文件 URI 炸 import 的坑(setdefault 预置合法 MILVUS_URI); 单测 8 例真 Lite 临时库, 394 绿
|
2026-09-07 11:49:43 +08:00 |
|
GaoYiYuan_0626
|
e34973f018
|
feat: T21-1 embedding 服务——Ollama bge-m3 批量 /api/embed(1024 维), 连接/模型/结构/维度四类失败一律 EmbeddingError 不静默降级(拍板口径), 空输入短路; settings 增 embed_dim/embed_timeout; 单测 10 例 mock HTTP 不依赖 Ollama, 386 绿
|
2026-09-07 11:46:24 +08:00 |
|
GaoYiYuan_0626
|
207fc79f61
|
test: T-03 评审闭环(PASS, P0=0)——P2-1 词表规范化断言修正/P2-2 补 7 条同构变体(你现在是管理员/ignore the above instructions 等)+变体单测/P2-3 窗口 TTL 断言+EXPIRE 失败取舍锁定; P3 session_id 落库截断+trace 兜底注释, 378 绿
|
2026-09-07 11:16:15 +08:00 |
|
GaoYiYuan_0626
|
cc6f34fbbd
|
feat: T-03 输入防护限流(T3-3)——actor 级 Redis 固定窗口 30 次/分(settings 可调), 超限 429 GUARD_RATE_LIMITED+留痕, Redis 故障 fail-open, 测试 4 例(429/窗口滚动/fail-open/注入计数), 376 绿
|
2026-09-07 11:10:26 +08:00 |
|
GaoYiYuan_0626
|
65b45aa917
|
feat: T-03 输入防护接入 chat(T3-2)——注入/超长命中即拒 400 + input_guard_log 留痕(fail-fast 不建会话, 留痕降级不改拒绝语义), Pydantic 硬顶 20000, 集成测试 7 例
|
2026-09-07 11:02:36 +08:00 |
|
GaoYiYuan_0626
|
497554da43
|
feat: T-03 输入防护服务(T3-1)——input_guard 纯函数检测(注入短语词表/oversize 4000) + 单测 20 例(不误杀用例/判定顺序锁定), 365 绿
|
2026-09-07 10:59:25 +08:00 |
|
GaoYiYuan_0626
|
c92d8c7783
|
test: 阶段C 评审 P2 补 advisor 归属覆盖与空 product_id 单测(345 绿)
|
2026-09-07 10:31:58 +08:00 |
|
GaoYiYuan_0626
|
930ea9db56
|
feat: 阶段C 风控对话线(C1 四只读 Tool + C2 risk 分支意图 + C3 A-6 验收与边界)
- C1: app/service/risk/chat_tools.py 新增 alert_query/customer_context/suitability_check/aml_lookup 四只读 Tool,挂 RISK_TOOL_REGISTRY(与 core_tools.ToolSpec 同构)
- C1: tool_service.run_tool 改查 core+risk 统一注册表并恒传 risk_repo;_normalize_params 读 spec 白名单;core_tools 三函数加 risk_repo=None;summarize 补四工具分支
- C2: match_intent 按 agent 分组扩 risk 关键词;agent_service.tool_node 守卫放宽(requires_customer=False 的 Tool 允许无绑定客户运行,支撑 A-6 全局待审)
- C3: A-6 验收(risk_officer 问待审预警→alert_query 全量→回复含待审数)+ 诱导处置边界(无处置 Tool、系统提示禁自动处置、诱导只触发只读且预警状态不变)
- 测试 tests/test_risk_chat_tools.py(21 例);全量 pytest 342 绿(原 321 + 21)
|
2026-09-07 10:26:54 +08:00 |
|
GaoYiYuan_0626
|
1216d26083
|
fix: T-04 复审闭环——P2-1 test_chat 夹具补 _risk_repo 打桩(防越权双写写脏演示 MySQL)/P3 归属码改为显式集合+前缀兜底/truncated 判定多取 1 条防恰好 500 误报, 321 绿
|
2026-09-07 09:51:38 +08:00 |
|
GaoYiYuan_0626
|
40a9ee21a6
|
fix: T-04 评审闭环——P1-1 留痕降级提 error 带定位字段/P1-2 对话越权接鉴权双写(utils/authz.py 下沉公共出口,deps 复用,service 不反向依赖 api)/P2 入参白名单+days 钳制[1,365]/list_holdings SQL LIMIT+truncated/时间窗集中 _now_naive; 补测 24 例(days 边界/非法入参/inactive 归属/双写断言/降级日志/上下文截断), 321 绿
|
2026-09-07 09:42:37 +08:00 |
|
GaoYiYuan_0626
|
301c78edc3
|
feat: T-04 Core RO Tool 节点——chat Tool 接入+归属校验+agent_tool_call 落库
- app/tool/core_tools.py: 三只读 Tool(query_customer_profile/holdings/recent_trades, Core RO 仅 SELECT) + TOOL_REGISTRY 白名单(requires_customer); JSON 安全化(Decimal 两位/时间 isoformat)
- app/service/tool_service.py: match_intent 关键词意图(仅 customer/advisor; risk/analyst 空转归 C1/C2) + assert_tool_access 归属断言(customer 本人/advisor assigned/risk_officer 全量/其余拒, 口径对齐 deps.assert_customer_access) + run_tool 编排(白名单→校验→执行→agent_tool_call 落库, 落库失败降级 warning)
- agent_service: 图 START→tool→llm→guard; Tool 结果注入 LLM 上下文(SystemMessage); 降级回复带 Tool 摘要; chat() 可选 session 上下文(缺省空转, T-07 兼容)
- session_repository: insert_tool_call(message_id 一期 NULL, session_id+trace_id 可还原)
- 归属拒绝口径: Tool 层不抛 403 改 blocked 留痕(AUTH_403_* 同码), 对话内呈现——API 层 deny 铁律不变
- tests: test_chat_tools 20 例(三态+落库字段+降级+图注入) + test_chat 4 例(全链路/JWT 外 debug 通道), _ddl 补 agent_tool_call/core_holding, 297 绿
- 真库冒烟: uvicorn+真 MySQL/Redis chat 触发持仓查询 success 落痕 47ms, 现场已清理
|
2026-09-07 08:43:36 +08:00 |
|
GaoYiYuan_0626
|
61711cb70a
|
fix: Wave 0 独立 AI 评审闭环(有条件通过→闭环, 273 绿)——P2-1 python-jose>=3.5.0(防 CVE-2024-33663/33664) P2-2 audit 降级+OPTIONS 测试 P2-3 JWT 通道 chat 3 例 P2-4 debug 兜底双闸门(dev+无 RS256 公钥) P2-5 留痕失败降级显式化(401/403 拒绝语义不漂移, _safe_unauth_audit 保护 repo 构造); P3 顺手: 401 归 platform/值域外 400 补留痕/Bearer 大小写不敏感/jti 加 uuid/CLI permissions+exp 上限/dev 默认密钥 warning/LLM 单例加锁/chat 主角色优先序+message strip+guard 日志脱敏/必填 claims 参数化+none 算法固化; P3 登记项(会话枚举/seq_no 锁/trace_id 口径/文档同步)归 M4 文档
|
2026-09-07 03:03:12 +08:00 |
|
GaoYiYuan_0626
|
ee5c78af66
|
feat: T-06 chat 最小闭环——api/chat(X-Agent-Type 分流+准入矩阵+customer 归属固定本人/advisor G-01 归属校验+SessionGuard actor/agent 一致+closed 409) + session_repository(agent_session/agent_message, 派生表补 alias 修 MySQL 1248) + memory_service(Redis 窗口 sess:{agent}:{id}:msgs TTL2h N20, miss/异常回源 MySQL) + main 挂载 + tests/test_chat 12 例, 260 绿
|
2026-09-07 02:41:42 +08:00 |
|
GaoYiYuan_0626
|
fb18c04a8a
|
feat: T-07 LangGraph StateGraph 骨架——compose(system 四 Agent 边界 prompt)→llm(DeepSeek/langchain-openai, 无 key 降级)→guard(customer/risk 免责声明+has_disclaimer, 未知类型 fail-safe 最严口径) + chat() 入口 + 图/LLM 单例缓存与测试隔离出口 + tests/test_agent_service 8 例(mock LLM 不依赖外网)
|
2026-09-07 02:34:57 +08:00 |
|
GaoYiYuan_0626
|
3cec034026
|
feat: T-02 审计中间件——http_access 全量访问审计(auth 注入 request.state, 排障路径跳过, 写库失败降级) + 独立 request_id(X-Request-Id 白名单透传贯通, B7 复审 P3-4) + 422/404/405/500 统一错误体(500 由 trace 中间件兜底生成并回写 trace 头, B7 复审 P2-2) + input_guard_log 双写(deps 401/403 留痕, platform 网关跳过 ENUM 口径, 挂账⑧收口) + repo.insert_input_guard_log + tests/test_audit_middleware 12 例, 240 绿
|
2026-09-07 02:32:03 +08:00 |
|
GaoYiYuan_0626
|
36f476f450
|
feat: T-01 JWT 鉴权——auth_service(Auth SDK: HS256/RS256 验签+必填claims显式校验+jti吊销 fail-open) + deps 工厂替换(Bearer 全环境, debug 头降级 dev 兜底) + X-Agent-Type 交叉校验(手册§4.6/§5.4 准入矩阵) + issue_dev_token CLI + redis_gateway exists/set_ex + lifespan 改验 jwt_ready + tests/test_auth_jwt 18 例, 228 绿
|
2026-09-07 02:23:33 +08:00 |
|
GaoYiYuan_0626
|
539d4915d7
|
fix: B9b 复审闭环——P2-1 SOP 交互重灌补 DROP jinrong_agent(reset.ps1 只重建 core+裸 CREATE TABLE 会 1050 中止); P2-2 补做 T-31 名下 P2-8 手工 SQL 对照收口(4 组合真库 SQL 推导与函数判定一致, 登记 SOP 核查单附行); P2-3 SOP 走查范围与 11/11 口径统一(A-6 归 M3/A-8 映射交代); P3: A-4/A-9 COUNT 当日窗+已处置单幂等用例+suitability/check 阻断响应补 G-08 两要素(advice/notice)+记忆文档数字同步; 留痕 scan_all 幂等读后写无锁取舍; 209 绿
|
2026-09-07 01:59:15 +08:00 |
|
GaoYiYuan_0626
|
03d77b9451
|
feat: B9b 演示走查——核查单收口: ①预警类 API 固定 disclaimer(alerts/handle/aml-scan) ②aml/scan 幂等防护(find_recent_aml_alert 同客户当日已有 aml 单不出单+skipped_existing) ⑥集成测试前置断言(A-1/A-3/A-4 清洁检查 fail+重灌提示, A-5 按 trade_id 定位); 演示 SOP 落地(脚本化重灌 MYSQL_PWD 方式); 真服务走查 A-1~A-5/A-7/A-9+核查单①②④⑤ 11/11 PASS(核查单⑥防护现场复现), 208 绿; M2 达成
|
2026-09-07 01:36:44 +08:00 |
|
GaoYiYuan_0626
|
e62fb1d291
|
fix: B9a 复审闭环——P2-1 skipped 分支 has_engine_error_audit 中间态警示(input_summary LIKE)+docstring 局限声明; P2-2 非首笔 trade 幂等用例; P3 顺手: 双脚本连接自检/ImportError 分支/非 dict payload raw 兜底/get_trade_by_id confirmed 过滤/勿并行声明, 8 例 204 绿, warning 路径真库复验后清理; docs 同步复审结论
|
2026-09-07 01:02:12 +08:00 |
|
GaoYiYuan_0626
|
fdf487dc32
|
feat: B9a 演示/运维脚本——subscribe_alerts(risk:pub:alert 订阅演示/连接自检/--duration) + rebuild_alerts(按 trade_id 幂等重放: find_alerts_by_trade payload LIKE 查已入单防重复出单与重复 append, 含 aml/已处置单) + core_ro.get_trade_by_id 只读扩展 + test_demo_scripts 5 例, 201 绿; 真库手工验证(出单→幂等 skip→missing exit1; 订阅端到端 trace 贯通)后现场清理; docs 同步(TODO/MEMORY/FLOW/开发计划)
|
2026-09-07 00:43:25 +08:00 |
|
GaoYiYuan_0626
|
516b1132a3
|
fix: B8 复审 P1-1——conftest except pytest.SkipRequested 引用不存在属性致 skip 路径炸收集(删, Skipped 继承 BaseException 直传, 错密码故障注入验证 skip 不 error); P3 顺手: teardown l3_snapshot 哨兵 + A-1 补 trace 响应头/suitability_log 两环; P2-1 演示库耦合前置断言挂 B9b 核查单⑥
|
2026-09-06 23:52:59 +08:00 |
|
GaoYiYuan_0626
|
c6ad0885d3
|
test: B8 收敛——sqlite 测试 DDL 单一事实源 _ddl.py(10 文件 45 处手写 DDL 清零)+localtime 时区收敛(B5 评审 P3-4, utcnow 边界修复)+测试内遗留建表清理, 196 绿; docs 同步 B8 完成状态
|
2026-09-06 23:37:03 +08:00 |
|
GaoYiYuan_0626
|
e7bd8880e2
|
test: B8 主体——conftest(演示数据校验/幂等代跑/TRD-TEST- teardown)+集成测试 A-1~A-5/A-7/A-9+trace一致性+审计JSON(11例)+_ddl.py 单一事实源+L3 DEL 行为断言(B7复审P2-1)+locks 文案中性化(P3-2), 196 绿
|
2026-09-06 23:27:37 +08:00 |
|
GaoYiYuan_0626
|
fe29b736ea
|
fix: B7 复审 P1-1——dispose_engines 显式 Engine.dispose()(手写单例字典替代 lru_cache, test_db 3 例, 独立评审有条件通过→闭环)
|
2026-09-06 23:06:32 +08:00 |
|
GaoYiYuan_0626
|
6195349dd6
|
feat: main 集成(路由挂载/trace 中间件/lifespan) + B7 挂账收口(引擎工厂/统一错误体/锁公共化/L3 缓存 DEL/死代码清理/处置原子事务/启动期 debug 校验, B7)
|
2026-09-06 20:48:50 +08:00 |
|
GaoYiYuan_0626
|
a78e9d4d31
|
fix: B6 复审收口——测试 Redis 隔离/网关审计口径 platform/死常量清理/回归断言补强
- P2: test_risk_api env 注入 FakePublisher,aml 推送不触真 Redis
- P3: deny/_authz_audit 增 agent_type 参数,simulate 越权审计传 platform
(与网关放行审计同口径);删 HANDLE_RESULTS 死常量(Literal 单处定义)
- P3: 补 start_date/end_date 过滤+分页 422 边界+suitability api 层审计断言;
补 app/service/risk/__init__.py
- 挂账: B7 行新增④项(启动期拒绝/引擎工厂覆盖三实例化点/handle 原子性/
input_guard_log);B9b 行核查单(disclaimer/scan 幂等/Swagger 手测/analyst);
TODO.md T-30/T-31/T-32 进度同步
|
2026-09-06 19:21:15 +08:00 |
|
GaoYiYuan_0626
|
3e40a2bb49
|
fix: B6 评审修复——鉴权审计统一 deny/401 留痕、start_date/end_date 对齐 PRD、simulate 回挂鉴权、异常与审计注入收敛
- P1-1: 403/401 全部经 deps.deny/_authz_audit 留痕(event_type='authz')
- P2-1: GET /alerts 参数名 start_date/end_date 对齐 PRD;page/page_size 用 fastapi.Query
- P2-2: /api/simulate/trade 回挂 get_auth_context(risk_demo 或本人),越权 403+审计
- P2-3: suitability/aml 直调补审计+request_ref 透传
- P3-1: 多角色 fail-closed 口径固化进测试;P3-3/P3-4 core_ro/risk_repo 必传;
P3-5 LookupError→NotFoundError 统一;P3-9 alert_service import 上提
- 测试: test_risk_api 权限矩阵/审计断言/多角色组合/非 dev 拒绝;
test_trade_gateway 客户本人 vs 越权 403(P3-4 模拟 _repo 注入 sqlite)
- 挂账: P3-2/P3-7(响应外壳+disclaimer)→B7;P3-6(scan 幂等)→B9b 前
|
2026-09-06 18:58:48 +08:00 |
|
GaoYiYuan_0626
|
e3fcf28b27
|
feat: 鉴权依赖(debug头/归属断言/越权审计) + 风控4 API(台账/处置/校验/AML扫描, B6)
|
2026-09-06 18:37:53 +08:00 |
|
GaoYiYuan_0626
|
46a1f24870
|
fix: 引擎异常审计降级/审计全量输入输出/TRD-TEST 注入点(B5 评审 P1-1、P2-1~3、P3 批量)
|
2026-09-06 18:17:44 +08:00 |
|
GaoYiYuan_0626
|
2a95b65ec8
|
feat: 模拟交易网关(suitability 阻断→落库→引擎, convert 400, B5)
|
2026-09-06 18:05:44 +08:00 |
|
GaoYiYuan_0626
|
03f8b63780
|
fix: FR-4 payload 上下文补组装/种子名单唯一命中/规则流水升序等(B4 评审 P1-1、P2-2~5、P3×7)
|
2026-09-06 17:40:13 +08:00 |
|
GaoYiYuan_0626
|
e8e5f7e981
|
feat: AML 名单匹配/全量扫描 + 事件引擎编排 + R-05 scoring 占位(B4)
|
2026-09-06 17:19:54 +08:00 |
|
GaoYiYuan_0626
|
65d4618968
|
refactor: L3 risk_score 一期不写保持 NULL,归 R-05 首写(B3 评审 P3-4 用户拍板)
|
2026-09-06 17:04:38 +08:00 |
|