Relay Dispatch 是 dev-relay 技能集中的任务派发组件,用于通过 worktree 隔离将实现任务委派给执行器。
用途
Relay Dispatch 适用于以下场景:将实现工作委派给执行器(codex、claude、opencode、pi、antigravity、cursor、cline),并通过 worktree 隔离;在评审结果为 changes_requested 后恢复同一运行;为相互独立的任务运行后台或并行派发。
不适用场景:编写 rubric 或进行规划(应使用 relay-plan);评审执行器输出(应使用 relay-review);任务缺少冻结的 Done Criteria(应先用 relay-ready 锚定)。
前置条件
公开的 /relay 源门必须在本命令之前选择路由。它要求存在 Git 检出,对于本地 Reviewed Result 交付不允许配置远程仓库,对于 GitHub 路由只接受精确支持的 GitHub 远程形态。派发本身从不初始化 Git,也不选择 forge。
输入
环境变量:可选的 RELAY_SKILL_ROOT,默认为 skills。
文件:派发提示词(--prompt-file 或 --prompt)、必需的 rubric(通过 --rubric-file)、可选的 Done Criteria 文件,以及可选的仓库相对路径的复制文件。
同级脚本:${RELAY_SKILL_ROOT:-skills}/relay-dispatch/scripts/dispatch.js。
使用方式
前台(阻塞式,适用于简单任务,默认执行器为 codex): node "${RELAY_SKILL_ROOT:-skills}/relay-dispatch/scripts/dispatch.js" . -b feature-auth -p "..." --rubric-file rubric.yaml
分离式(推荐用于长时间或后台工作,可在调用方 shell 退出后继续存活): node "${RELAY_SKILL_ROOT:-skills}/relay-dispatch/scripts/dispatch.js" . -b feature-auth -p "..." --rubric-file rubric.yaml --detach --json
在 changes-requested 评审后对同一运行恢复: node "${RELAY_SKILL_ROOT:-skills}/relay-dispatch/scripts/dispatch.js" . --run-id issue-42-20260403120000000 --prompt-file review-round-2-redispatch.md
指定执行器: node "${RELAY_SKILL_ROOT:-skills}/relay-dispatch/scripts/dispatch.js" . -e codex -b feature-auth -p "..." --rubric-file rubric.yaml
后台与并行派发请参见 ../relay/SKILL.md 的 Batch Mode 章节(并行分叉流程的唯一权威来源)。
支持的执行器:codex、claude、opencode、pi、antigravity、cursor、cline。通过 --executor 选择,通过 --model 显式选择模型,省略则使用适配器提供方默认值。默认超时:codex 为 2400,claude/opencode/pi/antigravity/cursor/cline 为 1800。能力协商与适配器契约记录在 references/agent-adapter-platform.md。
主要选项
CLI 采用封闭选项契约,不支持的标志会失败关闭。
关键标志:--branch/-b 启动新的保留运行;--base <ref> 选择发布基线(默认 origin/HEAD,缺失时必填);--run-id 请求同一运行重新派发。--prompt/-p 或 --prompt-file 提供执行器提示词。--rubric-file 对新派发为必需;--done-criteria-file 冻结单独的评审锚点,否则 rubric 被冻结为 Done Criteria。--executor/-e 与 --model/-m 选择执行。使用 --run-id 时省略 --executor 以使用 run.json 中绑定的不可变执行器;显式指定不同执行器会在读取提示词或写入尝试之前失败。--model 仍按每次尝试生效。--network-access、--timeout、--reasoning、--copy 配置本次尝试;复制输入必须是仓库内包含的常规文件。
提供方控制面传输始终对受信任 CLI 可用。工具网络默认对受信任本地派发启用;显式 --network-access disabled 的高级请求需要适配器原生拒绝,无法强制执行的适配器会失败关闭。已退役的公开 --sandbox 标志会作为未知选项失败;派发始终使用可写 worktree 语义,由适配器/阶段负责其真实的原生文件系统请求。
CLI 认证、HOME、XDG 配置及支持的令牌变量来自操作者的本地环境。凭据选择器标志已移除,会作为未知选项失败;Relay 从不复制认证文件或记录其路径。
适配器保留其实际调用工具与原生能力声明。提示词措辞从不控制派发准入,也不选择不同的结果/验证契约。
--fleet-id 需要带类型的 --ownership-json,且必须精确包含 sprint、track、component;父级与所有权摘要不可变。
--detach 启动分离式派发监督进程,打印回执,并在执行器完成前返回。
--dry-run 是零写入预检,用于检查输入、分支、能力、注册支持与调用形态。其 argv 仅用于诊断,绝不能直接启动:生产环境始终使用宿主监督进程。
派发自行准入。没有写入者代际、切换标志或迁移覆盖:新运行通过对其运行目录执行非递归 mkdir 来认领,若目录已存在则失败关闭。
--json 返回结构化输出以供编排。
持久化布局为 ~/.relay/runs/<repo-slug>/<run-id>/:不可变的 run.json、done-criteria.md 和 rubric.yaml;仅追加的 events.jsonl;以及每次尝试的 prompt、log 和 result 产物。已退役的路由提示与就绪身份标志不参与派发。
Relay 直接在受信任的本地主机上运行;它没有文件系统准入或配置文件编译器。派发始终以可写 worktree 语义运行,并让每个适配器/阶段请求其真实的原生文件系统隔离(Codex 请求 workspace-write,Cursor 请求 enabled,Claude 启用其文档化的 Bash 沙箱,Antigravity 保留其声明的标志)。Pi、OpenCode 和 Cline 直接运行。前台与 dry-run JSON 返回非持久的 filesystem_isolation requested/effective 诊断;缺失或仅声明的隔离从不拒绝派发。对于敌意工作者威胁模型,请使用外部容器或 VM。
执行器尝试保留不可变输入暂存、可执行绑定、超时/取消、继承范围清理与持久事实。Relay 本身从不提交、在 GitHub 路由上发布、记录验证或关闭本地结果;这些生命周期操作属于规范的 relay-recover recover。
JSON 使用 snake_case。前台输出包含 status、run_id、run_dir、worktree、attempt_id、host_handle、host_status、outcome、inspection,以及非持久的 filesystem_isolation 和 loopback_listen。分离式启动回执包含 status: "dispatched"、这些持久身份、dispatcher_pid 以及初始 inspection。每次尝试的日志路径记录在 attempt_started 中。
超时建议
简单工作使用默认值;当实现加验证需要更多时间时使用 --timeout 3600;仅对具有长最终门禁的复杂多文件工作使用 --timeout 5400。
验证成功
将 inspection.recommended_action 视为下一步的权威。completed 表示持久宿主与适配器结果均成功;failed 表示任一侧失败;cancelled 涵盖取消与超时。不成功的终态结果会使进程以非零退出。
成功的派发会保留 worktree。--run-id 调用首先执行只读检查,仅当折叠动作与建议都精确为 redispatch 时才继续。获取运行锁后重复该检查,并要求相同的动作键,然后才写入提示词或尝试事实;终态、过期、评审、发布、合并与操作者关注动作均失败关闭。
发布不属于派发。派发记录执行器尝试并返回派生动作。使用 relay-recover inspect,然后使用幂等的 relay-recover recover 操作,在选定该路由时提交并发布精确的 GitHub PR 修订,或关闭已评审的本地结果。
Claude、Codex、OpenCode、Pi 和 Cursor 的提示词使用绑定的 stdin 传输。Antigravity 和 Cline 是显式的 argv 可见例外,提示词上限为 256 KiB,且会暴露在本地进程列表中。主评审像派发一样继承操作者的环境 HOME/XDG CLI 会话;Relay 既不发现也不复制认证文件。
失败处理
超时或取消:检查保留的 worktree 与带类型建议;绝不视为已完成。执行器或输出解析错误:读取尝试日志/结果并遵循带类型建议。恢复被拒:遵循 inspection.recommended_action;派发仅准入精确的 redispatch。发布/本地关闭失败:使用规范的 relay-recover inspect 与幂等 recover;派发不发布也不关闭。分支冲突:在 worktree 中解决,或从更新的 main 创建新 worktree。网络/瞬时错误:等待 30 秒,重试一次;若再次失败,升级给用户。
恢复与操作者工具
任何中断或外部更改的运行 → 使用规范的 relay-recover.js inspect 检查,然后仅按其带类型建议使用 relay-recover.js recover --reason ... 应用;参见 references/recovery-playbook.md。中断或外部更改的运行 → references/operator-utilities.md。
注意事项
dispatch.js 失败时以非零退出;评审前请检查。成功的派发默认保留 worktree。如果并行 PR 触及相同文件,请一次合并一个并 rebase 另一个。