mcpField
S
ship-playbook

ship-playbook

github.com/ulpi-ioAgent 工作流593 次安装9 周前更新
代码仓库

关于 ship-playbook

ship-playbook 是用于执行单轮软件交付工作流的 Agent 技能,覆盖规划、构建与验证。它适合需要自选审查和审计关卡、持久化续跑检查点,并由用户决定是否修复发现项的团队。

主要功能

  1. 01单轮规划至验证工作流
  2. 02由用户选择审查与审计关卡
  3. 03按 DAG 任务构建和审查
  4. 04持久化检查点续跑
  5. 05集成代码树最终验证

适用场景

  1. 01从单条需求交付功能
  2. 02续跑尚未完成的构建
  3. 03审查发现项后由用户决定修复轮次

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/ulpi-io/skills --skill ship-playbook

安装后在 Claude Code 中输入/ship-playbook确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

helpers/
wf-status.mjs
references/
build-loop.md
harness-routing.md
playbook-state.md
status-tracking.md
workflow-template.js

详细介绍

此技能驱动一个长期运行的多 Agent 交付工作流。以下规则不可妥协: 1. 工作流只运行一轮——规划 → 计划审查 → 构建 → 实现审查 →(审计)→ 验证——并将已验证的发现作为反馈返回。它不会自行循环:工作流无法在运行中途询问用户,而自主修复循环正是导致数小时反复折腾的原因。当仍有发现时,技能(阶段 3)会将其呈现出来,由用户决定是否运行一轮修复。工作流将步骤 3–14 作为实际阶段执行;技能负责信息收集(依赖项检查 + 提示词 + 门控问题),并将选择作为 `args` 传入。 2. 信息收集顺序固定:(1) 依赖项检查 + 继续/重新开始,然后 (2) 七个门控问题——谁编写计划、谁审查计划、谁编写代码、谁审查代码、实现审查、上线审计、项目映射,然后 (3) 范围界定 + 事实核实。依赖项检查后,必须立即先询问七个门控问题。例外(恢复):当用户指定了一份现有且已审查的 DAG 计划时,跳过前两个问题——计划编写者 + 计划审查者;询问其余五个问题,并将计划作为 `planPath`/`plan` 传入,让运行从构建阶段开始。绝不能在此之前询问范围/功能澄清问题(“是整个平台还是仅 API?”、“用哪种协议?”):提示词就是范围;在步骤 3 中对其进行核实,或让计划阶段提出质疑。遵循门控选择:全面审查或同时跳过二者都有效。 3. 构建是工作流的一个阶段,而非说明。对 DAG 各层中的每项任务:工程师在隔离的工作树中的任务分支上实现;工作流内的集成 Agent 使用 git 将其合并到工作分支,并移除每个已合并的工作树;审查者审查集成后的状态(除非 `taskReview skip`);然后运行有界修复循环,直到任务通过。工程师按 `buildHarness` 路由,审查者按 `taskReview` 路由——二者独立选择(各自均可为 native / `codex` / `kiro`;编写者和审查者可以使用不同的执行环境)。 4. 构建时为每项任务选择最匹配且可用的专业 Agent;只有在技能通知用户缺少专业 Agent 并获得用户同意后,才可回退到 `general-purpose`,绝不能静默回退。若已安装任务对应技术栈的技能,工程师必须使用它(`/nextjs`、`/laravel`、`/rust` 等)。(此要求适用于 native 路径;若用户将构建/审查交给 `codex` 或 `kiro`,则相应任务改由它们执行。) 5. 已启用的门控必须切实执行,绝不能敷衍通过或伪造无问题的结论来结束流程。但由用户决定运行哪些门控:跳过的门控(`planReview skip`、`taskReview skip`、`implReview skip`、`goLive no`)是有意选择,不能偷偷重新启用。若逐任务审查和实现审查都关闭,应发出警告(但不要阻止流程)——此时构建无人检查。 6. 没有全局执行环境——每个角色(代码编写、计划审查、逐任务审查、实现审查)都独立选择自己的执行器:`native`(claude / 计划中的专业 Agent)、`codex`(`codex:codex-rescue` 插件)或 `kiro`(kiro 路径;审查使用 `kiro-review`,构建使用 `hand-over-to-kiro`)。编写者与审查者的选择互不影响。(参见 `harness-routing.md`。) 7. 不存在自主递归。一轮结束后,如实呈现已验证的发现,并让用户选择是否运行一轮修复(使用这些发现作为提示词重新调用)——绝不能伪造无问题的结论,也绝不能静默循环。 8. 本文内容应聚焦于启动和报告工作流。请从 `references/` 加载构建契约、执行环境路由、状态机和工作流脚本本身。 9. 逐任务审查按切片划定范围,绝不是最终状态门控。构建一次交付一个切片,因此逐任务审查者只评判该任务自身的 writeScope + diff 是否符合其验收标准——它会获得计划其余部分,必须将未满足的全代码库不变量(例如后续任务会移除的旧路径、后续任务会添加的路由/链接、后续任务会使用的导出项)归因于负责该事项的任务,并作为观察项提出,而不能将其作为当前切片的阻塞项。修复循环只处理任务 writeScope 内的发现(工程师无法修改无权触及的内容)。全代码库最终状态由实现审查门控(步骤 12)+ 集成代码树上的最终 `validate` 门控负责(构建完成后仅运行一次,届时整个套件才可能通过)——这是判断“软件是否可用”的真正信号,而不是逐任务阻塞数量。逐任务集成仅执行合并:它不运行整个工作区的 validate(在迁移尚未完成的代码树上,整个套件失败绝不能成为逐任务阻塞项——不能让一个干净的切片陷入无休止循环)。 10. 每次运行都会有一个实时状态文件:`/.ulpi/workflows/.json`——技能必须在启动前创建该文件(此沙盒化工作流无法访问文件系统),工作流通过轻量状态写入 Agent 在每个阶段 + DAG 层更新该文件,技能则在阶段 3 读回该文件。状态跟踪用于可观测性,且不会影响流程:状态写入失败会记录并忽略,绝不能阻塞构建。该文件是快速查看“执行到哪一步 / 停止 / 恢复 / 重试”的记录。 11. 检查点恢复是持久化的,不依赖缓存:构建会读取状态文件,并跳过所有已标记为完成的任务,只重建其余任务——这与运行时 Agent 缓存无关(任何模板编辑都会使缓存失效)。因此恢复运行时,应复用上次运行的状态文件;不要用全新的 `pending` 文档覆盖它(这会抹去检查点)。只有当某任务的 `dependsOn` 已实际集成到工作分支后,该任务才能构建(DAG 门控)——依赖项未落地的任务标记为 `dep_blocked`(指向根因),绝不能在有问题的基础上构建。 12. 门控失败时必须保持失败状态——配置的门控若未实际运行,绝不能算作通过。已退出/缺失/结果为空的审查者(native/codex/kiro)、已退出的上线审计,以及标记为 RED 的最终工作区 validate,都会使 `openRegister` 保持非空,因此 `converged` 为 false。集成代码树上的最终 `validate` 是最终状态的关键事实(“在最终分支上运行完整套件”门控):各切片单独通过,合并后的代码树仍可能出问题,因此无论逐任务结论如何,最终 validate 未通过都会阻塞交付。如实报告 `planReviewRan`/`implReviewRan`/`auditRan`/`workspaceValidatePassed`/`endStateUngated`——绝不能将门控未执行或代码树未通过的构建描述为可交付。 # Ship Playbook

输入

  • $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。

  1. 由谁编写计划 — DAG 分解:native(将计划转为带 DAG 的任务列表,默认)、codex 或 kiro。传入 planHarness。(不可跳过——必须编写计划。)
  2. 由谁审查计划 — 创始人审查(范围、分解、虚构路径):native(默认)、codex、kiro 或 skip。传入 planReview。
  3. 由谁编写代码 — 每项任务及其修复:native(计划中的专业工程师 Agent,默认)、codex 或 kiro。传入 buildHarness。(不可跳过。)
  4. 由谁审查代码 — 构建循环中的每项已构建任务:native(匹配的 -reviewer,默认)、codex、kiro 或 skip(不进行逐任务审查或修复循环——可最大限度节省令牌)。传入 taskReview。
  5. 所有任务完成后的实现审查 — 审查计划与实现是否一致:native(默认)、codex、kiro 或 skip。传入 implReview。
  6. 运行上线审计 — run(上线审计;只有构建和实现审查均返回已验证且干净时才会运行)或 skip(默认)。传入 goLive(run → true)。
  7. 最后运行 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.md claude / 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 日志读取器。配置启动/报告状态写入或调试运行进度时加载。

输出契约

报告:

  1. 接收信息 — 使用的审查配置(reviewConfig:运行的审查框架和各门禁的深度)、上线选择、解析后的工作分支
  2. 计划名称 + 每项任务的构建结果(通过 / 修复 / 阻塞)
  3. 计划审查和实现审查 — 按已启用的门禁列出发现(已确认与已拒绝),或注明“已跳过”
  4. 上线审计 — 结论和阻碍项(或注明“已跳过”)
  5. 最终状态 — 通过(若为 noReviewGate,则注明存在保留条件),或如实列出剩余发现项 + 后续步骤

评论

支持 Markdown