Files
.pouch/skills/ship/references/record.md
T

7.5 KiB
Raw Blame History

Ship 记录契约

目录

布局

.pouch/ship/<ship-id>/
  current.yaml      # 总账:kind、状态、stopAt、指针
  spec.md           # 短需求说明(short 和 long 都有)
  tasks.yaml        # 本 ship 的任务 DAG
  2-develop/test-manifest.yaml  # 开发者新增/修改测试的机器清单
  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
    review.yaml
    decisions.yaml
    risks.yaml
    handoff.yaml    # 仅 approved 后

status.md 给人看;Agent 以 current.yaml 为准。两份不一致时改 status.md。 阶段目录由 create_ship.py 初始化,由 next_step.py 在派发和收到结果时追加活动记录; 大日志留在原测试、构建或部署位置,阶段目录只保存摘要和路径。

新建 ship 使用可排序的 YYYYMMDD-短语,例如 20261014-dynamic-editor。旧的无日期 记录仍可读取和校验,不要为了改名移动既有 ship 目录。

current.yaml

必填:shipId、kind、status、title、spec、tasks、evidence。 shipId 必须等于目录名。

shipId: add-export-button
kind: short
title: 列表页增加导出按钮
status: in_progress
stopAt: review_ready
source:
  kind: user
  ref: null
parentShipId: null
childShipIds: []
spec:
  path: spec.md
  revision: null
  specStatus: null
  prd: null
  approvedRevision: null
  reviews: null
  handoff: null
tasks:
  path: tasks.yaml
delivery:
  stopAt: review_ready
  state: change_ready
manager:
  lastStep: null
  lastResult: null
  inFlight: null
evidence:
  testRuns: []
  artifacts: []
  deploys: []
  prs: []
  commits: []

kind:short | long。

status:draft、spec_review、approved、in_progress、blocked、done、parked、superseded。

delivery.state 使用 delivery-loop 内部里程碑:change_ready、verified、 pr_opened、merged、regression_passed、artifact_built、published、deployed。

用户可见的 canonical stopAt 与内部里程碑映射如下:

stopAt 停止含义 内部里程碑
develop_verified 开发验证完成:单元测试、新增功能集成测试和静态检查通过;不等于完整回归 verified
review_ready PR/MR 已创建,等待审核 pr_opened
release_ready PR 已合并且完整回归通过;尚未表示发布或部署 regression_passed
released 产物已构建并发布 published
deployed 目标环境实际部署完成并通过健康检查 deployed

为兼容旧记录,verified 是 develop_verified 的别名,validation_ready 是 release_ready 的别名;新记录应使用 canonical 名称。delivery.state 内部里程碑 名称保持不变。

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

同一套字段,厚度不同。

字段 short long
spec.md 四段:要做什么、不做什么、可观察验收、怎么验。有故障证据时加复现和根因 同一四段作摘要
spec/ 不要创建 specifier 写入 PRD、评审、决策、风险、handoff
spec.revision 等 保持 null 与 PRD 版本同步
tasks.yaml 恰好 1 条 DAG;dependsOn 指向本文件内 id
子项 无 默认是 task。只有该切片有独立 stopAt 并单独发布时才晋升为子 ship,写入 childShipIds

范围变大时保持同一 shipId,把 kind 改成 long,补 spec/ 并拆任务。

spec.md 不要写成 HTML PRD。long 的评审稿是 spec/prd-vNNN.html。

任务

tasks.yaml 只描述本 ship 的工作项,不是 ACK 缺陷板。

新建 ship 的任务默认带 testPlan。开发 worker 在 manifest 中记录测试的稳定 id、 runner、target、selector、覆盖的验收项和 added|changed 状态。verify 必须逐条执行 manifest;regress 在完整 tester catalog 和项目原生测试之外再次确认这些条目通过。 仅文档或明确无行为变化的任务可使用 policy: not_applicable,但必须填写被主会话接受的 testGap.reason 与 acceptedBy。

shipId: add-export-button
tasks:
  - id: T-01
    title: 在列表页增加导出按钮
    dependsOn: []
    expected:
      - 登录用户在列表页看到「导出」
    verification:
      - 浏览器打开列表页,按钮可见且可点
    testPlan:
      policy: required
      manifest: 2-develop/test-manifest.yaml
    status: open
    stopAt: review_ready

允许的任务 status:open、in_progress、blocked、verified、merged、done。

long 的子任务默认 stopAt 为 pr_opened 或 merged,不要单独打生产 tag 或升级生产。 父 ship 在依赖任务完成后做集成回归,再按父记录的 delivery.stopAt 继续。

从 spec/handoff.yaml 建任务时复制 id、title、dependsOn、expected、 verification,不要写进 .pouch/ack/tasks.yaml。

证据指针

不要把 tester 快照、镜像层或 compose 日志复制进 ship 目录。追加指针:

evidence:
  testRuns:
    - path: .pouch/tester/runs/20261013T031000Z-smoke-ab12.yaml
      result: pass
      suite: smoke
  artifacts:
    - sha: 0123456789abcdef0123456789abcdef01234567
      digest: sha256:abc
      ref: harbor.example.com/app:1.2.3
      venue: ci
  deploys:
    - env: test
      revision: 0123456789abcdef0123456789abcdef01234567
      health: pass
  prs:
    - url: https://git.example.com/app/-/merge_requests/12
      status: opened
  commits:
    - sha: 0123456789abcdef0123456789abcdef01234567
      role: baseline

delivery-loop 阶段与指针:

阶段 至少追加
change_ready commits role: baseline
verified testRuns
pr_opened prs
merged commits role: merged
regression_passed testRuns(回归)
artifact_built / published artifacts
deployed deploys

path 相对项目根。文件不存在则校验失败。用 scripts/append_evidence.py 追加后立刻 validate_ship.py。

旧 specifier 目录

打开某个 id 时按这个顺序:

  1. .pouch/ship/<id>/ 已存在:用它。若同时还留着 .pouch/specifier/features/<id>/,报告旧路径为遗留,不要两处同时写。
  2. 只有 .pouch/specifier/features/<id>/:把它移到 .pouch/ship/<id>/spec/,按旧 current.yaml 生成 ship current.yaml(kind: long),用 brief.md 补 spec.md 摘要,再校验。
  3. 两处都没有:由入口 skill 调用 create_ship.py 新建。