news 2026/9/19 23:10:01

omo-senpi 适配器 Live 驱动验证:DAG 依赖前沿(dependency-frontier)调度变更的隔离沙箱端到端证据

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
omo-senpi 适配器 Live 驱动验证:DAG 依赖前沿(dependency-frontier)调度变更的隔离沙箱端到端证据

omo-senpi 适配器 Live 驱动验证:DAG 依赖前沿(dependency-frontier)调度变更的隔离沙箱端到端证据

【免费下载链接】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

本文讲解 omo-senpi 适配器(packages/omo-senpipackages/senpi-task)在调度器语义变更时的 Live 验证方法论:如何用drive.mjs驱动真实 senpi 进程严格隔离的沙箱中加载重新生成的omo-task.js扩展包,并通过resolve-evidence-dir.mjs把证据写入仓库唯一的规范目录。文章以20260825-dag-dep-frontier变更(DAG 调度器以"依赖前沿准入"取代"严格 wave 屏障")为完整案例,读者可借此掌握 senpi 适配器的隔离 QA 流程、结果 JSON 解读与覆盖边界判断。

一、场景起点:一次 DAG 调度变更为何需要 Live 验证

2026-08-25 的 incidentdag_530ad299(sisyphuslabs "omo startup fixes PR wave")暴露了 DAG 调度器的一个真实缺陷:严格 wave 屏障(strict barrier)让 wave N+1 只能等待 wave N 最慢的节点全部结束,即使某个节点的依赖早已就绪,也会被无关的兄弟节点阻塞。修复分支fix/dag-dep-frontier将准入语义改为依赖前沿(dependency-frontier):节点准入只看"每个dependsOn节点是否completed+ 是否有空闲 resident 槽位",不再等待整波静止,详见变更证据 .omo/evidence/20260825-dag-dep-frontier/README.md。

关键点在于:调度器变更会被打进packages/omo-senpi/plugin/extensions/omo-task.js(minified 重写 + build marker)——重新生成的 bundle 才是调度器变更真正对外发布的表面。因此仅靠引擎级单元测试还不够,必须验证"真实 senpi 进程能否加载这个重新生成的 bundle,且适配器在 live harness 上仍然工作"。这正是本文主角——Live Senpi 驱动验证——的职责:

  • 驱动脚本:packages/omo-senpi/scripts/qa/drive.mjs(含--self-test
  • 验证对象:分支 worktree 上重新生成的omo-task.js扩展包
  • 运行方式:一个真实senpi会话加载插件,跑在 driver 自建的隔离沙箱中
  • 证据落盘:.omo/evidence/omo-senpi-adapter/20260825-dag-dep-frontier/

二、证据目录契约:resolve-evidence-dir.mjs 唯一路径

Live Senpi QA 的证据只能放在.omo/evidence/omo-senpi-adapter/<slug>/,这是仓库级约定(根目录AGENTS.md与 senpi-qa 技能共同指向的规范位置)。手工输入的替代路径(local-ignore/qa-evidence/...、临时目录、路径穿越)会静默地把证据丢弃在 PR 无法引用的地方,因此解析路径必须走脚本而不是约定。

resolve-evidence-dir.mjs(.agents/skills/senpi-qa/scripts/resolve-evidence-dir.mjs)只做"计算 + 校验",不创建目录

ev="$(node .agents/skills/senpi-qa/scripts/resolve-evidence-dir.mjs \ --repo-root "$(git rev-parse --show-toplevel)" --slug 20260825-dag-dep-frontier)" mkdir -p "$ev"

校验规则(源码见resolveEvidenceDirSAFE_SLUG正则/^[a-z0-9]+(?:-[a-z0-9]+)*$/):

约束说明
repoRoot 必须是 git worktree根目录下必须存在.git,否则以非零退出码拒绝
slug 必须是单个相对段小写字母、数字、单连字符;/...、路径穿越、绝对路径全部被正则拒绝
只解析不创建目录是否出现由调用方决定,被拒绝的 slug 不会留下游离目录
输出为绝对路径stdout 打印,退出码 0 表示通过

三、drive.mjs 隔离沙箱:让真实 senpi 运行在受控环境

3.1 沙箱结构与种子文件

createSandbox()在系统临时目录(mkdtempSync(join(tmpdir(), "omo-senpi-qa-")))下创建一整套隔离目录,并用realpathSync.native解析出规范路径,防止符号链接逃逸(drive.mjs 中createSandbox/seedSandbox):

沙箱成员用途
root任务专属沙箱根(如.../omo-senpi-qa-GAEzts
project沙箱工作目录(cwd)
agent隔离的 SENPI/OMO/PI coding agent 目录
xdg/xdg-data/xdg-cache隔离的 XDG 三目录
home隔离的 HOME

seedSandbox在 agent 目录写入两个关键文件:

  • settings.json{"defaultProjectTrust": "ask", "packages": [pluginRoot]}——只加载被测插件包(packages/omo-senpi/plugin),不继承开发者的真实配置;
  • trust.json{ "<canonicalCwd>": true }——只信任沙箱项目目录。

注释(源码原文)特别指出:omo 配置加载器从XDG_CONFIG_HOME读取用户作用域,如果不隔离,每条 lane 都会继承开发者真实的~/.config/omoagents 与 categories,结果就不可复现

3.2 环境变量隔离与"调用者目录被忽略"

runSenpi派生子进程时强制覆写环境变量(drive.mjs):

OMO_CODING_AGENT_DIR / SENPI_CODING_AGENT_DIR / PI_CODING_AGENT_DIR → 沙箱 agent 目录 HOME / USERPROFILE → 沙箱 home XDG_CONFIG_HOME / XDG_DATA_HOME / XDG_CACHE_HOME → 沙箱 xdg 三目录 PI_OFFLINE=1, OMO_SENPI_QA=1

其中最关键的行为:driver 会忽略调用者通过环境变量传入的SENPI_CODING_AGENT_DIR。证据 JSON 中providedSenpiCodingAgentDir: "IGNORED"即表示调用者提供的目录被设计性地无视——driver 永远使用自己新建的沙箱 agent 目录,因此真实的~/.senpi/agent永远不会被写入(对应 SKILL.md 的黄金规则:"The real agent dir stays untouched")。runSelfTest也会显式断言沙箱目录不等于process.env.SENPI_CODING_AGENT_DIRprocess.env.XDG_CONFIG_HOME

3.3 认证根目录(certification roots)

为了证明隔离真实有效,driver 会在沙箱内预置"认证根目录"并做前后快照对比(seedCertificationRoots/snapshotCertificationRoots):

  • 沙箱 home 下的~/.senpi/agent~/.omo/agent(预置PROTECTED_STATE_FILES各文件与persistent-state.json);
  • 三个 xdg 目录各写入.qa-sentinel哨兵文件。

同时用snapshotProtectedState/snapshotRealObserved真实~/.senpi/agent~/.omo/agent做前后快照。最终realSenpiUntouched: true只有在目录身份可用(directoryIdentityAvailable())且 senpi 判定为 untouched 时才为真——注意 SKILL.md 的提醒:整目录 digest 是佐证而非证明本身,结论要看 changed-path / untouched 字段。

四、验证流程:--self-test 与 live run 的判定逻辑

drive.mjs的入口分支(import.meta.url判定):带--self-testrunSelfTest(),否则走main()

4.1--self-test:先证明 harness 本身可靠

runSelfTest()创建沙箱、种子化、然后断言:

  • trust.json包含规范 cwd;
  • 沙箱 agent 目录不等于调用者传入的SENPI_CODING_AGENT_DIR(未被复用);
  • 沙箱 xdg config home 不等于调用者的XDG_CONFIG_HOME
  • 沙箱 xdg config home 确实存在;
  • 不存在的目录 digest 应为absent

全部通过输出SELF-TEST OK(即证据文件 drive-self-test.txt 的内容)。

4.2 Live run:两个真实 senpi 会话

main()的流程(scheduler 变更验证时实际执行):

  1. 前置快照:对真实~/.senpi/agent~/.omo/agent做保护态与观测态快照;
  2. 二进制解析SENPI_BIN环境变量指定 senpi 路径;若含/但文件不存在,或 PATH 上找不到,则结果为SKIP(reason:senpi-binary-unavailable)——无二进制时报 SKIP/FAIL 而不是静默降级到真实 home(黄金规则);
  3. 会话一(ultrawork 注入):以senpi -e <environment-receipt-entry> -e <mock-provider-entry> -p --provider omo-mock --model mock-1 "ulw please respond"启动,mock 脚本为steps: [{type:"text", text:"ultrawork scenario complete"}]。判定ultraworkInjected:子进程退出码为 0,且沙箱 agent 目录内收集到的.json/.jsonl/.log/.md文本包含<ultrawork-mode>标记;
  4. 会话二(comment-checker):以"write qa slop"提示词驱动 mock 的write工具调用写出qa-slop.ts,并通过OMO_COMMENT_CHECKER_BIN注入 comment-checker CLI(resolveCommentCheckerBincreateRequire从仓库解析@code-yeongyu/comment-checker/cli.js)。判定commentChecker:退出码 0 且沙箱文本包含comment-checker found issues in头则PASS,否则FAIL;找不到二进制则为SKIPPED-no-binary
  5. 汇总判定
result = ultraworkInjected && (commentChecker === "PASS" || commentChecker === "SKIPPED-no-binary") ? "PASS" : "FAIL"
  1. 收尾finallyrmSync(sandbox.root)删除任务专属沙箱(omo-senpi-qa-*目录在运行后被清理,driver 已退出,不留 QA 子进程)。

五、结果解读:drive-live.txt 逐字段

本次运行的证据 JSON 见 drive-live.txt:

{"result":"PASS","ultraworkInjected":true,"commentChecker":"PASS","realSenpiUntouched":true,"providedSenpiCodingAgentDir":"IGNORED","sandboxAgentDir":".../omo-senpi-qa-GAEzts/agent","sandboxCwd":".../omo-senpi-qa-GAEzts/project"}
字段含义
resultPASSultrawork 注入成功且 comment-checker 通过(或按设计跳过)
ultraworkInjectedtrue真实 senpi 会话加载插件后注入了<ultrawork-mode>
commentCheckerPASScomment-checker 在隔离会话中工作并识别出问题
realSenpiUntouchedtrue真实的~/.senpi/agent未被写入
providedSenpiCodingAgentDirIGNORED调用者传入的 agent 目录被设计性忽略,符合预期
sandboxAgentDir.../omo-senpi-qa-GAEzts/agent沙箱内隔离的 agent 目录
sandboxCwd.../omo-senpi-qa-GAEzts/project沙箱工作目录

printResult完整输出还包含isolationCertifiedrealHomeIsolationCertifiedcertificationLanerealSenpiChangedPathsobservationLimitsprotectedStateFilesrealHomesChecked等字段(见 drive.mjs 中printResult的 payload 构造),供证据 README 引用 changed-path / isolation 字段。

清理观察:任务专属沙箱omo-senpi-qa-GAEzts在运行后被删除;driver 已退出,因此本次 QA 不残留子 PID。主机上长期存在的 senpi 进程属于用户全局 omo-ai 安装(~/.bun/install/global/...),与本 QA 无关。

六、为什么这就够了:覆盖边界与省略项

关联证据文档明确论证了"为什么 Live 驱动证明已足够":

  • bundle 即发布表面:重新生成的omo-task.js是调度器变更的对外载体;真实 senpi 进程端到端加载它,证明 bundle 可加载、适配器在 live harness 上仍然工作;
  • 准入语义由引擎级测试证明:admission 语义本身是 engine-level 的,由20260825-dag-dep-frontier目录中的 failing-first 回归证明;senpi-qa 路由表将 "DAG state machine / runners" 映射到bun test packages/senpi-task不存在专门的 live DAG-admission driverdag-gate-proof.ts只是 manager 级 start 校验)——这与兄弟 PR #7320 的作用域决策一致。

明确的省略项(原文记录)

  • task-e2e.mjs/team-e2e.mjs未运行:它们演练 task/team 引擎,而本 PR 不修改该引擎(DAG 通过不变的startOwned契约驱动它,由bun test packages/senpi-task与消费方 gate 覆盖);
  • 捕获的 JSON 中不包含任何 secrets、token 或凭据

七、配套门禁:回归 RED/GREEN 与引擎级 gate

Live 驱动只是证据链的一环,DAG 变更本身由完整门禁矩阵支撑(见 .omo/evidence/20260825-dag-dep-frontier/README.md):

门禁结果
bun test packages/senpi-task/src/dag/scheduler-frontier.test.ts(pristineorigin/devRED:适配后的 R2 回归在 barrier 上失败(red-origin-dev.txt
同一测试(本分支)GREEN(green-branch.txt
bun test packages/senpi-task×21749 pass / 1 skip / 0 fail(rebased 后 1753 pass / 1 skip / 0 fail,dag suite 250 pass / 0 fail)
tsgo --noEmit -p packages/senpi-task/tsconfig.json通过,exit 0
bun test packages/omo-senpi/src/components/task483 pass / 0 fail(消费方 wiring:dag tool + runtime)
bun test packages/omo-senpi/src/bundle-size.test.ts1 pass / 0 fail(重新生成的 bundle 体积)
node packages/omo-senpi/scripts/qa/drive.mjs(+--self-test{"result":"PASS",...,"realSenpiUntouched":true}

回归测试精确钉住生产症状(就绪的依赖节点被无关的 running 兄弟节点饿死),且是事件驱动、journal-backed(whenStarted/状态订阅,无 sleep),不会靠时序运气通过。

值得注意的连带变化:SCHEDULER_FINGERPRINT_INPUT.waveAdmissionstrict-barrier迁移到dependency-frontier(manager 层、fingerprint.ts中定型)——准入语义变化时指纹输入必须变化,否则旧指纹下的运行不会被复用:同一 key 重新提交同一定义会报definition_conflict,直到 7 天保留期清理该 key。

八、写在最后:Live 驱动的适用边界

从 .agents/skills/senpi-qa/SKILL.md 的路由表可以总结出适用范围:Live driver 是 harness 证明,单元测试不算 Live QA。修改适配器 wiring 时用drive.mjs(快速前置条件先跑--self-test),改 DAG 状态机/runner 时跑bun test packages/senpi-task(单元 + chaos 不变量),两者各司其职。每条证据 README 都必须包含仓库统一的四段式(tested / observed / why it is enough / omitted),并记录 driver 的 changed-path / isolation 字段与沙箱 agent 目录路径;若 driver 未自删沙箱,调用方必须在写入清理回执前删除任务专属沙箱并确认子 PID 已终止。

一句话总结这套方法论的核心:用真实进程、隔离沙箱、可复现路径,把"bundle 可加载、适配器仍工作、真实 home 未被碰"变成一份 reviewer 无需重跑即可审计的 JSON 证据。

【免费下载链接】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),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/19 23:09:07

MATLAB改进秃鹰算法:从混沌初始化到Levy飞行扰动

1. 为什么要在MATLAB里做"改进秃鹰算法"如果你最近在调研智能优化算法&#xff0c;大概率见过秃鹰搜索算法的名字。它是Alsattar等人在2020年提出的一类新型元启发式算法&#xff0c;全称Bald Eagle Search&#xff08;BES&#xff09;&#xff0c;灵感来自秃鹰在捕食…

作者头像 李华
网站建设 2026/9/19 23:07:00

沪深300期现套利:可量化的对冲收益工程

简介&#xff1a;本资源是一份面向金融从业者、量化交易学习者及高校财经专业学生的沪深300股指期货期现套利策略教学PPT&#xff0c;系统讲解低风险绝对收益型套利逻辑与实操要点。内容覆盖套利原理&#xff08;基于期货交割制度与期现价格收敛&#xff09;、三大核心模块&…

作者头像 李华
网站建设 2026/9/19 23:06:12

10款AI工具助力学术写作效率提升

1. 学术写作工具的革命性升级去年指导本科生论文时&#xff0c;有个场景让我印象深刻&#xff1a;学生凌晨三点发来邮件&#xff0c;说查重率卡在22%降不下去。我打开他使用的传统写作软件&#xff0c;发现连基本的同义词替换功能都需要手动操作。这促使我开始系统评测AI写作工…

作者头像 李华
网站建设 2026/9/19 23:05:21

机器人仿真基础设施选型:Terraform自建还是ROS托管?

先交代背景&#xff1a;我这边主要负责机器人团队的仿真基础设施&#xff0c;Ubuntu 22.04、带显卡的云服务器、Gazebo 和 RViz 一套环境&#xff0c;说多不多&#xff0c;说少不少&#xff0c;但每来一个新人&#xff0c;靠手工搭环境能把人搭到怀疑人生。后来我开始转向 IaC&…

作者头像 李华