ship
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseSkill: 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+ release notes) · pr (push nhánh + mở Pull Request GitHub quavX.Y.Z) · mr (push nhánh + mở Merge Request GitLab quagh) · merge (liệt kê PR/MR đến → kéo nhánh về → gate+test → merge nếu xanh).glab
围绕 remote 固化工作流。运行准入条件 CHECKLIST,在每个 side-effect 步骤(push/tag/PR/MR/merge)之前停止并等待批准。五个级别——4 个外发(outbound)级别 + 1 个汇入(inbound)级别:push(完成所有步骤但不打 tag)· release(push + tag+ release notes)· pr(push 分支 + 通过vX.Y.Z创建 GitHub Pull Request)· mr(push 分支 + 通过gh创建 GitLab Merge Request)· merge(列出传入的 PR/MR → 检出分支 → gate+test → 通过时 merge)。glab
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 + skill sửa), không tự đóng issue, không tự cài/auth
/medic/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 问题(这是 + 修复类 skill 的职责),不自行关闭 issue,也不自行安装/auth
/medic/gh。glab
Mental model
思维模型
repo_role (framework · module · downstream · foreign) → bảng gate của ĐÚNG loại repo → 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]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 第二阶段]Input và output contract
输入与输出约定
| Field | Required? | Ý nghĩa | |
|---|---|---|---|
| In | | tự đọc | |
| In | mức | không (mặc định = push) | |
| In | duyệt của user | có, trước mọi side-effect | "yes" tường minh cho push/tag/release/PR/MR/merge/canary |
| Out | checklist + lệnh đề xuất | có | kết quả từng bước gate, UAT pha 1 hoặc lý do skip, commit msg, lệnh cuối |
| Out | văn bản | theo mức | |
| Out | side-effect | chỉ sau duyệt | push / tag / release / PR / MR / merge đã thực thi |
| 字段 | 必填? | 含义 | |
|---|---|---|---|
| In | | 自动读取 | |
| In | 级别 | 否(默认 = push) | |
| In | user 的批准 | 是,在任何 side-effect 之前 | push/tag/release/PR/MR/merge/canary 都需要明确的“yes” |
| Out | checklist + 建议命令 | 是 | 逐步展示 gate 结果、UAT 第一阶段结果或跳过原因、commit msg 和最终命令 |
| Out | 文本 | 视级别而定 | |
| Out | side-effect | 仅在批准后 | 已执行的 push / tag / release / PR / MR / merge |
Rules và capabilities
规则与能力
- RULE-01 (MUST): Không push khi đỏ — trừ khi user override tường minh; kể cả override phải ghi lý do vào patch note.
medic --ci - 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): xanh KHÔNG chứng minh đường remote chạy được — đó là việc của
medic --ci./fdk-uat/release/prcó 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ảmr) chỉ qua6c839d8/medic --ci, chưa từng qua UAT remote thật.ci-local - RULE-05 (MUST): Mức — TEST là điều kiện merge, không phải hình thức: phải kéo nhánh về + chạy
merge+ 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.medic --ci - 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 tự động.
Closes #N - 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: thiếu công cụ → DỪNG, báo user; đừng đoán host.glab - 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à . Nguồn
🏷 repo_role=<role> (khai báo | sổ máy | suy luận | ép tay)→ hỏi user xác nhận rồi ghi nhãn (suy luận; riêngrepo_role.py . --set <role>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:foreign/ci-local/UAT chỉ có nghĩa ởcapability-stamp; chạy chúng ởframework/modulelà chấm nhầm, bỏ chúng ởdownstreamlà hở. Bài học 20/09/2026:frameworkmột-luồng khiến việc ship repo engine phải tự nhớ quy trình khác hẳn./ship - 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 ; cấm nối gate với push bằng
rc=hay ống;(nuốt rc). Hai lần cháy cùng ngày 20/09/2026: push| tailkhic83b065đang đỏ, và tagmedickhiv3.0.1báo FAIL — cả hai do nối lệnh. Ởinstall-testkhi 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 (framework) để không chấm nhầm workflow.git worktree add --detach <tmp> HEAD - RULE-12 (MUST): = khách trong nhà người khác. Chỉ mức
foreign/pr, khôngmrthẳ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 ghipush, không thêm file cấu hình nào của ta vào repo..overstack.yaml - RULE-09 (MUST): Compose, đừng đẻ lại: dùng cho sức khoẻ,
mediccho version,git tag/ghcho PR/MR — skill này chỉ điều phối checklist.glab - 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):当 未通过时不得 push——除非 user 明确 override;即使进行了 override,也必须将原因记录到 patch note。
medic --ci - 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):通过并不能证明 remote 路径可以正常运行——这是
medic --ci的职责。 如果/fdk-uat/release/pr的 diff 带来新能力,在建议执行第 7 步之前,必须完成 UAT 第一阶段(canary);只有当 diff 确认没有增加 user 可见能力时才可跳过,并必须记录原因。2026-09-17 已实际验证的结论:此前所有 push(包括mr)仅通过了6c839d8/medic --ci,从未执行过真实 remote UAT。ci-local - RULE-05 (MUST):在 级别中,TEST 是合并条件,而不是形式要求: 合并前必须检出分支并运行
merge+ 真实测试;如果未通过,绝对不得 merge,应将 PR 原样留给作者处理。必须逐个处理,不得盲目批量合并多个 PR。medic --ci - 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: 如果缺少工具,则停止并告知 user;不要猜测 host。glab - RULE-10 (MUST):运行任何 gate 前,都必须知道自己处于哪种 repo 类型。 Checklist 第一行始终为 。如果来源为“推断”,则询问 user 确认并记录标签(
🏷 repo_role=<role>(声明 | 机器记录 | 推断 | 手动);对于repo_role.py . --set <role>,仅记录到机器账本,不修改他人的 repo)。该 repo 类型的 gate 不适用于其他类型:在foreign/module中运行downstream/ci-local/UAT 属于错误评估,而在capability-stamp中省略它们则会造成流程缺口。2026-09-20 的经验:让framework采用单一流程,会导致 framework repo 的发布流程无法记住与其他类型截然不同的要求。/ship - RULE-11 (MUST):读取 gate 的 rc 后再推送。 Push/tag 命令必须位于一个独立步骤中,并已打印及读取 ;禁止使用
rc=或;将 gate 与 push 串接,因为这会吞掉 rc。2026-09-20 同一天发生了两次问题:medic 仍为红色时 push 了| tail,以及c83b065报 FAIL 时创建了 taginstall-test——两者均由命令串接导致。在v3.0.1中,如果 working tree 含有被其他工具覆盖且尚未 commit 的陌生文件,应在 commit 的干净 CHECKOUT 上运行 gate(framework),避免错误评估 workflow。git worktree add --detach <tmp> HEAD - RULE-12 (MUST):表示处于他人主场中的客户仓库。 仅允许
foreign/pr级别,不允许默认直接 push 分支;必须遵循对方的 commit/CI 规则(阅读 CONTRIBUTING,不套用 R15 或 overstack 规则);不得安装软件、写入mr,也不得向该 repo 添加任何属于我们的配置文件。.overstack.yaml - RULE-09 (MUST):应进行组合编排,而不是重新造轮子:使用 检查健康状态,使用
medic管理 version,使用git tag/gh创建 PR/MR——此 skill 仅负责协调 checklist。glab - Capabilities:读取 repo 并在本地运行 gate;仅通过已经 auth 的工具,并在获得批准后写入 remote(push/tag/PR/MR/merge)。
Failure boundaries
失败边界
- Gate đỏ (/
medic --ci/ci-local) → blocked, in chỗ hở + lệnh sửa, không push.freshinstall - UAT FAIL ở pha nào → failed, dừng ship, xoá canary; pha 2 FAIL → gỡ commit khỏi remote theo bước 5.
/fdk-uat - 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 /
ghhoặc chưa auth → blocked, báo user cài + login.glab - Mức : PR đỏ → không merge PR đó (partial cho cả lô), báo lý do.
merge
- Gate 未通过(/
medic --ci/ci-local)→ blocked,打印缺口 + 修复命令,不得 push。freshinstall - UAT 在任一阶段 FAIL → failed,停止 ship 并删除 canary;如果第二阶段 FAIL,则按照 第 5 步将 commit 从 remote 移除。
/fdk-uat - 无法确定 diff 是否包含“新能力”或无法确定 version 级别 → clarify(询问 user),不得自行决定。
- 缺少 /
gh或尚未 auth → blocked,告知 user 如何安装和 login。glab - 级别:某个 PR 未通过 → 不得合并该 PR(整批结果为 partial),并报告原因。
merge
HOW
执行方式
Main workflow
主工作流
| Step | Type | Inputs | Action | Outputs/exit | Failure/next |
|---|---|---|---|---|---|
| W00 | deterministic | repo | | role + bảng gate | role không hợp lệ → blocked |
| W01 | deterministic | repo | Cổng sức khoẻ | rc 0 | đỏ → blocked |
| W02 | effect | diff, mức | UAT | PASS hoặc lý do skip | FAIL → failed |
| W03 | deterministic | worktree | Git sạch: | sạch | bẩn → dọn rồi lặp W03 |
| W04 | deterministic | diff | Selftest/kiểm nhanh engine đụng tới | rc 0 | đỏ → blocked |
| W05 | judgment | tag gần nhất | Version | tag đề xuất | không chắc bậc → clarify |
| W06 | judgment | | Patch note / PR-MR body trung thực, Known-limitations bắt buộc nếu có phần nửa vời | văn bản | — |
| W07 | deterministic | kết quả W01–W06 | Hiện checklist + đề xuất lệnh, DỪNG chờ duyệt | "yes" | không duyệt → cancelled |
| W08 | effect | duyệt | Thực thi theo mức; nếu W02 đã chạy thì UAT pha 2 ngay sau đó | side-effect + receipt | pha 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 (ĐẨY ĐI) chạy bước 1-8 dưới. Mức (GOM VỀ) chạy nhánh riêng ở step 8 (đọc mục "Mức merge").
push/release/pr/mrmergeBước 1, 3-4 áp dụng cho MỌI mức. Bước 2 (UAT) CHỈ //. Bước 5 (version tag) CHỈ mức . Bước 6 đổi tên "sản phẩm viết": →; /→ PR/MR body (cùng giọng người-dùng, cùng luật Known-limitations). không cần văn bản, chỉ commit msg. Mức không viết note (chỉ báo cáo kết quả test + quyết định merge/không).
releaseprmrreleasereleaseRELEASE-vX.Y.Z.mdprmrpushmerge- CỔNG SỨC KHOẺ — (hoặc
medic --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.python3 fdk/tools/medic.py --ci- Rồi (repo framework) — chạy TRỌN mọi step
python3 fdk/tools/ci-local.pycủ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.run: - Gồm probe (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:
freshinstall.bash harness/scripts/fresh-install-smoke.sh --remote
- Rồi
- UAT gate — (CHỈ mức
/fdk-uat/release/pr, KHÔNGmrthường):push/medic --ciở bước 1 chỉ cài quaci-localworking-tree — chứng minh "code trong máy lành", KHÔNG chứng minh "người lạfile://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 pushcurlkhông hề qua UAT).6c839d8- 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").
- Git sạch: ; đảm bảo rác ephemeral (
git status --short) đãscratchpad/…+.gitignorenếu lỡ track. Rà không có file bí mật/tạm lọt vào.git rm -r --cached - Selftest/kiểm nhanh các engine đụng tới (vd , test liên quan diff).
council.py selftest - Version: → tag gần nhất
git tag --sort=-v:refname | head -1→ đề xuấtvX.Y.Z(patch) hoặc minor/major nếu diff xứng — hỏi user nếu không chắc bậc.vX.Y.(Z+1) - 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 rồi danh sách bullet PHẲNG, mỗi bullet một dòng một ý.
Version X.Y.Z: - 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ì>. 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.Removed/Changed … - 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 + 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).
git log <tag-cũ>..HEAD - 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).
- Format: header
- 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.
- 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 bước 5.
/fdk-uat- push: commit + .
git push - release: commit + push + + tạo release (notes = patch note).
git tag vX.Y.Z - pr (GitHub): commit + +
git push -u origin <nhánh>. Base mặc định = nhánh chính repo (vdgh pr create --base <base> --head <nhánh> --title "…" --body-file <PR-body>), hỏi nếu không chắc.orca - mr (GitLab): commit + +
git push -u origin <nhánh>(hoặcglab mr create --source-branch <nhánh> --target-branch <base> --title "…" --description "…").-F <file> - Chọn công cụ theo remote: chứa
git remote get-url origin→github.com,gh→gitlab.glab/ship prép rõ công cụ; nếu công cụ chưa cài/chưa auth (ship mr/gh auth status) thì DỪNG, báo user cài+login (không tự làm).glab auth status - KHÔNG tự chèn /
Closes #Nvào PR/MR body trừ khi user yêu cầu tường minh — để user giữ quyền đóng issue tay.Fixes #N
- push: commit +
| 步骤 | 类型 | 输入 | 操作 | 输出/退出状态 | 失败/下一步 |
|---|---|---|---|---|---|
| W00 | 确定性 | repo | | role + gate 表 | role 无效 → blocked |
| W01 | 确定性 | repo | 运行健康 gate | rc 0 | 未通过 → blocked |
| W02 | 副作用 | diff、级别 | UAT | PASS 或跳过原因 | FAIL → failed |
| W03 | 确定性 | worktree | Git 状态干净:运行 | 干净 | 不干净 → 清理后重新执行 W03 |
| W04 | 确定性 | diff | 对受影响的 engine 执行 Selftest/快速检查 | rc 0 | 未通过 → blocked |
| W05 | 判断 | 最近的 tag | Version | 建议的 tag | 无法确定级别 → clarify |
| W06 | 判断 | | 如实编写 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/mrmerge第 1、3–4 步适用于所有级别。第 2 步(UAT)仅适用于 //。第 5 步(version tag)仅适用于 。第 6 步的“输出文档”对应关系为:→;/→ PR/MR body(使用面向 user 的语气,并遵循相同的 Known-limitations 规则)。 不需要文档,仅需 commit msg。 级别不编写 note,只报告测试结果和 merge/不 merge 的决策。
releaseprmrreleasereleaseRELEASE-vX.Y.Z.mdprmrpushmerge- 健康 GATE——(或
medic --ci)。FAIL → 停止,打印缺口 + 修复命令;gate 未通过时不得 push。Warn(已知债务)→ 可以通过,但必须在 patch note 中列出。python3 fdk/tools/medic.py --ci- 然后运行 (repo
python3 fdk/tools/ci-local.py)——在本地完整运行所有 GitHub workflow 的每一个framework步骤(L4)。medic 是 L2;有些 gate 仅存在于 CI(search-index、skill-provenance、retrieval-eval……)——080926 已实际发生:medic 通过并完成 push,但 CI 有 2 个 job 失败。失败 → 不得 push。run: - 其中包含 probe(E2E):通过 working-tree,将 curl 安装 overstack 到一个隔离的空项目(使用 mktemp 创建于 repo 外部),断言三大支柱 + harness 拦截 + orchestration-ready。失败意味着新用户安装路径已损坏 → 不得 push。完整的 curl-github + live acceptance 命令:
freshinstall。bash harness/scripts/fresh-install-smoke.sh --remote
- 然后运行
- UAT gate——(仅适用于
/fdk-uat/release/pr级别,不适用于普通mr): 第 1 步中的push/medic --ci仅通过ci-localworking-tree 安装——这只能证明“本地代码健康”,不能证明“陌生用户通过 curl 从 remote 安装后可以正常运行”(GH#77 的故障类型:“文档承诺了,但用户没有真正获得”;2026-09-17 pushfile://时实际测量确认其从未经过 UAT)。6c839d8- 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(不能留待以后处理)。
- Git 状态干净: 运行 ;确保 ephemeral 垃圾文件(
git status --short)已加入scratchpad/…,如果此前被 track,则执行.gitignore。检查是否有 secret/临时文件意外进入仓库。git rm -r --cached - Selftest/快速检查受影响的 engine(例如 、与 diff 相关的测试)。
council.py selftest - Version: → 最近的 tag 为
git tag --sort=-v:refname | head -1→ 建议vX.Y.Z(patch);如果 diff 的影响范围符合条件,也可以使用 minor/major——无法确定级别时询问 user。vX.Y.(Z+1) - 如实编写 PATCH NOTE(面向 USER 的 release-note 语气——Claude Code 风格): 编写 。
RELEASE-vX.Y.Z.md- 格式: 使用 header ,然后列出扁平 bullet;每个 bullet 一行表达一个要点。
Version X.Y.Z: - 语气: 以动词开头,描述 USER 能够感知到的变化,不要倾倒 commit 或内部实现。·
Fixed <症状> — <现在的行为>·Added <能力> — <可以用来做什么>。从读者的角度描述(“你/你的”),不要包含 SHA 或函数名,除非 user 直接使用了这些名称。Removed/Changed … - 按动词隐性分组: Added/Changed 在前,Fixed 在后(与 Claude release note 相同)。如果列表较短,无需添加分组标题。
- 来源: 读取 + 本次会话的 scratch-log → 将技术性 commit 转换为用户能够理解的句子(可以按用户感知到的价值合并或拆分 commit,不必与 commit 一一对应)。
git log <旧tag>..HEAD - Known-limitations(如果仍有半成品,则必须填写——比 Claude 更严格): proposal 尚未实现、coverage 不完整、medic 给出已知 warn 等情况,都应明确说明“正在进行中/已知问题”。保持沉默等同于夸大(council 于 2026-07-03 得出的经验)。
- 格式: 使用 header
- 向 user 展示 checklist + 建议命令(commit msg、push、tag/PR/MR、UAT 第一阶段结果或跳过原因)。停止并等待批准。
- user 批准后:按级别执行。在任何 side-effect 发生前,不得自行执行。如果第 2 步已执行 UAT 第一阶段并通过(PASS)→ 在 merge/tag/push 完成后,立即执行 UAT 第二阶段(main-URL smoke,等待 sentinel CDN),之后才能向 user 报告“完成”;如果 FAIL → 按照 第 5 步将 commit 从 remote 移除。
/fdk-uat- push: commit + 。
git push - release: commit + push + + 创建 release(notes = patch note)。
git tag vX.Y.Z - pr(GitHub): commit + +
git push -u origin <分支>。Base 默认使用 repo 的主分支(例如gh pr create --base <base> --head <分支> --title "…" --body-file <PR-body>),无法确定时询问 user。orca - 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会明确强制使用对应工具;如果工具未安装或尚未 auth(ship mr/gh auth status),则停止并告知 user 安装和 login(不得自行执行)。glab auth status - 除非 user 明确要求,否则不得自动在 PR/MR body 中插入 /
Closes #N——应由 user 保留手动关闭 issue 的权力。Fixes #N
- push: commit +
Luồng theo repo_role (W00 chọn MỘT cột; W01–W08 bên trên mô tả cột framework
)
framework按 repo_role 划分的流程(W00 选择一列;上面的 W01–W08 描述的是 framework
列)
framework| Bước | | | | |
|---|---|---|---|---|
| Gate | | 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 + | git sạch + test/CI của họ |
| UAT remote | khi diff có năng lực mới (B02) | smoke cài từ remote sau khi push ( | không | không |
| Version | | bump | theo dự án | theo họ |
| Bước cuối | push (· tag/PR theo mức) | push → CHỜ CI xanh → tag + release → re-pin ở framework ( | push / pr | CHỈ pr / mr |
| Cấm | installer ghi vào repo này (tự từ chối rc 3) | | đẩy file của framework, UAT, stamp | cài đặt, ghi cấu hình overstack, AI-attribution trái luật của họ |
| 步骤 | | | | |
|---|---|---|---|---|
| Gate | | 先 commit → 运行其自身的 test + eval + install-test(逐一读取 rc;install-test 从 HEAD clone,因此未 commit 的内容尚未经过测试) | 项目自身的 test + | Git 状态干净 + 对方的 test/CI |
| Remote UAT | 当 diff 带来新能力时(B02) | push 后从 remote 执行安装 smoke(将 module 的 | 无 | 无 |
| Version | 当下发到客户端机器的内容发生变化时,执行 | bump | 按项目规则执行 | 按对方规则执行 |
| 最后一步 | push(按级别执行 · tag/PR) | push → 等待 CI 通过 → tag + release → 在 | push / pr | 仅 pr / mr |
| 禁止 | installer 写入此 repo(自行拒绝并返回 rc 3) | | push framework 文件、UAT、stamp | 安装、写入 overstack 配置、违反对方规则的 AI-attribution |
Branches
分支
| ID | Kind | Guard | Hành vi | Skip / failure | Rejoin |
|---|---|---|---|---|---|
| B01 | conditional_required | mức = | W05 version + tag | mức khác → skip | W06 |
| B02 | conditional_required | mức ∈ {release, pr, mr} VÀ diff có năng lực mới | UAT pha 1 trước W07, pha 2 sau W08 | bugfix/refactor nội bộ → skip, ghi lý do vào checklist; không chắc → clarify | W03 |
| B03 | user_optional | mức = | Vòng GOM VỀ riêng (mục dưới), bỏ W02, W05–W06 | PR đỏ → không merge PR đó | báo cáo tổng |
| ID | 类型 | Guard | 行为 | 跳过/失败 | 汇合点 |
|---|---|---|---|---|---|
| B01 | conditional_required | 级别 = | W05 version + tag | 其他级别 → skip | W06 |
| B02 | conditional_required | 级别 ∈ {release, pr, mr},且 diff 带来新能力 | W07 前执行 UAT 第一阶段,W08 后执行第二阶段 | 内部 bugfix/refactor → skip,并在 checklist 中记录原因;无法确定 → clarify | W03 |
| B03 | user_optional | 级别 = | 独立的汇入流程(见下节),跳过 W02、W05–W06 | PR 未通过 → 不合并该 PR | 汇总报告 |
Mức merge
(GOM VỀ — duyệt-rồi-merge PR/MR đến)
mergemerge 级别(汇入——审批后合并传入的 PR/MR)
Không viết note/tag. Bỏ qua bước 2, 5-6; thay bằng vòng test-per-request:
- Chọn công cụ theo remote (như trên): →
github.com,gh→gitlab. Chưa auth → DỪNG báo user.glab - Liệt kê PR/MR đang mở của repo:
- GitHub:
gh pr list --json number,title,headRefName,mergeable,isDraft - GitLab: (hoặc
glab mr listnế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.--output json
- GitHub:
- 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 ; GitLab
gh pr checkout <n>(hoặcgit fetch origin merge-requests/<n>/head:mr-<n> && git checkout mr-<n>). b. Chạy GATE + TEST trên nhánh đó:glab mr checkout <n>+ 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: GitHubmedic --ci(hoặc --merge/--rebase theo repo); GitLabgh pr merge <n> --squash. Đỏ → 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 (glab mr merge <n>), dọn nhánh tạm.git checkout <nhánh-cũ> - 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 步,改为执行逐个请求的测试流程:
- 根据 remote 选择工具(同上):→
github.com,gh→gitlab。尚未 auth → 停止并告知 user。glab - 列出当前 repo 中已打开的 PR/MR:
- GitHub:
gh pr list --json number,title,headRefName,mergeable,isDraft - GitLab:(如果版本支持,也可以使用
glab mr list)。 向 user 展示列表;如果 user 指定了具体编号,则进行筛选,否则询问是全部处理还是选择部分。--output json
- GitHub:
- 对于每个 PR/MR(逐个处理,不得盲目合并):
a. 将分支检出到干净的 LOCAL 环境:GitHub 使用 ;GitLab 使用
gh pr checkout <n>(或git fetch origin merge-requests/<n>/head:mr-<n> && git checkout mr-<n>)。 b. 在该分支上运行 GATE + TEST:glab mr checkout <n>+ 与 PR diff 相关的 selftest/test。这是 merge 条件——未运行测试时不得 merge。 c. 通过 → 建议 merge 命令,停止并等待批准,然后 merge:GitHub 使用medic --ci(或根据 repo 规则使用gh pr merge <n> --squash/--merge);GitLab 使用--rebase。未通过 → 不得 merge;报告失败位置,并将 PR 原样留给作者修复。 d. Merge 后:切回原分支(glab mr merge <n>),清理临时分支。git checkout <旧分支> - 汇总报告: 对每个 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 dừng chờ duyệt từng PR. Không retry push/tag tự động khi lỗi mạng — báo user.
merge是否继续取决于工具返回的 rc(medic、ci-local、fdk-uat、test),而不是模型自行评估。所有 side-effect 都在 W07 停止并等待“yes”; 级别则针对每个 PR 分别停止并等待批准。遇到网络错误时,不得自动重试 push/tag;应报告给 user。
mergeExamples
示例
- Positive (module): ở repo gõ "ship release" → W00 in
orca-graph→ commit →🏷 repo_role=module (khai báo)rc 0 →pytest testsrc 0 →evals/run.pyrc 0 → bumptests/install-test.sh→ DỪNG duyệt → push → CI xanh → tag + release → nhắc bước re-pin ởVERSIONtheoRheinmir/setup.upstream_pin - Boundary (foreign): ở một repo không có stamp, không nhãn → W00 in → hỏi user xác nhận → chỉ đề xuất
🏷 repo_role=foreign (suy luận: không có fdk/wiki, không có .harness-stamp), đọc CONTRIBUTING của họ, không ghi file nào của overstack.ship pr - 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 + → user "yes" → push.
git push - Boundary/failure: "ship pr" có skill mới nhưng đỏ 1 job → blocked ở W01, in job đỏ + lệnh sửa, không push nhánh, không mở PR.
ci-local - Boundary: "ship merge" có 2 PR, PR #2 test đỏ → merge #1 sau duyệt, bỏ #2 kèm lý do (partial).
- 正向案例(module): 在 repo 中输入“ship release”→ W00 输出
orca-graph→ commit →🏷 repo_role=module (khai báo)rc 0 →pytest testsrc 0 →evals/run.pyrc 0 → bumptests/install-test.sh→ 停止等待批准 → push → CI 通过 → tag + release → 提醒按照VERSION在upstream_pin中执行 re-pin。Rheinmir/setup - 边界案例(foreign): 在一个没有 stamp、没有标签的 repo 中 → W00 输出 → 询问 user 确认 → 仅建议
🏷 repo_role=foreign (suy luận: không có fdk/wiki, không có .harness-stamp),阅读对方的 CONTRIBUTING,不向 repo 写入任何 overstack 文件。ship pr - 正向案例: 修改文档后输入“ship push”→ W01 通过,B02 skip(没有新能力,并记录原因),W03–W04 通过 → checklist + → user 回复“yes”→ push。
git push - 边界/失败案例: “ship pr”包含新 skill,但 有 1 个 job 未通过 → 在 W01 被 blocked,打印失败 job + 修复命令,不 push 分支,也不创建 PR。
ci-local - 边界案例: “ship merge”存在 2 个 PR,其中 PR #2 测试未通过 → 获得批准后 merge #1,附原因跳过 #2(partial)。