关于 run-parity
run-parity 是用于评估拉取请求基线与分支版本的仓库技能,可在相同语料上运行 React Doctor 并比较诊断结果。它生成经过验证且带来源记录的证据,支持诊断和性能比较。
主要功能
- 01配对评估基线与分支版本
- 02验证 NDJSON 产物
- 03检查基线缓存来源
- 04选择增量规则范围
- 05比较诊断与性能
适用场景
- 01检查拉取请求中的诊断变化
- 02比较限定规则范围的候选结果
- 03测量顺序扫描性能
- 04对多个拉取请求重复运行评估
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ millionco/ react-doctor --skill run-parity安装后在 Claude Code 中输入/run-parity确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
agents/openai.yamlscripts/baseline-cache-provenance.mjsbaseline-cache-provenance.test.mjsbuild-parity-index.mjscompare-parity-indexes.mjscompare-parity-performance.mjscompare-parity-performance.test.mjscompare-parity.mjscompare-parity.test.mjsfind-impacted-rules.mjsfind-impacted-rules.test.mjsparity-index.test.mjsvalidate-parity-input.jqvalidate-parity-input.test.mjsverify-matrix-artifact.mjsverify-matrix-artifact.test.mjs详细介绍
运行拉取请求对比
针对同一仓库提交运行拉取请求的 base 和 head。写入确定性的换行分隔 JSON(NDJSON)产物并进行比较。
准备运行
需要提供 VERCEL_OIDC_TOKEN 或 VERCEL_TOKEN,以及 VERCEL_TEAM_ID(或 VERCEL_ORG_ID)和 VERCEL_PROJECT_ID;还需要已通过身份验证的 gh,以及已推送的拉取请求 head。未经许可,不要推送更改。在此仓库中使用 ni 和 nr。
解析拉取请求:
gh pr view <pr-number-or-url> \
--json number,url,baseRefOid,headRefOid,headRepository,headRepositoryOwner
根据拉取请求 URL 确定 base 仓库。根据 headRepositoryOwner.login 和 headRepository.name 确定 head 仓库。使用返回的提交哈希,而不是分支名称。
创建 tmp/parity-pr-<number>-<head-short-sha>,并在运行后保留该目录。评估前运行 ni。
运行两个修订版本
从 packages/evals 运行。默认语料库包含排名最高的 2,000 个仓库,初始并发数为 200。为避免 Vercel Sandbox 过载,沙箱创建数量上限设为 20。评估器会清理资源,并以并发数 50、然后 10 重试失败的项目。
nr --silent eval \
--react-doctor-repository <base-repository-url> \
--react-doctor-ref <baseRefOid> \
> <absolute-run-directory>/baseline.ndjson
nr --silent eval \
--repositories <absolute-run-directory>/baseline.ndjson \
--react-doctor-repository <head-repository-url> \
--react-doctor-ref <headRefOid> \
> <absolute-run-directory>/candidate.ndjson
只有在 React Doctor 提交、语料库清单哈希、评估器架构和规则集/配置哈希完全一致时,才能缓存成功的基线。复用缓存的基线前,仍必须通过流式验证器。拉取请求可以共享此不可变基线,但绝不能合并各自的候选 head 或差异。
评估器会为每条记录标注准确的检测器提交、修订版本专属的规则/配置哈希,以及评估器源代码哈希。绝不要缓存较早的、未经标注的运行结果。通过常规输入验证器后,创建相邻的来源信息文件:
node .agents/skills/run-parity/scripts/baseline-cache-provenance.mjs create \
--baseline <baseline.ndjson> \
--corpus-manifest <corpus-manifest.json> \
--base-commit <full-base-commit> \
--repository <react-doctor-repository-url> \
--evaluator-source-hash <packages-evals-source-hash> \
--config-contract revision-local-rule-config-v1 \
--rule-set-hash <stamped-full-ruleset-hash>
在 packages/evals 中运行 nr --silent source-hash,获取预期的评估器哈希。每次复用前,都用 verify 运行同一命令。验证会流式读取原始 NDJSON 字节,要求完整基线的 ruleKeys: [],检查每条记录的生成方,并独立要求清单中精确固定的语料库项目集与清单一致。任何不匹配都会视为缓存未命中。
命中缓存时,不要将 base 放入 Vercel Sandbox:针对已验证的缓存基线运行上述常规的仅候选项命令,不要传入任何 --paired-* 选项。
缓存未命中时,或需要运行完整与限定范围的影子对比时,在同一个 Vercel 沙箱中评估两个检测器:
nr --silent eval \
--repositories <corpus-manifest-or-validated-input> \
--paired-baseline-output <absolute-new-baseline-path> \
--paired-base-react-doctor-repository <base-repository-url> \
--paired-base-react-doctor-ref <base-or-full-shadow-commit> \
--paired-base-rule <treatment-plugin/rule> \
--react-doctor-repository <treatment-repository-url> \
--react-doctor-ref <treatment-commit> \
--paired-execution sequential \
--rule <treatment-plugin/rule> \
> <absolute-run-directory>/candidate.ndjson
基线输出路径会以独占方式创建,绝不会覆盖现有产物。成对沙箱会将每个目标仓库只拉取一次,存入同一个对象存储,然后在彼此隔离的 base/treatment 目标工作树中运行扫描;检测器安装、配置文件和报告路径也各自隔离。只有双方都成功后才会输出一对项目结果,因此重试不会在任一输出中留下部分成功的项目对。成对写入使用单写入队列;若任一写入端失败,则回滚基线。任何非零退出的成对评估运行都会导致两个输出产物均无效且不可复用;应丢弃这些产物,不要将其交给比较器或存入缓存。
性能对比时,使用相同的 --paired-base-rule 和 --rule 值;进行完整规则对比时,则两者都省略。完整规则与限定范围的影子运行仍是有效的诊断证据,但不能作为性能证据。
配对沙箱请求 4 个 CPU 核心、8 GiB 内存和 20 GiB 磁盘。--paired-execution auto 是默认值,仅当沙箱至少有 4 个 CPU 核心时才会并行运行扫描。对于受控的顺序基准测试及下方的性能比较,请使用 --paired-execution sequential。只有在仅用于诊断、且会丢弃计时证据的奇偶一致性检查中,才使用 auto 或 parallel。配对评估默认使用 50 个沙箱,低于观测到的 4 核沙箱容量上限;仅当 Vercel Sandbox 分配支持不同的容量配置时,才传入 --concurrency。
两种模式共用相同的硬性尝试截止时间,并精确清理评估标签。每次配对扫描的命令上限为 5 分钟,避免少数卡住的沙箱耗尽整个尝试预算;普通评估器保留现有超时设置。
对于具有相同不可变基线和语料库的多个拉取请求,请使用可重复的矩阵处理描述符。首先获取准确的语料库标识和评估器哈希:
cd packages/evals
nr --silent matrix-corpus-identity <absolute-corpus-manifest-path>
nr --silent source-hash
每个描述符都是不可变的 JSON 文件,且必须采用以下精确格式:
{
"schemaVersion": 1,
"id": "pr-1234",
"artifactDirectory": "/absolute/path/pr-1234",
"reactDoctorRepository": "https://github.com/millionco/react-doctor.git",
"reactDoctorCommit": "<40-character-head-commit>",
"impactManifestPath": "/absolute/path/pr-1234-impact.json",
"impactManifestSha256": "<sha256>",
"group": {
"baseReactDoctorRepository": "https://github.com/millionco/react-doctor.git",
"baseReactDoctorCommit": "<40-character-base-commit>",
"baseFullRuleSetHash": "<full-base-rule-set-sha256>",
"baseArtifactPath": "/absolute/path/base-union-scoped.ndjson",
"baselineOutputPath": "/absolute/cache/full-baseline.ndjson",
"baselineProvenancePath": "/absolute/cache/full-baseline.provenance.json",
"corpusManifestPath": "/absolute/path/corpus.json",
"corpusManifestSha256": "<matrix-corpus-identity manifestSha256>",
"corpusProjectSetSha256": "<matrix-corpus-identity projectSetSha256>",
"evaluatorSourceHash": "<source-hash>",
"configContract": "revision-local-rule-config-v1",
"scanContract": "react-doctor-json-full-v1",
"reportContract": "react-doctor-complete-report-v1",
"projectRootPolicy": "manifest-root-dir-v1"
}
}
所引用的影响清单必须是 find-impacted-rules.mjs 的精确输出;其哈希、基线提交、头部提交、模式和候选规则键都会重新验证。Vercel Sandbox 启动前,矩阵运行器会获取固定的基线和头部提交,重新运行当前生成器,并要求清单输出逐字节一致。每个重复描述符都必须具有完全相同的分组对象、唯一且安全的 ID,以及不同的制品目录。
nr --silent eval \
--matrix-treatment /absolute/path/pr-1234.json \
--matrix-treatment /absolute/path/pr-1235.json \
--matrix-wave-width 2
通过验证的完整缓存命中可避免将基线交给 Vercel Sandbox。否则,只要有任一处理需要完整奇偶一致性检查,矩阵就会扫描一个完整基线;若无,则扫描一个已排序的增量规则范围并集。一个目标裸克隆为隔离的工作区提供数据。默认的双通道运行批次在每个沙箱中使用 4 个 CPU 核心和 8 GiB 内存;运行器会在 400 个 CPU 核心的限制下计算并发数,并将沙箱创建数量保持为 20。重试会保留成功的 (lane, project) 结果,并仅重试失败的工作,并发数依次为 50、10、2。每个处理都会以原子方式发布,内容包括候选 NDJSON、精确的语料库清单、描述符、影响清单、规则、哈希、计数和来源信息。基线缺失时,会将成功的处理标记为受阻,而不是据此独立作出合并决定。
将每个已发布的处理目录视为自包含证据。比较前,请验证其状态、规范的相对路径、生成方绑定、字节长度、哈希、精确记录数、完整报告以及语料库项目元组。切勿跟随来源信息中的共享缓存或范围基线源路径:
node .agents/skills/run-parity/scripts/verify-matrix-artifact.mjs \
<treatment-artifact-directory>
# Incremental treatment
node .agents/skills/run-parity/scripts/compare-parity.mjs \
--rules <treatment-artifact-directory>/rules.json \
<treatment-artifact-directory>/base.ndjson \
<treatment-artifact-directory>/candidate.ndjson \
> <treatment-artifact-directory>/parity.json
# Full treatment
node .agents/skills/run-parity/scripts/compare-parity.mjs \
<treatment-artifact-directory>/base.ndjson \
<treatment-artifact-directory>/candidate.ndjson \
> <treatment-artifact-directory>/parity.json
对于仅修改规则的拉取请求,请在运行候选项目前构建保守的影响清单:
node .agents/skills/run-parity/scripts/find-impacted-rules.mjs \
<repository-root> <base-ref> <head-ref> <impact.json>
仅当清单报告 "mode": "incremental" 时才使用增量模式。其 candidateRuleKeys 已包含已知的诊断交互闭包。请将这些键原样写入规则 JSON,并将每个键作为可重复的候选参数传入:
nr --silent eval \
--repositories <validated-baseline-or-corpus-manifest> \
--react-doctor-repository <head-repository-url> \
--react-doctor-ref <headRefOid> \
--rule <plugin/rule> \
> <absolute-run-directory>/candidate-scoped.ndjson
评估器会将所有未选中的、仅限当前修订版本的规则标记为 off。当范围内不包含安全扫描规则时,评估器还会跳过整个树范围的扫描。安全扫描规则变更、全局运行器/配置/报告/注册表变更、规则 ID 被移除或重命名、运行时边无法解析、解析失败以及其他不确定的依赖关系表面,都将回退到完整奇偶一致性检查。未先经过映射规则边界便访问宿主模块的插件实用工具,也会回退到完整奇偶一致性检查。没有运行时规则影响的清单使用完整模式;切勿构造空的增量规则范围。
每次运行都会保留其硬性外部超时。对于评估预算较短的情况,重试预留的总时间上限为尝试开始时剩余时间的 25%,至少留出 75% 用于实际工作,避免快照构建耗尽首次尝试的全部截止时间。 基线记录已解析的仓库哈希。将基线用作候选语料库,可避免默认分支在不同运行之间发生变化。
在运行候选项之前,以流式方式验证每条基线记录。这样无需将 NDJSON 语料库载入内存,即可拒绝未固定版本的仓库、评估错误、格式错误的报告和未完成的项目:
jq -e -n \
-f <repository-root>/.agents/skills/run-parity/scripts/validate-parity-input.jq \
<absolute-run-directory>/baseline.ndjson >/dev/null
如果基线命令以非零状态退出,或检查失败,请检查失败记录并停止。候选运行会拒绝未固定版本的评估 NDJSON。
要求两个命令都以零状态退出,并报告 100% 完成。否则,请报告失败的项目并停止比较。
比较结果
从仓库根目录运行:
node .agents/skills/run-parity/scripts/compare-parity.mjs \
<run-directory>/baseline.ndjson \
<run-directory>/candidate.ndjson \
> <run-directory>/parity.json
node .agents/skills/run-parity/scripts/compare-parity-performance.mjs \
<run-directory>/baseline.ndjson \
<run-directory>/candidate.ndjson \
> <run-directory>/performance-parity.json
解读退出代码:
0:诊断结果一致1:比较成功,但诊断结果有变化2:输入不完整或无效
评估器会重试不完整的报告,而不是将其记录为成功。比较器会再次验证两个输入;如果任一侧包含评估错误、格式错误的报告、缺少完成标记或不完整的旧版报告,就会以无效输入状态退出。它会将旧版和 v3 报告架构中的诊断规范化为相对于报告的标识,因此重叠的工作区扫描不会虚增计数,架构升级也不会被视为诊断变化。
比较器会以流式方式读取两个 NDJSON 输入,将基线记录暂存到系统临时目录,并逐步写入大型详细信息数组。它只会暂时保留已更改的诊断条目,以便确定性排序,因此请确保临时磁盘和输出容量与运行规模相称。
性能比较器要求报告完整的 v3 报告、项目覆盖范围、规则范围、配置约定和评估器源代码完全一致。仅在配对的顺序评估中运行,以确保基线和候选项使用同一 Vercel Sandbox 沙箱,且不会争用 CPU。退出代码 0 表示耗时处于固定的容噪阈值范围内,1 表示项目级或汇总级出现显著退化,2 表示证据无效。它会忽略基线扫描耗时少于一秒的项目;只有当单个项目的耗时至少增加 50%,且多出两秒时,才会标记该项目;只有在至少有十个符合条件的项目、比率达到 20%,且汇总延迟增加十秒时,才会标记全语料库退化。请检查输出的测量结果,再归因原因。矩阵通道会并发运行,且仅作为诊断证据;不要将矩阵产物传给性能比较器。
退出代码为 1 时,请先检查受影响的源代码位置,再对变化进行分类。
进行限定范围的比较时,请将完整基线筛选为相同规则和始终启用的不变项范围:
node .agents/skills/run-parity/scripts/compare-parity.mjs \
--rules <rules.json> \
<baseline.ndjson> \
<candidate-scoped.ndjson> \
> <run-directory>/parity-scoped.json
限定范围比较器会拒绝任意的范围外候选诊断,要求项目、框架和已分析文件的覆盖范围完全一致,保留重复项数量,并比较每个语义诊断字段,包括规范化后的主要路径和相关路径。
如果同一基线或候选项会被比较多次,请构建精简的 Merkle 索引:
node .agents/skills/run-parity/scripts/build-parity-index.mjs \
--rules <rules.json> <baseline.ndjson> \
> <baseline.index.json>
node .agents/skills/run-parity/scripts/build-parity-index.mjs \
--candidate --rules <rules.json> <candidate-scoped.ndjson> \
> <candidate.index.json>
node .agents/skills/run-parity/scripts/compare-parity-indexes.mjs \
<baseline.index.json> <candidate.index.json> \
> <index-diff.json>
如果整次运行的根哈希相同,则立即停止。若根哈希不同,则沿规则哈希继续检查,再检查项目分桶。空项目分桶和规则分桶会明确记录,范围或覆盖范围元数据漂移时会失败关闭。
在增量一致性历史足以成为必需门禁之前,请在完全相同的提交、语料库和并发策略下运行一次完整候选评估,并要求其经过规则筛选的输出与限定范围候选结果完全一致。报告实测墙钟时间和项目延迟;不要根据样本推算加速效果。
从仓库根目录验证比较器更改:
node --test .agents/skills/run-parity/scripts/compare-parity.test.mjs
node --test .agents/skills/run-parity/scripts/compare-parity-performance.test.mjs
node --test .agents/skills/run-parity/scripts/find-impacted-rules.test.mjs
node --test .agents/skills/run-parity/scripts/parity-index.test.mjs
node --test .agents/skills/run-parity/scripts/validate-parity-input.test.mjs
报告结果
报告拉取请求 URL、提交哈希、已比较和已跳过的项目数、诊断总数、新增和删除数量、变化最大的规则,以及产物路径。