首页
/ oh-my-openagent 纯结构重构 PR 的三层验证策略:以 delegate-task 常量拆分为例

oh-my-openagent 纯结构重构 PR 的三层验证策略:以 delegate-task 常量拆分为例

2026-09-04 19:10:42作者:谭伦延

本文以 oh-my-openagent 仓库中一份真实的 PR 验证策略文档为主体,完整还原“本地预检 → CI 门禁 → 多智能体评审 → 外部 Bot”的四步验证链路,并以 delegate-task/constants.ts 的模块化拆分为具体案例,讲解每个门禁要检查什么、失败时如何定位,以及“纯重构不改变运行时行为”这一声明如何被逐项证明。

背景:为什么“纯重构”也需要专门的验证策略

该策略文档(verification-strategy.md)服务于一次结构性重构:将 oh-my-openagent 中 654 行、承载 4 种职责的 constants.ts 拆分为聚焦单一职责的小模块。其执行计划(execution-plan.md)给出的拆分方案是:

新文件 职责 约 LOC
default-categories.ts DEFAULT_CATEGORIESCATEGORY_DESCRIPTIONS ~40
category-prompt-appends.ts 8 个 *_CATEGORY_PROMPT_APPEND 常量 + CATEGORY_PROMPT_APPENDS 记录 ~300(提示词文本,豁免 LOC 限制)
plan-agent-prompt.ts Plan agent 系统提示词常量 + 构造函数 ~250(提示词文本,豁免)
plan-agent-names.ts PLAN_AGENT_NAMESisPlanAgentPLAN_FAMILY_NAMESisPlanFamily ~30
constants.ts(更新) 从 4 个新文件 re-export,保持向后兼容 ~5

向后兼容通过两条路径保证:constants.ts re-export 全部 4 个新文件的内容;index.ts 已有的 export * from "./constants" 保持不变。从当前仓库源码看,该策略的向后兼容思路已体现在 index.ts 中:

export * from "./constants"

而当前的 constants.ts 顶部已采用“re-export barrel”形态,把 BUILTIN_CATEGORY_REQUIRES_MODELCATEGORY_DESCRIPTIONSCATEGORY_PROMPT_APPENDSCATEGORY_PROMPT_APPEND_RESOLVERSDEFAULT_CATEGORIES 统一从 ./builtin-categories 转出。从源码结构看,实际落地的文件命名(如 builtin-categories.ts)与计划稿中的 4 文件方案存在演进差异,但“原路径继续可用、新增模块只负责实现”的兼容策略是一致的。

纯重构的验证核心难题在于:“无行为变更”是一个声明,不是事实。策略文档因此把验证拆成逐层递进的门禁,每层只回答一个问题:编译是否通过?现有消费者是否被破坏?结构是否满足拆分目标?外部视角有无遗漏?

第一层:Pre-Gate 本地验证(Push 之前)

策略要求在推送前于 worktree 内跑完与 CI 相同的关键检查,外加一条专门针对 re-export 完整性的动态导出检查:

# In worktree
bun run typecheck
bun test src/tools/delegate-task/
bun run build

# Verify re-exports are complete
bun -e "import * as c from './src/tools/delegate-task/constants'; console.log(Object.keys(c).sort().join('\n'))"

其中 bun -e 一行是本次策略最有价值的细节:它把“barrel 是否完整”从主观判断变成了可核对的导出清单比对。文档给出的期望导出清单为(原文标注 "13 total",实际列出 19 个符号——这个计数偏差本身就是评审时 QA 代理应抓住的小坑):

  • ARTISTRY_CATEGORY_PROMPT_APPEND
  • CATEGORY_DESCRIPTIONS
  • CATEGORY_PROMPT_APPENDS
  • DEFAULT_CATEGORIES
  • DEEP_CATEGORY_PROMPT_APPEND
  • PLAN_AGENT_NAMES
  • PLAN_AGENT_SYSTEM_PREPEND_STATIC_AFTER_SKILLS
  • PLAN_AGENT_SYSTEM_PREPEND_STATIC_BEFORE_SKILLS
  • PLAN_FAMILY_NAMES
  • QUICK_CATEGORY_PROMPT_APPEND
  • ULTRABRAIN_CATEGORY_PROMPT_APPEND
  • UNSPECIFIED_HIGH_CATEGORY_PROMPT_APPEND
  • UNSPECIFIED_LOW_CATEGORY_PROMPT_APPEND
  • VISUAL_CATEGORY_PROMPT_APPEND
  • WRITING_CATEGORY_PROMPT_APPEND
  • buildPlanAgentSkillsSection
  • buildPlanAgentSystemPrepend
  • isPlanAgent
  • isPlanFamily

对照当前仓库可以验证这条检查为何必要:tools.test.ts 从 barrel 一次性导入 DEFAULT_CATEGORIESCATEGORY_DESCRIPTIONSisPlanAgentPLAN_AGENT_NAMESisPlanFamilyPLAN_FAMILY_NAMES 等符号——任何遗漏的 re-export 都会直接让这份测试在 import 阶段失败。而 buildPlanAgentSystemPrepend 这类函数在当前源码中仍是 barrel 的核心成员(constants.ts),它把“技能注入前的静态提示词 + 动态生成的类别/技能表格 + 技能注入后的静态提示词”三段拼成 plan agent 的完整系统提示词。

Gate A:CI(阻塞门禁)

CI 是唯一的硬阻塞门禁,用一条命令订阅其结果:

gh pr checks --watch

策略文档依据 ci.yml 列出预期通过的 4 个 CI 项:

  1. Tests (split):mock 密集型隔离测试 + 批量 bun test
  2. Typecheckbun run typecheck(即 tsc --noEmit
  3. Buildbun run build
  4. Schema auto-commit:仅在检测到 schema 变更时触发

文档对失败点的预判非常明确:没有预期失败点,因为这是纯 re-export 重构、无运行时行为变化。同时它预先写好了两类失败模式的标准排查路径,避免门禁失败后临时猜测:

  • Typecheck 报错 → 缺少 re-export 或引入 import 环。修复位置在新模块内,amend 提交后重推。
  • 测试报错 → 典型根因是 tools.test.ts 这类“从 ./constants 导入全部符号”的测试文件,要求 re-export barrel 必须完整。

这个预判与仓库现状互相印证:当前 constants.ts 顶部仅 3 行 import 类型/工具函数后即进入 re-export 块,没有任何指向新模块的循环引用——“无 import 环”这一 CI 风险点被结构本身消解。

Gate B:review-work 五代理并行评审

CI 通过后调用 /review-work,由 5 个并行代理从不同视角验证同一份改动。这份策略文档对每个代理的具体核查项都给出了可执行的断言,而非泛泛的“检查一下代码”:

  1. Oracle(目标/约束视角):验证“向后兼容”声明成立;逐一确认 13 条外部导入路径仍能解析。执行计划中为此附了完整的外部导入映射表(src/agents/atlas/prompt-section-builder.tssrc/agents/builtin-agents.tssrc/plugin/available-categories.tssrc/plugin-handlers/category-config-resolver.tssrc/shared/merge-categories.ts 及其测试均从 ../tools/delegate-task/constants 导入),使核查项可以逐条打勾。
  2. Oracle(代码质量视角):验证每文件单一职责、LOC 上限、无 catch-all 模块违规——这正是拆分 constants.ts 的原始动机,评审需要确认拆分结果确实满足目标。
  3. Oracle(安全视角):确认该重构无安全影响(提示词常量与名称判断逻辑不涉及权限边界)。
  4. QA(实机执行视角):实际运行 bun test src/tools/delegate-task/ 并确认全绿,而非仅阅读 diff。
  5. Context miner(上下文视角):确认没有相关未关闭的 issue/PR 与本次拆分冲突。

预期结论(Expected verdict)为 Pass:纯结构重构、无行为变化,五个视角均无实质风险。

Gate C:Cubic 外部 Bot 审查

第三个门禁是等待外部审查机器人 cubic-dev-ai[bot] 在 PR 上发布 “No issues found”。策略文档对此门禁的预期管理很务实:

  • 若 Cubic 提出问题,大概率是误报——典型场景是对“新增文件数量多”这一客观事实的机械告警(本次拆分恰好新增 4 个文件);
  • 处理方式是在 PR 评论中解释,而非盲目按 Bot 意见回改代码。

仓库自带的 PR 生命周期技能 work-with-pr 对 Cubic 门禁有更细的信号判别规范:批准信号是最新 Cubic 评论同时含 **No issues found** 与置信度 **5/5**;唯一允许“跳过”该门禁的情形是配额耗尽(Bot 发布配额/用量提示,或有界等待内始终未出现新评审),且必须显式记录为 SKIPPED 而非静默略过。发现问题从来不是跳过的理由。

Merge 策略与一处值得注意的差异

策略文档给出的收尾动作是:

gh pr merge --squash --delete-branch
git worktree remove ../omo-wt/refactor-delegate-task-constants

即 squash merge 将 2 个原子提交(“提取类别默认值与提示词常量”、“提取 plan agent 提示词与名称”)折叠为 dev 分支上的 1 个干净提交,随后移除任务专用 worktree 并清理。

需要注意一个仓库规则层面的差异:oh-my-openagent 自身的 work-with-pr 技能 明确写道“This repository requires merge commits. Never use --squash or --rebase”,并给出默认命令 gh pr merge "$PR_NUMBER" --merge --auto --delete-branch(自动合并,门禁全绿后由 GitHub 落地)。因此,若在当前仓库实际执行该验证策略,合并方式应服从仓库的 merge commit 规则,而策略文档中“两个原子提交折叠为一个”的叙述可替换为“保留原子提交历史、以 merge commit 并入 dev”。worktree 清理、失败时保留 worktree 供人工检查等配套纪律则不受影响。

小结:可复用的验证策略骨架

把这份文档抽象出来,它对“纯结构重构类 PR”给出了一个可直接复用的四段式骨架:

  1. 本地预检:typecheck + 定向测试 + build 之外,加一条 bun -e 动态导出比对,把 barrel 完整性从主观判断变成清单核对;
  2. CI 门禁:事先列出预期通过的 CI 项与最可能的两类失败模式,让失败后的定位成本趋近于零;
  3. 多代理评审:每个评审代理绑定一条可执行断言(导入路径数、LOC 上限、实机测试命令、冲突 issue 扫描),避免“看起来没问题”式的空洞评审;
  4. 外部 Bot:预先区分真问题与误报,并把“配额耗尽→SKIPPED”与“发现问题→必须修复”两种终态严格分开。

这套策略的价值不在于命令本身,而在于它把“验证”从 PR 合并前的被动等待,变成了一组在 push 之前就已写死、可逐项核对的断言——对任何“无行为变更”声明型改动,这都是比多跑一轮测试更有说服力的证明方式。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.12 K
2.72 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
527
590
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
904
1.82 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
854
1.34 K
docsdocs
暂无描述
Markdown
889
5.78 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.52 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.33 K
1.45 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
981
502
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
540
384