- Updated `RiskListAccess` and `ThresholdWriteAccess` to enforce access control in the risk repository and threshold repository, ensuring only authorized roles can perform sensitive operations. - Introduced new methods in `RiskRepository` for counting pending alerts and listing alerts with access checks, improving data security and compliance. - Enhanced the `chat.py` and `deps.py` files to integrate compliance roles into the risk management matrix, allowing for more granular access control. - Updated documentation to reflect the new testing baseline of 825 passed tests, indicating improved stability and functionality across the application. This update significantly strengthens the risk management capabilities, ensuring robust access control and compliance with organizational policies.
9.6 KiB
合并注意事项 · 风控 Agent 模块并入 main(AL-09 执行手册)
版本:2026-09-07 v1.0(基于
risk-control-agent分支 HEADcfbd056实测编制)
执行状态:AL-09 已完成(2026-09-08,工作分支merger) — 下文 §0~§7 为合并前手册,保留作审计参照;执行摘要见下节。
✅ AL-09 执行记录(2026-09-08)
| 项 | 结果 |
|---|---|
| 工作分支 | merger(已 merge 风控模块 + 宿主 Wave 0) |
| JWT 统一 | /api/auth/login → auth_service.issue_dev_token;gateway/jwt_service issuer/audience 读 settings |
| 模块 chat 恢复 | chat.py / agent_service.py / memory_service.py(含 sessions/stream) |
| S2 接缝 | auth_adapter.module_auth_from_host() 已接线 |
| trace 中间件 | ApiError / AppError / PermissionDenied / RequestValidationError / StarletteHTTPException re-raise;仅未捕获 → 500 |
| 边界测试 | tests/test_module_boundary.py 全绿(宿主 D 类文件排除跨层扫描) |
| 测试基线 | python -m pytest → 530 passed, 0 skipped(AL-09 当时快照)· 当前 merger 全量见 docs/memory/MEMORY.md §0(825) |
架构结论: 宿主 gateway/ 与模块 deps.py 双栈并存;对外 token 统一;模块 API 禁止 import app/gateway/。
用途:给合并执行人——风控模块开发方已交付(482 用例全绿 + 接口实调验收通过),本文档是该模块并入 main 的全部注意事项。逐项过完再动手,可避开已知的全部坑。 裁决依据(冲突逐文件怎么改):《风控Agent模块边界与合并接缝标注.md》§4 裁决表——本文档讲"操作顺序与坑",与它配合读。
0. 前置状态(合并前先核对)
| 项 | 状态 |
|---|---|
| 开发分支 | risk-control-agent,领先本地 main 85 提交 / 落后 0 |
| 最新交付 | HEAD cfbd056;tag risk-m1~m4(m4 = C4~C6 完成,仅本地) |
| 测试基线 | 482 passed 0 failed(系统 Python 3.13.14,sqlite + 真 MySQL 集成) |
| 接口验收 | 2026-09-07 实调通过:suitability/check 阻断+放行、simulate/trade 阻断、三条鉴权边界(401/403/403),错误体统一结构 |
| 分叉点 | 1ddd44a(09-05 旧骨架);main 侧在分叉后有 5 个提交,最关键的是 3995cb4 Wave 0 平行实现 |
1. 【最高风险】合并基底必须用本地 main(3995cb4),不要用 origin/main
实测:origin/main 仍停在 Initial commit 53701db,Wave 0(3995cb4)从未推送到远端。
- 若执行
git merge origin/main或git pull(默认合 origin/main):因 Initial commit 是分支祖先,会**"干净成功"零冲突,但完全不引入 Wave 0 的任何代码**——20 个冲突文件一个不报、13 类双套风险全部缺席,看似合并完成实则漏合并,且事后极难发现。 - 正确操作:
git merge main(本地 main,校验git rev-parse main=3995cb4)。 - 附带动作:合并前建议先让 main 侧负责人把 Wave 0 推上远端(
git push origin main),否则本次合并结果推到risk-control-agent远端后,远端历史里依然没有 Wave 0 的原初提交,后续审计/回溯会困惑。 - 本机 git 2.55 有 ref 异常史(fetch/update-ref 成功但读回旧值),一律用 commit hash 校验,不依赖 ref 名。
2. 冲突解决:20 个文件,逐个按裁决表,禁止批量 ours/theirs
git merge-tree --write-tree --name-only risk-control-agent main 实测 20 个冲突文件:
AGENTS.md app/main.py app/utils/exceptions.py
app/api/chat.py app/model/suitability.py app/utils/response.py
app/config/settings.py app/repository/core_ro.py docs/memory/ENVIRONMENT.md
app/gateway/__init__.py app/service/agent_service.py docs/memory/FLOW.md
scripts/core/02-seed-base.sql app/service/memory_service.py docs/memory/FRAMEWORK.md
tests/conftest.py docs/memory/ITERATION.md
docs/memory/MEMORY.md
docs/memory/REQUIREMENTS.md
docs/memory/TODO.md
- 逐文件裁决规则见《边界标注》§4(概要:core_ro / model-suitability / conftest / 02-seed-base / memory 六件套 以模块版为准并吸收 main 新增实质内容;chat / main / settings / agent_service / memory_service / exceptions / response 以 main 为主,模块侧功能经 4 接缝回挂)。
- 禁止
git checkout --ours/--theirs批量处理:两侧不是"新旧关系"而是"平行实现",批量必丢功能。
3. 静默并入文件:14 个(git 不报冲突、直接进仓库,双套风险)
代码 11 个(main 的 Wave 0 平行实现,与模块同名能力并存):
app/api/auth.py # main 的鉴权路由(模块无此路由,无冲突)
app/gateway/auth_deps.py # ┐
app/gateway/jwt_service.py # │ main 的鉴权四件套(vs 模块 app/service/auth_service.py + app/api/deps.py)
app/gateway/rbac.py # │
app/gateway/ownership.py # ┘
app/middleware/__init__.py # ┐
app/middleware/trace.py # ┘ main 的 trace 中间件(vs 模块 app/utils/trace.py + audit_middleware)
app/repository/agent_repository.py # ┐
app/repository/audit_repository.py # │ main 的三仓储(vs 模块 session_repository / risk_repository)
app/repository/advisor_rel_repository.py # ┘
app/utils/input_guard.py # main 的输入防护(vs 模块 app/service/input_guard.py)
测试 3 个:tests/test_wave0_auth.py / test_wave0_input_guard.py / test_wave0_trace.py(main 侧自带测试,合并后一并入库运行)。
另有 docs/来自客户的项目资料/ 约 20 个资料文件静默并入(纯文档,无风险,正常收下)。
双套并存是拍板过的架构决策(风控模块自治,模块内自带鉴权/防护/trace;与宿主耦合只走 4 接缝 S1 挂载点 / S2 AuthContext / S3 settings / S4 引擎工厂)。约束:模块代码绝不允许 import 上述 main 实现——tests/test_module_boundary.py 已用 21 例断言锁死(禁止跨层 import app.gateway.* / app.config.database / app.middleware.* / app.utils.input_guard / app.model.schemas)。合并后该测试必须全绿,红了说明冲突解决时误伤了边界。
4. 三处已知硬伤的处置
- JWT issuer 不一致:模块
.internalvs main.dev(audience 相同)。自治方案下不统一:模块链路走自己的 issuer,跨层身份转换走 S2 适配器app/api/auth_adapter.py(已预制、未接线,合并即用),避免全量 token 重签。 - main
DEFAULT_ROLES_BY_ACTOR无 STAFF-90001(风控演示账号):scripts/core/02-seed-base.sql手工融合时必保 STAFF-90001,并补 STAFF-31001/31002(C5 的 risk_manager 演示账号)。 - main
infer_rolesfail-open(app/gateway/jwt_service.py:89附近:未知 actor 默认["analyst"],含sql:execute:readonly):模块链路不调用它(模块为 fail-closed),但该代码随静默文件并入仓库后就是宿主侧 P1 安全缺陷。建议合并时一并修复(未知 actor 应拒绝),或至少登记为 main 侧待修事项,绝不给宿主路由接线。
5. 合并后必测清单(顺序执行,全过才算合并完成)
python -m pytest tests/test_module_boundary.py -q(系统 Python 3.13.14)——边界 21 例全绿,冲突解决没伤模块。- 中间件顺序实测:起 uvicorn 打任意 API,断言
http_access审计行带非空trace_id。main 的add_middleware(TraceMiddleware)与模块的@app.middleware叠加后,若 trace 落在 audit 内层,全部审计 trace_id 会变空(合规红线 P-05)。 - chat 链路端到端冒烟:
app/api/chat.py依赖agent_service,而 main 版签名是run_chat(ctx, msg, cust)、模块版是chat(...),不兼容。按边界标注 §4 #4 用适配层对接后,必须实调一次/api/chat确认不炸(单测可能因 mock 掩盖签名错配)。 - 按《演示SOP-风控模块.md》§2 重灌两库(合并后 02-seed-base 是融合版,库结构须重建)。
- 全量
python -m pytest -q——基线参考:模块侧交付时 482 绿 + main 侧 3 个 wave0 测试文件;有红灯先分清是环境残留(演示库未重灌)还是冲突解决引入。 tests/test_auth_adapter.py11 例(S2 适配器若已接线)。
6. 演示库重灌特别提醒(易误判为 bug)
- 种子客户 33 人中仅 6 人(1001/1002/1003/3001/4001/9527)会被
prepare_risk_demo.sql刷新为未过期,其余 27 人 expires_at 是 2026 年的绝对旧日期。只跑reset.ps1不跑prepare_risk_demo.sql→ 462 组合适性检查全部返回 risk_expired(约 82%),这是种子设计不是缺陷,但极易误判——重灌务必两步都跑。 reset.ps1是交互式(要输密码),不能无人值守直跑。
7. 交付基线快照(合并出问题时回滚参照)
- 分支交付态:
risk-control-agent@cfbd056(482 绿) - 功能里程碑:
risk-m1(阶段A)→risk-m2(阶段B 事件线)→risk-m3(阶段C 对话线)→risk-m4(C4~C6 追加需求) - 冲突裁决权威:《风控Agent模块边界与合并接缝标注.md》;模块需求权威:
docs/PRD/PRD-风控监测Agent.md(v1.1,§4A = 追加需求)