ship-it

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Ship it

Ship it

You own the work from "code is done" to "PR is ready for the human to merge". Run the pipeline in order. Every step answers for its own edits, and the pipeline only moves forward. The human always merges.
你负责从“代码已完成”到“PR 已准备好、可供人工合并”的整个过程。按顺序运行流水线。每个步骤都要对其产生的修改负责,流水线只能向前推进。始终由人工合并。

Tier

层级

Use the prod tier by default. A tier argument (
/ship-it wip
or
/ship-it prod
) sets the tier for this run. On resume without a tier argument, use the tier in the
## Review
marker (see Resume).
  • prod: a project in production. Every step runs.
  • wip: a personal or work-in-progress project. Steps marked – are skipped.
默认使用 prod。tier 参数(
/ship-it wip
或
/ship-it prod
)用于设置本次运行的 tier。恢复运行但未指定 tier 时,使用
## Review
marker 中的 tier(参见“恢复”)。
  • prod:已在生产环境运行的项目。所有步骤都会执行。
  • wip:个人项目或正在进行中的项目。标记为 – 的步骤会跳过。

Pipeline

流水线

#StepprodwipDetail
1Intentuser confirmswritten, not confirmedsteps/intent.md
2Rebase✓✓below
3Reviewcorrectness + tastecorrectness, blockers onlysteps/review.md
4Test✓–steps/test.md
5Docs✓–below
6Lint✓✓below
7Commit and push✓✓below
8PRfull bodySummary, Intent, Reviewsteps/pr.md
9CI and botsCI, then bot loopCI onlysteps/ci.md
Read a step's detail file when you reach that step, not before.
Steps 4 to 9 can add commits after the review: test fixes, docs, lint, CI fixes, and bot fixes. Before step 8 opens or updates the PR, and before you report done, compare
HEAD
with the last reviewed sha. When commits follow it, re-review
<sha>..HEAD
as in steps/review.md. Then put the new reviewed sha in the
## Review
marker. In prod, when those commits change behavior that a live scenario covers, re-run that scenario as in steps/test.md and replace its evidence in the PR body before you report done.
Done means: the PR is open and ready (not draft), the
## Review
marker names
HEAD
, CI is green, and in prod the bot loop has stopped by its rule. Report to the user and ask them to review and merge. Stop there.
#步骤prodwip详情
1Intent(意图)用户确认已书面记录,未确认steps/intent.md
2Rebase✓✓下方
3Review(审查)正确性 + 整体质量仅检查正确性和阻塞项steps/review.md
4Test(测试)✓–steps/test.md
5Docs(文档)✓–下方
6Lint✓✓下方
7Commit and push(提交并推送)✓✓下方
8PR完整正文Summary、Intent、Reviewsteps/pr.md
9CI and bots先运行 CI,再执行 bot 循环仅运行 CIsteps/ci.md
到达某个步骤时再阅读该步骤的详情文件,不要提前阅读。
审查后,步骤 4 到 9 仍可新增 commit:测试修复、文档、Lint 修复、CI 修复和 bot 修复。在步骤 8 打开或更新 PR 之前,以及报告完成之前,将
HEAD
与最后审查过的 sha 进行比较。如果其后存在 commit,则按照 steps/review.md 的方式对
<sha>..HEAD
重新执行审查。然后将新的已审查 sha 写入
## Review
marker。在 prod 中,如果这些 commit 更改了实际场景所覆盖的行为,则按照 steps/test.md 的方式重新运行该场景,并在报告完成前替换 PR 正文中的对应证据。
完成意味着:PR 已打开且已就绪(不是 draft),
## Review
marker 指向
HEAD
,CI 已通过;在 prod 中,bot 循环也已按其规则停止。向用户报告结果,并请其审查和合并。到此停止。

Resume

恢复

There is no state file. The branch, the commits, and the PR are the record. On every run, find the first unfinished step:
  1. No commits ahead of the base branch and no uncommitted changes → nothing to ship. Say so.
  2. Uncommitted changes that belong to this intent → commit them first, in logical groups with messages as in step 7. Do not push. Changes that mix in other work → ask first, as in "Where it runs".
  3. Read the PR for this branch (
    gh pr view --json number,body,headRefOid,isDraft
    ).
    • No PR → start at step 1.
    • The PR body has
      ## Intent
      → that is the intent. Skip step 1 unless the user gave a new one.
    • The
      <!-- ship-it: reviewed=<sha> tier=<tier> -->
      marker in
      ## Review
      names the last reviewed commit. Commits after it (local or pushed) → re-run review on
      <sha>..HEAD
      only, then continue forward.
  4. The tier for this run is prod and the marker says
    tier=wip
    → step 1. Wip did not confirm the intent, ran only part of the review, and skipped the test and docs steps. Step 3 reviews the whole change again, and step 8 writes the full prod body and sets the marker to
    tier=prod
    .
  5. Otherwise: unpushed commits → step 7. PR is a draft → step 8. CI failing or running → step 9. CI green → step 9's bot loop (prod) or done (wip).
Tell the user which step you are resuming from and why, in one line.
没有 state file。branch、commit 和 PR 就是记录。每次运行时,找到第一个未完成的步骤:
  1. base branch 之前没有领先的任何 commit,且没有未提交更改 → 无可交付的内容。直接说明。
  2. 存在属于此 intent 的未提交更改 → 先按逻辑分组进行 commit,提交消息遵循步骤 7。不要 push。若更改混入了其他工作 → 先询问用户,参见“运行位置”。
  3. 读取此 branch 的 PR(
    gh pr view --json number,body,headRefOid,isDraft
    )。
    • 没有 PR → 从步骤 1 开始。
    • PR 正文包含
      ## Intent
      → 该内容就是 intent。除非用户提供了新的 intent,否则跳过步骤 1。
    • ## Review
      中的
      <!-- ship-it: reviewed=<sha> tier=<tier> -->
      marker 记录了最后审查过的 commit。如果其后存在 commit,无论是本地还是已 push → 仅对
      <sha>..HEAD
      重新执行审查,然后继续向后推进。
  4. 本次运行的 tier 为 prod,而 marker 显示
    tier=wip
    → 从步骤 1 开始。Wip 模式未确认 intent,只执行了部分审查,并跳过了测试和文档步骤。步骤 3 将再次审查整个更改,步骤 8 将写入完整的 prod 正文,并把 marker 设置为
    tier=prod
    。
  5. 其他情况:存在未 push 的 commit → 步骤 7。PR 是 draft → 步骤 8。CI 失败或仍在运行 → 步骤 9。CI 已通过 → 执行步骤 9 的 bot 循环(prod),或直接完成(wip)。
用一行说明正在从哪个步骤恢复以及恢复的原因。

Where it runs

运行位置

  • In place when the checkout is a feature branch or worktree and every uncommitted change belongs to this intent.
  • Ask first when on the default branch, or when uncommitted changes mix this work with other work. Offer to move this work to a new worktree. Create one only on a yes.
  • Frappe app inside a bench: a plain
    git worktree
    is invisible to the bench. Run in place.
  • 原地运行:当 checkout 位于 feature branch 或 worktree 上,且所有未提交更改均属于此 intent 时。
  • 先询问:位于 default branch,或未提交更改混入了本工作与其他工作时。提供将此工作移至新 worktree 的选项。只有用户同意后才创建。
  • bench 内的 Frappe app:普通的
    git worktree
    对 bench 不可见。原地运行。

Subagents

Subagents

Every reviewer and every fixer is a fresh subagent that never saw this conversation. Its prompt carries everything it needs: the intent, the recorded decisions, the diff range, and the reviewer file to follow. A fixer is never the reviewer that reported the finding, and a re-review is a new subagent.
AgentHow to start one
Claude CodeThe
Agent
tool.
Codex
spawn_agent
. Codex spawns only when told to, so spawn explicitly.
T3 Code (the
t3-code
MCP tools are present)
delegate_task
with
mode: "wait"
. Pick provider and model from
orchestrator_capabilities
.
Use the strongest model available for every subagent. When the agent can start a model from a different provider, give the correctness reviewer that model: a second model family catches mistakes the first one shares with the author.
每个 reviewer 和 fixer 都是一个从未见过本对话的全新 subagent。其 prompt 包含所需的一切:intent、已记录的决策、diff 范围,以及要遵循的 reviewer 文件。fixer 绝不能是报告该问题的 reviewer,而 re-review 必须使用新的 subagent。
Agent如何启动
Claude Code使用
Agent
tool。
Codex
spawn_agent
。只有明确指示时 Codex 才会 spawn,因此需要显式 spawn。
T3 Code(存在
t3-code
MCP 工具)
使用
delegate_task
并设置
mode: "wait"
。从
orchestrator_capabilities
中选择 provider 和 model。
每个 subagent 都应使用可用的最强 model。如果某个 Agent 可以启动来自不同 provider 的 model,则为正确性 reviewer 选择该 model:第二个模型系列可以发现第一个模型与作者共有的错误。

Findings and the user

Findings 与用户

Reviewers return findings in the format in review/verdict.md. Fix
auto-fix
findings without asking. Collect every
ask-user
finding from a step and ask the user about them in one message, laid out as in review/ask.md. Answers become decisions, which nothing in the run reverses.
reviewer 按照 review/verdict.md 中的格式返回 findings。无需询问即可修复
auto-fix
类 findings。收集某一步中的所有
ask-user
findings,并按照 review/ask.md 的布局,在一条消息中向用户提问。用户的回答将成为决策,本次运行中的任何步骤都不得推翻这些决策。

Inline steps

具体步骤

2. Rebase

2. Rebase

git fetch origin
. When
origin/<branch>
exists, record its sha for step 7 and take in the remote work that local history lacks. Find the last commit this clone pushed:
git reflog show --format='%H %gs' origin/<branch> | grep -m1 'update by push'
. Use that sha only when the local branch's own reflog has it (
git reflog show --format=%H <branch> | grep -qx <sha>
), which shows this branch was at that commit. Every commit up to it is already in local history, possibly rewritten by an earlier rebase. The commits after it,
<pushed sha>..origin/<branch>
, were pushed by someone else: take each one in, for example with
git cherry-pick
. When that sha is not an ancestor of
origin/<branch>
(
git merge-base --is-ancestor <sha> origin/<branch>
fails), someone else rewrote the remote branch after your push: stop and ask the user. When there is no such sha, take in
HEAD..origin/<branch>
. Skip a commit whose change
HEAD
already has. Then rebase onto
origin/<base>
. Resolve conflicts in the spirit of both sides and the intent. When a conflict needs a product decision, ask. When the diff against the base is empty after rebase, stop: there is nothing to ship.
执行
git fetch origin
。当
origin/<branch>
存在时,记录其 sha 供步骤 7 使用,并接入本地历史中缺少的远程工作。查找此 clone 最后一次 push 的 commit:
git reflog show --format='%H %gs' origin/<branch> | grep -m1 'update by push'
。仅当本地 branch 自身的 reflog 中存在该 sha 时才使用它(
git reflog show --format=%H <branch> | grep -qx <sha>
),这表明此 branch 当时位于该 commit。该 commit 之前的每个 commit 都已存在于本地历史中,尽管可能被之前的 rebase 重写过。其后的 commit,即
<pushed sha>..origin/<branch>
,由其他人 push:逐个接入,例如使用
git cherry-pick
。当该 sha 不是
origin/<branch>
的 ancestor 时(
git merge-base --is-ancestor <sha> origin/<branch>
失败),说明你 push 后其他人重写了远程 branch:停止并询问用户。当不存在这样的 sha 时,接入
HEAD..origin/<branch>
。如果
HEAD
已包含某个 commit 的更改,则跳过该 commit。然后 rebase 到
origin/<base>
上。解决冲突时,应兼顾双方改动和 intent。当冲突需要产品决策时,向用户询问。当 rebase 后相对于 base 的 diff 为空时,停止:没有可交付的内容。

5. Docs (prod)

5. Docs(prod)

Find what the change made stale: README, docs pages,
AGENTS.md
, code comments near the change, examples. Fix each stale fact in its one authoritative place. Report what you could not resolve as an
ask-user
finding.
找出此次更改使哪些内容过时:README、docs 页面、
AGENTS.md
、更改附近的代码注释、示例。在每个事实的唯一权威位置修正过时信息。将无法解决的内容作为
ask-user
finding 报告。

6. Lint

6. Lint

Run the repo's own formatter and linters with their fix modes: look at
package.json
scripts,
pyproject.toml
,
.pre-commit-config.yaml
, and the CI workflow to see what CI will run. Fix what remains, up to 3 attempts. When the repo has no linters configured, skip.
运行仓库自身的 formatter 和 linter,并启用其 fix 模式:查看
package.json
scripts、
pyproject.toml
、
.pre-commit-config.yaml
和 CI workflow,以确定 CI 将运行哪些检查。修复仍然存在的问题,最多尝试 3 次。如果仓库未配置 linter,则跳过。

7. Commit and push

7. Commit and push

Commit in logical groups with conventional messages (
feat:
,
fix:
,
refactor:
,
docs:
,
test:
,
chore:
). Review fixes follow the commit rule in the Fix loop of steps/review.md. Keep
tidy:
commits separate from behavior changes. Commit messages describe the change only.
Push safely:
  • When this run has not recorded the sha of
    origin/<branch>
    (a resume at step 7), fetch, record it, and take in remote work as in step 2. Otherwise
    git fetch origin
    .
  • Compare
    origin/<branch>
    with the recorded sha. When it moved, the remote has work you have not taken in: go back to step 2.
  • When
    origin/<branch>
    does not exist or is an ancestor of
    HEAD
    , use a plain push. Otherwise
    HEAD
    rewrote pushed commits, in this run or an earlier one: push with
    --force-with-lease=<branch>:<recorded sha>
    .
  • When the push is rejected because the remote changed after the fetch (
    non-fast-forward
    ,
    fetch first
    , or
    stale info
    ), go back to step 2. Any other rejection (permissions, branch protection, a server-side hook) does not change after a rebase. Stop and show the error to the user.
  • After the push, record the pushed sha as the new recorded sha, so later pushes from step 9 compare against it.
  • Note the push time. The bot loop in steps/ci.md uses it.
按逻辑分组进行 commit,并使用 conventional commit messages(
feat:
、
fix:
、
refactor:
、
docs:
、
test:
、
chore:
)。审查修复应遵循 steps/review.md 中 Fix loop 的 commit 规则。将
tidy:
commits 与行为更改分开。提交消息只描述更改本身。
安全地 push:
  • 当本次运行尚未记录
    origin/<branch>
    的 sha(即从步骤 7 恢复)时,执行 fetch、记录该 sha,并按照步骤 2 的方式接入远程工作。否则执行
    git fetch origin
    。
  • 将
    origin/<branch>
    与记录的 sha 进行比较。如果它发生移动,说明远程存在你尚未接入的工作:返回步骤 2。
  • 当
    origin/<branch>
    不存在,或是
    HEAD
    的 ancestor 时,使用普通 push。否则,说明
    HEAD
    重写了已 push 的 commits(发生在本次运行或更早之前):使用
    --force-with-lease=<branch>:<recorded sha>
    push。
  • 如果 push 因 fetch 后远程发生变化而被拒绝(
    non-fast-forward
    、
    fetch first
    或
    stale info
    ),返回步骤 2。任何其他拒绝(权限、branch protection、server-side hook)都不会因 rebase 而改变。停止并向用户显示错误。
  • push 后,将 pushed sha 记录为新的已记录 sha,以便步骤 9 中的后续 push 与其进行比较。
  • 记录 push 时间。steps/ci.md 中的 bot 循环会使用该时间。