关于 ship-playbook
ship-playbook 是用于执行单轮软件交付工作流的 Agent 技能,覆盖规划、构建与验证。它适合需要自选审查和审计关卡、持久化续跑检查点,并由用户决定是否修复发现项的团队。
主要功能
- 01单轮规划至验证工作流
- 02由用户选择审查与审计关卡
- 03按 DAG 任务构建和审查
- 04持久化检查点续跑
- 05集成代码树最终验证
适用场景
- 01从单条需求交付功能
- 02续跑尚未完成的构建
- 03审查发现项后由用户决定修复轮次
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ ulpi-io/ skills --skill ship-playbook安装后在 Claude Code 中输入/ship-playbook确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
helpers/wf-status.mjsreferences/build-loop.mdharness-routing.mdplaybook-state.mdstatus-tracking.mdworkflow-template.js详细介绍
输入
$request:功能提示词——要规划、构建、审核和交付什么。可以包含harness=codex或golive=yes等覆盖项,用于预填受理信息。对于修复轮次,请将先前的发现作为提示词传入。 若要从现有且已审核的 DAG 计划中恢复,请指向该计划(例如resume .ulpi/plans/<name>.md或--plan .ulpi/plans/<name>.json):本次运行会跳过规划和计划审核,从构建阶段开始。
目标
始终以相同方式,将一个提示词转化为达到交付质量的成果:运行交付手册,将其作为单个可运行的工作流,其中包括有依据的 DAG 计划、可选的创始人计划审核、跨 DAG 层逐项构建的实现(每项任务均由用户选择的执行器编写并审核)、可选的计划与实现对照审核,以及可选的上线审计——最后将经过验证的发现作为反馈返回。它只运行一轮,不会自行循环;如果仍有发现,由用户决定是否运行修复轮次。
14 个步骤映射到工作流阶段:步骤 3 → 计划 · 步骤 4–9 → 计划审核(可选,有界循环)· 步骤 10–11 → 构建(可选逐项任务审核)· 步骤 12 → 实现审核(可选,计划与实现对照)· 步骤 14 → 验证(去重 + 对抗式验证 → 反馈)· 步骤 13 → 审计(仅当 goLive 为真且构建与实现均已验证无误时)。该技能会预先完成受理流程(依赖项检查 + 提示词 + 门控问题)。每个审核门控均按用户选择的深度运行(跳过 / 原生 / codex / kiro);不会自动递归——工作流会返回发现并停止。
阶段 1 — 受理
步骤 0 — 确定模式:新运行还是恢复(首先执行)
该技能有两种运行模式——在执行其他操作前先判断是哪一种:
- 新运行(默认——用户提供功能提示词)。执行完整的受理流程(依赖项检查 + 门控问题 + 范围确认),创建全新的状态文件,并使用完整的
args启动。 - 恢复先前的运行(用户说“恢复”“继续构建”,提供
wf_…runId,或指向现有的.ulpi/workflows/<id>.json)。不要重新执行受理流程,也不要覆盖状态文件。请改为在仓库根目录运行node <skill-dir>/helpers/wf-status.mjs --resume [<runId>]——它会读取该运行的状态文件,并打印用于重新启动的确切Workflow({ scriptPath, args }),其中已包含planPath(跳过重新规划)、checkpointResume:true(跳过已完成的任务)和相同的statusFile。原样启动该命令。持久化检查点使恢复不依赖会话(无需resumeFromRunId);构建阶段只会重新构建剩余部分。(如果--resume警告缺少launchArgs——这是 v1.7.0 之前的运行——请补上缺失的validate/hardRules;如果尚无状态文件,请先运行--write。)返回后跳到阶段 3 汇报。
阶段 1 的其余部分适用于新运行流程。
步骤 1 — 依赖项检查与设置(首先执行)
首先告诉用户,哪些条件能让该技能发挥最佳效果、目前已有哪些内容,以及还缺少什么——并附上可直接复制粘贴的安装命令。ship-playbook 会组合其他技能,并将任务路由给专业 Agent;安装的这些技能和 Agent 越多,结果就越好。
检测方式——共三种状态,而非两种。 技能只有在 Claude 启动时才会加载到可用技能列表中(Agent 只有在 Claude 启动时才会加载到 subagent_type 选项中),因此“已安装在磁盘上”≠“本次会话可用”。请对每项进行分类:
- 已就绪 — 已在已加载的可用技能列表 /
subagent_type选项中,可立即使用。不要列出。 - 已安装,需重启 — 不在已加载列表中,但已存在于磁盘上。检查时需识别符号链接(技能会注册为指向共享存储的符号链接,例如
.claude/skills/map-project → ../../.agents/skills/map-project):使用ls -laL .claude/skills/<name>或test -e .claude/skills/<name>(会跟随符号链接),不要使用find -type d(它会悄悄漏掉符号链接)。 将这些项目报告为“已安装 — 重启 Claude 以加载”,不要提供安装命令(它们已经安装)。 - 缺失 — 不在已加载列表中,也不在磁盘上。显示完整安装命令。
已加载列表是判断当前可用项目的唯一依据;只有通过识别符号链接的磁盘检查,才能区分“已安装但未加载(需重启)”和“确实缺失”,因此已安装但尚未加载的技能绝不能被误标为单纯的“缺失”。合理性检查:如果你要把一个明显存在的技能(刚刚用过的技能)报告为缺失,说明你的检查方法有问题。对外部 kiro-cli 二进制文件进行磁盘 / PATH 探测是另一回事(见下文)。
检测项目使用的技术栈,然后根据已加载列表检查以下项目有哪些已就绪、哪些缺失:
- 组合技能 —
plan-to-task-list-with-dag、plan-founder-review、go-live-audit、map-project/map-project-monorepo。 - 此技术栈的专业 Agent — 构建流程会分配的工程师 + 审查者配对。审查者的名称是完整工程师名称 +
-reviewer(不是缩写):例如nextjs-senior-engineer+nextjs-senior-engineer-reviewer;go-senior-engineer+go-senior-engineer-reviewer;laravel-senior-engineer+laravel-senior-engineer-reviewer。使用 精确的注册名称,绝不要缩写为nextjs-reviewer/go-reviewer。缺少任何一方都会被迫使用general-purpose,质量较低。 - 技术栈技能 — 检测到的技术栈对应的
/nextjs、/laravel、/rust等。 - 可选的 Harness 工具(仅当用户可能选择 codex / kiro 时):codex 插件
(
codex:codex-rescue);对于 kiro,检查 CLI 以及kiro-review技能(审查)和hand-over-to-kiro技能(构建)。检测 kiro CLI 时有两个注意事项:- 二进制文件名是
kiro-cli,不是kiro(单独的kiro通常是 Kiro IDE 的符号链接,而不是 CLI)。检查kiro-cli。 - 它通常位于
~/.local/bin,沙箱中的 Bash PATH 可能不包含此路径,因此即使已安装,command -v kiro-cli也可能返回空结果。使用不依赖特定位置的检查方式进行检测,例如command -v kiro-cli || ls ~/.local/bin/kiro-cli ~/.kiro/bin/kiro-cli /usr/local/bin/kiro-cli 2>/dev/null, 并确认它可以运行(kiro-cli --version)。文档:https://kiro.dev/docs/cli。
- 二进制文件名是
分别提供两张表——一张列出技能,一张列出 Agent——且仅列出尚未就绪的项目(即“缺失”或“已安装,需重启”)。不要列出已就绪的项目(不要添加“已存在 / 已就绪”部分)。每行显示项目、状态和操作:
- 状态 = 已安装,需重启 → 操作:“重启 Claude 以加载”(不要提供安装命令,因为它已存在于磁盘上)。
- 状态 = 缺失 → 操作:提供完整、可直接复制粘贴的安装命令:
- 技能 →
npx skills add https://github.com/ulpi-io/skills --skill <name>(组合技能、技术栈技能、kiro 辅助技能kiro-review/hand-over-to-kiro;kiro-cli本身 → 提供其文档链接 https://kiro.dev/docs/cli); - Agent →
npx agentshq add ulpi-io/agents@<agent-name>,每行都使用对应的精确注册名称——例如…@nextjs-senior-engineer和…@nextjs-senior-engineer-reviewer(审查者名称必须是完整工程师名称 +-reviewer,绝不能写成…@nextjs-reviewer)。
- 技能 →
如果某张表没有未就绪项目,则完全省略该表。然后使用 AskUserQuestion 提供两个选项:
- 继续使用当前已安装的内容(缺少的专用 Agent 会回退到
general-purpose;缺少的 harness 选项则不会提供)。 - 我来安装——然后重启:用户安装列出的项目,然后重启 Claude(新安装的技能/Agent 只会在启动时加载),并重新运行
/ship-playbook。请告知他们重启后再回来重新调用。
记录可用内容——这些内容会提供给 availableAgents,并限制你可提供的 intake 选项。
步骤 2 — 工作流门控问题(先问这些)
提示词是 $request。按执行顺序提出七个门控问题(分两次 AskUserQuestion 调用,每次最多 4 个),让它们读起来像实际运行流程,除非 $request 已经明确指定了答案。
RESUME 模式。 如果 $request 指向现有的已审查计划(.ulpi/plans/<name> 路径,或用户要求恢复),则运行从 BUILD 开始:跳过门控问题 1(由谁编写计划)和 2(由谁审查计划)——这两项已完成——只询问剩余五项(代码编写者、代码审查者、实现审查、上线审计、映射)。继续之前,读取计划的 .json 并确认其格式正确(包含 id / agent / writeScope / validate 的 tasks[],以及 layers[][]);如果格式错误或已过时,请说明情况,并提供重新规划的选项,而不是恢复计划。
这些门控问题必须最先提出——紧接依赖项检查(步骤 1)之后。 不要在提出这些问题前先问范围/功能澄清问题(“是要整个平台还是只要 API?”、“使用哪种 SSO 协议?”等)。提示词本身就是范围;如果范围宽泛或含糊,应在步骤 3 中明确(在这些门控问题之后),或让计划阶段在规划过程中质疑范围——绝不能在门控问题之前先来一轮提问。用户期望先配置工作流。
每个角色都独立选择执行器(每次编写和每次审查都分别选择——用 codex 编写、用 kiro 审查也可以)。只为步骤 1 确认已安装相应工具的角色提供 codex/kiro。默认设置为 LIGHT,以控制令牌成本;用户可以将每项提高到完整严格度,或跳过。
**选项排序规则:**先列出 native(标记为推荐/默认),然后是 codex,再是 kiro,并将 skip 作为最后提供的选项(它会显示为倒数第二项,紧靠自动添加的“其他”之前)。计划编写和代码编写不可跳过(必须完成);四个可选门控项(计划审查、代码审查、实现审查、上线审计、映射)都包含 skip。
- 由谁编写计划 — DAG 分解:
native(将计划转为带 DAG 的任务列表,默认)、codex或kiro。传入planHarness。(不可跳过——必须编写计划。) - 由谁审查计划 — 创始人审查(范围、分解、虚构路径):
native(默认)、codex、kiro或skip。传入planReview。 - 由谁编写代码 — 每项任务及其修复:
native(计划中的专业工程师 Agent,默认)、codex或kiro。传入buildHarness。(不可跳过。) - 由谁审查代码 — 构建循环中的每项已构建任务:
native(匹配的-reviewer,默认)、codex、kiro或skip(不进行逐任务审查或修复循环——可最大限度节省令牌)。传入taskReview。 - 所有任务完成后的实现审查 — 审查计划与实现是否一致:
native(默认)、codex、kiro或skip。传入implReview。 - 运行上线审计 —
run(上线审计;只有构建和实现审查均返回已验证且干净时才会运行)或skip(默认)。传入goLive(run→true)。 - 最后运行 map-project —
map-project、map-project-monorepo或skip(默认)。检测仓库布局并推荐匹配的变体。保存为mapRefresh——这不是 Workflow 参数(不在args对象中);SKILL 会在第 3 阶段、Workflow 返回后,在实际运行(未中止)时自行运行所选的映射技能。
默认设置(轻量且安全):planHarness native、planReview native、buildHarness native、taskReview native、implReview native、goLive skip、映射 skip。用户可以选择全力模式(启用所有审查,在需要时使用 codex/kiro,并启用上线审计)、将编写和审查委派给执行框架(任意编写/审查角色 → codex|kiro——编写者和审查者可以使用不同的执行框架),或选择快速模式(跳过审查)。如果 taskReview skip 且 implReview skip,请发出警告(但不要阻止):此时没有任何环节检查构建,因此干净的结论只代表工程师验证已通过。
步骤 3 — 范围确认、项目事实、Git 预检、Agent 列表
现在(完成门控问题之后)确认范围。 阅读代码库,了解其中已有的内容。如果
$request 范围宽泛或含糊(例如“可自托管的 SaaS 平台,支持 SSO”),请在此处缩小范围:优先
根据代码库推断范围;只有确实无法继续时才提出有针对性的范围问题——
或者保留宽泛的提示词,让计划阶段质疑范围。将最终确定的范围并入传入 args 的
prompt。
收集工作流所需的事实(不要询问用户——请阅读代码库):root(代码库的绝对路径)、
workingBranch(未经确认,绝不在受保护分支上构建)、validate(工作区的
类型检查 + lint + 测试命令),以及 hardRules(根目录 CLAUDE.md / 规格中的关键不变量)。
确认 root 是一个 Git 工作树——git -C <root> rev-parse --is-inside-work-tree 必须输出 true,
并且 workingBranch 必须存在且至少有一条提交记录。构建过程会创建并合并任务分支,因此
无法构建非 Git 文件夹(或没有提交记录的分支)。如果 root 不是 Git 仓库,请停止
并告知用户——建议执行 git init 并创建一个基线提交,或更正路径——不要启动流程。
将 availableAgents(来自步骤 1、此处存在的专业工程师 Agent 及 -reviewer 名称)和
allowGeneralFallback(仅当用户选择“在存在缺口的情况下继续”时为 true)传入工作流的 args。计划
随后只会分配此列表中的 Agent(不会凭空创建尚未安装的 Agent);对于仍有遗漏的情况,工作流会返回
missingAgents。如果用户在步骤 1 尚未看到缺口,绝不要悄悄用
general-purpose 替代缺失的专业 Agent。
从现有计划恢复时,还要在此处解析计划:读取 .ulpi/plans/<name>.json
(.md 是由它渲染生成的),验证 DAG 结构(tasks[] 包含 id / agent / writeScope / validate,
layers[][] 无环),并将 planPath(路径)——或解析后的 plan 对象——传入 args。不要
重新规划。工作流会加载并验证该计划,并跳过计划和计划审查阶段。如果计划缺失或格式错误,请停止并建议重新规划。
打开一个主 TodoWrite,使其与 references/playbook-state.md 中的阶段保持一致。
成功标准:已显示依赖状态,且用户已选择继续或重新开始;
planHarness、planReview、buildHarness、taskReview、implReview、goLive、mapRefresh、root
(已确认是 Git 工作树)、workingBranch、validate、hardRules 和 availableAgents
(如有缺口,还包括 allowGeneralFallback)均已确定。
阶段 2 — 运行工作流(步骤 3–14)
如果 goLive == yes,首先编写上线审计,这样步骤 13 就能整合经过验证的审计,而不是只做浅层检查:运行
go-live-audit 技能以生成针对项目定制的审计工作流,并获取工作流工具为其持久化的
scriptPath;将该路径作为 auditScriptPath 传入。
(如果跳过此步骤,步骤 13 将退回到内联查找器检查。)
首先创建实时状态文件(工作流沙箱无法访问文件系统,因此必须由技能创建)。选择一个
workflowId——ship-<UTC 时间戳>-<提示词简短 slug>(例如通过 Bash 执行
date -u +%Y%m%dT%H%M%SZ)——设置 statusFile = <root>/.ulpi/workflows/<workflowId>.json(绝对路径),并
Write 初始文档,以便监视程序在流程启动的瞬间就能看到运行状态。
恢复运行时——不要覆盖已有状态文件。 构建现在支持检查点恢复:它会读取状态
文件,并跳过所有已标记为完成的任务(passed/integrated/reviewing/fixing/blocked),
只重新构建其余任务。因此恢复先前的运行时,请重复使用其现有的 <root>/.ulpi/workflows/<id>.json
(传入同一个 workflowId/statusFile)——不要用全新的、所有任务均为 pending 的文档覆盖它,否则
检查点会丢失,所有任务都将重新构建。只有全新的运行才使用 Write 创建初始文档。
{ "schemaVersion": 1, "workflowId": "<id>", "skill": "ship-playbook", "status": "initializing",
"prompt": "<prompt>", "root": "<root>", "workingBranch": "<branch>", "createdAt": "<UTC now>",
"config": { "planHarness": "...", "planReview": "...", "buildHarness": "...", "taskReview": "...",
"implReview": "...", "goLive": false },
"plan": null,
"phases": { "plan": {"status":"pending"}, "plan_review": {"status":"pending"},
"build": {"status":"pending"}, "impl_review": {"status":"pending"},
"verify": {"status":"pending"}, "audit": {"status":"pending"} },
"tasks": {}, "openRegister": [], "result": null }
然后通过 Workflow 工具启动 references/workflow-template.js,并将 intake 作为 args 传入:
Workflow({ scriptPath: ".../references/workflow-template.js",
args: { prompt, root, workingBranch, validate, hardRules, goLive,
planHarness, planReview, buildHarness, taskReview, implReview,
auditScriptPath, availableAgents, allowGeneralFallback, warmWorktree,
planPath, kiroModel,
workflowId, statusFile, trackStatus, checkpointResume } }) // planPath → RESUME at build;
// workflowId/statusFile → live .ulpi/workflows/<id>.json
// (trackStatus:false disables); checkpointResume:false →
// force a full rebuild (default true: skip done tasks);
// warmWorktree:false → plain per-worktree install
// (default true: CoW-seed node_modules/vendor/Pods; Rust uses kache or CoW-seeds target/)
启动后,记录运行 ID 和完整的启动参数。 Workflow 工具会立即返回一个 runId(wf_…),
并在后台运行。通过 Bash+jq 将 runId、status:"running" 以及关键的完整
launchArgs(刚才传入的确切 args 对象:prompt、root、workingBranch、validate、hardRules、
所有 harnesses、goLive 等)写入状态文件:
jq --argjson la '<the args object>' '. + {runId:"<runId>", status:"running", launchArgs:$la}'
这样,状态文件就成为自描述且确定性的恢复来源——wf-status.mjs --resume
会原样读取 launchArgs,因此恢复时会重新触发完全相同的配置(无需手动组装,也不会产生偏差)。
要恢复之前的运行?请使用 wf-status.mjs --resume,不要手动组装 args。 在仓库根目录运行:
node <skill-dir>/helpers/wf-status.mjs --resume [<runId>] 会读取该运行的状态文件,并打印要重新启动的确切
Workflow({ scriptPath, args })——其中已包含 planPath(跳过重新规划)、
checkpointResume:true(跳过已完成的任务)以及相同的 statusFile。原样启动即可。持久化的
状态文件检查点让恢复不依赖会话——无需 resumeFromRunId。(如果运行早于 v1.7.0,或没有
launchArgs,--resume 会发出警告,此时需补充缺失的 validate/hardRules;
先运行 --write [<runId>],可根据日志补建状态文件。)
mapRefresh 特意不放在 args 中——这是 Workflow 不会执行的唯一 intake 答案。
地图刷新会根据已完成的代码重新生成 CLAUDE.md,因此该技能会在 Workflow 返回后,于第 3 阶段自行运行此操作
(见 Q7)。其余所有门禁答案都应放入上方的 args。
将 args 作为真正的 JSON 对象传入,而不是 JSON 编码后的字符串。 字符串化的内容会以一个字符串的形式传给
脚本,导致 typeof args === 'object' 检查失败,所有输入都会静默回退到
FILL: 占位符。对此脚本会直接抛出错误,而不是返回虚假的 converged:true,因此以字符串化参数启动会明确报错——
如果遇到这种情况,请以对象形式传入 args,作为全新运行重新启动(不要恢复)。(每个 role 参数无效时都会强制转换为安全默认值,因此拼写错误也能平稳降级。)
随后,Workflow 会一次性执行操作手册,并按照用户选择的级别运行每个门禁:
- 规划(步骤 3) — 规划器(依据
planHarness:native / codex / kiro)会无人值守地遵循“规划转为带 DAG 的任务列表”方法(自动选择模式),确保每条路径都对应真实仓库,为每项任务分配一位专业工程师、-reviewer和一项技术栈技能,写入.ulpi/plans/<name>.md+.json,并返回{tasks, layers}。恢复:提供planPath/plan时,此阶段会改为加载已审核的计划(由 Agent 读取、验证并规范化;不会重新规划),并跳过计划审核——运行从构建阶段恢复。 - 计划审核(步骤 4–9) — 审核员依据
planReview(skip/native/codex/kiro)执行。进行一轮有界循环 → 修复计划(优先处理 JSON,然后重新生成 MD;修复始终由 native 执行)→ 重新审核;当不再有 BLOCK/CONCERN(OBSERVATION 永远不会阻止流程)或无法收敛时退出,最多执行MAX_REVIEW(2)次。 - 构建(步骤 10–11) — 遍历 DAG 各层;对每项任务:工程师(工作树、任务分支)→ 工作流内集成 Agent(将
git merge合并到工作分支,并随合并逐个移除工作树)→ 审核员(除非taskReview skip)→ 有界修复循环,直至通过;各层之间设有屏障。每个新工作树都会快速配置(默认启用warmWorktree):先执行一次预热步骤(与规划并行),以预先填充缓存;然后,当锁文件未更改时,工程师会从主检出 CoW 克隆node_modules/vendor/Pods(Rust 使用kache共享 crate 编译结果——这是一种与路径无关、基于硬链接的 rustc-wrapper 缓存,通过.cargo/config.toml接入,因此工作树会还原已编译的 crate,而不是克隆target/;若没有 kache,则会对预热的target/进行 CoW 种子复制),否则回退到普通的冻结安装;warmWorktree:false会还原为每个工作树分别安装。工程师路由依据buildHarness;审核员路由依据taskReview——二者相互独立(使用 codex 编写、kiro 审核也完全可行)。构建和验证的并行任务会受到并发门控,因此宽 DAG 层或较长的问题列表不会触发 Claude API 速率限制:同时运行的工作树工程师最多为MAX_BUILD_PARALLEL(4)名,审核员/验证器最多为MAX_PARALLEL(6)名。Agent 总数不变——仅限制同时运行的数量。如果遇到 429 错误,请在references/workflow-template.js中调低这两个常量;如果账户限制较高,则可调高;绝不要将其设为 1–2。即使有并发上限,若 Agent 仍受到速率限制(返回空内容或执行中途被截断),也会先进行指数退避重试(RETRY_DELAYS,最多 4 次),之后才记录为受阻——因此,速率限制风暴不再会造成虚假的“任务受阻”噪声。 - 实现审核(步骤 12) — 审核员依据
implReview(skip/native/codex/kiro)执行。审核所有已构建内容,检查其是否符合计划。 - 验证(步骤 14) — 去重并以对抗性方式验证构建和实现阶段的问题。这些内容会成为返回的
openRegister——也就是反馈。不自动重新规划或重新构建;工作流返回后即停止。 - 审计(步骤 13) — 仅当
goLive已启用,且构建和实现审核均确认无问题时运行:通过workflow()钩子(auditScriptPath)内联组合经验证的go-live-audit工作流——门控 → 问题发现器 → 去重 → 双视角验证 → 批评者——∥ 第二条使用不同 Harness 的审计通道;其问题会成为openRegister。 通过三种方式查看进度:/workflows面板(实时 Agent 树)、状态文件 (cat <root>/.ulpi/workflows/<id>.json— 总体状态、各阶段和各任务的状态),或内置读取器node <skill-dir>/helpers/wf-status.mjs(直接从本次运行的日志中还原各任务的状态 — 即使运行尚未结束,或关闭了状态跟踪,也能正常工作)。请参阅references/status-tracking.md。要迭代 脚本,请编辑工具返回的scriptPath并通过{scriptPath}重新调用(还可传入resumeFromRunId以复用缓存的 Agent 结果)。每次传入resumeFromRunId时,都必须再次传入相同的args对象 — 它会复用缓存的 Agent 结果,但脚本会从头重新执行,因此省略args会导致CFG为空,脚本也会在FILL:守卫处直接抛出错误。始终包含启动运行时使用的完整args对象(包括workflowId/statusFile)。若要恢复之前的运行(而不是迭代脚本),请改用wf-status.mjs --resume— 详见下文的 resume 动词;它会自动为你传递完整的args。
成功标准:Workflow 运行至完成并返回
{ converged, ranReal, plan, planSupplied, build, openRegister, missingAgents, reviewConfig, noReviewGate, planReviewRan, implReviewRan, taskReviewDowngraded, auditRan, workspaceValidatePassed, endStateUngated, blockedTaskCount, workflowId, statusFile }。
第 3 阶段 — 报告并升级处理
读取 Workflow 结果:
- 首先,确认这次运行是真实执行的,而不是假通过。 如果结果中的
ranReal: false(或出现aborted消息),说明输入未传给脚本(或预检失败)。报告此失败,并使用真实的 JSON 对象作为args重新启动(进行全新运行);切勿将converged视为有意义的结果。 - 如果
missingAgents不为空,说明有些任务由general-purpose执行,因为此处未安装指定的 专业 Agent。列出缺少的 Agent 以及安装方法,让用户决定是否安装并重新运行,以获得更高质量的 输出。 - 如果
noReviewGate: true(用户跳过了逐任务审查和实现审查),对任何通过结论都必须加上 注意:这只表示工程师验证通过,构建没有经过任何审查。报告reviewConfig,让用户了解运行了 哪些审查关卡。 - 诚实报告关卡状态——已配置但实际上未运行的关卡绝不能算作“通过”。 Workflow 会在关卡
失败时将
openRegister保持为非空(因此converged为 false),但仍需报告原因,让用户知道 为什么:planReviewRan === false/implReviewRan === false→ 配置的计划审查员/实现审查员 无法运行(例如缺少 kiro CLI);taskReviewDowngraded非 null → 请求的逐任务审查员 (例如 codex)无法在此处运行,已降级为 native(会显示{requested, ranAs})——任务确实 经过了审查(由 native 执行),但要告知用户其请求的审查员并未运行;auditRan === false→ 上线审计失败(未确认上线);workspaceValidatePassed === false→ 集成后的代码树最终validate未通过(它未通过类型检查/lint/测试——这是影响最大的阻塞项)。endStateUngated === true(跳过了实现审查)→ 必须说明,即使代码树可以编译,整个代码库的语义最终状态也未经 把关。 blockedTaskCount > 0→ 有相应数量的任务未通过(工程师执行失败、审查阻塞,或因上游依赖 从未集成而处于dep_blocked状态——blocked on dependency <X>这样的原因会指向根因)。这些 任务列在openRegister中;请连同原因一并列出。- 归因既有失败。
build[]中的条目可能带有preexistingNote——其代码片段正确且已集成, 但它的验证未通过,仅仅是因为不属于它负责范围的既有失败(构建现在不会再丢弃这类正确的 工作;工程师会对照基线自行判断失败是新出现的还是既有问题)。此外,当workspaceValidatePassed === false时,workspace-validate标记会区分本次运行引入的失败 (真正的阻塞项)和基线中已存在的失败(需要另设负责人任务——并非本次运行导致),并按步骤列出[steps: typecheck=pass, lint=FAIL, …]。请说明这一区别,以便用户修复正确的问题;如果代码片段 已通过构建,但代码树因继承的故障而未通过验证,应正确解读为“工作已保留,并已指出真正原因”, 而不是“构建把它弄坏了”。 - 如果
planSupplied: true,说明本次运行是从预先审查过的计划恢复执行:按设计跳过了 规划和计划审查——请明确说明,避免用户误以为计划未经审查。 converged: true(真实运行,openRegister为空)→ 完成。报告各任务的构建结果、审查/ 审计结论(根据reviewConfig),以及计划的最终去向。openRegister非空 → 呈现反馈并让用户决定。列出已核实的阻塞/疑虑发现(文件:行号、 问题、建议修复方式,以及发现问题的关卡)。然后提供下一步选项:运行一轮修复(将这些发现 作为提示词重新调用工作流——使用相同的 intake)、手动修复,或接受风险继续。工作流不会 自行循环;绝不能将未解决的问题说成已通过。 工作流已将最终状态写入<root>/.ulpi/workflows/<id>.json(status=done/needs_fix/aborted、各任务结果、openRegister)。读取该文件以补充报告,并告知用户文件所在位置——它是本次运行的持久记录。如果运行中途失败(未写入最终状态),请先根据日志刷新文件,再报告:node <skill-dir>/helpers/wf-status.mjs --write
实时状态、停止与恢复——三个动词,均由状态文件和运行日志提供支持:
- status →
cat <root>/.ulpi/workflows/<id>.json(或node <skill-dir>/helpers/wf-status.mjs)——一目了然地查看:总体状态、当前阶段以及各任务的状态(pending → in_progress → dev_done → integrated → passed/blocked)。 - stop → 对运行执行
TaskStop,或使用/workflows面板。不会丢失任何内容——日志会缓存每个已完成的 Agent。 - resume → 在仓库根目录运行
node <skill-dir>/helpers/wf-status.mjs --resume [<runId>],并原样启动其输出的Workflow({ scriptPath, args })。它会使用运行中存储的launchArgs重新触发运行,并传入planPath(跳过重新规划)、checkpointResume:true(跳过已完成的工作)以及相同的statusFile——这是一次全新的、与会话无关的运行,且会携带完整的args。这是规范的恢复路径。 不要仅使用resumeFromRunId恢复:它会复用缓存的 Agent 结果,但脚本会从头重新执行;在新会话中,args会丢失 →CFG变为空 → 脚本会在FILL:守卫处直接抛出异常(在较旧版本中,它会执行一次虚假的清理操作,但实际上什么也不做)。只有在迭代脚本时才使用resumeFromRunId来复用缓存,并且仍必须传入相同的完整args对象。
在 v1.5.0 之前启动的运行(没有状态文件)? 根据运行日志补建状态文件:
node <skill-dir>/helpers/wf-status.mjs --write [<runId>] ——恢复计划、分支、任务列表及状态,以及冲突。日志中没有启动参数,因此请添加 --args '{…gate config + validate…}'(只有启动该运行的会话知道这些参数),以补全 resume 操作步骤。参见 references/status-tracking.md。
然后,如果用户在接收信息时选择刷新项目映射,并且运行确实执行过(ranReal,未中止),请最后执行该操作——调用所选技能(map-project 或 map-project-monorepo),使 CLAUDE.md 上下文映射反映构建刚刚落地的代码。若运行已中止或属于虚假清理(false-clean),则跳过(没有新增内容需要映射)。这是报告之后的最后一步。
成功标准:启用的门禁确实通过(需注明 reviewConfig / noReviewGate 的限制),或向用户如实列出仍然受阻的事项及后续步骤;持久状态文件反映最终状态;若用户提出要求,则刷新项目映射。
防护措施
- 不要主动运行;只能由用户明确触发(这会在多个轮次中生成许多 Agent)。
- 工作流只运行一轮,不会自行循环;修复轮次必须由用户主动选择
(将发现结果作为提示词重新调用)。每次运行由用户选择评审关卡——遵循用户的
planReview/taskReview/implReview选择;如果跳过逐任务评审和实现评审,则发出警告(不要阻止运行)。工作流负责步骤 3–14;技能负责接收阶段(依赖检查 + 提问)和第 3 阶段报告。 - 不要手工编写计划——工作流的计划阶段会遵循计划到任务列表(含 DAG)的方法,并为每项任务分配一名专业 Agent。
- 构建过程会为每项任务分配最合适的可用专业 Agent;只有在通知用户缺少专业 Agent 并征得用户同意后,才能退而使用
general-purpose(绝不能默默降级)。安装了技术栈技能时,工程师必须使用该技能(/nextjs、/laravel、/rust……)。 - 绝不要捏造通过结论——未解决的 BLOCK/CONCERN 发现应作为反馈返回,而非隐瞒。
- 工作流只运行一轮,不会自行循环;修复轮次必须由用户主动选择(将发现结果作为提示词重新调用)。不要重新引入自主递归。
- 不要将密钥/令牌传入任何 Agent 任务说明;只注明其所在位置,并对值进行脱敏。
- 未明确确认
workingBranch前,不要在受保护分支上构建。 - 不要在非 Git 文件夹或空仓库中启动构建——构建过程会创建并合并任务分支,因此需要一个带有已提交
workingBranch的 Git 工作树。 - 防止构建工作树污染关卡:工作流会在预检时、每次集成后以及结束时清理其
.claude/worktrees/构建检出目录;集成验证绝不能扫描.claude/worktrees/**或同级 Agent 目录。如果某次运行的关卡在任务范围之外的文件上失败,应先怀疑残留工作树,而非代码。 - 遵循 DAG;在依赖项集成之前,绝不能构建任务。构建按层集成,并在每层之间设置屏障,因此正确性取决于 PLAN 是否正确排列任务:每项任务的
dependsOn都必须已完成,且layers必须遵循拓扑顺序(每项任务都严格排在其所有依赖项之后)。计划阶段会设置dependsOn;计划评审会对不完整或顺序错误的图执行 BLOCK;构建的validatePlan会在计划的层违反dependsOn时中止,而不是基于错误的基础继续构建。若某项任务需要另一项任务的输出(目录/注册表条目、迁移、路由、导出符号或另一项任务新增的测试),却被安排先运行,这是 PLAN 缺陷——修正顺序,绝不要用运行时重试来掩盖。如果两个部分无法各自独立验证,就必须合并为一项任务。每项任务的validate必须限定在切片范围内(该切片及其依赖项集成后即可通过),绝不能是只有在最终状态下才会通过的全套 e2e。 - 逐任务评审限定在切片范围内,不是最终状态关卡:只有任务
writeScope内的缺陷才能成为逐任务 BLOCK。尚未满足、且由后续任务负责的全代码库不变量(尚未移除的旧路径、尚未构建的路由/链接/使用方)应记为该任务的观察项,绝不能阻止当前切片,也绝不能送入修复循环。最终状态由实现评审(步骤 12)和集成工作区验证来强制检查。排查嘈杂的“受阻任务”计数时,应先确认这些 BLOCK 是否属于其他任务负责的最终状态缺口,再判断当前切片是否损坏。 - 状态跟踪仅用于观察,不具阻断性:
.ulpi/workflows/<id>.json写入失败时应记录日志并忽略,绝不能阻止构建。绝不要以状态写入作为交付关卡;也绝不能仅因状态文件过期就报告运行失败——应改为从日志(wf-status.mjs)重建状态。
何时加载参考资料
references/workflow-template.js可运行的工作流,可一次性执行整个操作手册(规划 → 有界计划审查 → 在工作流中集成 git,跨 DAG 层由专家构建 → 实现审查 → 验证 → 上线审计),并返回已验证的发现。通过 Workflow 工具使用接收参数args启动;编辑后重新运行即可迭代。references/build-loop.md构建阶段所执行的构建 CONTRACT:必须选择专家配对、强制执行各技术栈技能要求、DAG 分层 + git 集成,以及任务退出门槛。references/harness-routing.mdclaude/codex/kiro/none如何映射到具体调用(codex:codex-rescue插件、kiro、原生调用),用于计划审查、代码审查和上线审计。references/playbook-state.md单次执行状态机、主 TodoWrite 结构、发现项架构 + 去重、验证阶段,以及通过还是需要反馈的决策(修复轮次由用户驱动,不会自动进行)。references/status-tracking.md实时状态文件(.ulpi/workflows/<id>.json)的架构 + 生命周期、各方何时写入、三个动词(status / stop / resume),以及helpers/wf-status.mjs日志读取器。配置启动/报告状态写入或调试运行进度时加载。
输出契约
报告:
- 接收信息 — 使用的审查配置(
reviewConfig:运行的审查框架和各门禁的深度)、上线选择、解析后的工作分支 - 计划名称 + 每项任务的构建结果(通过 / 修复 / 阻塞)
- 计划审查和实现审查 — 按已启用的门禁列出发现(已确认与已拒绝),或注明“已跳过”
- 上线审计 — 结论和阻碍项(或注明“已跳过”)
- 最终状态 — 通过(若为
noReviewGate,则注明存在保留条件),或如实列出剩余发现项 + 后续步骤