远程测试证明
Agent 的远程证明策略¶
Agent 会话默认在本地运行受信任的开发测试、变更门禁(changed gates)、typecheck/lint 和构建,仅在被触及的契约(contract)要求时才扩大范围。切勿在本地执行不受信任的仓库工具。当环境本身就是证明的一部分时,使用 Crabbox:例如 clean-machine、install/package、Docker、E2E、live、桌面或跨平台工作,或者当操作者明确请求远程证明时。不要仅仅将 Crabbox 用作通用计算卸载。配置好的 Testbox 工作流会注入(hydrate)凭据,因此不受信任的贡献者或 fork 代码必须改用 secretless fork CI(无凭据 fork CI),或经过清洗(sanitized)的 AWS Crabbox 直连方式。
不要为预期的工作提前预热。当第一条对环境敏感的命令就绪时,再惰性(lazily)获取后端;对后续远程命令复用返回的 tbx_... id;每次运行都同步当前 checkout,并在交接(handoff)前将其停止。
在分配(allocation)时,包装器(wrapper)会在 .crabbox/testbox-leases/ 下记录调用方任务、物理 checkout、HEAD、base、依赖输入以及 Testbox 准备指纹(preparation fingerprint)。复用要求这些输入匹配,包括在委托(delegation)前的最后一刻。仅修改源代码时,只要 HEAD 和准备输入保持不变,就可以复用该 box;每次运行都会同步 checkout。较旧或缺失的收据(receipt)要求停止当前持有的 lease,并通过包装器重新分配一个新的 lease。OPENCLAWB_TESTBOX_ALLOW_STALE 无法绕过这些检查。所有 provider 都要求 Crabbox 0.67.0 或更新版本。
Testbox 工作流会注册一个独立的、一次性的 checkout 用于原生同步。已注入(hydrated)的执行工作区(execution workspace)保持在原始绝对路径,因此原生 Git 清理和 rsync 无法删除那里的依赖、构建输出或被忽略的运行时文件。包装器在该执行工作区中应用并校验源代码 bundle,运行其冻结的依赖安装,并在执行 payload 之前再次检查源代码和 Git 身份。安装输出进入 stderr;安装或校验失败会中止 payload。它绝不会从调用方恢复运行时,也不会更改所选定的 rsync 二进制文件。
工作区准备发生变化时,需要一个新的 lease。缺失或重叠的执行工作区绑定会中止 payload;请停止该 lease 并预热一个新的。请使用 OpenClaw 包装器进行证明:直接的原生 Blacksmith 命令面向的是传输 checkout(transport checkout),后者刻意不包含已注入的运行时。
带 --artifact-glob 或 --require-artifact 的 Testbox 请求会从准备好的执行工作区收集产物。无论 payload 目录如何变化或正常失败退出,收集都会锚定在那里;现有的取消及与信号相关的产物扣留行为保持不变。
包装器使用随附的 Crabbox 插件,在 provider 发现、源代码同步或 lease 操作之前更新缺失或过时的 CLI 二进制文件。每条命令都使用当前受支持的 CLI 契约;对于 artifacts、providers 或 sync-plan --json,没有单独的版本要求。
Testbox 运行和 POSIX 远程变更门禁会将源代码对照固定的 base 冻结成 Git bundle。 对于未跟踪文件,选择逻辑使用 Crabbox 的同步策略,以及 Git 的 repository、info 和有效全局排除规则(包括仓库本地覆盖)。已跟踪的忽略文件(tracked ignored files)和已暂存的忽略新增文件(staged ignored additions)仍属于源代码;显式的隐私排除规则若与必需的已跟踪源代码冲突,则会在上传前停止运行。
命令会绑定 bundle 摘要(digest)和原始源代码树。在运行 payload 之前,接收方会应用删除操作,并恢复文件字节、符号链接目标字节和 Git 可执行模式,然后直接校验文件系统。Git 文本过滤器不会对此快照做规范化处理。缺失、过期或不匹配的 bundle 会失败关闭(fail closed)。生产者声明的删除项也必须不存在,即使远程索引已丢失这些删除项。删除操作使用与源代码选择相同的隐私策略;未知的被忽略运行时数据会被保留。接收方出现意外的非忽略文件时,会停止运行,而不是删除这些文件。校验收据会单独报告原始源代码修订版本(与合成的传输提交分开);远程 HEAD 标识的是该校验过的传输树,变更门禁会将其与固定的 base 进行比较。原始字节差异可能会保守地选择额外的变更路径。Git 路径名必须是 UTF-8;符号链接目标保持原始字节。符号链接形式的仓库 Crabbox 配置或忽略文件,以及被隐私排除的运行时配置,会在上传前被拒绝,而不会改变对其的信任或隐私处理方式。
本地测试命令 是常规的受信任开发路径。确保证明范围与被触及的契约相称。
对于不受信任的证明,使用 --provider aws 惰性预热。每次运行都必须设置 CRABBOX_ENV_ALLOW=CI,传入 --provider aws --no-hydrate,并在安装依赖或运行测试之前使用全新的临时远程 HOME。使用专门为该不受信任源代码新预热的 lease;绝不要复用受信任或此前已注入的 lease。从干净的受信任 main checkout 启动一个已安装的受信任 Crabbox 二进制文件,并仅通过 --fresh-pr 获取远程 PR;绝不要在本地执行不受信任 checkout 中的包装器或配置。取消设置 CRABBOX_AWS_INSTANCE_PROFILE,除非解析出的 aws.instanceProfile 为空,否则一律失败关闭。在任何安装/测试之前,使用受信任的绝对路径工具要求 IMDSv2 token,证明 IAM 凭据端点返回 404,并验证远程 git rev-parse HEAD 等于经完整审查的 PR head SHA。将该 lease 绑定到该 SHA,并在 head 变化时停止/重新预热。从干净的 main 中随 --fresh-pr 一起上传受信任的 scripts/crabbox-untrusted-bootstrap.sh;该脚本会安装固定版本(pinned)的 Node/pnpm,校验 SHA 和包管理器固定版本(pin),隔离 HOME,安装依赖,然后执行所请求的测试。如果 broker 无法证明不存在角色或不存在远程 PR,请改用 secretless fork CI。不要使用 hydrate-github、--no-sync 或凭据注入(credential-hydrated)的 Testbox 工作流。
取消设置所有 CRABBOX_TAILSCALE* 覆盖项,强制使用 --network public --tailscale=false,清除 exit-node/LAN 标志,并在上传任何脚本之前,要求 crabbox inspect 报告为公共网络且不存在 Tailscale 状态。
Crabbox 仓库设置¶
共享的 Crabbox 技能 负责可移植的租约、信任、同步和清理流程。本节负责 OpenClaw 包装器和工作流输入。日常任务所需的 Crabbox/Testbox 使用以及任务拥有的工作树无需再次确认;请保留无关工作以及现有的凭证、生产环境、预算和发布边界。
在仓库根目录通过包装器运行受信任的 OpenClaw 远端证明:
运行前请阅读 .crabbox.yaml 和已解析的提供者。仓库默认值是 blacksmith-testbox,其准备好的环境由 .github/workflows/ci-check-testbox.yml 负责。直接提供者使用 .github/workflows/crabbox-hydrate.yml。除非所请求的证明需要其他环境,否则保持已解析的提供者不变;容量或预置失败并不使不同提供者等同。
直接使用 .github/workflows/windows-blacksmith-testbox.yml 工作流可运行原生 Windows。包装器的 Blacksmith 适配器仅支持 Linux;显式指定 --provider blacksmith-testbox 可阻止自动 Azure 路由,但不会启用 Windows 支持。根据 2026-09-01 时的检查,Blacksmith CLI 0.4.57 面向 runner,且没有原生用户名覆盖机制,因此在此 Windows 镜像上受支持的 CLI 同步/运行仍然受阻。在依赖此结论前,请对照更新的 CLI 重新检查。使用每个 Testbox 专用密钥进行的原生 SSH 检查并非 CLI 端到端证明。
包装器会依次检查可执行文件同级候选 ../crabbox/bin/crabbox、PATH,以及 Git 公共检出目录的同级目录。请验证所选二进制及其来源,不要只相信目录名。当所选可执行文件缺失或过时时,插件会安装一份经过验证的受管副本。若要显式修复 Crabbox 源码,请在干净的任务拥有的检出中构建 ./cmd/crabbox,并保持操作员的安装不变。现有的 OPENCLAW_CRABBOX_WRAPPER_IGNORE_REPO_BINARY=1 设置会跳过第一个同级候选;此时 PATH 上的任务二进制优先于公共检出候选。同级目录脏乱或被占用并不构成停下来询问的理由。
Mantis 使用相同的插件自有发现机制和受管安装。相对可执行文件覆盖项和 PATH 条目会从其请求的 --repo-root 解析,版本探测也在该目录下以与租约命令相同的环境运行。其工作流通过 node scripts/crabbox-setup.mjs 准备可执行文件;该命令会将所选二进制和已验证版本以 JSON 形式输出,并在 GitHub Actions 中将其目录添加到 GITHUB_PATH。后续 QA 和媒体命令会复用该可执行文件。
对于所选的可信 Testbox 通道:
node scripts/crabbox-wrapper.mjs run --timing-json -- \
CI=1 NODE_OPTIONS=--max-old-space-size=4096 \
OPENCLAW_TEST_PROJECTS_PARALLEL=6 OPENCLAW_VITEST_MAX_WORKERS=1 \
OPENCLAW_TESTBOX=1 OPENCLAW_TESTBOX_REMOTE_RUN=1 \
pnpm test <path-or-filter>
对于多个命令,请使用唯一的任务标签并保留首次分配:
node scripts/crabbox-wrapper.mjs run --provider blacksmith-testbox --keep --label <task-name> -- <first-command>
node scripts/crabbox-wrapper.mjs run --provider blacksmith-testbox --id <tbx_id> --label <task-name> -- <next-command>
node scripts/crabbox-wrapper.mjs stop --provider blacksmith-testbox <tbx_id>
在整个任务中使用返回的租约 ID 和相同的标签。Codex、Claude Code 和 GitHub Actions 也会将复用绑定到各自的会话或运行身份。会话拥有的 warmup --timing-json 可在没有标签的情况下分配资源;人工 shell 使用上面带标签的 run --keep 流程。Stop 没有 --timing-json。
- 从任务检出进行预热。申领权属于检出路径;
--reclaim有意转移该所有权,且绝不改变仓库身份。稀疏暂存使用包装器的所有权路径。当其他命令拥有租约时,请勿同步或回收。 - 包装器复用需要 Crabbox 创建的本地 SSH 密钥。密钥缺失时需要进行全新预热。由 Blacksmith 直接创建的租约仍可通过
blacksmith testbox run --id <tbx_id>使用,但不能通过 Crabbox 包装器复用。 - 每次原生 Testbox 运行都会再次同步,包括复用的租约。
--no-sync无法保留远端基线。请在一条已同步命令中,在多个独立的远端工作树内比较修订版本;切勿在已同步根目录中切换 refs。 - 复合远端 shell 命令使用
bash -lc,而不是sh -lc;预置可能依赖 Bash 声明。Testbox 的工作流拥有 Chromium,因此不要向该提供者传递 Crabbox--browser。 - 保持上述租约指纹检查。发布证明没有过期租约覆盖。直接提供者的标志,如
--fresh-pr、--full-resync、--script*、--env-helper、捕获/下载标志和--stop-after,不能替代委派的 Testbox 工作流。 - 对于 Testbox 脚本,请将已同步的文件作为尾部命令参数运行,或使用
--shell。在源代码准备或租约工作之前,活动的--script和--script-stdin上传会被拒绝。
Blacksmith 源胶囊会在配置的同步根目录下为每个物理源工作树保留一个私有镜像。后续运行会再次枚举源资格,比较文件标识、大小、时间戳、模式和类型,并复制和哈希已更改的文件。未更改的源文件保持原位,并带有热 Git 索引 stat 数据。Git 的暂存跟踪和最终原始传输树使用独立的索引,从而保留相同的忽略文件和未跟踪文件选择规则。包装器会报告已复制和已复用的文件数量及准备时间。
在相同保留源 ref 上的提交会使镜像保持可复用;每个命令仍会记录其完整的当前见证,并在封存前重新检查源修订版本。
在整个命令执行期间,镜像保持独占锁定,包括工件保留和租约申领恢复。来自同一工作树的重叠运行会打印一条消息,并构建一个独立的全新胶囊。只有已完成的清理才会将空闲镜像记录为可复用;缺失见证、不支持的暂存位置或未解决的所有者都会使用全新暂存。冻结期间源发生变化会导致运行失败。缓存元数据、负载、见证仓库或 ref、或 Git 版本不匹配会在上传前冷重建。源枚举和元数据检查仍然随仓库规模扩展;在热运行时,源字节复制和哈希随已更改文件规模扩展。
私有镜像会禁用 Git hooks 和 fsmonitor;源枚举在镜像模式下也会禁用 fsmonitor。其他活动的 Git 回调会保留准备锁,无法生成可复用缓存。普通全新胶囊行为保持不变。
不同的工作树共享一个短暂的分配锁。繁忙的分配器会打印
[crabbox] waiting for source mirror allocation...,并最多等待 120 秒,
然后回退到新的胶囊。每个镜像的验证、冷准备以及驱逐时的载荷删除
都在槽位锁下运行,且不持有分配锁。
同步根最多容纳 32 个镜像槽位。分配会驱逐最近最少使用的空闲镜像;
处于活动状态、所有权损坏或中断的槽位仍受保护,并计入限制。
如果没有任何槽位可以安全回收,本次运行将使用普通的新的暂存。
staging inspect 会识别空闲镜像,staging recover <id>
可以在其独占锁下移除其中一个。自动的废弃暂存恢复会保留空闲镜像以供复用。
中断的命令保留现有的见证、声明和诊断恢复要求。
驱逐会在删除字节之前记录处置,并保留其槽位直到删除完成。
如果中断,staging inspect 会将已记录的处置报告为恢复候选项;
自动恢复或 staging recover <id> 可以在获取独占槽位锁后继续执行。
被替换的目录和未知元数据仍受保护。并发分配器在删除后重新检查容量;
正在处置的槽位仍计入 32 个槽位的限制。
独立的处置回执会在最终目录和锁删除后保留,因此即使载荷回执已消失, 恢复也能完成中断的命名空间清理。恢复会保留已记录的处置,而不是重写它。 其生产者已删除载荷的槽位也会收到一条清理记录;该记录要求载荷根保持不存在, 并且绝不授权删除替换根。这两种形式都会阻止槽位复用,直到清理完成。 达到 256 MiB 的私有 Git 对象会在下次复用时触发冷重建, 从而限制保留的对象历史,而不会修剪已保存索引背后的对象。
当远程同步使用隔离的检出时,包装器会在删除该检出或将其镜像返回到空闲缓存之前,
将原生 .crabbox/runs 和 .crabbox/captures 输出一起保留在新的
.crabbox/wrapper-artifacts/run-* 目录下。经过验证的原生输出会从空闲镜像中删除,
以便后续运行仅保留其自身的诊断信息。
其他原生 .crabbox 状态在工件保留后使用普通的完整检出处置;
下次运行会构建一个冷镜像。镜像锁会在其进程退出时自动释放,
但未解决的已准入消费者仍需要现有的暂存恢复检查,才能删除其快照。
即使原生文件名匹配,重复运行也会保留独立的证据。
包装器会打印从旧根到新根的映射;原生日志和生成的证明可能仍引用旧路径。
保留错误会使包装器失败,并在报告的路径保留临时检出以供手动恢复,
同时保留子进程的非零退出码。包装器拒绝工件树和目标父目录中的符号链接,
并且只复制常规文件和真实目录。在 POSIX 系统上,保留的文件使用模式 0600,
新目录使用 0700。如果保留失败,请在删除报告中的检出之前从该检出恢复输出。
已识别的未更改部分副本会被删除;无法验证的部分目标会被保留,
并与原始输出一起报告。
在正常完成或受支持的 POSIX 中断时,包装器会在恢复保留的租约所有权、 保留工件并删除可丢弃源之前,先完成其子进程树和输出流的收尾。 在 Ctrl-C 之后允许包装器完成;额外信号会复用该关闭流程及其有界升级。 包管理器代理可以在包装器完成之前返回其中断状态。 仅该状态或远程租约完成并不能证明本地清理已完成。
清理错误会被报告,并导致原本成功的调用失败; 已有的非零命令状态或取消状态会被保留。如果无法验证子进程终止, 包装器会保留其本地输入并报告需要恢复。保留的租约所有权恢复失败也会保留检出; 在删除检出之前,请将该租约恢复到原始仓库或停止它。 在恢复工件或删除其临时输入之前,请停止任何剩余的受管进程。
只有当可以证明暂存位于源仓库之外时,包装器才会记录未来的临时检出,
并使用位于载荷旁边的私有恢复元数据。默认 ~/.cache/openclaw/crabbox-sync
位置通常满足此条件。已配置的仓库本地根(包括 .artifacts/ 等被忽略的目录)
仍可通过普通的未标记暂存和清理继续工作。它们不会收到恢复回执或清单,
并在突然丢失后仍受保护。不确定的放置位置也会使用该兼容的未标记路径。
更改已配置的根或忽略规则不会在仓库内创建新的恢复元数据。 位于另一个根处的现有副本不会被移动或采用;请选择该根以检查它们。 此功能不会过滤现有用户数据、更广泛的源范围或显式的原始工作区挂载。 使用以下命令检查已记录的副本:
node scripts/crabbox-wrapper.mjs staging inspect
node scripts/crabbox-wrapper.mjs staging recover <id>
这些本地命令使用现有的 Crabbox 二进制文件,而不会安装它、启动提供程序、
更改声明或停止租约。恢复会检查原始原生声明命名空间,
将记录的快照与独立保留的 Git 引用进行验证,并在删除未更改的暂存之前
验证已保存的诊断信息。仍然指向暂存的声明需要操作员停止确切的租约,
或从真实仓库中显式回收它,然后重试。更改 HOME 或 XDG_STATE_HOME
无法证明旧命名空间中不存在。
一个没有已接纳消费者的已准备胶囊,可以在其所有者消失后被恢复。已接纳消费者需要持久化的写入方结算回执。可能启动准备辅助程序的 Git 配置,或额外的本地 Git 种子准备,仍会被保留,因为父命令完成并不能认证这些辅助程序。它们的普通执行保持不变。较早的实验性回执版本也仍受保护。 显式恢复可以在目标问题修复后重试待处理的诊断保存。自动恢复会保留工件或声明失败。缺失或已更改的已保存输出会阻止移除;恢复绝不会重新创建一个已消失的原始仓库来虚构保存目标。
脏源需要另一份完整的保留副本。在有意将该快照保留在独立的 Git 仓库和命名引用中后,显式选择它:
node scripts/crabbox-wrapper.mjs staging recover <id> \
--witness-repo /path/to/retained-repository --witness-ref refs/heads/saved-source
见证验证证明所选引用的对象存在且已连接。在 Git 2.50+ 上,它会跳过无关的引用数据库检查,因此 .git/refs 下诸如 Finder .DS_Store 之类的杂散文件不会阻止恢复。显式 staging recover 会根据见证对象存储扩展其工作预算:120 秒,外加每 GiB 30 秒,最多 30 分钟。包装器命令后的自动恢复保持 120 秒上限。
失败原因会区分预算耗尽、引用数据库错误,以及缺失或未连接的引用对象。
恢复不会创建备份仓库、归档或永久引用。某个阶段自身的 Git 对象或 bundle 不计为另一份副本。存活或不确定的所有者、未记录的写入方结算、被中断的恢复所有权、被替换的元数据、其他启动/进程命名空间,以及历史未标记目录,仍受保护。 恢复仅限于同一启动和已知的 PID 命名空间;即使重启同一台计算机,较早的副本仍受保护。完整 worktree 也仍受保护,因为钩子、过滤器和原始源需要单独证明。它们的普通清理会在精确的 Git 注册移除失败时保留剩余的 staging,包括注册符合条件时的其回执。仓库本地副本保持未标记。没有全局 worktree 修剪或强制恢复选项。
源传输命令最多检查 64 个有界头部,并使用 250 毫秒的软发现预算。此扫描不对负载进行哈希、不搜索 Git 历史,也不查询提供商。临时游标会使后续扫描跳过受保护的条目;
staging inspect --after <nextCursor> 也会分页本地报告。在成功正常完成后,包装器最多尝试一个已发现的候选项。帮助、
列表、版本输出和取消不会启动旧阶段恢复,并且恢复失败不会更改已完成命令的结果。检查报告会报告不完整扫描和已用时间;批量验证单独受限,可能需要更长时间。不受支持的
文件系统持久性(包括原生 Windows 目录刷新)会阻止孤儿恢复,同时保持普通操作。正常清理仍会移除其自身的成功或脏源 staging,而不需要独立的恢复见证。
这些是本地工件,不是已发布或完全脱敏的证明。Blacksmith 的原生失败 bundle 包含捕获的 stdout/stderr 和诊断元数据; 它不会自动包含远程 UI 截图或报告。在停止所拥有的 Testbox 之前,请单独获取这些内容,并在共享前检查所有工件中的机密和私有数据。
原生 Windows Testbox 空闲监视器使用正在运行的 sshd 服务的本地监听端口,而不是 Blacksmith 的外部转发 SSH 端口。已建立的 SSH 连接会保持任务存活;~/.testbox-last-activity 的修改时间覆盖 30 秒轮询之间的短命令。一旦两者都不表示最近活动,配置的空闲超时仍会结束任务。
共享技能的命令占位符映射到本指南中的聚焦命令。其可信引导程序是 scripts/crabbox-untrusted-bootstrap.sh;上述不可信路径调用已安装的可信 CLI,绝不调用 PR 的包装器。
对于显式选择的本地容器 lane,现有示例镜像是 node:24-bookworm,安装命令是 corepack pnpm install --frozen-lockfile --store-dir .pnpm-store,随后执行所选测试。当主机缓存无法跨文件系统时,保留 --no-hydrate 和仓库本地依赖存储。OpenClaw broker 登录端点是 https://crabbox.openclaw.ai;正常 broker 验证不需要请求 AWS 密钥。
实时 Gateway、channel 和 agent-turn 证明使用隔离的 OPENCLAW_STATE_DIR、一个空闲端口和真实用户路径。仅用于测试的插件工件可以使用 OPENCLAW_ALLOW_PLUGIN_INSTALL_OVERRIDES=1;这不会使它们成为官方安装。在共享 WebVNC 之前,请检查正在运行的应用截图。将证明媒体保留在产品仓库之外,并在生成器运行前后比较源哈希。如果最终计时结果已写入但门户同步挂起,请只中断任务包装器,并独立验证租约清理;切勿停止操作员的 Gateway。
本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 cl/openclaw