ship

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Skill: ship

Skill: ship

Workflow chốt quanh remote. Chạy checklist điều kiện, DỪNG chờ duyệt trước mọi bước side-effect (push/tag/PR/MR/merge). Năm mức — 4 mức ĐẨY ĐI (outbound) + 1 mức GOM VỀ (inbound): push (đủ mọi bước, không tag) · release (push + tag
vX.Y.Z
+ release notes) · pr (push nhánh + mở Pull Request GitHub qua
gh
) · mr (push nhánh + mở Merge Request GitLab qua
glab
) · merge (liệt kê PR/MR đến → kéo nhánh về → gate+test → merge nếu xanh).
围绕 remote 固化工作流。运行准入条件 CHECKLIST,在每个 side-effect 步骤(push/tag/PR/MR/merge)之前停止并等待批准。五个级别——4 个外发(outbound)级别 + 1 个汇入(inbound)级别:push(完成所有步骤但不打 tag)· release(push + tag
vX.Y.Z
+ release notes)· pr(push 分支 + 通过
gh
创建 GitHub Pull Request)· mr(push 分支 + 通过
glab
创建 GitLab Merge Request)· merge(列出传入的 PR/MR → 检出分支 → gate+test → 通过时 merge)。

WHAT

概述

Purpose và context

目的与上下文

  • Purpose: đưa thay đổi ra remote (push/release/PR/MR) hoặc gom PR/MR đến về (merge) CHỈ sau khi checklist điều kiện xanh, và dừng chờ duyệt trước mọi side-effect.
  • Trigger (when to use):
  • User nhắc "release" / "push" / "ship" / "lên release" / "chuẩn bị push" / "đủ điều kiện push chưa" / "mở PR" / "tạo MR".
  • Trước khi đẩy code lên remote, cắt một release, hoặc mở PR/MR để review-then-merge.
  • Muốn duyệt-rồi-merge các PR/MR đang mở của repo: "gom PR về merge" / "merge PR nếu test xanh" / "ship merge".
  • Non-goals: không tự sửa lỗi gate (việc của
    /medic
    + skill sửa), không tự đóng issue, không tự cài/auth
    gh
    /
    glab
    .
  • 目的: 将变更推送到 remote(push/release/PR/MR),或汇入 PR/MR(merge);只有在 checklist 条件全部通过后才可执行,并在每个 side-effect 前停止等待批准。
  • 触发条件(何时使用):
  • 用户提到“release”/“push”/“ship”/“上线 release”/“准备 push”/“检查是否满足 push 条件”/“开 PR”/“创建 MR”。
  • 在把 code 推送到 remote、创建 release,或打开 PR/MR 以供 review-then-merge 之前。
  • 希望先审批、再 merge 当前仓库中已打开的 PR/MR:“汇总 PR 并合并”/“测试通过则合并 PR”/“ship merge”。
  • 非目标: 不自行修复 gate 问题(这是
    /medic
    + 修复类 skill 的职责),不自行关闭 issue,也不自行安装/auth
    gh
    /
    glab
    。

Mental model

思维模型

repo_role (framework · module · downstream · foreign) → bảng gate của ĐÚNG loại repo → 
rồi mới tới chuỗi chung:
mức (push · release · pr · mr · merge) → gate sức khoẻ (medic --ci + ci-local) → UAT remote (chỉ release/pr/mr có năng lực mới) → git sạch → selftest → [version + patch note] → checklist → DỪNG duyệt → side-effect → [UAT pha 2]
. Các mức khác nhau ở bước cuối, không ở checklist.
repo_role(framework · module · downstream · foreign)→ 使用正确 repo 类型的 gate 表 →
然后才进入通用链路:
级别(push · release · pr · mr · merge)→ 健康 gate(medic --ci + ci-local)→ remote UAT(仅 release/pr/mr 带来新能力时)→ Git 状态干净 → selftest → [version + patch note] → checklist → 停止等待批准 → side-effect → [UAT 第二阶段]
。各级别只在最后一步不同,checklist 并无差异。

Input và output contract

输入与输出约定

FieldRequired?Ý nghĩa
In
repo_role
tự đọc
python3 harness/scripts/repo_role.py . --json
(máy khách:
~/.claude/harness/harness/scripts/repo_role.py
) — nhãn KHAI BÁO trong
.overstack.yaml
; thiếu thì suy kèm bằng chứng rồi HỎI user một lần và
--set
; ép tay lần này:
ship <mức> --as <role>
Inmứckhông (mặc định = push)
push
·
release
·
pr
·
mr
·
merge
— user mô tả phạm vi, không cần nhớ cờ
Induyệt của usercó, trước mọi side-effect"yes" tường minh cho push/tag/release/PR/MR/merge/canary
Outchecklist + lệnh đề xuấtcókết quả từng bước gate, UAT pha 1 hoặc lý do skip, commit msg, lệnh cuối
Outvăn bảntheo mức
release
→
RELEASE-vX.Y.Z.md
;
pr
/
mr
→ PR/MR body;
push
→ chỉ commit msg;
merge
→ báo cáo test + quyết định
Outside-effectchỉ sau duyệtpush / tag / release / PR / MR / merge đã thực thi
字段必填?含义
In
repo_role
自动读取
python3 harness/scripts/repo_role.py . --json
(客户端机器:
~/.claude/harness/harness/scripts/repo_role.py
)——读取
.overstack.yaml
中声明的标签;如果缺失,则依据证据推断,然后询问 user 一次并使用
--set
;此次手动强制指定:
ship <级别> --as <role>
In级别否(默认 = push)
push
·
release
·
pr
·
mr
·
merge
——user 描述目标范围即可,无需记忆命令标志
Inuser 的批准是,在任何 side-effect 之前push/tag/release/PR/MR/merge/canary 都需要明确的“yes”
Outchecklist + 建议命令是逐步展示 gate 结果、UAT 第一阶段结果或跳过原因、commit msg 和最终命令
Out文本视级别而定
release
→
RELEASE-vX.Y.Z.md
;
pr
/
mr
→ PR/MR body;
push
→ 仅 commit msg;
merge
→ 测试报告 + 决策
Outside-effect仅在批准后已执行的 push / tag / release / PR / MR / merge

Rules và capabilities

规则与能力

  • RULE-01 (MUST): Không push khi
    medic --ci
    đỏ
    — trừ khi user override tường minh; kể cả override phải ghi lý do vào patch note.
  • RULE-02 (MUST): Patch note không phóng đại — Known-limitations là bắt buộc nếu có phần chưa xong.
  • RULE-03 (MUST): Mức khác nhau ở BƯỚC CUỐI, không ở checklist: mọi mức đều qua gate sức khoẻ; chỉ khác sản phẩm cuối (tag / release / PR / MR / merge). Đừng tag khi user nói "pr"/"mr"; đừng mở PR khi user chỉ nói "push".
  • RULE-04 (MUST):
    medic --ci
    xanh KHÔNG chứng minh đường remote chạy được — đó là việc của
    /fdk-uat
    .
    release
    /
    pr
    /
    mr
    có năng lực mới BẮT BUỘC qua UAT pha 1 (canary) trước khi đề xuất bước 7; bỏ qua chỉ khi diff xác nhận không thêm năng lực gì user thấy, và phải ghi lý do. Quyết định đã cháy thật 2026-09-17: mọi push trước đó (kể cả
    6c839d8
    ) chỉ qua
    medic --ci
    /
    ci-local
    , chưa từng qua UAT remote thật.
  • RULE-05 (MUST): Mức
    merge
    — TEST là điều kiện merge, không phải hình thức:
    phải kéo nhánh về + chạy
    medic --ci
    + test THẬT trước khi merge; đỏ thì tuyệt đối KHÔNG merge, để nguyên cho tác giả. Một-tại-một, không merge gộp mù nhiều PR cùng lúc.
  • RULE-06 (MUST): PR/MR body cùng luật patch note: giọng người-dùng, Known-limitations bắt buộc nếu có phần nửa vời. Không SHA/tên hàm nội bộ. KHÔNG
    Closes #N
    tự động.
  • RULE-07 (MUST): Side-effect cần "yes": push/tag/release/PR/MR là hành động khó lùi (outward-facing) → luôn STOP show lệnh, chờ duyệt; không commit/PR-body AI-attribution (theo fdk).
  • RULE-08 (MUST): Không tự cài/auth
    gh
    /
    glab
    :
    thiếu công cụ → DỪNG, báo user; đừng đoán host.
  • RULE-10 (MUST): Biết mình đang ở LOẠI repo nào trước khi chạy bất cứ gate nào. Dòng đầu tiên của checklist luôn là
    🏷 repo_role=<role> (khai báo | sổ máy | suy luận | ép tay)
    . Nguồn
    suy luận
    → hỏi user xác nhận rồi ghi nhãn (
    repo_role.py . --set <role>
    ; riêng
    foreign
    ghi vào sổ MÁY, không đụng repo người khác). Gate của loại repo này KHÔNG áp cho loại khác:
    ci-local
    /
    capability-stamp
    /UAT chỉ có nghĩa ở
    framework
    ; chạy chúng ở
    module
    /
    downstream
    là chấm nhầm, bỏ chúng ở
    framework
    là hở. Bài học 20/09/2026:
    /ship
    một-luồng khiến việc ship repo engine phải tự nhớ quy trình khác hẳn.
  • RULE-11 (MUST): ĐỌC rc của gate rồi mới đẩy. Lệnh push/tag đứng ở một bước RIÊNG sau khi đã in và đọc
    rc=
    ; cấm nối gate với push bằng
    ;
    hay ống
    | tail
    (nuốt rc). Hai lần cháy cùng ngày 20/09/2026: push
    c83b065
    khi
    medic
    đang đỏ, và tag
    v3.0.1
    khi
    install-test
    báo FAIL — cả hai do nối lệnh. Ở
    framework
    khi working tree có file lạ chưa commit (vd bị tool khác ghi đè), chạy gate trên CHECKOUT SẠCH của commit (
    git worktree add --detach <tmp> HEAD
    ) để không chấm nhầm workflow.
  • RULE-12 (MUST):
    foreign
    = khách trong nhà người khác.
    Chỉ mức
    pr
    /
    mr
    , không
    push
    thẳng nhánh mặc định; theo luật commit/CI của HỌ (đọc CONTRIBUTING, không áp R15 hay luật overstack); KHÔNG cài, không ghi
    .overstack.yaml
    , không thêm file cấu hình nào của ta vào repo.
  • RULE-09 (MUST): Compose, đừng đẻ lại: dùng
    medic
    cho sức khoẻ,
    git tag
    cho version,
    gh
    /
    glab
    cho PR/MR — skill này chỉ điều phối checklist.
  • Capabilities: đọc repo + chạy gate cục bộ; ghi remote (push/tag/PR/MR/merge) CHỈ qua công cụ đã auth và sau duyệt.
  • RULE-01 (MUST):当
    medic --ci
    未通过时不得 push
    ——除非 user 明确 override;即使进行了 override,也必须将原因记录到 patch note。
  • RULE-02 (MUST):Patch note 不得夸大——如果仍有未完成部分,必须列出 Known-limitations。
  • RULE-03 (MUST):不同级别只在最后一步存在差异,而不在 checklist: 所有级别都必须通过健康 gate;区别仅在最终产物(tag / release / PR / MR / merge)。当 user 说“pr”/“mr”时不要打 tag;当 user 只说“push”时不要创建 PR。
  • RULE-04 (MUST):
    medic --ci
    通过并不能证明 remote 路径可以正常运行——这是
    /fdk-uat
    的职责。
    如果
    release
    /
    pr
    /
    mr
    的 diff 带来新能力,在建议执行第 7 步之前,必须完成 UAT 第一阶段(canary);只有当 diff 确认没有增加 user 可见能力时才可跳过,并必须记录原因。2026-09-17 已实际验证的结论:此前所有 push(包括
    6c839d8
    )仅通过了
    medic --ci
    /
    ci-local
    ,从未执行过真实 remote UAT。
  • RULE-05 (MUST):在
    merge
    级别中,TEST 是合并条件,而不是形式要求:
    合并前必须检出分支并运行
    medic --ci
    + 真实测试;如果未通过,绝对不得 merge,应将 PR 原样留给作者处理。必须逐个处理,不得盲目批量合并多个 PR。
  • RULE-06 (MUST):PR/MR body 遵循与 patch note 相同的规则: 使用面向 user 的语气;如果仍有半成品,必须列出 Known-limitations。不要包含 SHA 或内部函数名。不要自动添加
    Closes #N
    。
  • RULE-07 (MUST):Side-effect 需要“yes”: push/tag/release/PR/MR 都属于难以撤销的外部操作,因此必须始终停止、展示命令并等待批准;按照 fdk 的要求,不得在 commit/PR body 中添加 AI-attribution。
  • RULE-08 (MUST):不得自行安装或 auth
    gh
    /
    glab
    :
    如果缺少工具,则停止并告知 user;不要猜测 host。
  • RULE-10 (MUST):运行任何 gate 前,都必须知道自己处于哪种 repo 类型。 Checklist 第一行始终为
    🏷 repo_role=<role>(声明 | 机器记录 | 推断 | 手动)
    。如果来源为“推断”,则询问 user 确认并记录标签(
    repo_role.py . --set <role>
    ;对于
    foreign
    ,仅记录到机器账本,不修改他人的 repo)。该 repo 类型的 gate 不适用于其他类型:在
    module
    /
    downstream
    中运行
    ci-local
    /
    capability-stamp
    /UAT 属于错误评估,而在
    framework
    中省略它们则会造成流程缺口。2026-09-20 的经验:让
    /ship
    采用单一流程,会导致 framework repo 的发布流程无法记住与其他类型截然不同的要求。
  • RULE-11 (MUST):读取 gate 的 rc 后再推送。 Push/tag 命令必须位于一个独立步骤中,并已打印及读取
    rc=
    ;禁止使用
    ;
    或
    | tail
    将 gate 与 push 串接,因为这会吞掉 rc。2026-09-20 同一天发生了两次问题:medic 仍为红色时 push 了
    c83b065
    ,以及
    install-test
    报 FAIL 时创建了 tag
    v3.0.1
    ——两者均由命令串接导致。在
    framework
    中,如果 working tree 含有被其他工具覆盖且尚未 commit 的陌生文件,应在 commit 的干净 CHECKOUT 上运行 gate(
    git worktree add --detach <tmp> HEAD
    ),避免错误评估 workflow。
  • RULE-12 (MUST):
    foreign
    表示处于他人主场中的客户仓库。
    仅允许
    pr
    /
    mr
    级别,不允许默认直接 push 分支;必须遵循对方的 commit/CI 规则(阅读 CONTRIBUTING,不套用 R15 或 overstack 规则);不得安装软件、写入
    .overstack.yaml
    ,也不得向该 repo 添加任何属于我们的配置文件。
  • RULE-09 (MUST):应进行组合编排,而不是重新造轮子:使用
    medic
    检查健康状态,使用
    git tag
    管理 version,使用
    gh
    /
    glab
    创建 PR/MR——此 skill 仅负责协调 checklist。
  • Capabilities:读取 repo 并在本地运行 gate;仅通过已经 auth 的工具,并在获得批准后写入 remote(push/tag/PR/MR/merge)。

Failure boundaries

失败边界

  • Gate đỏ (
    medic --ci
    /
    ci-local
    /
    freshinstall
    ) → blocked, in chỗ hở + lệnh sửa, không push.
  • UAT FAIL ở pha nào → failed, dừng ship, xoá canary; pha 2 FAIL → gỡ commit khỏi remote theo
    /fdk-uat
    bước 5.
  • Không chắc diff có "năng lực mới" hay bậc version → clarify (hỏi user), không tự quyết.
  • Thiếu
    gh
    /
    glab
    hoặc chưa auth → blocked, báo user cài + login.
  • Mức
    merge
    : PR đỏ → không merge PR đó (partial cho cả lô), báo lý do.
  • Gate 未通过(
    medic --ci
    /
    ci-local
    /
    freshinstall
    )→ blocked,打印缺口 + 修复命令,不得 push。
  • UAT 在任一阶段 FAIL → failed,停止 ship 并删除 canary;如果第二阶段 FAIL,则按照
    /fdk-uat
    第 5 步将 commit 从 remote 移除。
  • 无法确定 diff 是否包含“新能力”或无法确定 version 级别 → clarify(询问 user),不得自行决定。
  • 缺少
    gh
    /
    glab
    或尚未 auth → blocked,告知 user 如何安装和 login。
  • merge
    级别:某个 PR 未通过 → 不得合并该 PR(整批结果为 partial),并报告原因。

HOW

执行方式

Main workflow

主工作流

StepTypeInputsActionOutputs/exitFailure/next
W00deterministicrepo
repo_role.py . --json
→ in
🏷 repo_role=…
; nguồn
inferred
thì hỏi user +
--set
; chọn cột gate ở bảng "Luồng theo repo_role"
role + bảng gaterole không hợp lệ → blocked
W01deterministicrepoCổng sức khoẻ
medic --ci
rồi
python3 fdk/tools/ci-local.py
(gồm probe
freshinstall
)
rc 0đỏ → blocked
W02effectdiff, mứcUAT
/fdk-uat
pha 1 — chỉ
release
/
pr
/
mr
có năng lực mới (B02)
PASS hoặc lý do skipFAIL → failed
W03deterministicworktreeGit sạch:
git status --short
, rác ephemeral không track
sạchbẩn → dọn rồi lặp W03
W04deterministicdiffSelftest/kiểm nhanh engine đụng tớirc 0đỏ → blocked
W05judgmenttag gần nhấtVersion
vX.Y.(Z+1)
— chỉ
release
(B01)
tag đề xuấtkhông chắc bậc → clarify
W06judgment
git log
, scratch-log
Patch note / PR-MR body trung thực, Known-limitations bắt buộc nếu có phần nửa vờivăn bản—
W07deterministickết quả W01–W06Hiện checklist + đề xuất lệnh, DỪNG chờ duyệt"yes"không duyệt → cancelled
W08effectduyệtThực thi theo mức; nếu W02 đã chạy thì UAT pha 2 ngay sau đóside-effect + receiptpha 2 FAIL → gỡ commit
Chi tiết từng bước (nguồn chân lý cho W01–W08):
Mô tả phạm vi thay vì nhớ cờ: "push" (chỉ đẩy) · "release" (đẩy + tag + notes) · "pr" (đẩy nhánh + Pull Request GitHub) · "mr" (đẩy nhánh + Merge Request GitLab) · "merge" (gom PR/MR đến → test → merge). Mặc định = push.
Mức
push/release/pr/mr
(ĐẨY ĐI) chạy bước 1-8 dưới. Mức
merge
(GOM VỀ) chạy nhánh riêng ở step 8 (đọc mục "Mức merge").
Bước 1, 3-4 áp dụng cho MỌI mức. Bước 2 (UAT) CHỈ
release
/
pr
/
mr
. Bước 5 (version tag) CHỈ mức
release
. Bước 6 đổi tên "sản phẩm viết":
release
→
RELEASE-vX.Y.Z.md
;
pr
/
mr
→ PR/MR body (cùng giọng người-dùng, cùng luật Known-limitations).
push
không cần văn bản, chỉ commit msg. Mức
merge
không viết note (chỉ báo cáo kết quả test + quyết định merge/không).
  1. CỔNG SỨC KHOẺ —
    medic --ci
    (hoặc
    python3 fdk/tools/medic.py --ci
    ). FAIL → DỪNG, in chỗ hở + lệnh sửa; không push khi đỏ. Warn (nợ đã biết) → cho qua nhưng LIỆT KÊ trong patch note.
    • Rồi
      python3 fdk/tools/ci-local.py
      (repo framework) — chạy TRỌN mọi step
      run:
      của mọi workflow GitHub tại local (L4). medic là L2; có gate CHỈ ở CI (search-index, skill-provenance, retrieval-eval…) — đã cháy 080926: medic xanh, push, CI đỏ 2 job. Đỏ → không push.
    • Gồm probe
      freshinstall
      (E2E): curl-cài overstack vào một dự án TRỐNG cô lập (mktemp ngoài repo) qua working-tree → assert 3 trụ + harness cắn + orchestration-ready. Đỏ = đường cài người-mới hỏng → KHÔNG push. Bản đầy đủ curl-github + acceptance live:
      bash harness/scripts/fresh-install-smoke.sh --remote
      .
  2. UAT gate —
    /fdk-uat
    (CHỈ mức
    release
    /
    pr
    /
    mr
    , KHÔNG
    push
    thường):
    medic --ci
    /
    ci-local
    ở bước 1 chỉ cài qua
    file://
    working-tree — chứng minh "code trong máy lành", KHÔNG chứng minh "người lạ
    curl
    remote về chạy được" (lớp lỗi GH#77: "doc hứa mà user không nhận được", đo thật 2026-09-17 khi push
    6c839d8
    không hề qua UAT).
    • Diff có năng lực MỚI (skill mới / rule mới cắn được / engine-tool mới) → BẮT BUỘC chạy tối thiểu PHA 1 (canary: push nhánh tạm, curl-cài từ raw của chính nhánh đó, kiểm năng lực mới reachable) trước khi sang bước 7. PHA 2 (main-URL smoke, chờ CDN) chạy NGAY sau khi user duyệt merge/tag thật ở bước 8 — không phải lúc đề xuất.
    • Diff thuần bugfix/refactor nội bộ, không thêm năng lực gì user thấy → bỏ qua bước này, ghi rõ lý do trong checklist bước 7 ("không có năng lực mới — skip UAT").
    • Không chắc diff có tính là "năng lực mới" hay không → hỏi user, đừng tự quyết bỏ qua.
    • Push canary là side-effect thật (đẩy nhánh tạm lên remote) → DỪNG hỏi user trước khi chạy, cùng luật side-effect của skill này. FAIL ở pha nào → dừng ship, báo lỗi cụ thể + xoá canary (không phải "để sau").
  3. Git sạch:
    git status --short
    ; đảm bảo rác ephemeral (
    scratchpad/…
    ) đã
    .gitignore
    +
    git rm -r --cached
    nếu lỡ track. Rà không có file bí mật/tạm lọt vào.
  4. Selftest/kiểm nhanh các engine đụng tới (vd
    council.py selftest
    , test liên quan diff).
  5. Version:
    git tag --sort=-v:refname | head -1
    → tag gần nhất
    vX.Y.Z
    → đề xuất
    vX.Y.(Z+1)
    (patch) hoặc minor/major nếu diff xứng — hỏi user nếu không chắc bậc.
  6. Patch note TRUNG THỰC (giọng release-note NGƯỜI DÙNG — kiểu Claude Code): viết
    RELEASE-vX.Y.Z.md
    .
    • Format: header
      Version X.Y.Z:
      rồi danh sách bullet PHẲNG, mỗi bullet một dòng một ý.
    • Giọng: verb-first mô tả thay đổi NGƯỜI DÙNG THẤY, không dump commit/nội-bộ.
      Fixed <triệu chứng> — <giờ ra sao>
      ·
      Added <khả năng> — <dùng để làm gì>
      ·
      Removed/Changed …
      . Viết từ góc người đọc ("bạn/của bạn"), không SHA, không tên hàm trừ khi user gõ trực tiếp.
    • Nhóm ngầm theo động từ: Added/Changed trước, Fixed sau (như release-note Claude). KHÔNG cần tiêu đề nhóm nếu danh sách ngắn.
    • Nguồn: đọc
      git log <tag-cũ>..HEAD
      + scratch-log phiên → DỊCH commit kỹ-thuật sang câu người-dùng-hiểu (1 commit có thể gộp/tách thành bullet theo giá trị cảm nhận, không 1-1).
    • Known-limitations (BẮT BUỘC nếu có phần nửa vời — điểm HƠN Claude): proposal draft chưa impl, coverage một phần, warn medic đã biết → khai rõ "đang làm/đã biết". Im lặng = phóng đại (bài học council 2026-07-03).
  7. Hiện checklist + đề xuất lệnh cho user (commit msg, push, tag/PR/MR, kết quả UAT pha 1 hoặc lý do skip). DỪNG chờ duyệt.
  8. Sau khi user duyệt: thực thi theo mức. Không tự chạy bước side-effect trước khi có "yes". Nếu bước 2 đã chạy UAT pha 1 (PASS) → merge/tag/push xong thì chạy NGAY UAT pha 2 (main-URL smoke, chờ sentinel CDN) trước khi báo user "xong"; FAIL → gỡ commit khỏi remote theo
    /fdk-uat
    bước 5.
    • push: commit +
      git push
      .
    • release: commit + push +
      git tag vX.Y.Z
      + tạo release (notes = patch note).
    • pr (GitHub): commit +
      git push -u origin <nhánh>
      +
      gh pr create --base <base> --head <nhánh> --title "…" --body-file <PR-body>
      . Base mặc định = nhánh chính repo (vd
      orca
      ), hỏi nếu không chắc.
    • mr (GitLab): commit +
      git push -u origin <nhánh>
      +
      glab mr create --source-branch <nhánh> --target-branch <base> --title "…" --description "…"
      (hoặc
      -F <file>
      ).
    • Chọn công cụ theo remote:
      git remote get-url origin
      chứa
      github.com
      →
      gh
      ,
      gitlab
      →
      glab
      .
      ship pr
      /
      ship mr
      ép rõ công cụ; nếu công cụ chưa cài/chưa auth (
      gh auth status
      /
      glab auth status
      ) thì DỪNG, báo user cài+login (không tự làm).
    • KHÔNG tự chèn
      Closes #N
      /
      Fixes #N
      vào PR/MR body trừ khi user yêu cầu tường minh — để user giữ quyền đóng issue tay.
步骤类型输入操作输出/退出状态失败/下一步
W00确定性repo
repo_role.py . --json
→ 打印
🏷 repo_role=…
;如果来源为
inferred
,则询问 user 并执行
--set
;从“按 repo_role 划分的流程”表格中选择 gate 列
role + gate 表role 无效 → blocked
W01确定性repo运行健康 gate
medic --ci
,然后运行
python3 fdk/tools/ci-local.py
(包含
freshinstall
probe)
rc 0未通过 → blocked
W02副作用diff、级别UAT
/fdk-uat
第一阶段——仅适用于带来新能力的
release
/
pr
/
mr
(B02)
PASS 或跳过原因FAIL → failed
W03确定性worktreeGit 状态干净:运行
git status --short
,确保 ephemeral 垃圾文件未被 track
干净不干净 → 清理后重新执行 W03
W04确定性diff对受影响的 engine 执行 Selftest/快速检查rc 0未通过 → blocked
W05判断最近的 tagVersion
vX.Y.(Z+1)
——仅适用于
release
(B01)
建议的 tag无法确定级别 → clarify
W06判断
git log
、scratch-log
如实编写 patch note / PR-MR body;如果仍有半成品,必须列出 Known-limitations文本—
W07确定性W01–W06 的结果展示 checklist + 建议命令,停止并等待批准“yes”未批准 → cancelled
W08副作用批准按级别执行;如果已运行 W02,则紧接着执行 UAT 第二阶段side-effect + receipt第二阶段 FAIL → 移除 commit
各步骤详情(W01–W08 的唯一事实来源):
通过描述目标范围来代替记忆命令标志:“push”(仅推送)· “release”(推送 + tag + notes)· “pr”(推送分支 + GitHub Pull Request)· “mr”(推送分支 + GitLab Merge Request)· “merge”(汇入 PR/MR → 测试 → merge)。默认 = push。
push/release/pr/mr
级别(外发)运行下面的第 1–8 步。
merge
级别(汇入)在第 8 步运行独立分支,详见“merge 级别”章节。
第 1、3–4 步适用于所有级别。第 2 步(UAT)仅适用于
release
/
pr
/
mr
。第 5 步(version tag)仅适用于
release
。第 6 步的“输出文档”对应关系为:
release
→
RELEASE-vX.Y.Z.md
;
pr
/
mr
→ PR/MR body(使用面向 user 的语气,并遵循相同的 Known-limitations 规则)。
push
不需要文档,仅需 commit msg。
merge
级别不编写 note,只报告测试结果和 merge/不 merge 的决策。
  1. 健康 GATE——
    medic --ci
    (或
    python3 fdk/tools/medic.py --ci
    )。FAIL → 停止,打印缺口 + 修复命令;gate 未通过时不得 push。Warn(已知债务)→ 可以通过,但必须在 patch note 中列出。
    • 然后运行
      python3 fdk/tools/ci-local.py
      (repo
      framework
      )——在本地完整运行所有 GitHub workflow 的每一个
      run:
      步骤(L4)。medic 是 L2;有些 gate 仅存在于 CI(search-index、skill-provenance、retrieval-eval……)——080926 已实际发生:medic 通过并完成 push,但 CI 有 2 个 job 失败。失败 → 不得 push。
    • 其中包含
      freshinstall
      probe
      (E2E):通过 working-tree,将 curl 安装 overstack 到一个隔离的空项目(使用 mktemp 创建于 repo 外部),断言三大支柱 + harness 拦截 + orchestration-ready。失败意味着新用户安装路径已损坏 → 不得 push。完整的 curl-github + live acceptance 命令:
      bash harness/scripts/fresh-install-smoke.sh --remote
      。
  2. UAT gate——
    /fdk-uat
    (仅适用于
    release
    /
    pr
    /
    mr
    级别,不适用于普通
    push
    ):
    第 1 步中的
    medic --ci
    /
    ci-local
    仅通过
    file://
    working-tree 安装——这只能证明“本地代码健康”,不能证明“陌生用户通过 curl 从 remote 安装后可以正常运行”(GH#77 的故障类型:“文档承诺了,但用户没有真正获得”;2026-09-17 push
    6c839d8
    时实际测量确认其从未经过 UAT)。
    • Diff 带来新能力(新 skill / 可拦截的新规则 / 新 engine-tool)→ 必须在进入第 7 步之前至少执行第一阶段(canary:push 临时分支,从该分支自身的 raw 地址执行 curl 安装,检查新能力可以正常访问)。第二阶段(main-URL smoke,等待 CDN)应在第 8 步中 user 批准真实 merge/tag 后立即执行,而不是在提出方案时执行。
    • Diff 仅包含内部 bugfix/refactor,没有增加 user 可见能力 → 跳过此步,并在第 7 步 checklist 中明确记录原因(“没有新能力——skip UAT”)。
    • 无法确定 diff 是否属于“新能力” → 询问 user,不得自行决定跳过。
    • Push canary 是真实的 side-effect(将临时分支推送到 remote)→ 执行前必须停止并询问 user,遵循本 skill 的 side-effect 规则。任一阶段 FAIL → 停止 ship,报告具体错误并删除 canary(不能留待以后处理)。
  3. Git 状态干净: 运行
    git status --short
    ;确保 ephemeral 垃圾文件(
    scratchpad/…
    )已加入
    .gitignore
    ,如果此前被 track,则执行
    git rm -r --cached
    。检查是否有 secret/临时文件意外进入仓库。
  4. Selftest/快速检查受影响的 engine(例如
    council.py selftest
    、与 diff 相关的测试)。
  5. Version:
    git tag --sort=-v:refname | head -1
    → 最近的 tag 为
    vX.Y.Z
    → 建议
    vX.Y.(Z+1)
    (patch);如果 diff 的影响范围符合条件,也可以使用 minor/major——无法确定级别时询问 user。
  6. 如实编写 PATCH NOTE(面向 USER 的 release-note 语气——Claude Code 风格): 编写
    RELEASE-vX.Y.Z.md
    。
    • 格式: 使用 header
      Version X.Y.Z:
      ,然后列出扁平 bullet;每个 bullet 一行表达一个要点。
    • 语气: 以动词开头,描述 USER 能够感知到的变化,不要倾倒 commit 或内部实现。
      Fixed <症状> — <现在的行为>
      ·
      Added <能力> — <可以用来做什么>
      ·
      Removed/Changed …
      。从读者的角度描述(“你/你的”),不要包含 SHA 或函数名,除非 user 直接使用了这些名称。
    • 按动词隐性分组: Added/Changed 在前,Fixed 在后(与 Claude release note 相同)。如果列表较短,无需添加分组标题。
    • 来源: 读取
      git log <旧tag>..HEAD
      + 本次会话的 scratch-log → 将技术性 commit 转换为用户能够理解的句子(可以按用户感知到的价值合并或拆分 commit,不必与 commit 一一对应)。
    • Known-limitations(如果仍有半成品,则必须填写——比 Claude 更严格): proposal 尚未实现、coverage 不完整、medic 给出已知 warn 等情况,都应明确说明“正在进行中/已知问题”。保持沉默等同于夸大(council 于 2026-07-03 得出的经验)。
  7. 向 user 展示 checklist + 建议命令(commit msg、push、tag/PR/MR、UAT 第一阶段结果或跳过原因)。停止并等待批准。
  8. user 批准后:按级别执行。在任何 side-effect 发生前,不得自行执行。如果第 2 步已执行 UAT 第一阶段并通过(PASS)→ 在 merge/tag/push 完成后,立即执行 UAT 第二阶段(main-URL smoke,等待 sentinel CDN),之后才能向 user 报告“完成”;如果 FAIL → 按照
    /fdk-uat
    第 5 步将 commit 从 remote 移除。
    • push: commit +
      git push
      。
    • release: commit + push +
      git tag vX.Y.Z
      + 创建 release(notes = patch note)。
    • pr(GitHub): commit +
      git push -u origin <分支>
      +
      gh pr create --base <base> --head <分支> --title "…" --body-file <PR-body>
      。Base 默认使用 repo 的主分支(例如
      orca
      ),无法确定时询问 user。
    • mr(GitLab): commit +
      git push -u origin <分支>
      +
      glab mr create --source-branch <分支> --target-branch <base> --title "…" --description "…"
      (或使用
      -F <file>
      )。
    • 根据 remote 选择工具:
      git remote get-url origin
      包含
      github.com
      →
      gh
      ,包含
      gitlab
      →
      glab
      。
      ship pr
      /
      ship mr
      会明确强制使用对应工具;如果工具未安装或尚未 auth(
      gh auth status
      /
      glab auth status
      ),则停止并告知 user 安装和 login(不得自行执行)。
    • 除非 user 明确要求,否则不得自动在 PR/MR body 中插入
      Closes #N
      /
      Fixes #N
      ——应由 user 保留手动关闭 issue 的权力。

Luồng theo repo_role (W00 chọn MỘT cột; W01–W08 bên trên mô tả cột
framework
)

按 repo_role 划分的流程(W00 选择一列;上面的 W01–W08 描述的是
framework
列)

Bước
framework
(Rheinmir/setup)
module
(orca-graph, uiux-asset…)
downstream
(dự án có
.llmwiki/
)
foreign
(repo người khác)
Gate
medic --ci
→
ci-local
(trên checkout sạch nếu cây có file lạ)
commit trước → test + eval + install-test CỦA CHÍNH NÓ (đọc từng rc; install-test clone từ HEAD nên chưa commit là chưa test)test của dự án +
llmwiki-validate
+
medic
(chế độ downstream)
git sạch + test/CI của họ
UAT remotekhi diff có năng lực mới (B02)smoke cài từ remote sau khi push (
install.sh
của module vào HOME tạm)
khôngkhông
Version
capability-stamp.py --update
KHI thứ đi xuống máy khách đổi (hook, shim, installer, tool global) — sha bề mặt không đổi vẫn phải bump, nếu không máy đã ở bản hiện tại sẽ không refresh
bump
VERSION
+ hằng trong code +
CHANGELOG
theo dự ántheo họ
Bước cuốipush (· tag/PR theo mức)push → CHỜ CI xanh → tag + release → re-pin ở framework (
upstream_pin
trong
.overstack.yaml
: copy SKILL nếu đổi →
sync-skills.py
→ ghi
commit
/
version
vào
fdk/skills.provenance.json
→ ship framework)
push / prCHỈ pr / mr
Cấminstaller ghi vào repo này (tự từ chối rc 3)
ci-local
,
capability-stamp
đẩy file của framework, UAT, stampcài đặt, ghi cấu hình overstack, AI-attribution trái luật của họ
步骤
framework
(Rheinmir/setup)
module
(orca-graph、uiux-asset……)
downstream
(包含
.llmwiki/
的项目)
foreign
(他人的 repo)
Gate
medic --ci
→
ci-local
(如果工作树存在陌生文件,则在干净 checkout 上运行)
先 commit → 运行其自身的 test + eval + install-test(逐一读取 rc;install-test 从 HEAD clone,因此未 commit 的内容尚未经过测试)项目自身的 test +
llmwiki-validate
+
medic
(downstream 模式)
Git 状态干净 + 对方的 test/CI
Remote UAT当 diff 带来新能力时(B02)push 后从 remote 执行安装 smoke(将 module 的
install.sh
安装到临时 HOME)
无无
Version当下发到客户端机器的内容发生变化时,执行
capability-stamp.py --update
(hook、shim、installer、全局 tool)——即使表面 sha 未变也必须 bump,否则已经处于当前版本的机器不会刷新
bump
VERSION
+ 代码中的常量 +
CHANGELOG
按项目规则执行按对方规则执行
最后一步push(按级别执行 · tag/PR)push → 等待 CI 通过 → tag + release → 在
Rheinmir/setup
中重新 pin(
.overstack.yaml
中的
upstream_pin
:如果 skill 有变化则复制 SKILL →
sync-skills.py
→ 将
commit
/
version
写入
fdk/skills.provenance.json
→ ship framework)
push / pr仅 pr / mr
禁止installer 写入此 repo(自行拒绝并返回 rc 3)
ci-local
、
capability-stamp
push framework 文件、UAT、stamp安装、写入 overstack 配置、违反对方规则的 AI-attribution

Branches

分支

IDKindGuardHành viSkip / failureRejoin
B01conditional_requiredmức =
release
W05 version + tag
vX.Y.Z
+ release notes
mức khác → skipW06
B02conditional_requiredmức ∈ {release, pr, mr} VÀ diff có năng lực mớiUAT pha 1 trước W07, pha 2 sau W08bugfix/refactor nội bộ → skip, ghi lý do vào checklist; không chắc → clarifyW03
B03user_optionalmức =
merge
Vòng GOM VỀ riêng (mục dưới), bỏ W02, W05–W06PR đỏ → không merge PR đóbáo cáo tổng
ID类型Guard行为跳过/失败汇合点
B01conditional_required级别 =
release
W05 version + tag
vX.Y.Z
+ release notes
其他级别 → skipW06
B02conditional_required级别 ∈ {release, pr, mr},且 diff 带来新能力W07 前执行 UAT 第一阶段,W08 后执行第二阶段内部 bugfix/refactor → skip,并在 checklist 中记录原因;无法确定 → clarifyW03
B03user_optional级别 =
merge
独立的汇入流程(见下节),跳过 W02、W05–W06PR 未通过 → 不合并该 PR汇总报告

Mức
merge
(GOM VỀ — duyệt-rồi-merge PR/MR đến)

merge 级别(汇入——审批后合并传入的 PR/MR)

Không viết note/tag. Bỏ qua bước 2, 5-6; thay bằng vòng test-per-request:
  1. Chọn công cụ theo remote (như trên):
    github.com
    →
    gh
    ,
    gitlab
    →
    glab
    . Chưa auth → DỪNG báo user.
  2. Liệt kê PR/MR đang mở của repo:
    • GitHub:
      gh pr list --json number,title,headRefName,mergeable,isDraft
    • GitLab:
      glab mr list
      (hoặc
      --output json
      nếu bản hỗ trợ). Hiện danh sách cho user; nếu user chỉ định số cụ thể thì lọc, không thì hỏi làm hết hay chọn.
  3. Với mỗi PR/MR (một-tại-một, không gộp mù): a. Kéo nhánh về LOCAL sạch: GitHub
    gh pr checkout <n>
    ; GitLab
    git fetch origin merge-requests/<n>/head:mr-<n> && git checkout mr-<n>
    (hoặc
    glab mr checkout <n>
    ). b. Chạy GATE + TEST trên nhánh đó:
    medic --ci
    + selftest/test liên quan diff của PR. Đây là điều kiện merge — KHÔNG merge khi chưa chạy. c. Xanh → đề xuất lệnh merge, DỪNG chờ duyệt, rồi merge: GitHub
    gh pr merge <n> --squash
    (hoặc --merge/--rebase theo repo); GitLab
    glab mr merge <n>
    . Đỏ → KHÔNG merge; báo cáo chỗ đỏ + để PR nguyên cho tác giả sửa. d. Sau merge: quay lại nhánh gốc (
    git checkout <nhánh-cũ>
    ), dọn nhánh tạm.
  4. Báo cáo tổng: mỗi PR/MR → đã-merge / bỏ-qua-vì-đỏ (kèm lý do) / bỏ-qua-vì-user.
不编写 note/tag。跳过第 2、5–6 步,改为执行逐个请求的测试流程:
  1. 根据 remote 选择工具(同上):
    github.com
    →
    gh
    ,
    gitlab
    →
    glab
    。尚未 auth → 停止并告知 user。
  2. 列出当前 repo 中已打开的 PR/MR:
    • GitHub:
      gh pr list --json number,title,headRefName,mergeable,isDraft
    • GitLab:
      glab mr list
      (如果版本支持,也可以使用
      --output json
      )。 向 user 展示列表;如果 user 指定了具体编号,则进行筛选,否则询问是全部处理还是选择部分。
  3. 对于每个 PR/MR(逐个处理,不得盲目合并): a. 将分支检出到干净的 LOCAL 环境:GitHub 使用
    gh pr checkout <n>
    ;GitLab 使用
    git fetch origin merge-requests/<n>/head:mr-<n> && git checkout mr-<n>
    (或
    glab mr checkout <n>
    )。 b. 在该分支上运行 GATE + TEST:
    medic --ci
    + 与 PR diff 相关的 selftest/test。这是 merge 条件——未运行测试时不得 merge。 c. 通过 → 建议 merge 命令,停止并等待批准,然后 merge:GitHub 使用
    gh pr merge <n> --squash
    (或根据 repo 规则使用
    --merge
    /
    --rebase
    );GitLab 使用
    glab mr merge <n>
    。未通过 → 不得 merge;报告失败位置,并将 PR 原样留给作者修复。 d. Merge 后:切回原分支(
    git checkout <旧分支>
    ),清理临时分支。
  4. 汇总报告: 对每个 PR/MR 标注已 merge / 因未通过而跳过(附原因)/ 因 user 要求而跳过。

Validation và stopping

验证与停止条件

Điều kiện đi tiếp là rc của công cụ (medic, ci-local, fdk-uat, test), không phải model tự đánh giá. Mọi side-effect dừng ở W07 chờ "yes"; mức
merge
dừng chờ duyệt từng PR. Không retry push/tag tự động khi lỗi mạng — báo user.
是否继续取决于工具返回的 rc(medic、ci-local、fdk-uat、test),而不是模型自行评估。所有 side-effect 都在 W07 停止并等待“yes”;
merge
级别则针对每个 PR 分别停止并等待批准。遇到网络错误时,不得自动重试 push/tag;应报告给 user。

Examples

示例

  • Positive (module): ở repo
    orca-graph
    gõ "ship release" → W00 in
    🏷 repo_role=module (khai báo)
    → commit →
    pytest tests
    rc 0 →
    evals/run.py
    rc 0 →
    tests/install-test.sh
    rc 0 → bump
    VERSION
    → DỪNG duyệt → push → CI xanh → tag + release → nhắc bước re-pin ở
    Rheinmir/setup
    theo
    upstream_pin
    .
  • Boundary (foreign): ở một repo không có stamp, không nhãn → W00 in
    🏷 repo_role=foreign (suy luận: không có fdk/wiki, không có .harness-stamp)
    → hỏi user xác nhận → chỉ đề xuất
    ship pr
    , đọc CONTRIBUTING của họ, không ghi file nào của overstack.
  • Positive: "ship push" sau khi sửa doc → W01 xanh, B02 skip (không năng lực mới, ghi lý do), W03–W04 xanh → checklist +
    git push
    → user "yes" → push.
  • Boundary/failure: "ship pr" có skill mới nhưng
    ci-local
    đỏ 1 job → blocked ở W01, in job đỏ + lệnh sửa, không push nhánh, không mở PR.
  • Boundary: "ship merge" có 2 PR, PR #2 test đỏ → merge #1 sau duyệt, bỏ #2 kèm lý do (partial).
  • 正向案例(module): 在
    orca-graph
    repo 中输入“ship release”→ W00 输出
    🏷 repo_role=module (khai báo)
    → commit →
    pytest tests
    rc 0 →
    evals/run.py
    rc 0 →
    tests/install-test.sh
    rc 0 → bump
    VERSION
    → 停止等待批准 → push → CI 通过 → tag + release → 提醒按照
    upstream_pin
    在
    Rheinmir/setup
    中执行 re-pin。
  • 边界案例(foreign): 在一个没有 stamp、没有标签的 repo 中 → W00 输出
    🏷 repo_role=foreign (suy luận: không có fdk/wiki, không có .harness-stamp)
    → 询问 user 确认 → 仅建议
    ship pr
    ,阅读对方的 CONTRIBUTING,不向 repo 写入任何 overstack 文件。
  • 正向案例: 修改文档后输入“ship push”→ W01 通过,B02 skip(没有新能力,并记录原因),W03–W04 通过 → checklist +
    git push
    → user 回复“yes”→ push。
  • 边界/失败案例: “ship pr”包含新 skill,但
    ci-local
    有 1 个 job 未通过 → 在 W01 被 blocked,打印失败 job + 修复命令,不 push 分支,也不创建 PR。
  • 边界案例: “ship merge”存在 2 个 PR,其中 PR #2 测试未通过 → 获得批准后 merge #1,附原因跳过 #2(partial)。