Commit Graph
3 Commits
Author SHA1 Message Date
lzf_0626 468ae0bd47 fix(admin): 激活意图不再归档同 Agent 的其他意图(风控 4 意图曾只剩 1 条生效)
两个相关的缺陷,都属于**静默失效**型。

1. `admin_service._transition_intent_config`(真正的 bug)

   激活一个意图时按 `agent_type` 过滤旧 active 版本并归档,但唯一键是生成列
   `active_key = concat(agent_type, ':', intent_code)` —— 同一 `agent_type` 下
   **不同意图码本就允许并存**。于是激活 `general` 会把
   `risk_overview` / `risk_search` / `risk_evidence` 一并归档:风控运行期只剩 1 条
   active 意图,问"查看当前风险概览"被分到 `general`(confidence 0.5),
   而**没有任何报错**。该函数自己的 docstring 写的正是正确行为,实现与它不符。

2. `tools/publish_risk_agent_config.py`(使脚本无法自愈)

   按 `intent_code` 单键建 dict 收集现有意图,而列表**按 id 倒序**返回且同一意图码
   有多个版本,于是**旧版本覆盖新版本**;取到 v1 后再"版本 +1"算出的正是已被占用的
   v2,创建必然 409 IDEMPOTENCY_CONFLICT。现象是 4 条意图全部"创建失败"而库里
   其实都有,`tools/seed_demo_data.py` 第 7 步因此必然失败。

修复后实测:

- 库里 4 个风控意图全部 active;
- 问"查看当前风险概览" → `intent=risk_overview`、`confidence=1.0000`
  (修复前为 `general` / 0.5);
- `tools/seed_demo_data.py` 10/10 步完成、退出码 0(修复前第 7 步退出码 1)。

回归测试:`test_activating_one_intent_does_not_archive_sibling_intents`。
已确认把修复回退后该用例**确实失败**(`['beta'] != ['alpha', 'beta']`),
不是永远通过的空测试 —— 原有用例盖不住这个缺陷,因为它建的第二个意图始终停在 draft、
从未激活过。

门禁:ruff 通过;mypy 250 文件 0 错;unit+contract 1381 passed / 0 failed;
integration 104 passed;e2e 冒烟 40/40。
2026-09-13 22:08:04 +08:00
zhangshy a122f7afba 修复风控预警记录查询与准备脚本 2026-09-11 16:40:15 +08:00
lzf_0626 39c7ab51f4 feat(risk): 发布风控配置并补齐缺失的 RBAC 权限
修 docs/25 里的 P0:风控的意图配置与工具白名单一条都没发布,而白名单是失败关闭的,
导致任何工具调用都被拒。按组员交付的《20-Agent工具白名单与意图配置》补齐。

1. tools/publish_risk_agent_config.py:导入 4 条 risk 意图配置(id=61-64,active)与
   4 条 agent_tools 白名单(risk_overview / risk_search / risk_evidence / general)。
   发布版本 id=188 active,并且**继承了现有 5 条配置项**——config_release 是整版本替换
   语义,不继承会把客服的 4 条白名单和示例 Agent 的 fund_query_demo:fund_quote 静默清空。

2. tools/grant_risk_alert_read_permission.py:补齐 risk:alert:read 权限。
   实测发现这条权限在 sys_permission 里**根本不存在**,连 risk_operator 角色也没有,
   所以任何身份调用风控工具都会拿到"缺少工具权限"。交付文档第 116 行正把这一项列为
   接入前置条件。权限匹配实际用 permission_code 全串(identity_repository.py:25-37),
   resource/action 只是元数据(照 fund:quote:read 的拆法);data_scope 取 all,因为
   risk_query_service.py:194、risk_analysis_service.py:126 等按 context.data_scope == "all"
   决定是否放行全量数据。只授权 risk_operator,不动 admin(交付文档只要求前者)。

验证(以 9002 risk_operator 身份实测):
- "查看当前风险概览" → status=succeeded、意图 risk_overview、工具真实返回数据
- "查询高风险预警"   → status=succeeded、意图 risk_search
修复前两者均为 failed + ForbiddenAgentError: 缺少工具权限。
2026-09-11 12:18:34 +08:00