---
summary: "scripts/pr 的规范包装器信任、进程锁和具体化依赖项"
read_when:
- "更改 PR 包装器监督、锁定、依赖项具体化或工具根选择"
title: "PR 包装工具"
---
# PR 包装工具
- 受监督的 PR 操作通过继承的进程配置禁用自动 Git 维护,保留存储库设置。显式维护在完成之前仍必须加入。 PR 源获取还会禁用自动维护:获取一个 PR 不会授权在存储库范围内修剪不相关的工作树元数据。
- `scripts/pr` 根据 PR 跨链接工作树序列化审查、准备和合并操作; `scripts/pr gc` 跳过活动锁或不确定锁。其子命令分类表是规范的包装器信任边界:不匹配的本地包装器可能仅运行带有 `--dev-wrapper` 或 `OPENCLAW_PR_DEV_WRAPPER=1` 的分类 `advisory` 子命令;分类 `landing` 子命令始终需要 canonical/origin-main 包装器代码。当签出是干净的并且字节与获取的 `refs/remotes/origin/main` 相同时,包装器与 origin/main(过时的基础或包装器编辑分支)不同的工作树会大声替换规范签出的包装器;仅当没有可用的锚匹配包装器时,它才会拒绝。成功的命令返回是受信任的同步完成合约:每个 PR- 状态变异子级都必须在返回之前加入,并且此类工作绝不能守护进程或显式转义操作组和锁定通知 FD。干净退出时释放需要领导者的完成标记;仅持有通知管道的逃逸后代会产生响亮的警告释放而不是保留(#124583)。失败的命令会在其显式预副作用验证标记保持活动状态时自动释放,或者在副作用之后自行退出(状态 1-127,无信号),并且完整的排空观察到其组已死亡并且每个通知管道持有者都消失了;只留下 fd 关闭逃逸者残留,一个干净的出口已经接受。干扰、挥之不去的小组工作、仍然开放的管道以及控制器丢失都将被锁定,因为无法反驳分离的孩子。验证不存在任何子工具后,使用报告的exact-OID `scripts/pr lock-recover` 命令。切勿手动绕过或删除这些引用。
- Materialized 包装器在移交之前将选择性第三方依赖项固定到其已安装的真实包目录,而不是可变的顶级 `node_modules` 别名。锚定的 `pr-lib/materialize-dependencies.mjs` 拥有该集合;孩子也会在交接时完成,因为年长的父母可能会钉更少的包裹。重新进入会保留已固定的安装。对于早于该助手的锚点,父级针对提取的清单执行相同的设置; #149585 之前没有清单的锚点保留其原始的四个工具依赖项。缺少包目录或与锚定包清单不同的版本在锁定获取之前失败;在干净的可信主检出中恢复冻结的依赖项并重试。不要在物化期间链接整个工作区依赖关系树或安装到规范结帐中;只有下面明确选择的单独工具根可能会刷新。保持已解析的包安装完整,直到受监督的命令完成;固定路径不会复制或冻结包内容。 `test/scripts/eager-import-closure.test.ts` 根据复制的源和固定的包导出检查存档的急切导入;当源关闭发生变化时,保持 `pr-lib/wrapper-components.txt` 为最新状态。在执行提取之前运行 `pnpm test test/scripts/eager-import-closure.test.ts -t "PR wrapper inventory"` 进行源端库存检查。它命名了缺少的急切运行时导入和过时的已删除路径;现有的 shell 启动的助手、工作人员和数据资产仍然是显式的库存根。
`OPENCLAW_PR_TOOLING_ROOT` 选择对物化包装器的第三方依赖项的同一存储库进行完整检出;否则,规范签出的 Git 配置中的 `openclaw.pr.toolingRoot` 应用,然后是规范签出本身。当其签出没有 `node_modules` 时,独立的 CI 观察程序和 Crabbox 入口点会解决来自同一工具根的缺失第三方软件包,并具有相同的显式根身份检查和确切的软件包版本。他们从不链接安装或从另一个结账解析工作区包。包装器仍然根据现有信任锚选择和验证代码。安装的软件包版本必须与锚清单完全匹配。如果不匹配,则在重新检查之前,将获取、快进并与 `pnpm install --frozen-lockfile` 一起安装一次显式选择的、单独的、干净的 `main` 签出。获取输出流并将其快进到 stderr,无需 diffstat,而不是被捕获,因此无论输出大小如何,刷新后的根数千次提交都会刷新。陈旧的脏根或非主根无法刷新;稀疏且不相关的根总是被拒绝。规范结帐永远不会刷新。保持所选安装不变,直到命令完成。此设置适用于依赖物化切换;就地包装器保留其签出的依赖上下文,并且包装器选择保持不变。
配置失败会将经过编辑的错误图打印到 stderr。保留该输出:包装器不会创建失败收据。租约心跳响应错误包括验证、续订或确认阶段、失败触发器、请求计数器、已用时间以及剩余响应、操作和租约预算。这些是在故障更改心跳状态之前进行的观察(`0` 启动、`1` 就绪、`2` 关闭、`3` 丢失)。奇怪的更新进度计数器意味着更新占用了工作人员;已完成的请求计数器可以解释为什么仅消极响应预算没有更早失败。两者均不延长租赁或运营预算。诊断不会更改超时或恢复行为,并且成功的重试不会确定早期故障的原因。
## 重新运行失败的 CI 测试
`pnpm test:ci-failed ` 使用经过验证的 `gh` CLI 读取失败的 CI 作业并打印聚焦的本地校样。 `--repo` 默认为 `openclaw/openclaw`。 PR 目标为其当前头 SHA 选择最新已完成或正在进行的 `ci.yml` 运行;运行目标选择确切的运行。
该命令提取每个失败或超时作业的日志一次,最多有四个正在运行的请求,同时处理失败的作业,并跳过 CI 控制作业。它显示每个作业的 existing/new/unknown 之前的类以及已删除重复的 Vitest 文件和测试名称。新的和未知的故障首先出现;除非设置了 `--include-pre-existing`,否则先前存在的故障会单独出现并从重新运行命令中排除。分类使用与 PR 故障表相同的所有者。
该命令打印一个 `pnpm test ` 选择。当一个文件最多包含三个安全引用的测试名称时,它会添加一个测试名称过滤器;否则它将重新运行整个选定的文件。显示的测试名称过滤器使用单引号,并嵌入转义撇号,以便安全复制到 zsh 或 bash 中;执行参数保持不带引号。非 Vitest 失败显示其失败的步骤名称以及“没有 Vitest 重新运行;读取日志”以及作业日志 URL。 `--run` 使用本地运行器的默认工作器行为执行选定的测试命令。 `--json` 发出 `{ run, failures: [{ job, class, files: [{ file, tests }], failedSteps, url, reason }], command }`。
`--run` 设置 `OPENCLAW_NODE_TEST_PLAN_CONTINUE_ON_FAILURE=1`,因此普通测试失败不会隐藏后来选择的文件;使用与手动 `pnpm test` 命令相同的选择加入,而基础设施故障仍然会停止调度。
PR CI失败后,运行`pnpm test:ci-failed `,修复新的故障并调查未知的故障,然后运行`pnpm test:ci-failed --run`,直到本地通过并推送一次。 PR CI 为修复后的磁头提供了广泛的证据。切勿运行完整的本地套件或使用 `gh run rerun` 追逐绿色。已有故障遵循[故障表登陆规则](https://github.com/openclaw/openclaw/blob/main/.agents/skills/openclaw-pr-maintainer/references/landing.md#red-main-and-inherited-failures);该表提供证据,而不是自动放弃登机口。