资讯动态

gsd-core 补丁重放验证中的 pristine 基线漂移检测:修复 `verify-reapply-patches` 误报(PR 3767)

发布时间:2026/9/29 2:56:28 来源:尧图企业网站定制
【免费下载链接】gsd-coreGit. Ship. Done - Core项目地址https://gitcode.com/gh_mirrors/ge/gsd-core点击查看免费下载导读GSDGit. Ship. Done在每次更新时会重装受管文件并将此前被用户修改过的文件备份到gsd-local-patches/随后通过/gsd:update --reapply工作流把用户定制内容重新合并回新版本。本文围绕 changeset.changeset/archived/vivid-eagles-climb.md记录的 PR #3767 修复展开当gsd-pristine/目录中的原始基线快照在备份之后被后续 GSD 更新刷新为更新版本时verify-reapply-patches验证器此前会对上游删除的每一行产生虚假的fail_user_lines_missing失败修复后验证器改为读取backup-meta.json中记录的pristine_hashes对磁盘上每个 pristine 文件做 SHA-256 校验检测到哈希不匹配即基线漂移时将该文件以ok_pristine_drift_detected的 ok 状态上报而不是误报失败。读完本文你将掌握该验证器的工作原理、基线漂移的成因、修复的判定逻辑、相关退出码与 JSON 报告结构以及如何在reapply-patches工作流中处理漂移。问题背景更新后重新应用本地补丁的验证链路GSD 更新流程会删除并重装受管文件。为了不丢失用户对工作流、命令或 Agent 文件的本地修改安装器在重装前会做 SHA-256 哈希比较将被修改过的文件保存到gsd-local-patches/同时生成backup-meta.json元数据。更新完成后reapply-patches.md描述的工作流负责将这些备份backup与**原始未修改基线pristine baseline及新安装版本new version**做三方比较从而把用户定制与版本漂移区分开。工作流在第 5 步设置了“Hunk 验证门”Hunk Verification Gate其中 5a 是绑定门运行确定性的验证脚本gsd-core/bin/verify-reapply-patches.cjs逐文件断言用户添加的行通过相对 pristine 基线的真实 diff 计算而非 LLM 的自由文本汇报在合并后的输出中仍然存在。这正是 Bug #2969 的教训——之前第 5 步门检查信任 LLM 每个 hunk 的“verified: yes/no”自由文本而 LLM 即使内容被静默丢弃也会填yes因此修复方案把检查移到确定性脚本中脚本在任何缺失时以非零退出码失败。基线漂移pristine drift如何产生误报验证器计算“用户添加行”的方式是user_added diff(backup, pristine_on_disk)问题在于pristine_on_disk可能来自比备份捕获时更新的 GSD 版本。gsd-pristine/目录在后续某次 GSD 更新时被刷新为新版本的原始快照而backup-meta.json中pristine_hashes记录的是备份时的哈希。此时若仍以磁盘上的新 pristine 作为 diff 基线上游在新旧版本之间删除的行会反过来表现为“用户添加的行却不在合并结果中”于是对每一条被上游删除的行都产生fail_user_lines_missing误报——即使用户的真实定制完好地保留了。测试文件tests/reapply-verify-hunks.test.cjs在“Bug #3657”分组的注释中给出了精确的根因描述pristine_on_disk来自比backup-meta.json.pristine_hashes记录的版本更晚的 GSD 版本备份中存在但被上游更新删除的行被当成“必须存活的用户添加行”从而引发误报。修复方案哈希校验 漂移跳过PR #3767changeset 类型Fixed的修复思路很直接验证器从补丁目录下的backup-meta.json读取pristine_hashes映射readPristineHashes实现文件缺失、不可读或没有pristine_hashes字段时返回空对象调用方把空映射视为“任何文件都没有记录的哈希”而不是错误对每个待验证文件先按path.join(pristineDir, relPath)解析其 pristine 快照若磁盘上的快照存在且是普通文件计算其 SHA-256sha256基于 UTF-8 内容与pristine_hashes中记录的值比对匹配→ 基线有效VALIDATED正常做 diff 验证不匹配→ 判定为漂移DRIFTED跳过该文件并上报ok_pristine_drift_detected而不是用错误基线做 diff 产生误报。源码中resolvePristineBaseline函数gsd-core/bin/verify-reapply-patches.cjs把这一判定集中实现并返回结构化的基线解析结果PRISTINE_RESOLUTION冻结枚举validated记录哈希匹配、unvalidated快照存在但无记录哈希、drifted记录哈希不匹配即 #3657、absent_recorded有记录哈希但任何地方都找不到快照#934/#4145、overbroad无 pristine 目录或路径不是文件。在verifyFile中当基线解析结果为DRIFTED时直接返回if (resolution PRISTINE_RESOLUTION.DRIFTED) { result.reason REASON.OK_PRISTINE_DRIFT_DETECTED; return result; }该文件的状态保持okmissing为空数组reason 为ok_pristine_drift_detectedREASON冻结枚举 中的OK_PRISTINE_DRIFT_DETECTED。配套的哈希优先恢复与 git 历史兜底resolvePristineBaseline中还包含两级额外的恢复逻辑均以pristine_hashes记录值为唯一权威#4145 哈希优先恢复当规范路径path.join(pristineDir, relPath)未命中但记录了哈希时通过findPristineByHash在gsd-pristine/下做确定性的有序扫描寻找 SHA-256 与记录值字节完全相同的文件早期版本写入器可能把快照存到了缺少gsd-core/前缀的路径。模块 src/pristine-baseline.cts 同时被验证器和安装器的保留检查使用避免两个读取方再次漂移。#4135 git 历史兜底当配置目录本身是 git 仓库时通过findPristineInGit只读地执行git log/git show从提交历史中找回 blob 哈希等于记录值的基线每次文件最多遍历 100 个提交子进程 10 秒超时任何失败返回null而不是抛出异常最终退到absent_recorded姿态。无论通过哪条路径恢复恢复出的基线都因哈希校验而天然可信从而解析为VALIDATED。漂移与真实失败如何区分修复不是“见到不匹配就放行”的无差别跳过。测试用成对用例锁定了边界当磁盘 pristine 与记录哈希匹配无漂移时用户添加行确实从合并结果中丢失验证器必须仍报fail_user_lines_missing并以退出码 1 失败——见tests/reapply-verify-hunks.test.cjs的反向测试当磁盘 pristine 与记录哈希不匹配漂移时验证器以退出码 0 通过reason 为ok_pristine_drift_detected——见tests/reapply-verify-hunks.test.cjs。换句话说哈希不匹配门只在“确实无法用正确基线做 diff”时跳过文件只要基线有效真实的丢失内容照样被抓住。这也符合 #2969 确立的总体取向宁可假阳性停机可恢复也不要在内容丢失时静默成功不可恢复。退出码与 JSON 报告漂移的结构化输出验证器默认门模式的退出码约定脚本头部注释退出码含义0每个用户添加行都存在于合并文件中门通过1至少一个文件有缺失行门失败同时触发覆盖率门失败时此码优先2用法 / 结构错误例如 patches 目录缺失、缺少--patches-dir/--config-dir3可选的覆盖率门失败--min-baseline-coverage未达标#4135漂移不是失败每个漂移文件仍是status: okreason: OK_PRISTINE_DRIFT_DETECTED保持向后兼容但 JSON 报告新增了顶层聚合字段供工作流区分漂移与真实失败gsd-core/bin/verify-reapply-patches.cjs{ checked: 2, failures: 0, drifted: 1, drifted_files: [agents/gsd-executor.md], no_baseline: 0, no_baseline_files: [], baseline_covered: 1, results: [ { file: agents/gsd-executor.md, status: ok, missing: [], reason: ok_pristine_drift_detected } ] }测试还验证了聚合的正确性多个文件漂移时drifted与drifted_files正确累计tests/reapply-verify-hunks.test.cjs无漂移时drifted0、drifted_files[]tests/reapply-verify-hunks.test.cjs。工作流中的处理Step 5a 漂移检查与解决路径reapply-patches工作流的 Step 5a 在拿到--json报告后即使VERIFY_STATUS为 0也会解析drifted与drifted_files字段做漂移检查reapply-patches.md如果DRIFTED_COUNT 0停止并向用户报告设置DRIFT_DETECTEDtrue并退出 1不进入 5b 或清理步骤。报告提示解决后再重跑/gsd:update --reapply给出的解决路径有三条(a) 将 pristine 快照重新锚定到backup-meta.json记录的版本(b) 从备份恢复受影响文件并手动重新合并cp {patches_dir}/{file} {installed_path}再重新应用定制(c) 如果接受上游变更把backup-meta.json中每个漂移文件的pristine_hashes条目更新为当前磁盘哈希再重跑以刷新基线重新验证。如果VERIFY_STATUS非零解析 JSON对每个失败文件列出缺失行每文件最多 5 行提示手工重新合并或从备份恢复然后重跑验证未解决前不得进入清理步骤。基线覆盖率标题#4135每次运行都先打印“Baseline coverage: N of M file(s) verified against a pristine baseline”使“12/13 个文件根本没被 diff 验证”的绿色运行与完全验证的运行在展示上无法混淆需要更谨慎的环境可加--min-baseline-coverage 0..1让验证器在覆盖率低于阈值时以退出码 3 失败真实内容失败仍以退出码 1 优先。与分类器--classify的联动漂移判定同样约束着 Step 4 的预合并分类器--classify模式Bug #4136。分类器回答“用户修改是否已被上游采纳Incorporated”的问题而唯一可信的依据是哈希校验过的 pristine 基线只有VALIDATED基线且每个显著用户添加行都逐字出现在新安装版本中才可判定为incorporated。因此漂移#3657 形态→ 分类unknown永不判定为Incorporatedtests/reapply-verify-hunks.test.cjs有记录哈希但快照缺失#934 形态→unknowntests/reapply-verify-hunks.test.cjs无--pristine-dir两方回退→unknowntests/reapply-verify-hunks.test.cjs有快照但无记录哈希旧安装器、未校验基线→unknowntests/reapply-verify-hunks.test.cjs。这是因为“错误的Incorporated会静默退役一个活跃定制比没有Incorporated更糟”。分类器与后合并门共享同一份resolvePristineBaseline语义classifyFile保证二者对“什么算可用基线”永不漂移。运行验证器参数与使用方式验证器是独立的 Node 脚本位于 gsd-core/bin/verify-reapply-patches.cjs在源码仓库中随gsd-core/bin/安装到${GSD_HOME}/gsd-core/bin/因此调用时不需要 gsd-tools 二进制目录。完整参数usage: verify-reapply-patches.cjs --patches-dir path --config-dir path [--pristine-dir path] [--json] [--classify] [--min-baseline-coverage 0..1]参数必填说明--patches-dir是gsd-local-patches/目录--config-dir是运行时配置目录如~/.claude或等效目录--pristine-dir否gsd-pristine/目录缺省时回退到“把每条显著备份行都当作必需”#2969 取向过度宽泛但安全--json否输出 JSON 报告而非人类文本--classify否预合并模式把每个备份文件分类为 incorporated / needs_merge / unknown#4136始终退出 0--min-baseline-coverage否可选严格门#4135低于阈值时退出码 3默认关闭工作流中推荐的调用方式是用 bash 数组拼接参数避免含空格路径被拆开并把 stdout结构化 JSON与 stderr 分离捕获防止 Node 警告污染 JSON 解析示例见reapply-patches.md。关于退出码的语义、JSON 报告的字段形态以及漂移/无基线/覆盖率三类聚合字段均可在脚本头部注释与 tests/reapply-verify-hunks.test.cjs 的断言中找到直接依据工作流对漂移文件的三种解决路径则完整记录在 reapply-patches.md。小结PR #3767 通过“读取backup-meta.json的pristine_hashes 对磁盘 pristine 文件做 SHA-256 校验 哈希不匹配时以ok_pristine_drift_detected跳过”三件事消除了verify-reapply-patches在 pristine 快照被刷新后对每条上游删除行的fail_user_lines_missing误报。该修复与 #2969确定性验证替代自由文本、#934缺失基线告警而非误报、#4135基线覆盖率门、#4136预合并分类、#4145哈希优先恢复共同构成了reapply-patches工作流“宁可假阳性停机、不可静默丢内容”的完整防线任何无法用正确基线做 diff 的情形都只产生结构化、非阻塞的诊断而只要基线有效真实的用户内容丢失就一定会被确定性脚本抓住。赞分享【免费下载链接】gsd-coreGit. Ship. Done - Core项目地址https://gitcode.com/gh_mirrors/ge/gsd-core点击查看免费下载相关推荐gsd-core 补丁重放的三方合并基线gsd-pristine/ 填充机制与 reapply-patches 确定性验证gsd core 补丁重放的三方合并基线gsd pristine/ 填充机制与 reapply patches 确定性验证 本篇技术指南聚焦 gsd core解读 verify-reapply-patches 基线漂移防护通过 pristine_hashes SHA-256 校验消除更新后的误报失败解读 verify reapply patches 基线漂移防护通过 pristine_hashes SHA 256 校验消除更新后的误报失败 .change人工智能AI 应用提示工程开发工具工作流自动化AI Agentgsd-core 补丁重放验证器运行时解析修复/gsd-update --reapply Step 5 确定性验证门的安装路径演进gsd core 补丁重放验证器运行时解析修复/gsd update reapply Step 5 确定性验证门的安装路径演进 导读 本文围绕 gsd cor上一篇ONNX Runtime 排错指南从模型加载报错到推理跑通的完整路径下一篇ONNX Runtime 错误排查完整指南加载失败、GPU 不生效、推理慢、结果不一致快速定位创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑