Kilo 上游合并审查实战:用七份专项报告守住 OpenCode 合并质量
【免费下载链接】kilocodeKilo is the all-in-one agentic engineering platform. Build, ship, and iterate faster with the most popular open source coding agent.项目地址: https://gitcode.com/GitHub_Trending/ki/kilocode
Kilo 是一个基于开源代码代理项目 OpenCode 演进的全栈工程平台,日常通过 script/upstream 下的自动化脚本持续合入上游更新。本文将完整讲解仓库中.kilo/command/review-upstream-merge.md定义的合并审查流程:如何针对一次上游合并 PR 分支并行运行七类专项审查,分别产出KILOCODE_CHANGE_MARKERS.md、INFRASTRUCTURE_CHANGE.md、OPENCODE_MENTIONS.md、UNNECESSARY_MARKERS.md、BROKEN_PIPELINE_CHAINS.md、CONFIG_REGRESSION.md、TESTS.md七份报告,并最终提交报告、以被审查 PR 分支为基线创建草稿 PR。读完本文,你将掌握这套"合并后把关"方法论,以及如何借助find-reset-candidates.ts、reset-to-upstream.ts、fix-kilocode-markers.ts等脚本快速定位问题。
审查流程总览:并行子代理与报告交付
.kilo/command/review-upstream-merge.md定义的核心工作流非常明确:
- 基于待审查 PR 创建分支,确保本地拥有被审查 PR 的全部代码;
- 并行启动多个子代理(subagent),每个子代理负责一类专项审查;
- 每类审查结果保存为仓库根目录下的一个 Markdown 报告文件,供人类阅读——因此"拿不准"时必须记录一条 finding 供人工核验,而不是自行下结论;
- 全部子代理完成后,提交报告文件,并以被审查 PR 分支为 base创建草稿 PR(draft PR)。
报告文件的编写有明确约束:不要包含逐文件的详尽检查清单(exhaustive per-file checklists)。报告应概括审查范围与方法论(scope and methodology),然后只列出 findings(发现的问题)、值得注意的非问题项(notable non-findings)、命令输出与限制说明(limitations)。
这一设计体现了该流程的核心理念:自动化先穷尽检查面,人类只阅读结论与存疑点。每份报告都遵循"宁可多报一条,不可漏报一条"的原则——When in doubt, add a finding。
KILOCODE_CHANGE_MARKERS.md:标记完整性与合理性逐文件核查
kilocode_change标记是 Kilo 标识"相对上游有有意差异"的核心机制。它的语法在 script/upstream/utils/markers.ts 中有完整定义:
- 独立行标记:
// kilocode_change、# kilocode_change、/* kilocode_change ... */(见standalone正则); - 区块标记:
kilocode_change start/kilocode_change end成对出现,用于包裹一段 Kilo 专属代码; - 新文件标记:
kilocode_change - new file,用于标识上游不存在、Kilo 新建的文件; - 标记风格随文件扩展名切换:
.ts/.tsx/.js用//风格,.css用/* */风格,.yml/.yaml/.toml/.sh用#风格(见styles映射); - 文本标记不支持的扩展名(
.json/.jsonc/.lock/.png等)会直接拒绝注入(见unsupported集合); script/upstream/目录本身被排除在标记注释范围之外(见exempt)。
该报告的审查要求是:
- 获取被审查 PR 中变更文件的完整列表;
- 逐文件核查是否意外删除了任何
kilocode_change标记; - 对每个变更文件,同时对比 Kilo 的
main分支与 PR 中的上游合并版本; - 判断每次标记删除、标记移动或 Kilo 专属变更是否合理,并给出评注。
报告只需要提及被检查的文件数量,但只列出有 findings 或需要人工核验的文件,不设 "Files Checked" 完整清单。
这条审查与仓库工具链直接呼应:如果标记被误删或标记区块与上游实际差异不再匹配,可以用 script/upstream/fix-kilocode-markers.ts 重建——它会找到最近一次已合入HEAD的上游 tag(由仓库根目录的.opencode-version文件记录,回退到ls-remote+merge-base --is-ancestor自动发现),读取该上游版本、套用品牌转换、剥离现有标记,再围绕真正存在差异的行重新注入标记。
INFRASTRUCTURE_CHANGE.md:基础设施变更专项审查
该报告审查 PR 是否新增、删除或修改任何基础设施,例如:
- GitHub Actions 与 CI 配置;
- 发布/部署脚本;
- Docker 与构建基础设施;
- 包管理器 / workspace 基础设施;
- 仓库自动化、issue 模板、changelog 自动化;
- 生成的 SDK / 构建自动化。
Kilo 的目标是"合入上游代码但保留自己的基础设施"(We want to merge upstream code but keep our own infrastructure),因此任何与基础设施相关的变更都要标记。拿不准就加 finding,并注明需要人工检查。
从 script/upstream/utils/config.ts 的defaultConfig可以印证这套策略在合并侧的具体落点:
keepOurs列表包含.github/workflows/publish.yml、.github/workflows/close-stale-prs.yml、.github/pull_request_template.md等,注释明确写着 "GitHub workflows - MANUAL REVIEW (can break CI/CD)";skipFiles列表排除了一批上游工作流(deploy.yml、docs-update.yml、opencode.yml、publish-vscode.yml等),以及sst.config.ts、infra/**、packages/console/**、packages/web/**等 Kilo 不发布的托管平台文件;- script/upstream/merge.ts 在合并完成后还会重新生成锁文件(
bun.lock、Cargo.lock等)并运行bun ./script/generate.ts重新生成 OpenAPI spec 与 SDK,保证生成物与合并后的代码同步。
因此基础设施审查的实际对象,正是这些"被 keepOurs 保护、被 skipFiles 移除、或需要再生成"的文件在 PR 中是否出现异常变动。
OPENCODE_MENTIONS.md:面向用户视角的 OpenCode 残留
该报告检查合并后是否在面向用户(user-facing)的位置出现了 OpenCode 而非 Kilo 的提及,或链接到 OpenCode 相关 Web 资产。重点排查面包括:
- UI 字符串(UI strings);
- 文档与帮助文本(docs, help text);
- 展示给用户的包元数据(package metadata);
- URL;
- CLI 输出;
- 配置文档;
- 生成的 SDK / OpenAPI 描述;
- 错误消息(error messages)。
这背后对应合并自动化中的"品牌转换"策略:packageMappings将opencode-ai、@opencode-ai/cli、@opencode-ai/sdk、@opencode-ai/plugin映射为@kilocode/cli、@kilocode/sdk、@kilocode/plugin;i18n 文件通过 script/upstream/transforms/transform-i18n.ts 做字符串替换。OpenCode 品牌残留大多发生在上游新增了未被转换规则覆盖的用户可见字符串时——这正是本报告要拦截的缝隙。
UNNECESSARY_MARKERS.md:无实质差异的多余标记
反向审查:合并后的文件是否还带着kilocode_change标记,但实际内容与上游已无差异(陈旧标记)。审查步骤明确给出了两条命令:
- 先用
script/upstream/find-reset-candidates.ts --dry-run检查 PR 中变更的文件是否有实际与上游一致的重置候选; - 发现候选后,用
script/upstream/reset-to-upstream.ts --dry-run逐文件核验。
script/upstream/find-reset-candidates.ts 的分类逻辑直接支撑这条审查线。它以git diff --name-only <最近合入的上游 commit>..HEAD预筛文件,然后按桶分类:
| 分类桶 | 含义 | 处置 |
|---|---|---|
identical | 本地字节已与转换后上游一致 | 无需处理 |
markers-only | 剥离kilocode_change标记后与上游一致 | 自动重置 |
cosmetic-only | 非标记差异仅剩空白或行序调整(行多重集相同) | 自动重置 |
small-diff | 非标记、非空白差异行数 ≤--review-limit(默认 5) | 自动重置 |
large-diff | 超过阈值 | 跳过 |
upstream-missing | 上游不存在该文件 | 跳过 |
local-missing | 本地缺失 | 跳过 |
binary-diff/binary-identical | 二进制文件 | 跳过 / 无需处理 |
too-large | 上游 blob 超过 256 KB | 跳过 |
其行数统计使用进程内多重集 diff(纯 JS、无子进程),行移动不计为漂移,因此"是否与上游有实质差异"的判断更准确,也避免高并发下 git 子进程的管道阻塞。工具还通过keepOurs/skipFiles配置自动豁免"有意保留或有意移除"的文件,防止批量重置破坏 Kilo 的既定决策。
reset-to-upstream.ts则是单文件版本:找到最近合入的上游 tag,读取该文件,套用与合并自动化相同的品牌转换后写回工作区;上游不存在的文件会被删除;二进制文件按原始字节还原,不做文本转换。所有重置都以未提交的工作区改动形式落地,git diff是最直接的安全网。
BROKEN_PIPELINE_CHAINS.md:端到端调用链断裂排查
这是七份报告中最考验代码理解力的一份。它针对"Kilo 自定义功能需要跨多文件、多层协作,但合并可能移除或改动了中间环节"的场景——代码仍能编译,因此问题可能是静默的。
需要警惕的典型形态(文档原文列举):
- 参数被设置但从未被读取(a parameter that is set but never read);
- 字段被填充但从未被传递(a field that is populated but never passed through);
- 事件被发出但不再被处理(an event that is emitted but no longer handled);
- 配置项被定义但从未传播到使用处(a config option that is defined but never propagated);
- 类型定义在一侧扩展但另一侧未消费(a type definition extended on one side but not consumed on the other)。
审查方法:对 PR 中的每个kilocode_change标记,追踪完整链路——值/行为在哪里引入、需要流经哪里、最终在哪里被消费,逐环验证合并后链路是否仍然完整。需要特别关注:
- 跨多个组件或函数层传递的 props / 参数;
- 写入 state、context 或 storage、在别处被读取的值;
- 发送方与接收方必须匹配的消息类型、事件、IPC handler;
- 在一处定义、在另一处检查的配置或功能开关;
- 一侧扩展、另一侧消费的类型定义。
报告要求同样明确:拿不准就加 finding,编译通过不能证明链路完整(Compiling code is not proof the chain is intact)。这条审查直接对应合并自动化的现实:上游合入会带来接口重构,而kilocode_change区块内的 Kilo 逻辑往往引用着上游同步重构的符号——链路的任何一环断裂都不会报编译错,只会表现为运行时静默失效。
CONFIG_REGESSION.md:opencode 配置回退逻辑回归
该报告专门核查 PR 是否重新引入或恢复了opencode配置文件的回退逻辑,或意外破坏了当前"仅接受.kilo配置"的代码。
背景是:Kilo 已移除对opencode配置目录的回退支持。需要排查的具体情形:
- 任何新增或恢复的读取
opencode配置路径的代码; - 上游在配置发现(config discovery)、加载(loading)或路径解析(path resolution)中新增了我们已剥离的
opencode回退候选; - 多路径搜索中因移除或重排
opencode而破坏.kilo专属查找的变更。
同样遵循"拿不准就加 finding"原则,且配置路径的变更应人工核验。配置系统是 Kilo 与上游分叉的敏感区:一旦上游新增了opencode配置文件的探测分支而 Kilo 未同步剥离,用户的.kilo配置就可能被意外忽略,或者用户旧有的 opencode 配置被错误加载——这属于典型的"合并引入的静默行为回归"。
TESTS.md:Kilo 专属测试删除检查
最后一份报告检查 PR 是否移除了任何Kilo 专属测试。判断依据:
- 测试所在路径包含
kilo或kilocode(例如packages/opencode/test/kilocode目录,它同时出现在kiloDirectories保护名单中); - 测试包含 Kilo 专属断言(assertions);
- 测试使用 Kilo 专属 fixtures;
- 测试中出现
kilocode_change标记。
Kilo 专属测试是 Kilo 自定义行为的"唯一自动化证据",一旦在上游合并中被静默删除,kilocode_change标记标注的定制逻辑就失去了回归保护。这条审查与前面的KILOCODE_CHANGE_MARKERS.md形成互补:一个管"定制代码的标记",一个管"定制代码的测试"。
报告汇总与草稿 PR 交付
全部七份报告完成后,工作流要求:
- 提交所有报告文件(commit the report files);
- 以被审查 PR 分支为 base 创建草稿 PR(create a draft PR with the reviewed PR branch as base)。
结合 script/upstream/merge.ts 的既有约定可以推断,仓库的合并流程本身会生成upstream-merge-report-<version>.md冲突报告、创建backup/<branch>-<timestamp>备份分支与<author>/kilo-opencode-<version>合并分支;审查流程产出的七份报告则是在合并 PR 之上追加的"质量门禁"——人类审阅者拿到这些报告后,可以只针对 findings 逐条核验,而不是重新遍历整个 PR。
附录:审查流程依赖的工具链与源码索引
审查流程中可反复调用的关键工具与文档:
- 合并自动化总览:script/upstream/README.md(脚本清单、转换策略、CLI 选项、回滚方式);
- 合并编排主脚本:script/upstream/merge.ts(8 步流程:环境校验 → 拉取上游 → 冲突报告 → 建分支 → 预合并转换 → 合并 → 自动化解冲突 → 重生成锁文件与 OpenAPI/SDK);
kilocode_change标记语法与解析:script/upstream/utils/markers.ts;- 合并策略配置(keepOurs / skipFiles / kiloDirectories / packageMappings):script/upstream/utils/config.ts;
- 批量重置候选发现:script/upstream/find-reset-candidates.ts;
- 单文件重置:script/upstream/reset-to-upstream.ts;
- 标记重建:script/upstream/fix-kilocode-markers.ts;
- 漂移分类与重置共用逻辑:script/upstream/utils/reset.ts;
- 冲突分析与报告生成:script/upstream/utils/report.ts。
需要说明的是:find-reset-candidates.ts与reset-to-upstream.ts的"最近合入上游版本"判定依赖仓库根目录的.opencode-version单行 tag 文件,它由merge.ts在每次成功合并后写入;若该文件缺失,工具会回退到较慢的自动发现流程。实际运行审查命令前,请确保工作区基于目标 PR 分支、无未提交改动,并已配置好上游 remote。
【免费下载链接】kilocodeKilo is the all-in-one agentic engineering platform. Build, ship, and iterate faster with the most popular open source coding agent.项目地址: https://gitcode.com/GitHub_Trending/ki/kilocode
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考