
omo-senpi 精选只读 Agent 的验证体系从命令矩阵、边界拒绝到构建内容摘要的完整测试路线【免费下载链接】oh-my-openagentOmO: Just type mass ulw keyword with your prompt. Now you are the master of graph engineering.项目地址: https://gitcode.com/gh_mirrors/oh/oh-my-openagent导读本文以packages/omo-senpi与packages/senpi-task中的精选只读curated read-onlyAgent 为对象完整还原其验证测试测了什么、为什么够了、刻意没测什么。读者将掌握一套可复用的 Agent 安全回归测试方法论从类型检查、单元测试、E2E 沙箱驱动到基于 Bun metafile 输入图的构建内容摘要新鲜度校验以及如何用证据目录evidence约束测试边界。背景被验证的对象——curated read-only Agent 是什么在 omo-senpi 中curated agent 指一组经过严格限制的内置子代理subagent。从 内置 Agent 注册表 可以确认curated 集合由四个 Agent 构成explore代码库搜索专家定义见 explore.tslibrarian资料检索类 Agentplan-consultant计划咨询 Agentplan-reviewer计划评审 Agent。它们共有的安全契约是三条硬性约束强制 in-process 执行explore的AgentDefinition中executionMode: in-process而 execution-mode.ts 中的resolveDagNodeExecutionMode对 curated 名称无条件强制in-processDAG 节点无法通过task.dag或omo.json配置覆盖。只读工具面工具面由 child-options.ts 的buildChildSessionOptions组装——curated Agent 的bash工具会被移除替换为 curated-readonly-bash.ts 中的受限只读 broker。不可作为团队成员member-validator.ts 明确拒绝 curated read-only agent 出现在 team spec 中必须通过task工具委托。本文讨论的验证工作what-tested.md正是围绕如何证明这套契约在任何被拒绝的边界上都成立而设计的。命令与测试面九条命令构成的分层验证矩阵原验证文档完整记录了九条命令覆盖从静态类型到真实二进制的五个层级。逐条拆解如下。层级一静态类型检查两条tsgo --noEmittsgo --noEmit -p packages/senpi-task/tsconfig.json tsgo --noEmit -p packages/omo-senpi/tsconfig.jsontsgo是无 emit 的 TypeScript 类型检查分别校验任务引擎包senpi-task与插件包omo-senpi。这一步保证createCuratedReadonlyBashTool返回的ToolDefinition、CuratedReadonlyBashParams的 typebox schema、以及 E2E 分析脚本依赖的类型面全部自洽。它是后续所有测试的前提——类型层错误会在 0 运行成本下被拦截。层级二单元测试两条bun testbun test packages/senpi-task packages/omo-senpi bun test packages/omo-opencode/src/shared/markdown-link-audit.test.ts第一条运行两个核心包的完整单元测试其中与 curated Agent 直接相关的是 curated-readonly-bash.test.ts它覆盖只读命令规划planCuratedReadonlyCommandcurl --silent https://example.com/docs会被规整为curl --disable --silent ...强制关闭配置文件gh search code ...原样放行突变类请求全部拒绝curl --request POST、curl --output artifact、curl --data x1、gh api ... --method DELETE、gh repo clone一律抛出read-only错误输出截断边界超过行数DEFAULT_MAX_LINES或字节数DEFAULT_MAX_BYTES的输出保留响应头部并附加[truncated: ...]提示失败信息同样被限制在预算内详见 curated-readonly-bash.ts 的capResultText实现。第二条markdown-link-audit.test.ts属于文档准确性维度详见下文为什么这样就够了。层级三包级集成测试脚本bun run test:senpi根目录 package.json 中该脚本展开为bun run build:senpi-plugin tsgo --noEmit -p packages/omo-senpi/tsconfig.json bun test --timeout 20000 packages/omo-senpi bun test ./.agents/skills/senpi-qa/scripts/resolve-evidence-dir.test.mjs注意它先执行build:senpi-plugin再跑测试意味着测试运行在最新构建产物之上从流程上杜绝测的是旧代码的偏差同时--timeout 20000给 omo-senpi 的构建类测试留出余量构建测试单次真实双构建约需 14 秒见 build-extension.test.mjs 的注释。层级四构建产物新鲜度检查--checkbun test packages/omo-senpi/plugin/scripts/build-extension.test.mjs node packages/omo-senpi/plugin/scripts/build-extension.mjs --check第一条直接驱动 build-extension.test.mjs 的回归用例第二条是构建检查器的 CLI 入口。两者共同验证一个核心目标检入的扩展 bundle 与当前源码严格同步。其机制在下一节展开。层级五端到端沙箱驱动两条 E2ETMPDIRworktree/.omo/tmp SENPI_BIN/opt/homebrew/bin/senpi CURATED_AGENTS_E2E_OUT_DIRevidence-dir node packages/omo-senpi/scripts/qa/curated-agents-e2e.mjs TMPDIRworktree/.omo/tmp SENPI_BIN/opt/homebrew/bin/senpi TASK_E2E_OUT_DIRevidence-dir node packages/omo-senpi/scripts/qa/task-e2e.mjs这两条命令通过环境变量注入运行参数语义如下环境变量作用TMPDIR指向 worktree 内.omo/tmp隔离沙箱与系统临时目录SENPI_BIN指定真实的 senpi 可执行文件路径示例为 macOS Homebrew 路径按平台替换CURATED_AGENTS_E2E_OUT_DIRcurated E2E 的判定结果verdict JSON输出目录TASK_E2E_OUT_DIRtask E2E 的证据输出目录E2E 脚本是验证体系中最重的环节其工作流见 curated-agents-e2e.mjs前置隔离快照对真实~/.senpi/agent目录做内容摘要digestDirectory、凭据摘要credentialDigest与目录快照snapshotDir种子沙箱seedScenario()创建沙箱写入.omo/omo.json分类配置、mock-script.json预编排的 child/parent 步骤脚本与qa-probe.ts探针文件驱动 senpi以--provider omo-mock --model mock-1等参数 spawn 真实 senpi 二进制注入SENPI_CODING_AGENT_DIR、XDG_CONFIG_HOME等隔离环境事后分析读取 task 记录、事件日志、child 上下文运行 curated-agents-e2e-analysis.mjs 的检查矩阵隔离复核再次对真实~/.senpi/agent做摘要断言凭据摘要未变real_senpi_untouched并归类沙箱运行造成的变更产出判定所有检查项为PASS才输出PASS结果并可选写入curated-agents-e2e.json证据文件。E2E 使用的 mock providercurated-agents-e2e-mock-provider.ts从127.0.0.1的本地 mock completions 服务提供回退模型gpt-5.6-luna-fastEXPLORE_FALLBACK_MODEL其注释明确说明curated explore child 以 in-process 方式运行senpi 从 provider 配置重建 in-process child 请求无baseUrl的配置会被直接拒绝因此 child 永远不会到达扩展的streamSimple——这正是child 路径可观察且离线的实现基础。构建检查器的演进从 mtime 与手工清单到内容摘要验证文档指出了一项关键设计变化构建检查器不再比较 mtime也不再维护手工维护的 source-root 列表。旧方案的两个缺陷是mtime 比较容易因文件系统行为产生误报/漏报手工清单一旦漏掉某个源码文件bundle 悄然过期也不会被发现。新方案build-extension.mjs基于四个输入计算一个确定性内容摘要完整的 Bun metafile 输入图buildEntry以--metafile产出*.meta.jsondigestBuildSources读取其inputs键并排序build-extension.mjs稳定的相对输入路径toPortableBuildPath(relative(repoRoot, inputPath))将路径归一为相对仓库根的稳定形式避免绝对路径污染摘要构建设置BUILD_SETTINGStarget、format、minify 选项、loader 别名等见 build-extension.mjs构建脚本自身readFile(fileURLToPath(import.meta.url))把脚本本体纳入哈希构建逻辑本身的改动同样触发过期判定。摘要算法为 SHA-256逐个输入文件累积更新。--check模式build-extension.mjs的流程是在系统临时目录mkdtemp中重新构建全部六个产物——omo.js、omo-task.js、omo-member.js、memory-run-supervisor.mjs、omo-init-deep-advisor.js与runtime/agent-toolkit-sdk/sdk.js——然后独立验证检入产物的正文摘要将重建产物与检入产物逐项比较artifactsMatch。在仓库外临时目录重建是一个刻意的隔离设计注释说明若在 repoRoot 内重建输出树会成为被哈希源码的临时兄弟某些 CI 上会导致 sidecar 产物与外部目录构建不一致673 vs 672 个模块输入相同——因此--check的校验过程绝不污染它要验证的源码树。回归测试的三类断言build-extension.test.mjs 的回归测试验证了三类行为主图包含 curated 只读 bash 实现断言构建输入图中包含packages/senpi-task/src/runners/in-process/curated-readonly-bash.ts。这直接回应传递性 bundle 新鲜度——curated 工具的实现文件必须被纳入 bundle 依赖图否则摘要机制无从感知其变更旧产物 mtime 通过检查即旧文件的时间戳不影响新鲜度判定证明检查完全基于内容摘要而非 mtime篡改失败分别篡改产物正文或源码标记body or source-marker tampering断言checkExtensionCurrent返回stale-output。测试通过复制已构建产物树到独立临时目录进行可变操作见 build-extension.test.mjs避免污染共享构建。为什么这样就够了被拒绝边界的一一对应验证文档给出的核心论断是该套件覆盖了每一个被拒绝的边界。逐条对照源码与测试显式模型的禁用disablement with an explicit modelE2E 中 parent 调用subagent_type: explore与subagent_type: nonexistentcurated-agents-e2e-scenarios.mjs分析器断言record_model_source的resolved_model.source agent并断言 parent 输出包含未知 target 的错误清单Available agents: explore, librarian, ...证明即便显式指定模型curated 解析仍走 agent 定义路径不可覆盖的 in-process 执行unoverrideable in-process executionexplore.ts的executionMode: in-process与 execution-mode.ts 的强制逻辑构成双保险E2E 通过真实 senpi 二进制验证 child 以 in-process 方式重建mock provider 注释为证无 shell 的只读远程研究shell-free read-only remote researchcurated-readonly-bash.ts仅允许curl与ghexecFile直接调用可执行文件而不经过 shell参数经白名单校验CURL_BOOLEAN_FLAGS、GH_API_VALUE_FLAGS等集合E2E 中bash --output forbidden-via-bash.txt被拒绝并断言沙箱中该文件不存在bash_forbidden_file_absent完整的回退字面量complete fallback literalsmock provider 从本地服务提供回退模型E2E 断言 child 上下文中出现EXPLORE_PERSONA_SENTINELYou are a codebase search specialist.与EXPLORE_TASK_SENTINELOMO_CURATED_EXPLORE_E2E_20260719证明回退路径的提示词与工具面完整可观察独立的实时分析期望independent live-analysis expectationscurated-agents-e2e-analysis.mjs 的检查矩阵独立于 senpi 实现声明期望值record_tool_allow逐项对比EXPECTED_EXPLORE_TOOL_ALLOWread、find、grep、ls、bash、lsp_diagnostics 等 9 项、mutation_tools_hidden断言 child 上下文不可见edit/write、bash_mutation_rejected断言 bash 事件存在is_error记录传递性 bundle 新鲜度transitive bundle freshnessmetafile 输入图摘要涵盖所有传递依赖--check在隔离临时目录重建比对文档准确性documentation accuracymarkdown-link-audit.test.ts 遍历git ls-files *.md的全部检入 Markdown解析行内链接、引用式链接、嵌套链接与角括号目标剥离代码块与行内代码后断言每个本地目标都存在且不包含维护者本机路径/Users/...、/home/...——这保证了文档与仓库实际文件的一致性所有任务证据文件all task evidence filestask-e2e.mjs负责验证任务证据文件的完整性与正确性证据统一输出到TASK_E2E_OUT_DIR指定的目录。明确遗漏与证据边界验证文档在测了什么之外同样诚实地声明了没测什么这是该文档方法论中值得注意的部分未发起任何真实外部模型请求全部模型交互由本地 mock 完成E2E 完全离线可重复未复制任何用户凭据、认证头、原始环境或完整转录沙箱隔离通过摘要比对real_senpi_untouched、credentialIsolationClean保证真实~/.senpi/agent不被触碰.omo/**下的证据有意不提交CURATED_AGENTS_E2E_OUT_DIR与TASK_E2E_OUT_DIR写入的是运行时证据属于工作区内的临时产物不进入版本库。这三条边界共同定义了本套验证的信任半径在不接触真实凭据、不产生外部依赖的前提下通过内容摘要、沙箱与 mock 的组合把 curated Agent 的全部被拒绝边界变成可断言、可重复、可回归的检查项。小结从what-tested.md记录的九条命令出发本文还原了 omo-senpi curated read-only Agent 验证体系的完整面貌类型检查保证契约形状、单元测试钉死参数级安全策略、构建内容摘要消灭产物过期类漂移、双层 E2E 用真实二进制在沙箱中验证运行时行为而为什么够了与明确遗漏两节则给出了判定充分性的判据与信任边界。对任何需要在子代理系统中实施只读 Agent 约束的团队这条命令矩阵 → 边界枚举 → 摘要校验 → 沙箱隔离的路线都具备直接的可移植性。【免费下载链接】oh-my-openagentOmO: Just type mass ulw keyword with your prompt. Now you are the master of graph engineering.项目地址: https://gitcode.com/gh_mirrors/oh/oh-my-openagent创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考