验证¶
下方的初始作者记录描述的是原始 macOS 树。末尾的 Linux 跟进记录则涵盖本 PR 中集成的 serve 改动及后续修复。这两条记录具有不同的工具链和缓存状态。
已验证基线:24574576e4fa74ff56eda965ae287555b7552c03,即已获取的 main b83b9caf 上 environment-serve 增量的顶端(本次增量在此基础上构建)。
工作树将 manifest-view、streamable-HTTP 和 serve 增量作为提交承载于上游 main b83b9caf 之上;本次增量的更改则是其上未提交的编辑。下述每项检查均按书面方式在本树完成审查修复后运行;所报告的内容均实际执行过。时间数据为 macOS 的 /usr/bin/time -l 命令统计(elapsed、user、system 秒数,以及命令及其等待的子进程的最大常驻集大小),运行环境为 macOS 26.5.1,Node 22.23.1,npm 12.0.2,Docker 29.5.3,以及一个持有 agentenv-framework 0.9.1334 的 Python 3.12.12 虚拟环境。
已处理的审查发现¶
对第一轮结果进行对抗性审查后,发现两个 should-fix 问题和七个 nit;每一个都在其所属边界处、于下述门禁运行前完成了修复。
- bundle README 曾指导读者运行
agent-env run <name>,这只有在文件夹恰好与环境同名且从 bundle 的父目录运行时才有效。README 现在改为在 bundle 根目录运行agent-env run .,并在其他工作目录下指明该文件夹的路径;services 测试断言了新文本块以及旧命令的缺失。 - lane verifier 在
REA_*变量未设置时从PATH解析agent-env和docker。现在它要求使用绝对的REA_AGENT_ENV_COMMAND和REA_DOCKER_COMMAND,在缺失时抛出标准的可操作消息,指明 npm 脚本名称并说明未安装任何内容,同时检查两个路径均存在;工作流从command -v docker导出REA_DOCKER_COMMAND,与虚拟环境中的agent-env并列;docs/testing.md列出了这两个变量,并移除了PATH默认值。未添加 Linux preflight,因此该 lane 在 macOS 主机上仍可运行。 - 脆弱的
assert.doesNotMatch(stdout, /failed/)已移除;退出码0以及tasks/smoke.json v<n>: passed摘要即可决定结果。 - 内部的
agent-env run超时为 15 分钟,位于 30 分钟的作业之内,因此挂起的运行以 verifier 的失败回执结束,而非 runner 的终止;docs/testing.md已说明这一点。 - 该配对曾被读取两次:一次解析以进行认证,再一次从磁盘重新读取用于字节精确复制,因此在两次读取之间被替换的文件会被未经检查地复制。
readEnvironmentExportInputs现在通过常规文件读取器一次性读取每个文件,使用共享的 UTF-8 JSON 解析器从这些字节解析值,命令则将相同的缓冲区传给 export 以进行复制;对内联 JSON、目录和非 JSON 文件的拒绝按角色进行类型化,规范、计划和两份指南均说明了单次读取。 - tarball Dockerfile 曾将 6 MB 的
rea-agents.tgz留在镜像的/tmp中;安装层现在会将其移除(&& rm /tmp/rea-agents.tgz),并通过下方构建镜像中/tmp的列表得到确证。 - verifier 按设计规范传递
--sandbox local;规范记录了任务的sandbox_type: local已固定提供方,而该标志是对其的复述。 - verifier 通过 Node 的类型剥离从
tests/fixtures/导入 HAR 构建器,这一做法被保留,并在规范的 limits 中记录了原因(不在scripts/下保留第二份副本;范围清单已列出该 fixture)。 - 写入并非事务性的;
docs/cli.md现在说明,在第一个文件之后发生主机故障会留下部分文件夹以供检查,且下一次尝试会拒绝非空目录;规范的 limits 也做了同样说明。
设置¶
npm ci 已完成(退出码 0;373 个顶层条目)。/usr/bin/time -l npm run build 通过,3 个任务成功,耗时 7.60 秒(user 14.81 秒,sys 2.69 秒,3013410816 字节);/usr/bin/time -l npm run test:prepare 通过,6 个任务成功、3 个缓存,耗时 1.63 秒(user 3.47 秒,sys 0.81 秒,400752640 字节)。
静态门禁¶
每个门禁均在最后一次源码编辑后的最终树上依序运行:
npm run check:fast(带模块边界的类型检查和 lint;2 个任务成功;耗时 5.28 秒,user 23.22 秒,sys 2.93 秒,4564680704 字节);
npm run format 未重写本次增量文件以外的任何内容(“Finished in 635ms on 4077 files”),且 npm run format:check 通过(“All matched files use the correct format”;0.87 秒,user 4.30 秒,sys 0.64 秒,224051200 字节);
npx knip 未报告任何发现(3.49 秒,user 5.04 秒,sys 0.72 秒,805191680 字节);
npm run verify:test-discovery 报告 “Discovered all 1597 test files exactly once”(0.55 秒,user 0.38 秒,sys 0.14 秒,141492224 字节);
npm run check:ci:tasks(typecheck、lint:built、format:check、knip、metadata:check、jscpd、scan:todos)通过,8 个任务成功,lint 为 “3764 files, 0 errors, 1690 warnings”,jscpd 为 “3171 files, 2587 clones, 3.34% duplicated lines”,低于 3.5% 阈值(耗时 4.89 秒,user 15.19 秒,sys 3.86 秒,874627072 字节);
npm run docs:check 通过,包括 README 一致性测试(6 个任务、5 个测试;耗时 4.00 秒,user 3.86 秒,sys 0.94 秒,290111488 字节)。
actionlint 1.7.7(-shellcheck= -pyflakes=,来自审查的临时虚拟环境)对 .github/workflows/real-agentenv.yml 和 .github/workflows/ci.yml 未报告任何发现。对 23 个新增或修改文件进行不区分大小写的禁止词和标记注释 grep,仅匹配到 package.json 中的 scan:todos 脚本名称以及本文件。
测试项目¶
源码组:/usr/bin/time -l npx vitest run --project services --project conformance 通过,涵盖 122 个文件、1524 个测试,耗时 11.08 秒 elapsed,user 23.10 秒,sys 2.24 秒,1631240192 字节。本次增量的文件为
environmentBundle.test.ts(7 个测试:计划的文件集和复制目标;registry Dockerfile 固定到 PACKAGE_METADATA.version 并带就绪探针层;tarball Dockerfile 安装并移除 /tmp/rea-agents.tgz;verifier 文本将 get_annotations 命名为第一个无参数 GET 工具并记录第 25 条记录的状态 200;冒烟任务;README 的来源、agent-env run . 文本块和权限说明;名称覆盖以及六个被拒绝的名称)、
environmentExport.test.ts(6 个测试:读取器返回每个文件的字节和解析值;按角色拒绝内联 JSON、目录和格式错误的 JSON;写入不存在的目录时读取字节原样复制并报告大小;tarball 复制;拒绝非空目录、文件路径和缺失 tarball 且不写入任何内容;接受已存在的空目录)、
environmentSource.test.ts(4 个测试;加载器采用报告操作),
以及 conformance 测试 environmentBundlePackagePin.test.ts(1 个测试:registry 安装行以 rea-agents@<package.json version> 结尾,且绝不使用 latest 或范围)。
在 npm run test:prepare 之后构建的测试组执行了 /usr/bin/time -l npx vitest run --project cli-boundary --project boundary,覆盖了 environmentExportCli(3)、ciChangeScope(228)、ciRequiredLanes(17)、workflowActionPinning(5)、ciCachePolicy(6)、cliToolCoverage(1)、cliStartupImports(5)和 ciTestProjects(11),共 8 个文件、276 个测试通过,耗时 432.80 秒(用户态 303.47 秒,系统态 92.63 秒,内存 422412288 字节);tests/boundary/filesystem/productCatalog 单独通过(10 个测试,5.32 秒)。cli-boundary 文件通过构建后的 CLI 从 fixture 配对中写出文件夹,并检查七个写入路径、字节完全一致的副本以及 Dockerfile 的第一行和 CMD;它拒绝非空目录,并保留其中已有的一个文件;同时拒绝不匹配的配对且不创建目录。
本地端到端运行¶
在此工作树中使用构建后的 CLI,从一个全新的临时目录开始:inspect-web-network-capture grafana-like.har har --format json --json 写入了捕获 Evidence ev_4ee4759b…(28 条记录);inspect-analysis-view 使用内联源和全部三条模板规则,写入了 manifest Evidence ev_6553a8e5…,其中父级为 grafana-example,包含 19 个工具,视图摘要为 8d1eb3ee…。对检出内容执行 npm pack --ignore-scripts 生成了 rea-agents-6.6.0.tgz(6039238 字节)。environment-export manifest.json --evidence capture.json <tmp>/grafana-example --package-tarball <tgz> --json 以 0 退出,并打印了 status: exported、tool_count: 19、package_source: {kind: tarball} 以及以下八个文件:README.md(2076 字节)、envs/grafana-example/env.toml(37)、envs/grafana-example/Dockerfile(441)、artifacts/check_grafana-example/verify.py(1534)、tasks/smoke.json(291)、envs/grafana-example/manifest.json(15701)、envs/grafana-example/evidence.json(58296)和 envs/grafana-example/rea-agents.tgz(6039238);cmp 确认两份 Evidence 副本以及 tarball 与输入逐字节一致。Dockerfile 的安装行内容是 RUN npm install -g --ignore-scripts --no-fund --no-audit /tmp/rea-agents.tgz && rm /tmp/rea-agents.tgz,README 的运行部分就是 agent-env run . 代码块。
/usr/bin/time -l agent-env run <tmp>/grafana-example 在 43.66 秒内以 0 退出(用户态 5.19 秒,系统态 3.26 秒,内存 129318912 字节),输出如下:
[tasks/smoke.json] step 1/2 env done in 25.1s
[tasks/smoke.json] step 2/2 replay (env_outcome_verifier)
replay: listed 19 tools, expected 19; get_annotations replayed status 200, recorded 200
[tasks/smoke.json] passed in 25.1s
Tasks:
tasks/smoke.json v1: passed (replay: 1), 25.1s, instance @local/…/grafana-example/smoke-nwvvojs7
Tore down 1 sandbox.
docker ps -aq 在运行前后列出了相同的三个既有容器(一个 Grafana 容器、一个已退出容器,以及框架在之前会话中创建的 registry,与本次运行无关);没有新增容器,镜像数量从 19 增加到 20,对应构建的环境镜像 5a5b3bf62aae。docker run --rm --entrypoint sh 5a5b3bf62aae -c 'ls -la /tmp; rea --version; id -un' 在 /tmp 中仅列出了 node-compile-cache(没有 rea-agents.tgz),打印了 6.6.0,并以 node 用户运行。
REA_AGENT_ENV_COMMAND=<venv>/bin/agent-env REA_DOCKER_COMMAND=$(command -v docker) /usr/bin/time -l node scripts/verify-agentenv-environment.mjs 在 37.24 秒内以 0 退出(用户态 10.42 秒,系统态 4.45 秒,内存 268533760 字节),并打印了回执 status: passed、public_cases: 5、upstream: agentenv-framework 0.9.1334、runner: darwin arm64; host Docker、docker_before: {containers: 3, images: 20}、agent_env_run: {exit_code: 0, seconds: 32},其 stdout 末尾也是相同的通过摘要;此外还有 docker_after: {containers: 3, images: 21, new_containers: []} 和 process_lineage.status: verified,且没有后代进程。
该通道的首次托管运行发生在没有任何先前框架状态的 runner 上,在 agent-env run 期间创建了框架的镜像存储辅助容器 agentenv-registry(registry:2,容器 b2e047f4c6cd);运行本身通过(exit_code: 0、354 秒、tasks/smoke.json v1: passed、“Tore down 1 sandbox.”),但泄漏检查的初始形式将该辅助容器计入并判为失败。现在的检查会按名称列出容器,排除 agentenv-registry[-<port>],并将其报告在 image_store_helpers 下;本地回执之所以是 image_store_helpers: [],是因为该辅助容器在本次运行前已存在。Public ECR 的匿名拉取配额在六次托管运行中的两次拒绝了框架对 postgres:16-alpine 的拉取(第二次,以及堆栈重建后的第六次),错误为 429 Too Many Requests, Data limit exceeded;现在,当失败带有该 registry 的特征时,验证器会在 90 秒后重试一次运行,并在回执中记录 attempts: 2 和 retried_for。本地回执报告 attempts: 1。
删除该辅助容器(docker rm -f agentenv-registry)后再次运行验证器,在本地重现了全新主机的路径:运行重新创建了它,回执以 image_store_helpers: ["agentenv-registry"]、new_containers: [] 通过(agent_env_run: {exit_code: 0, seconds: 33})。在未设置 REA_DOCKER_COMMAND 的情况下,验证器在触碰任何内容之前即以 1 退出,错误为“verify:agentenv:environment requires absolute REA_DOCKER_COMMAND; see docs/testing.md. No dependencies are installed by this verifier.”;当 REA_AGENT_ENV_COMMAND=agent-env 为相对路径时,它也以 1 退出,并使用同一个句子指名该变量。
通过构建后的 CLI 触发的拒绝行为:导出到已写入的 bundle 目录时以 1 退出,错误为 invalid_request,问题路径为 ["directory"],消息为“is not empty (4 entries); choose an absent or empty directory”;使用单条所选记录的 capture 导出 manifest(--record 0,ev_3249d233…)时以 1 退出,错误为 invalid_request,问题路径为 ["evidence", "evidence_id"],消息为“The manifest was projected from a different capture than the supplied evidence file.”,且未创建目录;将截断的 broken.json 作为 Evidence 文件时以 1 退出,错误为 invalid_request,问题路径为 ["evidence"],原因为 invalid_format,消息为“broken.json is not valid JSON: Unexpected end of JSON input”,且未创建目录。未使用 --package-tarball 的导出会写入一个 Dockerfile,其安装行为 RUN npm install -g --ignore-scripts --no-fund --no-audit rea-agents@6.6.0(package.json 中的版本),且旁边没有 tarball;使用 tarball 的变体会复制 rea-agents.tgz,并安装和删除 /tmp/rea-agents.tgz。
独立审查¶
对第一遍的对抗性审查即本次增量的独立审查;其发现及修复已列于上文。修复过程中又浮现一项观察:单次读取辅助程序通过导出模块而非 CLI 的共享 JSON 输入解析器来路由导出的输入拒绝,因此内联 JSON 拒绝现在在 manifest 或 evidence 问题路径上呈现为带类型的 invalid_request,而非解析器的 input_path/input_reason 信封;CLI 边界测试并不依赖该信封。
范围与测量限制¶
框架就绪探测、端口变量默认值及 env.toml 名称是在第一遍运行该包时发现的,而非通过阅读已发布的契约;它们被记录在规范中,作为对设计文件集的三项增补。本地运行和验证器使用了宿主机的 Docker,且框架的网关与服务数据库镜像已由先前会话构建完成,因此“首次运行同时构建基础设施”的路径未在此计时。验证器的容器检查比较 docker ps -aq 前后的输出;运行期间构建的镜像按设计保留,仅被计数。npm pack --json 在本宿主机上为 npm 12 的对象形状,在托管运行器上为 npm 11 的数组形状;验证器两者都接受,但本地仅实际执行了前者。托管的 real-agentenv 工作流未从本树派发。构建后的项目在本宿主机的 Node 22.23.1 上运行,而非固定的 24.18.0。/usr/bin/time -l 的数据涵盖每条命令及其等待的子进程;Docker 自身的工作在守护进程中运行,不在其内。未运行 Windows。
Linux 后续验证(2026-10-19)¶
原始 PR 在 #4955 和 #4975 合并后已从 main 更新。这些后续修订保留了作者的提交与可移植名称检查;将私有 JSON 解析器输出一次性封存以供共享的不可变认证/重放使用;在读取前预留封存工作;在导出前预检所服务的目录;按输入角色转换变更文件的失败;在 CLI 注册期间延迟导出导入;并在归属其结果前验证所提供的框架可执行文件。默认的 rea mcp 传输方式仍为 stdio。
在 Linux x64 上执行,使用 Node 24.18.0、npm 11.16.0、Docker 20.10.24、Python 3.12.13 及一个隔离的 agentenv-framework==0.9.1334 环境:
turbo run typecheck lint:built format:check docs:check:built knip metadata:check artifacts:skills --concurrency=1:十个任务通过,一个已缓存,耗时 289.315 秒,CPU 284.552 秒,进程族峰值 RSS 4450.18 MiB。- 聚焦的源码/编译后 CLI/SDK/生命周期/配置运行在 24 个文件中通过了 399 项测试。后续运行通过了更新后的 231 个 CI 选择用例、三个可执行文件身份用例及十个产品目录用例。后者需要先生成其目录;最初的缺失文件失败属于准备工作,而非通过的检查。
- 四个先前记录的、未经认证的真实 GitHub API 响应随检出 tarball 一起导出。生成的 Dockerfile 未作更改即构建成功。一个全新的非 root 容器通过官方 MCP SDK 将每个响应重放两次,body、状态、Evidence 序号/ID 及不可信内容来源均匹配。发现/卡片一致性与 tarball 移除均通过。独立测试与框架一样提供
ENVIRONMENT_NAME。使用构建镜像进行运行时验证耗时 12.393 秒 / CPU 6.002 秒 / 进程族 RSS 313.11 MiB;镜像构建成本已排除。Docker stats 采样为 250.5 MiB,并非测得的容器峰值。 - 生产环境的
verify-agentenv-environment.mjs观察到agent-env 0.9.1334,导出了其 28 条记录的、源端所有的 Grafana 形状固定数据,使用真实框架部署并通过了tasks/smoke.json。收据报告了五个公共用例、一个已拆除的沙箱、无新任务容器及无受监管的后代进程。此次成功运行使用了已准备好的基础设施:141.697 秒 / CPU 101.971 秒 / 进程族 RSS 501.61 MiB。此前的尝试失败是因为本宿主机的代理环境需要可选的 SOCKS 支持,且其默认的 home 沙箱目录不可写。仅清除了测试进程的代理变量;受支持的XDG_STATE_HOME和AGENT_ENV_LOCAL_SANDBOX_DIR指向临时存储。共享的 Docker 守护进程未被重新配置或重启。框架的持久化注册表辅助程序与镜像按其文档化行为保留。
一个匹配的公共 environment-serve/SDK 任务将后续修订前的 serve 构建与最终实现进行了对比。两者均使用相同的 GitHub 捕获,包含 1,000 个合成 HAR 扩展项(每项包含额外容器)、一次首次调用及二十次热态相同重放。固定数据生成已排除。这是受控的压力数据,而非新观测到的应用数据。更大规模的 25,000/75,000 项投影尝试返回了现有的带类型表示预算拒绝;该预算未被放宽。
| 测量项 | 之前 | 之后 |
|---|---|---|
| 冷监听器启动 | 2189.064 ms | 2862.860 ms |
| 首次调用 | 76.950 ms | 45.265 ms |
| 二十次热调用 | 324.119 ms | 267.132 ms |
| 完成任务耗时 | 3.229 s | 3.885 s |
| 完成任务 CPU | 3.196 s | 3.827 s |
| 进程族峰值 RSS | 466.43 MiB | 470.21 MiB |
这些单一的已完成样本并不足以确立整体的速度或内存改善。独立的身份回归测试表明,大型报告的 JSON 树是共享而非复制的,且调用方拥有的可变树不会被冻结。未测量 Token 使用量。CPU 为子进程用户+系统时间;进程族内存每 50 毫秒对后代进程 RSS 进行采样求和,可能将共享页面计算两次。Docker 守护进程/容器的 CPU 与峰值不在该进程族测量范围内,仍属未测量。构建一次只执行一个任务、使用一个 CPU 及软性 3 GiB Go 限制;Docker 构建为串行且限制为一个 CPU/4 GiB,独立重放容器为一个 CPU/2 GiB。此次后续验证未测试 Windows 执行及已发布的注册表包;检出 tarball 在发布前证明了代码本身。
输出所有权与最终审查后续¶
输出边界现在使用现有的 SafeOutputTree 所有者,而不是单独的目录准入和路径名写入。它在发布前后检查已接纳的根目录、父目录、文件身份和完整条目清单,保留失败关闭的权限,并在回滚时保留调用者现有的空根目录。可选包在输出写入前以一个常规文件描述符持有,通过哈希/回读验证进行流式传输,并在释放前检查是否发生变化。POSIX 文件模式独立于 umask 设置并验证为 0600;新拥有的目录为 0700。现有根目录权限仍由调用者所有。Windows 隐私取决于所选目标 ACL;不声明仅所有者 Windows ACL 保证或 Windows 运行时验证。可移植路径名操作仍要求可信的目标和父目录,以防并发替换。
在 umask 0400 下,一个编译后的 CLI 反例在模式修复前失败,而在修复后成功,所有生成的文件均可按 0600 读取,且 Evidence 字节完全一致。公共 CLI 覆盖还验证了 symlink/.. 对于目标和包路径保留其文件系统含义。真实文件系统测试涵盖了目标替换、外部条目、父符号链接、只读权限和已接纳 tarball 的替换。受控的关闭失败测试覆盖了发布后恢复和持续保留的所有权。
清单所有者接受规范等价的 Unicode 目录列表,而不会合并不同的文件名:先进行 NFC 多重集比较,再执行原始路径身份检查。测试在真实拥有的文件上模拟分解形式的 readdir 拼写,并创建一个额外的、不同的 Linux 分解形式外来文件。这些确立了边界行为,而不是实际的 HFS+ 执行。Manifest、Evidence 和 tarball 描述符使用共享资源作用域的关闭重试。持久性失败保留规范清理租约,并产生带标签的 environment-export 错误。编译后的 JSON CLI 回归测试在目标写入之前注入一次持久性 manifest 关闭失败。
框架验证器复用 execNpm,并遵循所选的 npm_execpath。四个进程边界归属测试用例通过,包括一个与 PATH 冲突的 npm。这些受控可执行文件仅验证归属。
合并 main b4938aed5 后,生成的 Dockerfile 使用 checkout 包原样构建,并在全新的非 root 容器中,通过官方 MCP SDK 重放了所有四个捕获的公共 GitHub API 响应各两次。输入字节、status/body/Evidence/来源、发现/卡片一致性和包移除均通过。热基础镜像构建加上打包/导出/运行时验证:40.699 秒耗时,8.274 秒进程 CPU,421.04 MiB 峰值进程族 RSS。固定的真实 agent-env 0.9.1334 验证器随后通过所有五个公共用例和冒烟任务,拆除其沙箱,并报告没有新的任务容器或受监督的后代进程:156.895 秒 / 102.871 秒 CPU / 500.34 MiB。框架基础设施此前已准备好。后来的 Unicode、关闭失败和 npm 选择修复各自有独立的边界回归;它们并不构成新的真实平台覆盖。
主合并前的一次匹配导出对比使用了相同的 manifest(6,416 字节)、capture(98,519 字节)和 checkout tarball(6,221,957 字节),所有复制的输入均字节精确。输出所有者修复前/后:1.827/2.604 秒耗时,1.807/2.545 秒 CPU,316.43/334.11 MiB 峰值进程族 RSS。这些是单进程采样,且宿主机文件系统缓存不受控;额外的所有权检查增加了测量成本。它们并不表明速度或内存改进。
所有后续重型工作一次使用一个 CPU 和一个测试/构建任务。Docker 构建限制为一个 CPU/4 GiB,独立运行时容器为一个 CPU/2 GiB。进程族 RSS 每 50 ms 采样一次,可能会重复计算共享页面。Docker 守护进程/容器的 CPU 和峰值内存、agent 令牌以及新框架基础设施成本均未测量。此前记录的早期 catalog 堆拒绝并未作为一次通过的运行来呈现。
对已审查源码的最终聚焦验证通过了 33 个文件中的 452 项测试(包括 232 个 CI 选择用例和编译后的 CLI 回归测试):161.276 秒耗时 / 159.900 秒 CPU / 1242.43 MiB 峰值进程族 RSS。最终的 typecheck/build/lint 门禁通过:218.427 秒 / 218.130 秒 CPU / 4449.45 MiB。
本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 rea2/rea