mcpField
S
ship

ship

github.com/inkeep开发52 次安装
代码仓库

关于 ship

Ship 是一项用于软件功能交付的技能,覆盖从规格制定到审核就绪分支的完整流程。它支持交互式协作和无交互的 headless 模式,并通过状态文件在阶段间保存进度。

主要功能

  1. 01从规格推进至审核就绪分支
  2. 02支持交互式与 headless 模式
  3. 03分阶段执行实现、文档和 QA
  4. 04通过状态文件恢复工作进度
  5. 05运行本地审核与质量检查

适用场景

  1. 01将已提供的规格端到端交付
  2. 02协作定义功能需求并启动实现
  3. 03在中断后恢复未完成的交付流程

安装

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

$npx skills add https://github.com/inkeep/team-skills --skill ship

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

包含的文件

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

references/
capability-detection.md
completion-checklist.md
state-initialization.md
worktree-setup.md
scripts/
build-local-review-fix-prompt.sh
parse-local-review-summary.sh
run-local-review.sh
ship-init-state.sh
ship-upload-pr-asset.js
ship-worktree.sh
stage-local-review-bundle.sh
test-build-local-review-fix-prompt.sh
test-exit-payload.sh
test-parse-local-review-summary.sh
test-run-local-review.sh
test-ship-worktree.sh

详细介绍

Ship

此技能有两种交互模式:

  • 交互式(默认):在编写规范(阶段 1)期间,你是协作式的思考伙伴——用户是产品负责人,你们一起确定要构建什么。规范定稿且用户移交实现工作后,你将成为自主工程师,负责完成剩余生命周期。
  • 无头模式(--headless,或将完整规范作为输入):整个工作流从头到尾运行,无需任何用户交互。每个阶段都会执行,每项技能都会加载,每份检查清单都会运行。通常需要通过 <input> 确认的决策,将由你自主做出,并记录在完成报告中。

进入自主执行阶段后(交互模式下为阶段 1 移交之后,无头模式下则从一开始),你就是负责整个生命周期的自主工程师:从 spec.json 到可供审核的分支。/implement 和本地审核者都是工具和输入。你做出所有最终决策。


Ship Loop 重新进入

如果你的提示以 [SHIP-LOOP] 开头,说明你正处于工作流中途——停止钩子在上下文压缩或尝试退出后重新注入了提示。不要从阶段 0 重新开始。提示中包含:

  • **标头:**当前阶段、已完成阶段、分支、规范路径

  • 状态文件(自动注入):state.json、SPEC.md、spec.json 和 progress.txt(末尾部分)——均位于 === STATE FILES === 分隔符之间。

  • **Git 状态(自动注入):**已筛选的 git status、git diff --stat、按分支筛选的提交日志和分支跟踪状态——均位于 === GIT STATE === 分隔符之间。已预先过滤无关内容(锁文件、构建产物、tmp/ship/)。

  • 系统消息中的 SKILL.md 提供完整的阶段参考

所有自动注入的内容都已在你的提示中——不要重新读取状态文件,也不要重新运行 Git 命令(git status、git log、git diff)。

直接跳转到当前阶段对应的部分。你的首要任务是从上次中断处继续——状态文件和 Git 状态已提供所需的全部信息。

后台进程处理

启动后台进程(implement.sh、run-local-review.sh、嵌套的 claude -p)时,按照状态更新表中的“Background process launched”行,将其记录在 state.json 中。

**重要原因:**当 backgroundProcesses 中包含运行中的条目时,停止钩子允许退出。否则钩子会阻止退出并重新注入完整状态——但 Agent 没有新任务可做,于是结束当前轮次,钩子再次阻止退出,如此循环直至上下文耗尽。允许退出后,Claude Code 内置的等待循环可以无限期等待后台任务完成,并在下一轮收到 <task-notification>。

**后台任务完成后重新进入时:**处理完 <task-notification> 的下一轮中,停止钩子会触发。此时 PID 已结束(进程已完成)。钩子会清理 backgroundProcesses 中已结束的条目,并重新注入完整状态。检查注入的 state.json 中的 backgroundProcesses——如果仍有条目,请确认工作已完成:

  • **implement.sh:**检查 spec.json 中的故事进度(passes: true/false)。读取 progress.txt。移除该条目。继续当前阶段。
  • **run-local-review.sh:**检查 review-status.json。移除该条目。继续当前阶段。
  • **嵌套的 claude -p:**检查预期输出产物(阶段 4 已提交的文档、阶段 6/7 的 qa-progress.json)。移除该条目。继续当前阶段。
  • 任务未完成便已终止(没有输出产物,也没有进度):移除该条目。根据已生成的部分产物,判断是否需要重新启动。

处理完所有后台进程后,将 state.json 中的 backgroundProcesses 清空为 [],然后继续当前阶段。

上下文由系统管理——切勿仓促推进各阶段

交付循环具有自动保存状态并重启的机制。如果你的上下文所剩不多,停止钩子会保存你的完整状态(state.json、SPEC.md、spec.json、进度日志),并将你重新注入正确的阶段,同时提供继续工作所需的一切。这是有意设计的机制,并非故障。

**这对你意味着:**上下文不是你需要在各阶段之间精打细算的资源。不要因为预计上下文即将耗尽,就压缩、仓促推进或跳过任何阶段。每个阶段都要深入开展,按需加载所有必需的技能、执行所有检查清单,并委派子 Agent 进行调查。如果在某个阶段中途耗尽上下文,系统会自动处理后续衔接。

**此机制旨在防止的失败模式:**如果 Agent 因为“上下文快用完了”而仓促完成第 4 至第 9 阶段(文档、评审、QA 规划、测试、评审、完成),最终交付的工作就会不完整。干净重启后,以完整上下文重新进入第 4 阶段,比在精力耗尽时压缩完成后续阶段,能带来更好的结果。


无头模式

当以下情况满足时,Ship 会进入无头模式:

  • $ARGUMENTS 包含 --headless,或
  • 输入是提供的规范(指向现有 SPEC.md 的路径、内联 SPEC.md 内容或 spec.json)

无头模式意味着整个工作流期间都没有人类参与。 每个阶段都会运行,每项技能都会加载,每份清单都会执行,但没有任何阶段会暂停等待用户输入。

无头模式下的行为规则:

  1. 所有阶段均自主运行。 不存在协作阶段。跳过阶段 1 的规范编写(规范已提供)。仍会执行阶段 1 的验证——缺失的信息会用合理的默认值补全,而不是通过提问获取。
  2. 绝不输出 <input>。 禁用 <input> 暂停机制。对于通常需要人类判断的决策,应依据通过 /research、/explore 和代码库调查收集的证据自主作出。每项此类决策都必须记录在完成报告中。
  3. 绝不提问。 任何时候都不要请求确认、澄清或批准。如果状态存在,阶段 0 的恢复会自动继续。阶段转换无需经过确认环节。
  4. 审查关卡仅供参考。 如果审查关卡在达到最大自动修复次数后仍未收敛,应记录剩余问题并继续。不要陷入僵局。
  5. 向所有支持 --headless 的子技能传递 --headless(/qa、/debug、/qa-plan)。对于嵌套子进程(阶段 3、5、6),按 /nest-claude 约定启用非交互模式。
  6. 必须加载每项技能。 对于工作流要求加载的技能,不得以直接操作代替。每一步都必须加载所有技能——它们包含无头模式仍须遵循的质量关卡和清单。
  7. 内联规范内容: 如果输入是内联 SPEC.md 内容(而非文件路径),则在继续之前将其写入 specs/<feature-name>/SPEC.md。根据规范标题或问题陈述确定功能名称。

headless 标志会记录在 state.json 中(参见 references/state-initialization.md),并在压缩上下文或重新进入时保留。重新进入时,Agent 会从 state.json 中读取 headless: true,并继续以无头模式运行。

⚠️ 已知错误:子进程执行历来会跳过后续阶段。

当 /ship 本身作为嵌套的 claude -p 子进程运行时(例如通过 /nest-claude 委派),由于上下文压缩导致子进程状态跟踪丢失,阶段 5–9 历来会被跳过。这是错误行为,不可接受。 如果你是 Ship 编排器,无论是在子进程中还是顶层对话中,都必须执行每个阶段。此错误的存在不代表可以跳过任何阶段。

如果你不是作为子进程运行(即你是顶层 Agent 或以交互方式运行),则完全不受此限制影响。执行每个阶段。

如果你是作为子进程运行: 抵制跳过阶段的倾向。加载每项技能,启动每个子进程,运行每个阶段。如果上下文压缩中断了你,停止钩子会在正确的阶段重新注入你——相信它,并从那里继续。


Ship 工作目录

所有执行状态都存储在可配置的工作目录中(已加入 gitignore)。解析优先级如下:

优先级来源默认值
1会话锚点(按 session_id 索引,由 ship-worktree.sh 写入——仅供停止钩子使用)--
2环境变量 CLAUDE_SHIP_DIR_OVERRIDE(用于 Docker/CI/隔离环境的显式覆盖)--
3根据 git 根目录动态解析$(git rev-parse --show-toplevel)/tmp/ship

Ship 脚本会根据 git rev-parse --show-toplevel 动态解析 Ship 目录——无需手动维护环境变量。在此技能及其子技能(/implement、/cancel-ship)中,tmp/ship/ 指解析后的 Ship 目录。Shell 脚本(ship-init-state.sh、implement.sh、ship-stop-hook.sh)会动态解析此目录——每个工作树都会自动获得自己的 tmp/ship/ 目录。

进入工作树后,脚本会通过 git rev-parse 自动将目录解析为该工作树的 tmp/ship/。

状态文件

所有执行状态都存储在 tmp/ship/ 中(已加入 gitignore)。唯一提交的产物是 SPEC.md。子技能(/spec、/implement)会管理各自的内部产物——详情请参阅它们的 SKILL.md 文件。

文件内容创建时间更新时间读取者
tmp/ship/state.json工作流状态——当前阶段、功能名称、规格路径、分支、能力、质量关卡、修订、后台进程第 1 阶段(Ship)每次阶段转换时(Ship);后台进程启动/完成时停止钩子(重新注入、进程检测)、Ship(重新进入)
tmp/ship/loop.md循环控制——迭代计数器、最大迭代次数、完成承诺、session_id(用于隔离)第 1 阶段(Ship)每次重新进入时(停止钩子递增迭代次数并写入 session_id)停止钩子(阻止/允许退出)
tmp/ship/last-prompt.md上次重新注入的提示词——停止钩子最近一次重新进入时构建的完整提示词,用于调试停止钩子每次重新进入时(覆盖)仅用于调试
tmp/ship/spec.json用户故事——验收标准、优先级、通过/失败状态第 2 阶段(/decompose)每次迭代时(设置 passes: true)implement.sh、迭代、Ship
tmp/ship/progress.txt迭代日志——已完成的工作、经验总结、阻碍因素第 3 阶段开始时(implement.sh)每次迭代时(追加)迭代、Ship
tmp/ship/review-output.md最新的便携式本地审查摘要,来自审查关卡(第 5、8 阶段)审查关卡每次本地审查通过时(覆盖)Ship、用户
tmp/ship/review-status.json解析后的本地审查状态——建议、风险、问题数量,以及关卡是否仍处于阻塞状态审查关卡每次本地审查通过时(覆盖)Ship、本地审查脚本
tmp/ship/qa-progress.jsonQA 场景与结果——状态、备注、bootstrapResult第 6 阶段(/qa-plan)第 7 阶段(/qa)——场景状态、证据、bootstrapResult。第 7 阶段退出关卡(Ship)——当编排器解决了 /qa 未能解决的场景时,将 blocked 改为 validated,并设置 resolvedBy: "parent"。Ship(第 6→7 阶段之间的阶段关卡、完成报告)
tmp/ship/ship-summary.mdShip 摘要——规格偏差、QA 缺口、延期范围、已发现的机会第 9 阶段(Ship)仅第 9 阶段/pr
SPEC.md (已提交)产品与技术规格——需求、设计、决策、非目标第 1 阶段(/spec 或用户)仅第 1 阶段所有阶段、迭代
何时更新哪些内容
事件state.json其他文件
阶段 1 结束运行 ship-init-state.sh — 创建 state.json 和 loop.md(参见阶段 1,第 3 步)—
阶段 2 开始—/decompose 创建 tmp/ship/spec.json
阶段 3 开始—/implement 创建 tmp/ship/implement-prompt.md、tmp/ship/progress.txt
审查关卡(阶段 5、阶段 8)如果 state.json 已存在,则更新本地审查状态run-local-review.sh 将可移植的审查包暂存到 tmp/ship/pr-review-plugin/,覆盖 tmp/ship/review-output.md,并将其解析为 tmp/ship/review-status.json
任意阶段 → 下一阶段将 currentPhase 设为下一阶段,将规范阶段名称追加到 completedPhases,并刷新 lastUpdated。规范名称:"Phase 2"、"Phase 3"、"Phase 4"、"Phase 5"、"Phase 6"、"Phase 7"、"Phase 8"、"Phase 9"。停止钩子会在允许完成前验证 completedPhases 中是否包含阶段 2–9;缺少条目会阻止退出。—
用户修订(任意阶段)追加到 amendments[]:{"description": "...", "status": "pending"}—
识别出延后处理的范围(任意阶段)追加到 deferredScope[]:{"description": "...", "phase": "Phase N", "source": "..."}—
发现机会(任意阶段)追加到 surfacedOpportunities[]:{"description": "...", "phase": "Phase N", "source": "..."}—
启动后台进程(阶段 3、4、5、6、7、8)将以下字段追加到 backgroundProcesses[]:taskId、pid(未知时为 null)、type("implement"、"review" 或 "nested-claude")、phase、command、startedAt(ISO 8601)、description。使用 jq 进行追加(通过临时文件读取、修改并写入)。进程完成后,按 taskId 筛选并移除对应条目。—
迭代完成一个用户故事—tmp/ship/spec.json:将用户故事的 passes: true。tmp/ship/progress.txt:追加迭代日志。
阶段 6 QA 规划—/qa-plan 创建 tmp/ship/qa-progress.json,其中包含计划的场景、缺口和补充内容
阶段 7 QA 执行—/qa 更新 tmp/ship/qa-progress.json — 场景状态、bootstrapResult、证据
阶段 7 退出关卡(解决阻塞项)—对于 /qa 退出后由协调器解决的场景,Ship 会更新 tmp/ship/qa-progress.json,将状态从 blocked 改为 validated,并设置 resolvedBy: "parent"
阶段 9 → 已完成设置 currentPhase: "completed"。将 "Phase 9" 追加到 completedPhases。停止钩子的三部分关卡会验证:(1) 输出中包含完成承诺,(2) currentPhase === "completed",(3) completedPhases 中包含阶段 2–9 的所有阶段。停止钩子删除 loop.md
停止钩子重新进入—loop.md:迭代次数递增。根据 state.json + SKILL.md 重新注入提示词。
/cancel-ship保留以供检查删除 loop.md

工作流

阶段转换

从任一阶段进入下一阶段之前:

  1. 确认当前阶段的所有未决问题均已解决。

  2. 确认你对当前阶段的产出有较高把握。

  3. 无头模式下:所有阶段均自主运行。不要输出 <input> 或请求确认。根据证据做出最合理的判断,并在完成报告中记录。

  4. 交互式协作阶段(用户正在积极提供输入):明确询问用户是否准备好继续。收到确认前不要继续。

  5. 交互式自主阶段:自行判断,但如果某项决策需要你无法自主做出的人类判断,应暂停并咨询用户(例如存在重大权衡的架构选择、面向产品或客户的决策、范围变更,以及猜错代价较高的模糊需求)。 暂停前: 彻底研究当前情况——收集所有相关背景,探索各种方案并评估权衡。应向用户提供完整的决策简报,而不是含糊地提问。

    暂停时: 在消息开头输出 <input>Input required</input>,然后列出:

    • 情况:发生了什么,以及为什么需要做出决定
    • 已收集的背景:你研究了什么、发现了什么、尝试了什么
    • 方案:具体选项及各自的权衡
    • 你的建议:你会选择哪个选项,以及原因(如果有建议)
    • 提示:"Would you like me to research any of these options more deeply before you decide?"

    stop hook 会检测 <input>,并让你等待用户回复。循环会保持活动状态——用户回复后,你完成相应操作,循环便会自动恢复。

    不要因以下情况暂停: 你能够依据证据自行决定的常规工程决策、通过阅读代码或文档即可回答的问题,以及可以通过 /research 或 /explore 解决的任何事项。判断标准:该团队的高级工程师会自行做出决定,还是会将问题升级给产品负责人?

  6. 根据上方的“When to update what”表更新 tmp/ship/state.json(Phase 1 结束前该文件不存在)。

    • 修订: 当用户要求原始规范中未包含的变更——临时任务、改进、调整,或经用户批准的评审反馈范围扩展——在执行前将其追加到 amendments:{ "description": "<简要说明内容>", "status": "pending" }。完成后将 status 设为 "done"。此日志会在上下文压缩后保留,并告知恢复后的 Agent 规范之外还收到过哪些工作请求。
  7. 更新任务列表:将已完成阶段的任务标记为 completed,并将下一阶段的任务标记为 in_progress。

  8. 累积延期范围和发现的机会。 每次阶段转换时,留意本阶段出现但本次 ship 流程不会处理的事项,并将其追加到 state.json。分为两类:

    • deferredScope[] — 已确认需要处理但有意暂不处理的工作(原则上接受但推迟的评审建议、发现的相邻 Bug、已知但未处理的边缘情况、实现过程中发现的后续工作)。追加:{ "description": "<需要完成的工作>", "phase": "Phase N", "source": "<发现来源>" }。
      • 纳入评审结果: 每个评审关卡后(Phase 5 /review-cloud、Phase 4/Phase 8 /review-local),读取评审结果中与未来相关但被拒绝的发现。对于 /review-local:读取 review-status.json 中的 deferredFindings[]。对于 /review-cloud:读取完成输出中的被拒绝发现列表。将每项与未来相关的内容追加到 deferredScope[],source 设为 "review-cloud" 或 "review-local",phase 设为当前阶段。
    • surfacedOpportunities[] — 深入代码后发现但并非必须完成的想法、改进或架构观察。追加:{ "description": "<观察内容>", "phase": "Phase N", "source": "<发现来源>" }。

    立即将这些内容持久化到 state.json——与 amendments[] 使用相同的做法。持久化到 state.json 的条目会在上下文压缩后保留;仅记录在对话中的条目不会保留。Phase 9 的 Ship Summary 会读取这些数组。


创建阶段任务列表(每次全新运行的第一个操作)

开始 Phase 0 之前,使用 TaskCreate 为每个阶段创建任务。这样可以提前展示完整工作流,并确保不会跳过任何阶段。

按以下顺序创建这些任务:

  1. Phase 0:检测上下文和起始点 — 恢复检查、功能名称、工作树、能力检测、范围校准
  2. Phase 1:编写规范并交接(/spec) — 搭建规范框架、调查、加载 /spec、验证
  3. Phase 1 退出:启用自主执行(ship-init-state.sh) — 运行初始化脚本以创建 state.json + loop.md,确认两个文件均存在。这会启用停止钩子,让 Agent 持续完成所有剩余阶段。
  4. Phase 2:分解(/decompose) — 加载带有 SPEC.md 路径的 /decompose,生成 spec.json
  5. Phase 3:实现(/implement) — 建立理解、加载带有 spec.json 的 /implement、实现后审查
  6. Phase 4:文档(/docs) (嵌套子进程) — 启动嵌套 Claude,编写或更新所有受影响的文档部分
  7. Phase 5:审查关卡 — QA 前(/review-local) — 运行本地审查收敛循环、评估发现的问题、修复已验证的问题
  8. Phase 6:QA 规划(/qa-plan) (嵌套子进程) — 启动嵌套 Claude,通过 /qa-plan 根据 spec.json + 代码 + 差异生成 qa-progress.json
  9. Phase 7:测试 / QA(/qa) (嵌套子进程) — 启动嵌套 Claude,通过 /qa 根据 qa-progress.json 执行
  10. Phase 8:审查关卡 — QA 后(/review-local) — 对最终代码(包括 QA 修复)运行本地审查收敛循环
  11. Phase 9:完成 — 执行完成检查清单、向用户汇报、输出完成承诺

每个阶段开始时,将其任务标记为 in_progress。阶段完成时,将其标记为 completed。

重新进入 Ship Loop([SHIP-LOOP])时: 先检查 TaskList。如果任务已存在,则恢复执行——将已完成阶段的任务标记为 completed(如果尚未标记),然后从当前阶段的任务继续。如果不存在任务(会话早于此步骤),则创建任务,并根据 state.json 中的 completedPhases 将已完成阶段标记为 completed。


Phase 0:检测上下文和起始点
从上一次会话恢复

首先,检查 tmp/ship/state.json 是否存在。如果存在:

无头模式: 自动恢复。加载状态并跳转到记录的阶段。不要询问。

交互模式:

  1. 读取状态文件,并向用户展示恢复的状态:功能名称、当前阶段、已完成阶段和任何待处理的修订。
  2. 询问:“之前针对 [feature] 的 /ship 会话在 [phase] 阶段中断。要从那里恢复,还是重新开始?”
  3. 如果恢复:加载状态(规范路径、分支、工作树路径、质量关卡、能力、修订),并跳转到记录的阶段。重新读取 SPEC.md 以及状态文件中引用的任何产物。检查 amendments 数组中的待处理项——这些是用户在编写规范后提出、可能仍需处理的更改。如果 tmp/ship/loop.md 不存在(循环未启用),则按照 Phase 1 第 3 步重新启用。
  4. 如果重新开始:删除状态文件;如果 tmp/ship/loop.md 存在,也将其删除,然后照常继续。
第 1 步:确定功能名称和起点

确定用户想构建什么,以及是否已有规格说明。在此处快速探索即可——调用几次 Grep/Glob/Read 来熟悉情况(例如,查找相关目录、确认模块是否存在)。但不要进行长时间调查、启动 Explore 子 Agent 或加载技能。深入调查将在脚手架搭建完成后的第 1 阶段进行。

条件操作
用户提供了现有 SPEC.md 的路径(或内联规格说明内容)加载它。从规格说明中提取功能名称。启用无头模式——提供规格说明意味着工作流将端到端运行,无需交互(参见“无头模式”部分)。如果输入是内联内容,请先将其写入 specs/<feature-name>/SPEC.md。
用户传入了 --headless 标志(并提供功能描述)启用无头模式。从描述中提取功能名称。在第 1 阶段根据描述生成 SPEC.md 脚手架,然后自主继续。
用户提供了功能描述(没有 SPEC.md,也没有 --headless)可以快速探索相关区域以熟悉情况。然后提取一个简短的功能名称(例如,revoke-invite、org-members-page、auth-flow)。如果描述过于含糊,无法命名,请提出 1–2 个有针对性的问题——只需足以确定语义名称,无需深入界定范围。
存在歧义询问:“你是否已有 SPEC.md,还是要从头编写规格说明?”
第 2 步:创建隔离的工作环境

现在已有功能名称,请建立一个隔离的工作目录,以便从一开始就将所有构件放在功能工作区中。

默认行为:除非另有指定,/ship 会从 origin/main 创建一个全新的工作树。这样可以确保并发运行的 /ship 实例不会相互冲突——每个工作树都有自己的 tmp/ship/ 状态目录。可通过以下选项覆盖:

  • --local — 跳过工作树创建,直接使用当前检出状态
  • --branch <name> — 跳过工作树创建,检出指定的现有分支

加载:references/worktree-setup.md — 包含完整的决策表、设置流程和依赖安装说明。

优先使用辅助脚本,而不是临时运行 git worktree 命令:

<path-to-skill>/scripts/ship-worktree.sh ensure --feature "<feature-name>"

辅助脚本会创建一个全新的同级工作树,让每个 /ship 请求都拥有自己的工作区。只有当你已经位于工作树中(而非主检出目录)时,它才会复用当前检出目录。

规格说明移交:如果提供了 --spec <path>,请在创建工作树之前将路径解析为绝对路径,然后在 cd 进入工作树后将其复制进去。操作流程请参见 references/worktree-setup.md。

脚本会通过 git rev-parse --show-toplevel 动态解析 ship 目录——进入工作树后无需手动重新导出变量。

第 3 步:检测执行环境

加载:references/capability-detection.md — 列出所有能力(质量门禁、浏览器、macOS、Docker、技能)的探测表及降级方案。

记录结果。**在交互模式下:**如果有任何能力不可用,请简要说明缺少的内容,作为协商检查点——用户可能可以在工作继续之前解决问题。**在无头模式下:**记录不可用的能力并继续——每项子技能中都已预先规划降级方案。

步骤 4:根据范围校准工作流

评估任务,并确定每个阶段的适当深度。始终执行每个阶段——范围校准调整的是严谨程度,而不是是否执行某个阶段。

任务范围规格深度(阶段 1)实现深度(阶段 3)文档深度(阶段 4)审查深度(阶段 5、8)测试深度(阶段 7)
功能(新能力、多文件、面向用户)完整 /spec → SPEC.md → spec.json完整 /implement 迭代循环完整文档流程——产品文档 + 内部文档完整本地审查收敛循环完整 /qa
增强(扩展现有功能,范围适中)SPEC.md,包含问题 + 验收标准 + 测试用例;/spec 可选/implement 迭代循环如有影响,更新现有文档完整本地审查收敛循环/qa(根据范围校准)
Bug 修复 / 配置更改 / 基础设施(范围较小、针对性更强的更改)SPEC.md,包含问题陈述 + 对“已修复”状态的定义 + 验收标准/implement 迭代循环(根据范围校准)仅在行为发生变化时更新文档本地审查收敛循环如面向用户,则进行有针对性的 /qa

始终生成 SPEC.md——仅通过对话得出的结论无法在上下文丢失后保留。

在内部记录范围级别——它决定了各阶段的深度。此处不要给出详细的逐阶段计划,也不要等待批准;直接进入阶段 1,让 SPEC.md 的框架记录初始范围。用户通过规格交接(阶段 1,步骤 2)确认范围,而不是通过单独的计划批准步骤。


阶段 1:编写规格并交接(/spec,交互模式下协作完成)

**在提供了规格的无头模式下:**完全跳过步骤 1——规格已存在。跳转到步骤 2(验证)。验证后,直接进入步骤 3(激活状态),无需等待确认。

**在使用 --headless 标志但未提供规格的无头模式下:**根据功能描述搭建 SPEC.md 的框架(将其写入 specs/<feature-name>/SPEC.md),执行以下调查步骤,然后进入步骤 2,无需等待确认。

**在交互模式下:**用户是产品负责人——你的工作是帮助他们清晰地梳理要构建的内容,指出他们可能遗漏的考量,并与他们共同制定严谨的规格。

步骤 1:编写规格说明

先搭建脚手架,再逐步完善。 如果用户的描述确实过于模糊,无法搭建脚手架(例如只说“改进系统”,没有具体说明),最多提出 1~2 个范围界定问题。如果请求足够具体,可以写出问题陈述——即使还不完整——就跳过提问,立即编写脚手架。不要在脚手架成形前进行冗长的范围界定对话。

将其写入 specs/<feature-name>/SPEC.md(相对于仓库根目录)。这是 /spec 技能默认的路径约定——完整的覆盖优先级(环境变量、AI 仓库配置、用户覆盖)请参阅 /spec 中的“Where to save the spec”。脚手架应包含:

  • 问题陈述(目前你对问题的理解)
  • 初步需求和验收标准(即使还不完整)
  • 已知约束或技术方向
  • 待解答问题(仍需澄清的事项)

脚手架不必完整,但必须写入磁盘,以便在上下文压缩后仍能保留,并为后续完善对话提供依据。深入探索(调查、待解答问题、决策、/spec)应在脚手架成形后进行,而不是之前。

脚手架成形后——进行调查。 现在,脚手架已为对话提供依据,可以开展深入调查,为规格说明提供参考:

  1. 追踪现有系统。 加载 /explore 技能,了解相关部分当前的工作方式——模式、共享抽象、数据流和影响范围。对于 Bug 修复,使用系统追踪的视角,从入口点开始跟踪执行过程,直至出错位置,并找出根本原因(而非仅仅症状)。
  2. 研究第三方依赖。 如果功能涉及第三方库、框架、包、API 或外部服务,请加载 /research 技能,在设计解决方案之前,先核实其功能、约束和正确用法。每次都要这样做,而不只是觉得依赖陌生时才做。即使你之前用过某项依赖,它也可能已经发生变化、存在未记录的约束,或在当前上下文中表现不同。不要依据假设的 API 形式编写规格说明——务必先核实。
  3. 更新脚手架。 根据调查结果修订 SPEC.md,补充根本原因(针对 Bug)、系统约束、API 形式、依赖能力,以及以调查结果为依据的完善后验收标准。

这项调查不可省略——它能让规格说明立足于现实,而不是建立在假设之上。假设某个 API 以特定方式工作,或某个模块具有特定接口,都会导致实现过程中出现意外,而这些问题之后修复的成本更高。

然后完善规格说明。 加载 /spec 技能,通过交互流程深化并完成规格说明。脚手架和调查结果能为 /spec 提供基于实际情况的起点,而非一张白纸。

在规格说明流程中,确保通过证据记录以下内容(而非仅凭愿望设想):

  • 所有测试用例和验收标准。标准应描述可观察到的行为,而非内部机制(示例请参阅 /tdd)。
  • 失败模式和边缘情况
  • 第三方依赖的约束和 API 形式(通过 /research 核实,而非假设)

如果范围评估表明应采用较轻量的规格说明流程(增强或 Bug 修复):直接完善脚手架,而不调用 /spec。上述调查步骤仍然适用——规格说明流程较轻量,不代表调查也可以简化。最终的 SPEC.md 仍必须记录:问题陈述、根本原因(针对 Bug 修复)、“完成”的定义(验收标准)以及计划进行的测试。

如果用户提供了现有的 SPEC.md(在第 0 阶段检测到):跳至步骤 2。

步骤 2:验证规格说明

阅读 SPEC.md。确认其中包含足够的实现细节:

  • 问题陈述和目标明确
  • 已定义范围、要求和验收标准
  • 已列出测试用例(或可根据验收标准推导)
  • 已提供技术设计(架构、数据模型、API 形式——至少说明方向)

如果缺少任何内容:**在交互模式下,**通过向用户提出有针对性的问题或给出合理的默认值来补全缺漏(明确标注为假设)。**在无头模式下,**使用合理的默认值补全缺漏——在 SPEC.md 中将其标注为假设,然后继续。

**在交互模式下:**在用户确认 SPEC.md 已可用于实现之前,不要继续。此确认即为交接——从此刻起,由你自主负责执行。

**在无头模式下:**验证完成后立即继续。提供的规格说明即视为用户的最终决定。

步骤 3:激活执行状态

加载: references/state-initialization.md — 其中包含初始化脚本的调用方式和字段参考。

使用第 0 阶段(能力、范围)和第 1 阶段(功能名称、规格说明路径、分支)的值运行 <path-to-skill>/scripts/ship-init-state.sh。传入 --session-id 和你的会话 ID(可从钩子输入 JSON 中获取),以将所有权写入 loop.md——这可防止并行 ship 会话同时认领此循环。**不要手动编写 state.json 或 loop.md——始终使用该脚本。**手写 JSON/YAML 是导致停止钩子失败的头号原因。完整参数列表和默认值请参阅参考文档。

脚本运行后,确认这两个文件都存在:

test -f tmp/ship/state.json && test -f tmp/ship/loop.md && echo "State initialized" || echo "ERROR: state files missing"

如果缺少任一文件,请检查脚本输出中的错误并重新运行。两个文件都存在之前,不要进入第 2 阶段。

该脚本会激活用于自主执行的停止钩子。循环将持续运行,直到出现 <complete>SHIP COMPLETE</complete> 或达到 20 次迭代。可使用 /cancel-ship 手动取消。


第 2 阶段:分解(/decompose)

使用 SPEC.md 路径加载 /decompose 技能。/decompose 会读取规格说明、分析代码库,并生成 tmp/ship/spec.json——其中包含按依赖关系排序的结构化用户故事、可验证的验收标准和 QA 场景。

进入第 3 阶段之前,确认 tmp/ship/spec.json 存在。


第 3 阶段:实现(/implement)
步骤 1:了解代码库

确认你真正理解了该功能——而不只是确认规格说明包含正确的章节。检验自己:你能否清楚说明该功能的作用、重要性、技术实现方式、风险最高的部分,以及你会优先测试的内容?如果不能,请重新阅读规格说明并调查代码库,直到能够回答。针对目标区域加载 /explore 技能(目的:实现),以了解你需要使用的模式、约定和共享抽象。根据 /explore 的发现和 SPEC.md 建立理解——不要漫无目的地浏览实现文件;让 /explore 引导你的探索。如果需要深入了解特定子系统,可将有针对性的问题委派给子 Agent(例如:“src/middleware/ 中的身份验证中间件链如何运作?遵循哪些约定?”)。你的理解应着眼于架构,而非逐行分析。这些理解将用于之后评估实现输出和审查者的反馈。

步骤 2:加载 /implement 技能

使用 Phase 2 中的 spec.json 路径加载 /implement 技能。由于 spec.json 已存在,/implement 会从 Phase 2(Prepare)开始,跳过其内部转换步骤。无论范围大小,提示词编写和迭代循环都由 /implement 负责。不要直接编写实现代码——所有实现都必须通过 /implement 及其子进程(implement.sh)完成,即使变更看起来简单到可以直接内联处理。

加载 /implement 技能以处理完整的实现生命周期——从规范转换(SPEC.md → spec.json)到提示词编写和执行。向它提供以下内容:

  • SPEC.md 的路径——这是优先级最高的输入。不得省略。
  • 第 1 步中获取的代码库上下文——你通过 /explore 识别出的模式、约定和共享抽象
  • Phase 0 中覆盖质量门禁命令的设置(可能与 pnpm 默认值不同)
  • Phase 0 中的浏览器可用性(如果浏览器工具不可用,请传递 --no-browser,让 /implement 调整验收标准)
  • Phase 0 中的 Docker 执行设置(如果传递了 --implement-docker,请将其作为 --docker 转发给 /implement;如果提供了 compose 文件路径,也一并传递)

等待 /implement 完成。如果它报告自动执行不可用并将任务交给用户,请等待用户表示已完成。用户表示完成后,重新读取 SPEC.md、spec.json 和 progress.txt,以重新掌握上下文。

后台进程跟踪: 当 /implement 通过 Bash(run_in_background: true) 启动 implement.sh 时,立即根据状态更新表中“Background process launched”一行的要求,将后台进程记录到 state.json 中。使用类型 "implement",描述 "Implementation iteration loop"。implement.sh 完成后,移除对应条目。

步骤 3:实现后审查

实现完成后,在继续之前确认输出令你满意。你要对这段代码负责——实现输出只是起点,而不是终点。不要自己逐一阅读每个变更文件来审查输出;请委派子 Agent 进行有针对性的验证:“实现是否符合 SPEC.md 的验收标准?是否存在遗漏、死代码或尚未解决的 TODO?每项验收标准是否都有对应测试?”根据发现采取行动。对于较小且明显的问题,直接修复。对于根因不明确的问题,加载带有 --headless 的 /debug 技能进行诊断——/debug 将返回结构化发现(根因、建议修复方案、影响范围),但不会自行实施修复。根据其发现应用修复。对于需要重新实现某个 story 的大型返工,请根据具体反馈重新加载 /implement 技能。

如果你进行了任何代码更改(无论是直接修复,还是重新调用 /implement):请重新运行质量门禁(测试套件、类型检查、lint),并确认全部通过。/implement 会以通过状态退出,但其迭代循环之外的实现后修复由你负责验证。

阶段 4:文档(/docs,嵌套子进程)

启动一个嵌套 Claude Code 实例(通过 /nest-claude 子进程模式启动干净的子实例)来编写或更新文档。子进程会加载 /docs,并独立完成整个文档生命周期。尽早编写文档,以便两个评审关卡(阶段 5 和阶段 8)都能评估文档的质量和准确性——完整的评审人员名单(包括 pr-review-docs)会在文档已就绪的情况下运行。

向子进程提供:

  • SPEC.md 的路径(了解已构建内容及其原因的主要来源)

后台进程跟踪: 通过 Bash(run_in_background: true) 启动嵌套 Claude 子进程时,按照状态更新表中的“已启动后台进程”行将其记录到 state.json 中。使用类型 "nested-claude",描述 "Documentation subprocess (/docs)"。完成后移除。

子进程退出后,确认文档更改已提交到分支。

文档维护规则

在后续所有阶段中,文档都必须保持最新:

  • 阶段 5 或阶段 8(评审)之后: 如果评审反馈导致代码更改,请评估这些更改是否会影响本阶段编写的文档。继续之前先更新文档。
  • 用户请求修改之后: 如果用户在阶段 4 之后请求更改,请在修改代码的同时更新受影响的文档。
  • 阶段 9(完成)检查点: 确认文档仍准确反映最终实现。

阶段 5:评审关卡——QA 前(/review-local)

运行本地评审收敛循环。这是两个评审关卡中的第一个——它会在 QA 测试前评审实现和文档。不要假设目标仓库 vendored 了评审插件——先将插件包暂存到 tmp/ship/,然后执行暂存的副本。

通过此技能的辅助脚本,在仓库根目录运行。评审会并行调度 17 个评审人员,并最多运行 5 轮修复——这通常会超过 Bash 工具的 600 秒超时时间。务必使用 run_in_background: true 运行。 启动后,按照状态更新表中的“已启动后台进程”行将后台进程记录到 state.json 中(类型 "review",描述 "Pre-QA local review gate")。完成后移除。

Bash(command: "<path-to-skill>/scripts/run-local-review.sh",
     run_in_background: true,
     description: "Local review gate")

如果分支的目标不是自动检测到的基分支,请显式传入 --target <branch>。

如果本次 /ship 运行启用了 Docker 执行,请在 Docker 模式下运行同一辅助脚本,以便评审在仓库沙盒内运行,而不是在主机上运行:

Bash(command: "<path-to-skill>/scripts/run-local-review.sh --docker [compose-file]",
     run_in_background: true,
     description: "Local review gate (Docker)")

评审完成时,你会收到 <task-notification>。等待期间可以处理轻量任务,但不要修改代码。如果需要在运行期间检查进度,请使用后台 Bash 调用返回的输出文件路径执行 Read。预计耗时:10-30 分钟,具体取决于差异大小和修复轮数。

辅助脚本会将可移植的评审插件暂存到 tmp/ship/pr-review-plugin/,然后在主机上或 Docker 沙盒内运行 tmp/ship/pr-review-plugin/scripts/pr-review.sh。这与 /implement 模式一致:容器会使用绑定挂载仓库中的暂存文件,而不是主机上的插件安装。

默认情况下,辅助脚本会自动检测目标分支(如果存在则使用 PR 基分支,否则使用仓库默认分支 / origin/HEAD,然后是 main)。收到 <task-notification> 后,脚本的标准输出包含结构化返回载荷——直接解析该载荷,不要手动读取文件:

退出信封(=== LOCAL REVIEW EXIT ===):始终存在。包含 exit_code、exit_reason、轮次计数、修复提交 SHA、最后一条建议、阻塞状态、持续时间以及取证文件的路径。首先读取此项以确定结果。

评审状态(=== REVIEW STATUS ===):已解析的 review-status.json 内容——包括建议、风险、问题数量和阻塞原因。所有非崩溃退出都会提供此项。 迭代日志(=== REVIEW ITERATION LOG ===):审查轮次和修复响应的完整时间顺序记录(发现了什么、修复者处理了什么/拒绝了什么/推迟了什么)。仅在退出码非零时包含(阻塞、致命)——编排器需要这些上下文来决定如何补救。退出码为 0(已收敛)时,迭代日志会保留在磁盘上(信封中包含文件指针),以免占用父级上下文。

退出原因及处理方式:

exit_reason含义操作
converged纯粹的 APPROVE——关卡通过抽查修复内容(审查信封中列出的修复提交),然后继续
fixer_no_changes修复者评估了所有发现,并拒绝/推迟了所有处理——代码未发生更改迭代日志中包含修复者对每项被拒绝发现的理由。**交互模式:**将被拒绝的发现上报给用户。**无头模式:**记录剩余发现并继续——迭代日志中包含修复者基于证据给出的理由。
max_passes_exhausted所有修复轮次结束后仍存在阻塞问题迭代日志会显示尝试过哪些操作。**交互模式:**在问题解决前不要继续。**无头模式:**记录剩余发现并继续。
allow_blocking存在阻塞问题,但已设置 --allow-blocking继续——调用方已明确接受阻塞结果
fatal_error脚本崩溃(暂存、审查调度或解析失败)检查 stderr 中的错误消息。如果信封中存在部分状态(审查状态或迭代日志),请用作上下文。若为暂时性错误,则重试。
  • 收敛后,抽查修复内容——自动修复 Agent 表现不错,但也并非万无一失。

阶段 6:QA 规划(/qa-plan,嵌套子进程)

启动一个嵌套的 Claude Code 实例(干净的子实例,通过 /nest-claude 子进程模式),以生成 QA 测试计划。该子进程会加载 /qa-plan,并检查 spec.json + 代码 + 差异,生成内容更完善的 tmp/ship/qa-progress.json。

**后台进程跟踪:**按照“已启动后台进程”行的要求,在 state.json 中记录此子进程(类型 "nested-claude",描述 "QA planning subprocess (/qa-plan)")。完成后移除该记录。

向子进程提供:

  • SPEC.md 的路径
  • spec.json 的路径(tmp/ship/spec.json)
  • 如果 ship 在无头模式下运行,则传入 --headless

子进程退出后,继续之前先检查 qa-progress.json:

  1. 读取 planMetadata——检查是否存在矛盾(scenarios[].enrichment.gapType === "contradiction")和关键实现缺口(scenarios[].enrichment.gapType === "fixable_gap")。
  2. **如果存在矛盾:****交互模式:**通过 <input> 暂停——矛盾意味着规格假设了不可能实现的内容。向用户说明这些矛盾,并请其在继续前解决。**无头模式:**尽力合理解决(选择最符合规格问题陈述的解释)。在完成报告中记录矛盾及所选解释。不要暂停。
  3. 如果存在关键缺口(主要用户旅程无法测试——没有路由、身份验证失效、主页返回 500):**交互模式:**通过 <input> 暂停——说明这些缺口,并询问是继续还是先修复。**无头模式:**如果可能,尝试直接修复。如果无法修复,则记录并继续——QA 将确认该缺口是否确实存在。
  4. **如果仅存在可修复缺口:**继续——/qa 会在执行期间解决这些问题(/qa 的步骤 5b)。
  5. **如果没有问题:**继续进入阶段 7。

Phase 7:测试 / QA(/qa,嵌套子进程)

启动一个嵌套 Claude Code 实例(干净的子实例,通过 /nest-claude 子进程模式)执行 QA 测试。该子进程加载 /qa,并根据 tmp/ship/qa-progress.json 运行完整的手动 QA 生命周期:环境引导、差距解决、使用可用工具(浏览器、macOS、bash)执行测试、记录结果以及记录差距。

后台进程跟踪: 根据“已启动后台进程”这一行,将此子进程记录到 state.json 中(类型 "nested-claude",描述 "QA execution subprocess (/qa)")。完成后移除记录。

向子进程提供:

  • SPEC.md 的路径
  • 如果范围校准表明范围较轻(错误修复 / 配置变更),请传递此上下文,以便 /qa 相应地校准测试深度
  • 传递 --headless,让 /qa 跳过工具可用性协商检查点并自主运行

Phase 7 退出门槛 — 进入 Phase 8 前请确认:

  • /qa 已完成:子进程已退出,qa-progress.json 已更新测试结果。剩余差距和无法解决的问题均已记录——它们不会阻止进入 Phase 8。
  • 如果 /qa 修改了任何代码:重新运行质量门禁(测试套件、类型检查、lint)并确认全部通过。/qa 会修复发现的错误——你需要验证这些修复不会引发其他问题。
  • 解决受阻场景(见下文)。
  • 你能够向另一位工程师说明实现:测试了什么、存在哪些边界情况,以及如何处理这些情况

解决受阻场景(适用时):

如果 qa-progress.json 中有 status: "blocked" 的场景,且你能够解决(例如,编写 /qa 子进程无法编写的测试、修复环境问题,或提供缺失的依赖项),请予以解决:

  1. 编写测试、验证代码或修复。
  2. 更新 qa-progress.json 中的场景:
    {
      "status": "validated",
      "resolvedBy": "parent",
      "resolvedAt": "<ISO 8601 timestamp>",
      "resolvedNote": "Covered by <test-file-path> via <approach>",
      "previousStatus": "blocked",
      "previousNotes": "<original blocked reason from /qa>"
    }
    
  3. 保留 previousStatus 和 previousNotes 以供审计——下游使用者(例如 /pr)会利用它们区分由父进程解决的场景和经 /qa 验证的场景。

如果受阻场景确实无法解决(需要外部服务、生产凭据或硬件访问),请保持其状态为 blocked——该场景会作为需要人工验证的事项进入 PR。


Phase 8:审查门禁 — QA 后(/review-local)

再次运行本地审查收敛循环。此轮将以全新视角审查最终完整状态——实现、文档以及 QA 所做的任何代码变更。

使用与 Phase 5 相同的脚本,并设置 run_in_background: true。根据“已启动后台进程”这一行,将后台进程记录到 state.json 中(类型 "review",描述 "Post-QA local review gate")。完成后移除记录。

Bash(command: "<path-to-skill>/scripts/run-local-review.sh",
     run_in_background: true,
     description: "Post-QA review gate")

每次调用都是独立运行的——脚本会在开始时清理之前的审查状态。适用相同的 --docker 选项。等待 <task-notification>,然后解析 stdout 中的结构化返回载荷——完整的退出原因表和响应协议请参见 Phase 5。

交互模式: 在此审查门禁通过前,不要进入 Phase 9。无头模式: 与 Phase 5 相同——如果经过最大轮次后门禁仍未收敛,请记录情况并继续。

第 8 阶段退出门槛:QA 过时检查

在 post-QA 审查门禁实施自动修复后,检查这些修复是否使之前的任何 QA 场景失效。读取 tmp/ship/qa-progress.json,并将已验证的场景与第 8 阶段提交进行比较。

识别第 8 阶段提交:使用 qa-progress.json 中的 qaCompletedAtCommit 字段(由 /qa 作为最后一步写入)。运行 git log <qaCompletedAtCommit>..HEAD,准确获取 QA 之后的提交。检查每个提交修改了哪些文件。

全局失效条件:

  • CSS/样式文件发生变更 → 将所有视觉场景标记为过时
  • API 路由/处理程序发生变更 → 将所有集成场景标记为过时

路径启发式规则:

  • 文件位于 src/pages/settings/(或等效路径模式)→ 将名称或路由中包含 "settings" 的场景标记为过时
  • 文件变更涉及某个组件 → 将引用该组件页面/路由的场景标记为过时

标记过时场景:在 qa-progress.json 中为该场景添加 staleness 元数据:

{
  "staleness": {
    "stale": true,
    "staleAfterCommit": "<commit-hash>",
    "validatedAtCommit": "<original-validation-commit>",
    "reason": "CSS changes in src/styles/settings.css may invalidate visual verification"
  }
}

对过时场景的处理:

  • 过时的视觉、集成或错误状态场景 → 触发选择性 QA 重跑(仅重新执行这些类别中的过时场景,而非完整计划)
  • 过时的可用性或边缘情况场景 → 仅提供建议(在 qa-progress.json 中记录,但不重跑)

如果第 8 阶段没有提交修改与任何 QA 场景相关的文件,则完全跳过过时检查。


第 9 阶段:完成

加载: references/completion-checklist.md — 完整的验证清单(质量门槛、文档、本地审查)和完成报告模板。

逐项执行清单。向用户汇报后,输出完成承诺以结束 ship 循环:

SHIP COMPLETE


所有权原则

以下原则指导你在整个过程中的行为:

  1. 你是工程师,而不是传话人。/implement 生成代码;审查者提出修改建议;CI 报告失败。你要决定如何处理每一项。

  2. **结果优先于流程。**工作流阶段旨在组织你的工作,而不是强迫你不断推进。完成当前步骤后,绝不要仅仅因为完成了就进入下一步;只有当你对目前构建的内容真正有信心时才继续。如果有任何不确定之处,就停下来调查。行动之前,应先深入了解代码库、产品、规范意图以及你的决策所带来的影响。

  3. **委派调查;深入完成每个阶段。**信息收集工作默认交由子 Agent 处理:探索代码库、诊断测试失败、分析 CI 日志、审查实现结果中的代码,以及发现模式。这是提升效率的策略,而非配额限制。委派能让你专注于协调和决策,同时由子 Agent 处理范围明确的研究任务。向每个子 Agent 提出清晰的问题,提供相关文件路径或错误消息,并说明所需的输出格式。依据调查结果采取行动,而不是直接依据原始代码或日志。只有在任务很简单时(一个小文件、一条快速命令),才直接调查。判断标准:如果需要超过 2-3 次工具调用,或会产生超过约 100 行输出,就应委派。如果任何时候上下文不足,ship 循环的自动保存/重启机制会确保工作连续性;不要为了追求速度而牺牲阶段深度。 该委派什么、在顶层运行什么、以及该嵌套什么: 三种执行模型:

    • 顶层(Skill 工具,共享上下文):管理状态或做出升级决策的编排阶段——/spec、评审关卡、完成阶段。这些阶段需要编排器上下文(状态文件、规范路径、阶段感知能力,以及使用 <input> 暂停的能力)。
    • 嵌套 Claude——干净子进程(/nest-claude 子进程模式):适合使用全新上下文并保持独立性的执行阶段——/implement(已通过 implement.sh 使用子进程)、/qa-plan、/qa、/docs。干净子进程会加载自己的技能,从磁盘读取产物(而非父进程上下文),不会受到前序阶段的偏见影响。所有通信都通过磁盘产物进行(spec.json、qa-progress.json、progress.txt)。每个子进程退出后,编排器都会读取输出产物。
    • Task 子代理(临时,不继承技能):范围明确的调查——代码库探索、测试失败诊断、CI 日志分析、模式发现。绝不要将流水线阶段委派给 Task 子代理——它会失去工具、技能和上下文。

    子代理机制: 子代理不会继承你的技能。对于普通调查,这并不重要——只需提供明确的问题和文件路径。如果子代理需要调查技能(例如 /explore),请使用 general-purpose 类型(它具备 Skill 工具),并在提示词开头写上 Before doing anything, load /skill-name skill——这样就能可靠地触发 Skill 工具。接着提供上下文和任务:

    Before doing anything, load /explore skill
    
    Explore src/middleware/auth/ for pattern discovery (purpose: implementing).
    We're adding role-based access control — report existing auth conventions,
    shared abstractions, and middleware chain composition. Return a pattern brief.
    
  4. 重证据,不凭直觉。 决策前使用 /research 调查代码库、API 和模式——不只是在遇到陌生内容时才这么做。直接检查代码库。必要时进行网络搜索。标准是:你能否向资深工程师解释自己的推理,并用证据为其辩护?如果不能,说明调查还不够充分。

  5. 把握回应尺度。 研究、规范制定和评审可能会提出许多方法、顾虑和选项。你的任务不是处理每一种可能性,而是评估哪些与当前情境相关,并采取行动。对于每个重要决策,请权衡:

    • 必要性: 这是在解决已验证的问题,还是假设性问题?
    • 适度性: 解决方案的复杂度是否与问题的复杂度相匹配?
    • 证据: 有什么具体证据支持这种方法,而非其他方案?
    • 可逆性: 如果判断有误,之后能否更改?
    • 副作用: 这项决策还会影响什么?
    • 最佳实践: 代码库和生态系统中已确立的模式给出了什么建议?

    如果证据不足以支撑这种复杂度,就优先选择更简单的方法——但“更简单”是指减少环节,而非减少要求。跳过已验证要求的方案并不简单,而是有缺陷。

    过度倾向的表现:实现研究中提出的每一种方案,为假设性问题构建可配置性。

    过度简化的表现:对不熟悉的代码路径不做调查就跳过,缺乏证据却宣称有把握。

  6. 明确指出,不要隐瞒。 如果发现异常之处——设计异味、测试缺口、与规范相矛盾的评审建议——请明确提出。如果问题较为重要,请暂停并征求用户意见。

  7. 优先采用正式测试。 只有在场景确实难以自动化时才进行手动测试。每当你说“我手动测试过”,都应该追问:“这能否改为测试?”


反模式

  • 在设置前进行深入调查。 在 Phase 0 期间启动 Explore 子 Agent、加载技能或对代码库进行扩展探索。可以快速探索一下(进行几次 Grep/Glob/Read 调用)以熟悉情况,但深入调查——/explore、/research、子 Agent——应在 Phase 1(脚手架搭建完成后)进行。用户说“添加邀请撤销”时,你立即就有了功能名称(revoke-invite);无需先梳理整个邀请系统。
  • 未充分理解就开始实现。 尚未建立对功能、代码库相关部分或规范意图的整体认识,就直接开始编写代码。
  • 使用与仓库指定不同的包管理器
  • 未经用户确认就强制推送或执行破坏性 Git 操作
  • 离开工作树前未进行清理。合并后或拆除已放弃的请求时,使用 ship-worktree.sh cleanup。
  • 以“工作很小”为由绕过 /ship。 范围校准(Phase 0,Step 4)会针对各种任务规模调整深度——修复 Bug 时会使用精简的 SPEC.md,并按任务校准测试。工作流始终会运行;严谨程度则按需调整。在 /ship 之外直接实现,就意味着没有规范(需求会在上下文压缩时丢失)、没有状态持久化、没有 QA,也没有评审关卡。即使是涉及 4 个文件的安全修复,也仍然需要规范来定义“修复完成”的标准、验证该标准的测试,以及记录相关内容的 PR。
  • 以“改动很简单”为由跳过 /implement。 /implement 始终会运行——它负责将规范转换为 spec.json、生成实现提示词并执行迭代循环。即使是小改动,也能从结构化提示词和验证周期中受益。在 /implement 之外直接实现,就会失去 spec.json 跟踪、进度日志和质量关卡循环。
  • 手动编写状态文件。 切勿直接以原始 JSON/YAML 格式手动编写 tmp/ship/state.json 或 tmp/ship/loop.md。始终使用 ship-init-state.sh。手动编写的文件是停止钩子故障的首要原因——JSON 格式错误、字段缺失、YAML frontmatter 错误——而由此产生的 Bug(钩子静默退出、循环从未启动)在上下文压缩前都无法察觉,届时就太晚了。
  • 虚假宣称已完成。 在所有阶段确实完成且 Phase 8 的所有验证检查均通过之前,切勿输出 <complete>SHIP COMPLETE</complete>。Ship 循环旨在持续运行直至真正完成——不要谎称完成来提前退出。
  • 因担心上下文不足而赶进度或跳过阶段。 切勿因为觉得上下文快用完了,就压缩、简略处理或跳过 Phase 3-8。Ship 循环的停止钩子会自动保存状态,并在重启后以完整上下文将你带回正确阶段。重启后从正确阶段重新开始,比在上下文所剩无几时压缩处理多个阶段效果更好。每个阶段都会加载技能、运行检查清单并完整完成——上下文压力绝不是跳过或简略处理的正当理由。如果你发现自己在想“上下文快用完了,我快速处理完剩余阶段吧”——请停下。这种想法正是反模式。
  • 以项目特性为由为跳过 QA 阶段找借口。 切勿因为项目是“没有 UI 的后端 SDK”、“已有全面的测试”或“不需要手动 QA”就跳过 Phase 6 或 7。这些都是借口,不是正当的跳过理由。/qa-plan 和 /qa 会测试所有类型的项目——后端 SDK 存在 API 契约、错误处理、边界情况和集成行为,而现有单元测试往往会漏掉这些内容。“全面的测试覆盖”恰恰是 /qa-plan 的模拟检测和覆盖率实况检查要验证的内容——如果覆盖真实,/qa 会很快确认;如果覆盖是模拟的或浅层的,/qa 就会发现你可能漏掉的问题。无头模式中的标志表示“自主运行”,而非“简化流程”。如果你发现自己在写“QA 主要是检查我们已有的测试覆盖率”——请停下。这句话正是反模式。加载技能。启动子进程。让 /qa-plan 和 /qa 完成各自的工作。
  • 委派给子进程时,擅自假定所有阶段都已运行。 当 /ship 作为嵌套的 claude -p 子进程运行时,由于上下文压缩会丢失子进程状态跟踪,Phase 5-9 过去经常被跳过(参见 Headless mode 部分中的“Known bug”)。如果将 /ship 委派给子进程,完成后务必检查 state.json 中的 completedPhases,并手动运行缺失阶段(通常是 QA 和第二轮评审)。

附录:参考资料和脚本索引

路径适用场景跳过的影响
/decompose 技能将 SPEC.md 转换为结构化的 spec.json,其中包含用户故事、依赖项排序和 QA 场景(阶段 2)规范缺乏结构、没有依赖项排序,也没有 QA 场景
/implement 技能编写实现提示词并执行迭代循环(阶段 3)没有实现提示词,也没有自动化执行
/qa-plan 技能根据 spec.json、代码和差异推导 QA 测试计划(阶段 6)QA 场景没有以实现为依据、没有双向追踪,也无法检测差距
/qa 技能使用可用工具进行 QA 验证(阶段 7)遗漏面向用户的 Bug、视觉问题、失效的 UX 流程以及未记录的差距
/docs 技能编写或更新文档——产品和内部层面(阶段 4)未编写文档、格式错误、遗漏文档涉及的层面,或与项目惯例不一致
references/worktree-setup.md创建工作树(阶段 0,步骤 1)工作内容会混入主目录
references/capability-detection.md检测执行上下文(阶段 0,步骤 2)子技能会收到错误标志、阶段被跳过,或基于错误假设运行
references/state-initialization.md激活执行状态(阶段 1,步骤 3)Stop hook 无法恢复上下文,循环无法激活
references/completion-checklist.md最终验证(阶段 9)未完成的工作会被当作“已完成”交付
scripts/run-local-review.sh运行本地审查收敛循环(阶段 5、阶段 8),可选执行有限次数的修复明显的审查问题会被遗漏,或 Ship 因缺少确定的下一步而停滞
scripts/build-local-review-fix-prompt.sh将阻塞性的本地审查结果转换为有限范围的修复提示词,供人工或自主后续处理修复循环无法根据审查结果自动生成交接内容并进入修复步骤
scripts/ship-worktree.sh复用或创建请求专用的工作树,并在合并后清理工作内容会混入主检出目录、过期工作树不断堆积、已完成的分支长期遗留
scripts/ship-upload-pr-asset.js将现有截图或录屏上传到 Bunny CDN(单独使用)即使有可用的程序化 CDN 路径,PR 图片流程仍依赖手动上传到 GitHub
/debug 技能诊断实现过程中(阶段 3)或测试过程中(阶段 7)遇到的故障根因——当无法从错误中直接看出原因时盲目调试:不理解根因就修复表象,浪费迭代周期

评论

支持 Markdown