feat(ship): add stage audit trail and sortable ids

This commit is contained in:
2026-10-14 10:57:16 +08:00
parent 4814bc1026
commit 57879cffdd
10 changed files with 371 additions and 4 deletions
+86
View File
@@ -0,0 +1,86 @@
# Ship 主会话:只编排
入口 `short-ship` / `long-ship` / `pr-ship` 的**当前会话是管理员**。它跟用户说话、
维护账本、按 `next_step.py` 开新 agent,然后等待结果。它不把具体步骤的 skill
读进自己的上下文,也不亲自做那些步骤。
## 目录
- [主会话可以做](#主会话可以做)
- [主会话不能做](#主会话不能做)
- [循环](#循环)
- [怎么开新 agent](#怎么开新-agent)
- [失败](#失败)
## 主会话可以做
- 跟用户确认范围、停止点、批准 PRD、授权生产部署,并写完成报告。
- 跑 ship 脚本:`new_ship_id.py`、`create_ship.py`、`next_step.py`、`append_evidence.py`(仅当 worker
已给出指针而漏写时)、`validate_ship.py`。
- 读写 `.pouch/ship/<id>/` 账本:`spec.md`、`tasks.yaml`、`current.yaml` 的
`status` / `delivery.state` / `spec.*` / `manager.*` / 任务 `status`。
- 按 `next_step.py` 的 JSON 开一个(或 long 的一轮并行 `implement_task`)新 agent,
把 [worker-prompt.md](worker-prompt.md) 填好交给它,**等到它返回**再继续。
需要看字段含义时读 [record.md](record.md)。不要预读其它 skill。
## 主会话不能做
- 不要读取或执行:`hunt`、`tester`、`builder`、`deployer`、`releaser`、`check`、
`specifier`、`delivery-loop`,以及它们的 `references/`。
- 不要改业务代码、跑测试、开/合 PR、obtain、发版、部署、写 HTML PRD。
- 不要在开不出新 agent 时改由自己做该步。
- 不要 fire-and-forget:派出去就回复“已派发”并结束本轮。
- 不要让 worker 再去调 `short-ship` / `long-ship` / `pr-ship`。
`next_step.py` 的 `actor` 为 `manager` 时,这一步就是跟用户说话或改账本,不是去加载
执行类 skill。
## 循环
1. 没有 `ship-id`:先用 `new_ship_id.py --phrase <短语>` 生成
`YYYYMMDD-短语`,再跑 `create_ship.py`,写 `spec.md` 四段(short)
或进入 long 的 specifier 步。功能任务不要写入 `.pouch/ack/tasks.yaml`。
2. 跑:
```bash
python3 <ship-skill>/scripts/next_step.py \
--project-root <root> --ship-id <id> --entry short|long|pr
```
3. 按 JSON 行动:
- `status: done`:写完成报告,结束。
- `status: blocked` / `ask_user`:告诉用户缺口或问题,等回复。生产部署(`stopAt:
released` 且下一步是 `deploy`)必须再问一次,除非当前这句话已经授权。
- `actor: manager`:补账本或问用户,再跑 `next_step.py`。
- `actor: worker`:开新 agent,等待,把结果写入 `manager.lastStep` /
`manager.lastResult` / `manager.lastSummary`,按 `targetState` / `taskId` 更新账本,立刻
`validate_ship.py`。失败不要自己补做。
4. 重复直到 `done`、`blocked` 且用户不再推进,或用户叫停。
不要凭记忆跳过 `next_step.py`。long 的无依赖 `implement_task` 可以一轮并行多个,
仍要全部等完再进入下一步。
## 怎么开新 agent
必须是 **fresh** 会话,prompt 只用 [worker-prompt.md](worker-prompt.md) 填好的那一份。
- 当前运行时有子 agent / Task / spawn:用它,不要把执行类 skill 先读进本会话。
- 当前就在 Orca 里:再读已安装的 `orchestration`,做 supervised dispatch(inject 后
`check --wait` 直到 `worker_done` 或 `escalation`)。不要在本文件复制 orca 命令。
- 没有开新 agent 的能力:`blocked`,说明缺什么。不要自己执行。
把 `next_step.py` 返回的 `stage` 字段填入 worker prompt 的 `<stage>`,让 worker 把摘要
写到对应的 `1-spec`、`2-develop` 等目录。worker 返回后把 summary/evidence 一并写入
`manager.lastSummary` 和阶段 `activity.md`。
一次只派 JSON 里的这一步(long 的并行 implement 除外)。worker 需要用户决定时,它
返回 `ask`;主会话问用户,再派或改账本。
## 失败
- worker `fail` / `blocked`:停在现场,报告摘要和证据。主会话不要接手做该步。
用户明确说重试时,再开一个**新** agent,不要复用刚失败的会话。
- 校验失败:先修账本再继续,不要假装阶段已完成。
- 范围涨到需要 PRD 或多条任务:同一 `ship-id` 把 `kind` 改为 `long`,之后 `--entry
long`。
+22
View File
@@ -17,6 +17,15 @@
spec.md # 短需求说明(short 和 long 都有)
tasks.yaml # 本 ship 的任务 DAG
status.md # 给人看的一页摘要
1-spec/ # 规格、评审、根因和 handoff
2-develop/ # 开发任务和变更
3-test/ # 任务验证与集成回归
4-review/ # PR、审核与合并
5-build/ # 合并后的构建/obtain
6-publish/ # 发布产物
7-deploy/ # 部署与健康检查
stage.yaml # 阶段状态和包含的步骤
activity.md # 该阶段的调度、结果和证据摘要
spec/ # 仅 long:PRD 版本、评审、handoff
brief.md
prd-v001.html
@@ -27,6 +36,11 @@
```
`status.md` 给人看;Agent 以 `current.yaml` 为准。两份不一致时改 `status.md`。
阶段目录由 `create_ship.py` 初始化,由 `next_step.py` 在派发和收到结果时追加活动记录;
大日志留在原测试、构建或部署位置,阶段目录只保存摘要和路径。
新建 ship 使用可排序的 `YYYYMMDD-短语`,例如 `20261014-dynamic-editor`。旧的无日期
记录仍可读取和校验,不要为了改名移动既有 ship 目录。
## current.yaml
@@ -57,6 +71,10 @@ tasks:
delivery:
stopAt: review_ready
state: change_ready
manager:
lastStep: null
lastResult: null
inFlight: null
evidence:
testRuns: []
artifacts: []
@@ -75,6 +93,10 @@ evidence:
`source.kind`:`user` | `hunt` | `ack` | `pr` | `feishu`。修 ACK 缺陷时
`source.kind: ack` 且 `ref` 为缺陷任务 id。
`manager` 由入口主会话维护,可选。`lastStep` / `lastResult` / `lastSummary` 记录刚结束的那一步;
`inFlight` 在 worker 未返回时写成步骤名,返回后清掉。worker 不要写这些字段。
`lastResult`:`pass` | `fail` | `blocked` | `ask`。
## short 与 long
同一套字段,厚度不同。
+4
View File
@@ -7,6 +7,7 @@ delivery-loop 的正文,不要让 worker 再开一层 ship 入口。
你是 ship <ship-id> 的 worker,只做步骤 <step>。
项目根:<project-root>
Ship 目录:.pouch/ship/<ship-id>/
当前阶段目录:.pouch/ship/<ship-id>/<stage>/
任务 id:<taskId 或「无」>
目标 delivery.state:<targetState 或「不改」>
停止点 stopAt:<stopAt>
@@ -37,6 +38,9 @@ pass;没有 HOST、设备或浏览器的测试根必须记录 environment-fail
- summary: 三句以内,做了什么、证据在哪、还缺什么
- evidence: 写入的指针
- ask: 若 status=ask,要主会话问用户的那一个问题
同时把本次工作的命令、关键结果、阻塞和证据路径写入当前阶段目录的
`activity.md`;不要把完整日志复制进 ship,只写可复核摘要和外部文件路径。
```
`<skill>` 必须用 `next_step.py` JSON 里的 `skill` 字段,不要改成别的。`skill` 为