feat: rename bugfix-ship/requirement-flow to short-ship/long-ship with shared ship records

short-ship and long-ship share one ship-id record under .pouch/ship/<id>/.
specifier writes PRDs into spec/; delivery-loop appends evidence pointers.
Old names stay as deprecation stubs so existing installs keep working.
This commit is contained in:
2026-10-13 23:11:58 +08:00
parent 93341b3c69
commit af6e139d30
47 changed files with 1497 additions and 222 deletions
+9 -8
View File
@@ -1,17 +1,18 @@
# specifier
把复杂需求整理成经过多轮人工评审的 HTML PRD,并在批准后生成交给 ACK 执行的需求 handoff。
把复杂需求整理成经过多轮人工评审的 HTML PRD,并在批准后生成交给 long-ship 执行的需求 handoff。
## 什么时候使用
- 要做跨模块、跨页面、跨服务或带数据迁移的复杂功能。
- 要先写 PRD、比较方案、梳理风险,再进入开发。
- 需要把 PRD 给人反复评审,确认后再交给 `/ack`。
- 需要把 PRD 给人反复评审,确认后再交给 `long-ship`。
小改动直接使用 `/ack`;已知 Bug 使用 `/hunt`;单次架构取舍使用 `/think`。
小改动直接使用 `short-ship`;已知 Bug 使用 `/hunt`;单次架构取舍使用 `/think`。
## 使用前准备
- 同时安装 `ship`;批准后的开发走 `long-ship`。
- 项目应位于 Git 仓库中,便于读取现有代码、文档和历史决策。
- 用户需要参与 PRD 评审,并明确批准具体版本。
- 不需要外部账号或网络资源;生成的 HTML 应能离线打开。
@@ -20,7 +21,7 @@
```text
用 specifier 处理“给后台增加多租户权限管理”这个复杂需求:先调研现状,生成 HTML PRD,
我会逐轮评审。批准后再生成 ack handoff,不要提前派开发。
我会逐轮评审。批准后再生成 long-ship handoff,不要提前派开发。
```
## Agent 会做什么
@@ -29,14 +30,14 @@
2. 形成目标、范围、非目标、方案、交互/架构、风险、依赖和可观测验收。
3. 生成可离线打开的版本化 HTML PRD;保留每个历史版本并记录本轮变更。
4. 根据用户意见反复修改,直到用户明确批准指定版本。
5. 仅在批准后生成 `handoff.yaml`,供 `/ack` 创建和执行任务。
5. 仅在批准后生成 `spec/handoff.yaml`,供 `long-ship` 创建和执行任务。
6. 用户需要远程查看,或说“把 HTML 渲染出来”时,可调用独立的 `previewer` skill;它用 Node
渲染并通过 Tailscale 暴露为 HTTP URL,同时返回应该使用的 Tailscale IP。
Specifier 只负责需求规格,不修改业务代码,也不替代 ACK 的开发和独立测试。
Specifier 只负责需求规格,不修改业务代码,也不替代 long-ship 的开发和独立测试。
## 如何判断完成
- 评审阶段:得到一个带版本号的 HTML PRD、变更记录、风险和未决问题。
- 交接阶段:用户明确批准某个版本,且 `handoff.yaml` 绑定了该版本和完整验收信息。
- 开发阶段:改用 `/ack`,由 ACK 负责 Developer、Test、回归和交付闭环。
- 交接阶段:用户明确批准某个版本,且 `spec/handoff.yaml` 绑定了该版本和完整验收信息。
- 开发阶段:改用 `long-ship`,任务和证据写在同一个 ship id 下。
+48 -38
View File
@@ -2,14 +2,15 @@
name: specifier
description: >-
把复杂或跨模块需求整理成可评审、可版本化的 HTML PRD,并在用户明确批准某个版本后
生成交给 ack 的结构化 handoff。用户说做复杂功能、写 PRD、梳理需求、设计方案、需求
评审、反复改需求或交给 ack 开发时使用;小改动、Bug 根因排查和单纯架构讨论不使用。
生成交给 long-ship 的结构化 handoff。用户说做复杂功能、写 PRD、梳理需求、设计方案、
需求评审、反复改需求或交给 long-ship 开发时使用;小改动、Bug 根因排查和单纯架构讨论
不使用。
---
# Specifier:复杂需求规格化
把模糊需求变成经过人确认的需求基线,再交给 `ack` 执行。HTML 是给人评审的正式交付物,
结构化状态和 handoff 是给 Agent/ACK 消费的机器接口。
把模糊需求变成经过人确认的需求基线,再交给 `long-ship` 执行。HTML 是给人评审的正式交付物,
结构化状态和 handoff 是给 ship 记录消费的机器接口。
---
@@ -17,46 +18,53 @@ description: >-
- 用户要做跨模块、跨页面、跨服务或有数据迁移的复杂功能。
- 用户要求写 PRD、产品方案、需求规格、架构/交互方案,并需要多轮确认。
- 用户要求把确认后的需求交给 `/ack` 开发。
- 用户要求把确认后的需求交给 `long-ship` 开发。
## 不适用
- 单文件或范围明确的小改动:直接交给 `/ack`。
- 已有复现证据的 Bug:使用 `/hunt` 找根因,再按需要交给 `/ack`。
- 单文件或范围明确的小改动:使用 `short-ship`。
- 已有复现证据的 Bug:使用 `/hunt` 找根因,再按需要交给 `short-ship`。
- 只问一个技术选型或一次性方案判断:使用 `/think`。
- 用户尚未批准的需求:不得创建 ACK 任务、派 worker、改业务代码或开始交付。
- 用户尚未批准的需求:不得创建开发任务、派 worker、改业务代码或开始交付。
---
## 工作目录和事实源
每个需求使用独立目录 `.pouch/specifier/features/<feature-id>/`。开始前检查目录是否已存在,
不要覆盖既有版本;已有需求要进入对应版本的 `review` 或 `revise` 模式。
每个需求使用独立 ship 目录 `.pouch/ship/<ship-id>/`。规格文件写在 `spec/`。开始前读取
已安装的 `ship` skill;已有需求要进入对应版本的 `review` 或 `revise` 模式。
```text
.pouch/specifier/features/<feature-id>/
├── current.yaml # 当前版本、状态和批准信息
├── brief.md # 需求输入和现状摘要
├── prd-v001.html # 人类评审版本,不覆盖旧版本
├── review.yaml # 每轮意见、修改请求和确认
├── decisions.yaml # 关键方案决策
├── risks.yaml # 风险、依赖和缓解措施
└── handoff.yaml # 仅 approved 后生成,交给 ack
.pouch/ship/<ship-id>/
├── current.yaml # ship 总账;spec.revision / specStatus 在这里
├── spec.md # 短摘要
├── tasks.yaml # 批准后由 long-ship 写入,本 skill 不写
└── spec/
├── brief.md
├── prd-v001.html
├── review.yaml
├── decisions.yaml
├── risks.yaml
└── handoff.yaml # 仅 approved 后生成,交给 long-ship
```
目录名使用稳定、短、小写连字符的 feature ID。若用户未提供,先从需求生成候选并说明;
目录名使用稳定、短、小写连字符的 ship id。若用户未提供,先从需求生成候选并说明;
不要用日期、随机数或当前分支名冒充业务 ID。
`.pouch/specifier/` 只保存需求规格状态,不复制 skill 内容,不修改项目的 `AGENTS.md`、
`CLAUDE.md` 或已有 ACK 状态。HTML 可引用仓库中的文档和代码路径,但不能依赖外部网络资源。
若只有旧路径 `.pouch/specifier/features/<id>/`,按 ship `record.md` 迁到
`.pouch/ship/<id>/spec/` 后再继续。不要两处同时写。
`.pouch/ship/<id>/spec/` 只保存需求规格,不复制 skill 内容,不修改项目的 `AGENTS.md`、
`CLAUDE.md` 或 ACK 缺陷板。HTML 可引用仓库中的文档和代码路径,但不能依赖外部网络资源。
## 模式路由
- **新建**:探查现状,建立 brief,生成 `prd-v001.html`,状态为 `review`。
- **评审 / 修改**:读取当前版本和 `review.yaml`,把用户意见转成修改项,生成新版本,
- **新建**:探查现状,建立 `spec/brief.md`,生成 `spec/prd-v001.html`,把
`spec.specStatus` 设为 `review`。
- **评审 / 修改**:读取当前版本和 `spec/review.yaml`,把用户意见转成修改项,生成新版本,
展示变更摘要和仍未决的问题。
- **批准**:只在用户明确批准指定版本后,把状态改为 `approved`,冻结需求基线。
- **交接**:仅针对 `approved` 版本生成 `handoff.yaml`;用户要求继续开发时把它交给 `/ack`。
- **批准**:只在用户明确批准指定版本后,把 `spec.specStatus` 改为 `approved`,冻结需求基线。
- **交接**:仅针对 `approved` 版本生成 `spec/handoff.yaml`;用户要求继续开发时把它交给 `long-ship`。
- **状态**:只读报告当前版本、待决策、风险和是否可以交接。
详细评审状态机和确认规则见 [review-loop.md](references/review-loop.md)。HTML 页面结构和
@@ -64,14 +72,14 @@ description: >-
## 新建和调研
1. 先判断需求是否真的复杂;不复杂时给出转 `/ack` 的建议,不强行生成 PRD。
1. 先判断需求是否真的复杂;不复杂时给出转 `short-ship` 的建议,不强行生成 PRD。
2. 读取项目覆盖层、相关文档、历史决策和代码;优先确认现有能力、模块边界、数据模型、
API、权限、运行约束和回归用例。不要从 README 或猜测中虚构项目事实。
3. 形成现状与目标差异:背景、用户、场景、目标、非目标、范围、约束、成功标准。
4. 对关键方案给出取舍,记录推荐方案、被否决方案、最脆弱假设、风险、依赖和回滚方向。
5. 描述必要的产品流程、交互状态、领域模型、状态流、API/数据变化和非功能要求。
6. 按可独立验证的垂直切片拆任务,写出依赖、关键路径、`expected` 和 `verification`,
但不要写入 `.pouch/ack/tasks.yaml`。
但不要写入 `.pouch/ack/tasks.yaml` 或本 ship 的 `tasks.yaml`(任务由 long-ship 在批准后创建)。
7. 按模板生成自包含 HTML PRD,并在回复中说明文件路径、版本、待确认问题和下一步。
8. 用户需要在其它设备查看 HTML,或说“把这个 HTML 渲染出来”时,调用已安装的
`previewer` 能力传入该文件;不要在 `specifier` 内复制 Node/Tailscale Serve 逻辑。
@@ -98,20 +106,21 @@ description: >-
需求评审状态,HTML 被展示不等于用户批准。回复中要同时给出 Tailscale IP 和 URL,不能只
说“已经渲染”或只返回本机 `127.0.0.1`。
## 批准和 ACK 交接
## 批准和 long-ship 交接
批准前只允许写 specifier 自己的需求目录。批准后仍不自动启动 worker;先生成 `handoff.yaml`,
其中必须绑定:feature ID、PRD 版本和路径、需求范围、非目标、决策、任务依赖、验收信号、
风险、回滚/发布注意事项和回归候选。
批准前只允许写该 ship 的 spec 目录和 `current.yaml` 的 spec 字段。批准后仍不自动启动
worker;先生成 `spec/handoff.yaml`,其中必须绑定:ship id、PRD 版本和路径、需求范围、
非目标、决策、任务依赖、验收信号、风险、回滚/发布注意事项和回归候选。同步
`current.yaml` 的 `spec.specStatus`、`spec.approvedRevision`、`spec.handoff`。
`handoff.yaml` 是 ACK 的输入,不是 ACK 的执行记录。用户明确要求继续开发时,提示使用:
`handoff.yaml` 是 `long-ship` 的输入,不是执行记录。用户明确要求继续开发时,提示使用:
```text
/ack 使用 specifier handoff:.pouch/specifier/features/<feature-id>/handoff.yaml
/long-ship 使用 handoff:.pouch/ship/<ship-id>/spec/handoff.yaml
```
ACK 应引用批准的 HTML 版本,不复制另一份可漂移的 PRD。若 ACK 不存在、handoff 缺字段或
需求状态不是 `approved`,停止交接并报告缺口。
long-ship 应引用批准的 HTML 版本,不复制另一份可漂移的 PRD。handoff 缺字段或需求状态
不是 `approved` 时,停止交接并报告缺口。
## 安全边界
@@ -123,6 +132,7 @@ ACK 应引用批准的 HTML 版本,不复制另一份可漂移的 PRD。若 AC
## 验证
完成前检查:HTML 可离线打开、版本号与 `current.yaml` 一致、旧版本未被覆盖、每个未决问题
有明确状态、每个任务有可观测验收、handoff 只在 `approved` 后存在且绑定正确的 PRD 版本。
需要交给 ACK 时,先确认 handoff schema 与用户批准版本一致,再停止等待 ACK。
完成前检查:HTML 可离线打开、版本号与 ship `current.yaml` 的 `spec.revision` 一致、旧版本
未被覆盖、每个未决问题有明确状态、每个任务有可观测验收、handoff 只在 `approved` 后存在
且绑定正确的 PRD 版本。需要交给 long-ship 时,先确认 handoff schema 与用户批准版本一致,
再停止等待 long-ship。
+1 -1
View File
@@ -1,6 +1,6 @@
interface:
display_name: "Specifier"
short_description: "Draft and review complex requirements as HTML PRDs"
default_prompt: "Use $specifier to turn this complex feature request into a reviewable HTML PRD."
default_prompt: "Use $specifier to turn this complex feature request into a reviewable HTML PRD in the ship record."
policy:
allow_implicit_invocation: true
+2 -2
View File
@@ -28,7 +28,7 @@ HTML 是给人离线评审的交付物,不是运行中的产品页面。它必
- 颜色和状态不能只依靠颜色表达;为状态提供文字标签。
- 长表格允许横向滚动,代码或 API 示例使用 `pre`,正文保持可复制。
- `h1` 只有一个;标题层级连续;链接和表格有可读的焦点/边框状态。
- 页首显示 feature ID、PRD 版本、状态、生成时间和基于的版本。
- 页首显示 ship id、PRD 版本、状态、生成时间和基于的版本。
- 变更内容用文字摘要或 `ins` / `del` 标记表达,不要只用颜色标记。
## 内容质量
@@ -36,4 +36,4 @@ HTML 是给人离线评审的交付物,不是运行中的产品页面。它必
- 把“体验好”“性能足够”“支持权限”等不可验证表述改成可观察信号或明确待决策项。
- 不把实现方案伪装成用户需求;需求、决策和任务分开写。
- 未知事实写“待确认”,并加入未决问题,不填看似合理的数字、接口或页面。
- 每条验收都能被 ACK 的 Test 按步骤观察;测试工具不可用时仍能区分产品失败和环境失败。
- 每条验收都能被 long-ship / Test 按步骤观察;测试工具不可用时仍能区分产品失败和环境失败。
+15 -12
View File
@@ -9,15 +9,17 @@
## 状态
`current.yaml` 至少记录:
ship `current.yaml` 的 spec 字段至少记录:
```yaml
featureId: tenant-permissions
currentRevision: v002
status: review
prd: prd-v002.html
approvedRevision: null
reviews: review.yaml
shipId: tenant-permissions
kind: long
spec:
revision: v002
specStatus: review
prd: spec/prd-v002.html
approvedRevision: null
reviews: spec/review.yaml
```
允许的状态:
@@ -55,11 +57,11 @@ reviews: review.yaml
## 每轮评审
1. 读取 `current.yaml`、当前 HTML 和所有未解决的 review 项;不要只读用户最新一句话。
1. 读取 ship `current.yaml`、当前 HTML 和所有未解决的 review 项;不要只读用户最新一句话。
2. 将新反馈归类:`change`、`decision`、`question`、`rejected`、`parked`。
3. 说明每个反馈对范围、架构、任务和验收的影响。
4. 生成新版本 HTML,保留旧文件。
5. 更新 `current.yaml` 和 `review.yaml`,并在回复中给出:新版本路径、变更摘要、未决问题、
5. 更新 ship `current.yaml` 的 spec 字段和 `spec/review.yaml`,并在回复中给出:新版本路径、变更摘要、未决问题、
是否仍需批准。
如果反馈只影响措辞,也生成新版本;评审记录需要保持可追溯。若用户明确说不采纳,记录理由,
@@ -82,7 +84,8 @@ reviews: review.yaml
- HTML 版本、状态文件和 review 记录一致。
如果用户说“继续”“可以”“看起来不错”,但没有绑定版本,继续保持 `review`,请用户确认
具体版本。批准后把 `approvedRevision` 写入 `current.yaml`,再生成 handoff;不要同时启动 ACK。
具体版本。批准后把 `spec.approvedRevision` 写入 ship `current.yaml`,再生成
`spec/handoff.yaml`;不要同时启动 long-ship 或 ACK。
## 批准后的变更
@@ -94,5 +97,5 @@ reviews: review.yaml
4. 标记受影响的任务、验收、风险和 ACK handoff 字段;
5. 重新等待用户批准。
已经进入 ACK 的任务不会因 HTML 更新而自动改变。需要执行变更时,明确告诉用户应创建新的
ACK 任务或由 ACK 重新规划,不能静默改写执行记录。
已经进入 long-ship 的任务不会因 HTML 更新而自动改变。需要执行变更时,明确告诉用户应
修订本 ship 的 `tasks.yaml` 或重新规划,不能静默改写执行记录。
@@ -1,6 +1,16 @@
featureId: <feature-id>
currentRevision: v001
status: review
prd: prd-v001.html
approvedRevision: null
reviews: review.yaml
# 已并入 ship current.yaml 的 spec 字段。新建需求请用 ship 模板,不要单独写这份文件。
# 迁移旧 .pouch/specifier/features/<id>/current.yaml 时按此对照:
# featureId -> shipId
# currentRevision -> spec.revision
# status -> spec.specStatus
# prd -> spec.prd(路径加上 spec/ 前缀)
# approvedRevision -> spec.approvedRevision
# reviews -> spec.reviews
shipId: <ship-id>
spec:
revision: v001
specStatus: review
prd: spec/prd-v001.html
approvedRevision: null
reviews: spec/review.yaml
handoff: null
@@ -1,8 +1,8 @@
featureId: <feature-id>
shipId: <ship-id>
specifierRevision: v001
status: approved
prd:
path: prd-v001.html
path: spec/prd-v001.html
revision: v001
scope:
goals: []
+1 -1
View File
@@ -30,7 +30,7 @@
<main>
<article>
<header>
<p class="meta"><span class="badge">Feature: {{feature_id}}</span><span class="badge">PRD: {{revision}}</span><span class="badge status">状态:{{status}}</span></p>
<p class="meta"><span class="badge">Ship: {{ship_id}}</span><span class="badge">PRD: {{revision}}</span><span class="badge status">状态:{{status}}</span></p>
<h1>{{feature_title}}</h1>
<p>{{one_sentence_summary}}</p>
<p class="muted">生成时间:{{generated_at}} · 基于版本:{{changed_from}}</p>