Files
group_xinghuo_jinrong/docs/项目框架设计/合并注意事项-风控模块并入main.md
T
GaoYiYuan_0626 96dcec931e docs: 合并注意事项手册(给合并执行人) + 文档口径清理
- 新增《合并注意事项-风控模块并入main.md》:面向合并执行人的 AL-09 操作手册——
  基底锁定(本地 main 3995cb4,origin/main 停在 Initial commit 勿用)/20 冲突文件
  指引裁决表/14 个静默并入文件清单(11 代码+3 测试,双套风险与边界防呆)/三处
  硬伤处置(issuer 不统一/STAFF-90001 必保/infer_roles fail-open P1)/合并后
  必测清单(边界测试→中间件顺序→chat 签名→重灌→全量)/演示库重灌提醒
- TODO/MEMORY 口径落账:接口实调验收通过(2026-09-07 AI 代验:三接口契约+三
  鉴权边界 401/403/403 零偏差,前端未 init 口径为后端接口验证);合并 main
  移交合并执行人;模块侧开放项=actor_id 透传评估+前端入口归属拍板;修正
  AL-09 旧口径(9 文件→实测 20 文件);删重复待办行
2026-09-07 20:52:58 +08:00

8.5 KiB
Raw Blame History

合并注意事项 · 风控 Agent 模块并入 main(AL-09 执行手册)

版本:2026-09-07 v1.0(基于 risk-control-agent 分支 HEAD cfbd056 实测编制) 用途:给合并执行人——风控模块开发方已交付(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. 三处已知硬伤的处置

  1. JWT issuer 不一致:模块 .internal vs main .dev(audience 相同)。自治方案下不统一:模块链路走自己的 issuer,跨层身份转换走 S2 适配器 app/api/auth_adapter.py(已预制、未接线,合并即用),避免全量 token 重签。
  2. main DEFAULT_ROLES_BY_ACTOR 无 STAFF-90001(风控演示账号):scripts/core/02-seed-base.sql 手工融合时必保 STAFF-90001,并补 STAFF-31001/31002(C5 的 risk_manager 演示账号)。
  3. main infer_roles fail-open(app/gateway/jwt_service.py:89 附近:未知 actor 默认 ["analyst"],含 sql:execute:readonly):模块链路不调用它(模块为 fail-closed),但该代码随静默文件并入仓库后就是宿主侧 P1 安全缺陷。建议合并时一并修复(未知 actor 应拒绝),或至少登记为 main 侧待修事项,绝不给宿主路由接线。

5. 合并后必测清单(顺序执行,全过才算合并完成)

  1. python -m pytest tests/test_module_boundary.py -q(系统 Python 3.13.14)——边界 21 例全绿,冲突解决没伤模块。
  2. 中间件顺序实测:起 uvicorn 打任意 API,断言 http_access 审计行带非空 trace_id。main 的 add_middleware(TraceMiddleware) 与模块的 @app.middleware 叠加后,若 trace 落在 audit 内层,全部审计 trace_id 会变空(合规红线 P-05)。
  3. chat 链路端到端冒烟:app/api/chat.py 依赖 agent_service,而 main 版签名是 run_chat(ctx, msg, cust)、模块版是 chat(...),不兼容。按边界标注 §4 #4 用适配层对接后,必须实调一次 /api/chat 确认不炸(单测可能因 mock 掩盖签名错配)。
  4. 按《演示SOP-风控模块.md》§2 重灌两库(合并后 02-seed-base 是融合版,库结构须重建)。
  5. 全量 python -m pytest -q——基线参考:模块侧交付时 482 绿 + main 侧 3 个 wave0 测试文件;有红灯先分清是环境残留(演示库未重灌)还是冲突解决引入。
  6. tests/test_auth_adapter.py 11 例(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 = 追加需求)