
oh-my-openagent 的 ULW 自动续跑指令深入解析 omo-codex 的 ulw-execute-continuation 机制【免费下载链接】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导读在 oh-my-openagentOmO的 omo-codex 插件中ulw-execute-continuation组件为 Codex 会话提供了一条自动续跑指令directive当代理正处于一份 Prometheus 工作计划ULW plan的执行中途时每次 Codex Stop hook 触发都会把这条指令注入模型上下文要求它不询问、不停顿而是持续推进直至顶层复选框全部勾选。本文以 directive.md 为骨架结合组件源码与测试完整讲解指令的字段结构、执行协议、硬性约束、最终门禁Final gate与停止条件并给出可复现的本地验证方法。读完本文你将掌握该指令的每个占位符含义、hook 注入链路、计划清单解析规则以及外部阻塞逃生口的准确用法。一、背景为什么需要一条自动续跑指令ULW在 OmO 中对应 mass ulw 关键词触发的工作模式要求代理把一次大任务拆解为带顶层复选框top-level checkbox的 Markdown 计划并逐项推进。但 Codex 的会话存在天然的回合turn边界一轮回复结束、用户没有新输入时会话可能停下来等待。ulw-execute-continuation要解决的就是这个缝隙——让代理在本回合结束时自动继续执行下一项任务直到整份计划完成。这条指令的载体是 Codex Stop hook。注册关系见 hooks/hooks.json{ hooks: { Stop: [ { hooks: [ { type: command, command: node \${PLUGIN_ROOT}/components/ulw-execute-continuation/dist/cli.js\ hook stop, timeout: 10, statusMessage: (OmO 5.0.0-beta.74) Checking Ulw-Execute Continuation } ] } ] } }每当 Codex 准备停止Stop 事件时该命令被调用。CLI 入口在 cli.ts 中实现从 stdin 读取 JSON payload调用runStopHook若返回非空则原样输出。CLI 同时支持hook subagent-stop子命令但该通道被刻意去接de-wired即不注入根计划、不输出任何内容防止子代理被错误续跑。二、指令的模板结构与占位符directive.md本身是一个模板每次注入前codex-hook.ts 中的renderDirective会读取原始文件见 directive.ts并把{{PLACEHOLDER}}替换为当前计划的实际状态。模板支持以下占位符占位符含义替换来源{{PLAN_NAME}}活动计划的名称boulder.json中works[].plan_name{{PLAN_PATH}}活动计划的 Markdown 路径works[].active_plan解析后的路径{{BOULDER_PATH}}Boulder 状态文件路径固定为cwd/.omo/boulder.json{{REMAINING_COUNT}}剩余顶层复选框数getPlanChecklist统计{{TOTAL_COUNT}}顶层复选框总数getPlanChecklist统计{{NEXT_TASK_LABEL}}下一个未完成任务的标签首个未勾选复选框的文本无则显示none (final gate pending){{WORKTREE_BLOCK}}工作树声明块当works[].worktree_path存在时渲染为一条- Worktree: ...行否则为空{{LEDGER_PATH}}证据台账路径固定为cwd/.omo/ulw-execute/ledger.jsonl{{SESSION_ID}}当前 Codex 会话 id替换为带codex:前缀的会话 id从源码看renderDirective用String.prototype.replaceAll逐项替换codex-hook.ts因此即使模板被修改只要占位符约定不变注入逻辑即可复用。三、指令要求代理这一回合做什么指令的核心执行协议分为 10 步任何一轮续跑都必须遵循先读计划与台账{{PLAN_PATH}}与{{LEDGER_PATH}}是唯一事实来源禁止依赖对先前回合的记忆。判断剩余数剩余数为 0 时跳过复选框执行直接进入 Final gate否则选择## TODOs或## Final Verification Wave下第一个未勾选的顶层复选框忽略 Acceptance Criteria / Evidence / Definition of Done 下的嵌套复选框。完整遵循ulw-execute技能技能文件位于 SKILL.md组件 README 明确指向该路径上下文丢失时可重新读取。划分任务层级tier默认 LIGHT——窄变更、存在于现有层内只需一条真实表面real-surface证据HEAVY——新模块/抽象、认证安全、外部集成、schema/迁移、并发、跨域重构等必须执行完整的逐标准验证体制。不确定时取 HEAVY绝不降级。原子子任务并行派发通过multi_agent_v1.spawn_agent并行派发除非子任务存在具名阻塞依赖fork_context: false优先若使用multi_agent_v2需传task_name、fork_turns: none且wait_agent只接受timeout_ms。子任务消息必须自包含以TASK: 指令开头包含DELIVERABLE、SCOPE、VERIFY全部七段并带一个 Manual-QA 通道HTTP 用curl -iTUI 用send-keys做启动冒烟、xterm.js Web 终端做色彩/视觉证据禁止tmux capture-pane浏览器在 Codex 中用browser:control-in-app-browser其余场景用 playwright-core 脚本等给出精确调用方式与 PASS/FAIL 可观测结果。不信任 DoneClaim任何 worker 声称完成都必须经过独立的 AdversarialVerify只有confirmed是唯一通过判定false-positive、needs-fix、needs-human-review会带精确反馈打回执行者。正确解读 mailbox 信号wait_agent超时只代表没有新消息不代表子代理完成长任务要求先发WORKING: task - phase卡住才发BLOCKED: reason对已完成但缺交付物的子代理发送TASK STILL ACTIVE: return deliverable or BLOCKED: reason仍无响应则记录 inconclusive、安全关闭并以更小粒度重新派发。勾选与台账验证全部子任务后用apply_patch将- [ ]改为- [x]重读计划确认计数下降再向台账追加一条task-completed记录。失败不重开子代理失败时以FAILED: exact errorDiagnosis: observationFix: instruction的修复消息重新派发而不是从头再来。四、硬性约束什么才算真实证据指令对证据的定义极其严格这部分对应了组件测试中反复验证的质量门槛先有失败证明后有产品代码必须有一条接缝处的单元测试或子任务 Manual-QA 场景先录得失败仅镜像实现mock 调用断言、固定常量的测试不算证据。改动既有行为时先做 PIN——在未改动代码上跑通的基线特征化测试要求精确输入、精确可观测结果、精确断言再按 PIN → RED → GREEN → SURFACE 推进。--dry-run不算证据should work不算证据tests pass不算完成证明。TUI 视觉证据必须走真实 xterm.js Web 终端运行node script/qa/web-terminal-visual-qa.mjs --title surface --command cmd --input {Enter} --evidence-dir dirlive pty Chrome 内 xterm.js--from-file capture可重放原始流并引用terminal.png、terminal.txt、metadata.json。禁止as any/ts-ignore/ts-expect-error禁止删除失败测试。逐一探测 ultraqa 对抗类凡是触发事实成立的对峙类畸形输入、提示注入、取消/恢复、陈旧状态、脏工作树、挂起或长命令、flaky 测试、误导性成功输出、反复中断都必须记录可观测结果适用类未探测时仅靠干净的 happy-path 产物不算 PASS跳过的类要写一行 not-applicable 理由。清理回执cleanup receipt是强制的QA 产生的一切 teardown脚本、tmux、浏览器上下文、PID、端口、容器、临时目录要注册为 todo 并执行残留 QA 状态 BLOCKED 而非 PASS。工作树边界若boulder.json设置了 worktree 路径所有文件编辑与命令都必须在其中进行不得越入主仓库PR/分支相关的工作必须使用任务所有的 git worktree主工作树只作只读上下文。会话 id 前缀写入boulder.json的session_ids必须带codex:前缀裸 id 在读取时按opencode:旧格式处理。五、Final gate完成前的最后一道门当所有顶层复选框勾选后指令要求代理先完成以下动作再宣告结束在真实表面real surface上运行自己的手动 QA并对照每一条验收标准做自审只有当用户明确要求 strict / rigorous / high-accuracy 审查时才派发一个门禁审查者gate reviewer且每个子任务最多一次仅在观察到失败时才运行debugging运行时审计将可观测证据记录到{{LEDGER_PATH}}未通过门禁前不得创建 PR、不得做 PR/分支交接、不得合并、不得输出最终完成答复。PR/分支工作的收尾也有明确模式停留在任务所有的 worktree 中创建/更新 PR等待 CI/review/Cubic 门禁默认合并除非显式退出然后清理。门禁与生命周期通过后在最终答复前把 Boulder 工作标记为 completed。最后必须脱敏 secrets、tokens、凭据、认证头、cookies、环境转储、日志与 PII并遵循会话开始时记录的交付模式--make-pr在 PR 打开后以 PR URL 交接仅用户显式要求才合并--ship则持续工作直到 PR 被 MERGED修复 CI 与 review 门禁随后删除 worktree 并同步.omo/状态。六、本回合的停止条件什么情况下回合真的结束指令定义了五种可被 Stop hook 识别并放行的停止情形正常推进某顶层复选框在五阶段 QA 门禁Phase 1 读取、Phase 2 自动化、Phase 3 通道场景、Phase 4 对抗类探测、Phase 5 门禁决策后翻转为- [x]Stop hook 重新评估若仍有复选框则再次续跑。外部阻塞只有用户或外部状态才能清除的阻塞缺硬件、凭据、授权或服务不可用——经过一次权威检查后停止重试与派发审查者以ulw-execute-blocked-external作为答案的整首行随后说明精确阻塞点与恢复工作的可观测条件。三次失败同一 agent 可控子任务上出现 3 次实质不同的失败修复尝试后最多派发一次严格审查者仍被阻塞则按第 2 种标记交接。安全边界遇到破坏性命令、机密外泄或生产写入时停止并提供安全的替代方案。全部完成所有顶层复选框- [x]且 Final gate 通过输出 ORCHESTRATION COMPLETE 块并结束。输出纪律同样重要只汇报状态变化派发了哪个子代理、场景 PASS/FAIL 及产物路径、勾选了哪个复选框、追加了什么证据禁止打印 Should I continue?、复述计划或回顾先前回合——续跑由 Stop hook 驱动台账与计划才是持久记录。七、Hook 侧实现boulder 状态读取与清单解析指令的注入并非无条件。runStopHookcodex-hook.ts在任何以下情况返回空串即不阻塞、不续跑payload 不是合法的 Stop 输入stop_hook_active为 true、字段不完整等上一条助手消息带有合法的外部阻塞标记transcript 中出现上下文压力标记如context compacted、context_length_exceeded、codex ran out of room in the models context window等见 codex-hook.ts——这是防止在上下文被压缩后继续蛮干的自保机制boulder.json中不存在活动工作、工作已完成、工作不属于当前codex:session_id或计划无可读的顶层清单。状态解析在 boulder-reader.ts 中完成读取cwd/.omo/boulder.json同时兼容works映射结构与单工作mirror结构按updated_at/started_at选中最新的属于当前会话的工作只有active或paused状态可续跑。若工作声明了worktree_path计划路径会优先解析到 worktree 内不存在时才回退主仓库。清单计数在 plan-checklist.ts 中实现规则与指令第 2 步完全一致结构化模式下只统计## TODOs与## Final Verification Wave两个节下的列 0 复选框TODO 项形如- [ ] N. ...Final Wave 项形如- [ ] F1. ...###级嵌套复选框不计无结构化节时退化为简单清单解析任意顶层- [ ]/- [x]代码块栅栏内的内容被跳过避免把示例误当任务结果输出completed / remaining / total / nextTaskLabel正是{{REMAINING_COUNT}}、{{TOTAL_COUNT}}、{{NEXT_TASK_LABEL}}的数据来源。八、外部阻塞逃生口正确书写与 hook 识别ulw-execute-blocked-external是让回合正常结束的唯一用户介入通道。指令要求它在两种位置出现作为答案的整首行第一行若 ultrawork 需要ULTRAWORK MODE ENABLED!作为第一行则标记单独放在第二行。hook 侧codex-hook.ts不仅校验标记位置还要求标记之后的后续行中存在非空内容——即必须写出精确阻塞点与恢复条件。这一设计避免了裸回声代理把提示词中的标记原样复读绕过续跑守卫。只有标记出现在正文中间、后续讨论中时计划仍会继续。九、本地验证Smoke Test 复现注入行为组件 README 给出了完整的本地验证流程可在不启动 Codex 的情况下观察 hook 输出。核心步骤创建临时目录与计划文件、写入boulder.json、把 Stop payload 通过 stdin 管道交给 CLITMP$(mktemp -d) mkdir -p $TMP/.omo/plans cat $TMP/.omo/plans/test.md EOF ## TODOs - [ ] Task one - [ ] Task two EOF cat $TMP/.omo/boulder.json EOF {schema_version:2,active_work_id:w1,works:{w1:{work_id:w1,active_plan:.omo/plans/test.md,plan_name:test,session_ids:[codex:smoke-session],status:active}}} EOF PAYLOAD{session_id:smoke-session,turn_id:t1,transcript_path:,cwd:$TMP,hook_event_name:Stop,model:gpt-5.5,permission_mode:default,stop_hook_active:false} npm run build echo $PAYLOAD | node dist/cli.js hook stop PAYLOAD_LOOP{session_id:smoke-session,turn_id:t1,transcript_path:,cwd:$TMP,hook_event_name:Stop,model:gpt-5.5,permission_mode:default,stop_hook_active:true} echo $PAYLOAD_LOOP | node dist/cli.js hook stop rm -rf $TMP预期行为第一条命令输出包含decision:block的 JSONreason 即渲染后的 directive 全文第二条stop_hook_active: true即正在运行 Stop hook 的防循环场景输出为空向hook subagent-stop传入 SubagentStop payload 同样无输出。组件测试 codex-hook.test.ts 与 boulder-reader.test.ts 覆盖了这些分支包括计划全部完成时仍阻塞直至 Final gate 通过、以及 worktree 路径解析等细节。十、设计要点小结无网络、无遥测该组件只读取本地 hook payload、.omo/boulder.json、活动计划与内置 directive不做任何网络调用也不存储遥测见 README.md 的 Privacy 一节。注入即续跑block 完整指令正文 告诉 Codex 继续工作这与普通的阻塞等待用户语义相反是 ULW 自动推进的关键。证据优先指令用大量篇幅约束证据标准PIN → RED → GREEN → SURFACE、对抗类探测、清理回执从源头防止看起来完成了的假阳性。会话隔离codex:前缀与session_ids匹配确保每个会话只续跑自己的活动工作多平台会话opencode:旧格式在读取时被归一化兼容。【免费下载链接】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),仅供参考