主题
a-cdm 二开整改 · 细节方案(可执行)
来源:二开实现合理性审计 + 交叉报告,实代码勘察于 2026-05-18。 范围:仅整改方案与安全闸,不含代码改动。落地走 a-cdm MR 流程(红线:禁直接
maincommit)。 说明:ba_report在harness/deerflow/pipelines/下,是 a-cdm 自有代码(上游无此目录),清理它不违反「vendored 原生只读」红线。
整改 1【紧急】锁死 vendored 鉴权/checkpointer 不变量(防 cherry-pick 静默越权)
问题(实据)
deer-flow/backend/aegra.json:14→"auth.path": "./packages/harness/deerflow/auth/acdm_auth.py:auth"deer-flow/backend/langgraph.json:19→"auth.path": "./packages/harness/deerflow/auth/acdm_auth.py:auth"deer-flow/backend/langgraph.json:16→"checkpointer.path": "./packages/harness/deerflow/agents/checkpointer/async_provider.py:make_checkpointer"
上游同名文件的 auth.path 指向 ./app/gateway/langgraph_auth.py:auth。手工 cherry-pick 上游对这两个 JSON 的演进时,一旦带回上游 auth.path,owner_sub 隔离立即失效 → 跨用户数据越权,且无任何信号。当前无 CI 防护。
方案:加一个秒级 CI 断言 job(每个 MR 必跑,无路径过滤以防绕过)
① 新增脚本 deer-flow/backend/scripts/check_vendored_invariants.py(纯 stdlib,无依赖):
python
#!/usr/bin/env python3
"""校验 vendored deer-flow 的 a-cdm 定制不变量未被 cherry-pick 静默回退。
失败即阻断合并。"""
import json, sys, pathlib
BACKEND = pathlib.Path(__file__).resolve().parents[1] # deer-flow/backend
INVARIANTS = [
("aegra.json", ("auth", "path"), "./packages/harness/deerflow/auth/acdm_auth.py:auth"),
("langgraph.json", ("auth", "path"), "./packages/harness/deerflow/auth/acdm_auth.py:auth"),
("langgraph.json", ("checkpointer", "path"), "./packages/harness/deerflow/agents/checkpointer/async_provider.py:make_checkpointer"),
]
fail = []
for fname, keypath, expect in INVARIANTS:
p = BACKEND / fname
try:
node = json.loads(p.read_text(encoding="utf-8"))
for k in keypath: node = node[k]
except (OSError, KeyError, json.JSONDecodeError) as e:
fail.append(f"{fname}:{'.'.join(keypath)} 读取失败 ({e})"); continue
if node != expect:
fail.append(f"{fname}:{'.'.join(keypath)} = {node!r},期望 {expect!r} —— 疑似把 a-cdm 鉴权/checkpointer 回退到上游!")
if fail:
print("❌ vendored 定制不变量被破坏:"); [print(" -", m) for m in fail]; sys.exit(1)
print("✅ vendored 定制不变量校验通过")② 新增 CI job(.gitlab-ci.yml,照 deerflow-backend:import-check 风格,但极轻、无 venv、不加 changes: 过滤——让任何 cherry-pick 都躲不过):
yaml
deerflow-backend:vendored-invariants:
image: $BASE_IMAGE
stage: lint
timeout: 2m
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event" || $CI_COMMIT_BRANCH'
script:
- python3 deer-flow/backend/scripts/check_vendored_invariants.py③ 人类标记 新增 deer-flow/backend/VENDORED-INVARIANTS.md:一句话写明「aegra.json/langgraph.json 的 auth/checkpointer 路径为 a-cdm 定制,cherry-pick 上游此二文件务必保留;由 CI job deerflow-backend:vendored-invariants 强制」。JSON 不支持注释,故用旁置文档 + CI 双保险。
成本:job <5s;收益:把"最接近踩雷的越权风险"从靠人记变成机器强制。优先级最高,先做这个。
整改 2【中】清理 BA 报告遗留死代码(唯一的造轮子残留)
问题(实据)
ba_report 旧执行路径(含审计点名的 agent_runner.py 裸 create_react_agent,丢 18 middleware)已于 2026-05-17 整体 deprecated,但死代码 + 死测试未清,污染认知与 import 面。
- 活路径(保留):
aegra_graphs/ba_report.py:12→from deerflow.pipelines.ba_report import make_step_runner。即 live =step_runner.py+step_state.py+nodes/prompt_builder.py+ 两个__init__.py。 - 已 deprecated(候选删除,8 个):
agent_runner.py、skill_runner.py、pipeline.py、state.py、nodes/confirm.py、nodes/knowledge_sync.py、nodes/polish.py、nodes/base.py。 - 死测试:
tests/unit/test_ba_agent_integration.py(只测 deprecatedagent_runner)、tests/test_ba_report_pipeline_env.py(测 deprecatedpipeline/state/nodes)。tests/test_step_runner.py测 livestep_runner→ 保留。
删前必过的安全闸(顺序执行,任一不过则停)
- 读
ba_report/__init__.py与nodes/__init__.py:确认它们不在模块加载时 import 任何 deprecated 模块。若__init__顶层from .pipeline / .agent_runner / ...引了死模块,直接删会炸 live 的from deerflow.pipelines.ba_report import make_step_runner。→ 必要时先把__init__的死 import 摘掉。 - 核验 live 不依赖死模块:
step_runner.py、step_state.py、nodes/prompt_builder.py不得 importpipeline/state/agent_runner/skill_runner/nodes.{confirm,knowledge_sync,polish,base}。特别注意nodes/base.py:它标了 deprecated,但若 liveprompt_builder.pyimport 了nodes.base,则base.py不可删(存在标注矛盾,以 live 实依赖为准)。 - 删除 8 个 deprecated 模块 + 2 个死测试;若
test_ba_report_pipeline_env.py内含对 live 行为的断言,则改指向step_runner而非整体删。 - 跑 CI:
deerflow-backend:import-check(importapp.gateway.app)+ ba_report 相关单测全绿,且aegra_graphs/ba_report.py可正常graph()。
价值
消除审计认定的唯一实质造轮子残留;缩小 import 面与维护认知负担。非紧急,但因团队主线已收敛回 live step_runner,这是收尾。
整改 3【高】上游 199 提交安全 fix 补丁清单
由独立审计任务专项产出 → docs/code-wiki/上游安全fix-backport清单.md(P0 必补 / P1 评估 / P2 可不跟 + 每月甄别 runbook)。本文不重复,以那份为准。
执行优先级
- 整改 1(紧急,秒级 CI,堵越权雷)→ 立即
- 整改 3 的 P0 项(见 backport 清单)→ 高
- 整改 1③ + 整改 2(文档标记 + 死代码清理)→ 中,可合并进一个清理 MR
- 均走 a-cdm MR 流程,勿直接
maincommit