Skip to content

a-cdm 二开整改 · 细节方案(可执行)

来源:二开实现合理性审计 + 交叉报告,实代码勘察于 2026-05-18。 范围:仅整改方案与安全闸,不含代码改动。落地走 a-cdm MR 流程(红线:禁直接 main commit)。 说明:ba_reportharness/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.pycreate_react_agent,丢 18 middleware)已于 2026-05-17 整体 deprecated,但死代码 + 死测试未清,污染认知与 import 面。

  • 活路径(保留):aegra_graphs/ba_report.py:12from 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.pyskill_runner.pypipeline.pystate.pynodes/confirm.pynodes/knowledge_sync.pynodes/polish.pynodes/base.py
  • 死测试:tests/unit/test_ba_agent_integration.py(只测 deprecated agent_runner)、tests/test_ba_report_pipeline_env.py(测 deprecated pipeline/state/nodes)。tests/test_step_runner.py 测 live step_runner保留

删前必过的安全闸(顺序执行,任一不过则停)

  1. ba_report/__init__.pynodes/__init__.py:确认它们不在模块加载时 import 任何 deprecated 模块。若 __init__ 顶层 from .pipeline / .agent_runner / ... 引了死模块,直接删会炸 live 的 from deerflow.pipelines.ba_report import make_step_runner。→ 必要时先把 __init__ 的死 import 摘掉。
  2. 核验 live 不依赖死模块:step_runner.pystep_state.pynodes/prompt_builder.py 不得 import pipeline/state/agent_runner/skill_runner/nodes.{confirm,knowledge_sync,polish,base}特别注意 nodes/base.py:它标了 deprecated,但若 live prompt_builder.py import 了 nodes.base,则 base.py 不可删(存在标注矛盾,以 live 实依赖为准)。
  3. 删除 8 个 deprecated 模块 + 2 个死测试;若 test_ba_report_pipeline_env.py 内含对 live 行为的断言,则改指向 step_runner 而非整体删。
  4. 跑 CI:deerflow-backend:import-check(import app.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. 整改 1(紧急,秒级 CI,堵越权雷)→ 立即
  2. 整改 3 的 P0 项(见 backport 清单)→ 高
  3. 整改 1③ + 整改 2(文档标记 + 死代码清理)→ 中,可合并进一个清理 MR
  4. 均走 a-cdm MR 流程,勿直接 main commit

公司内部参考 · 由 claude-wiki-gen 基于源码自动生成的二次分析