SuperAPI AI Directory

ship

General & other

View repository

Updated 10-15 22:33

About this skill

Skill: ship

Workflow to finalize around the remote. Run the condition checklist, STOP and wait for approval before every side-effect step (push/tag/PR/MR/merge). Five tiers — 4 OUTBOUND tiers + 1 INBOUND tier: push (all steps, no tag) · release (push + tag vX.Y.Z + release notes) · pr (push branch + open GitHub Pull Request via gh) · mr (push branch + open GitLab Merge Request via glab) · merge (list PR/MR incoming → pull branch back → gate+test → merge if green).

WHAT

Purpose and context

  • Purpose: get changes out to the remote (push/release/PR/MR) or pull incoming PR/MR back in (merge) ONLY after the condition checklist is green, and stop to wait for approval before every side-effect.
  • Trigger (when to use):
  • User mentions "release" / "push" / "ship" / "lên release" / "chuẩn bị push" / "đủ điều kiện push chưa" / "mở PR" / "tạo MR".
  • Before pushing code to the remote, cutting a release, or opening a PR/MR for review-then-merge.
  • Want to review-then-merge the repo's open PR/MRs: "gom PR về merge" / "merge PR nếu test xanh" / "ship merge".
  • Non-goals: does not fix gate failures itself (that is the job of /medic + the fix skill), does not close issues itself, does not install/authenticate gh/glab.

Mental model

repo_role (framework · module · downstream · foreign) → bảng gate của ĐÚNG loại repo → and only then the common sequence: 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]. The tiers differ in the final step, not in the checklist.

Input and output contract

Field Required? Meaning
In repo_role auto-read python3 harness/scripts/repo_role.py . --json (client machine: ~/.claude/harness/harness/scripts/repo_role.py) — DECLARED label in .overstack.yaml; if missing, infer with evidence then ASK the user once and --set; force manually this time: ship <mức> --as <role>
In tier no (default = push) push · release · pr · mr · merge — user describes the scope, no need to remember flags
In user approval yes, before every side-effect explicit "yes" for push/tag/release/PR/MR/merge/canary
Out checklist + proposed commands yes result of each gate step, phase-1 UAT or skip reason, commit msg, final command
Out text per tier release → RELEASE-vX.Y.Z.md; pr/mr → PR/MR body; push → commit msg only; merge → test report + decision
Out side-effect only after approval push / tag / release / PR / MR / merge executed

Rules and capabilities

  • RULE-01 (MUST): Do not push when medic --ci is red — unless the user explicitly overrides; even with an override, the reason must be recorded in the patch note.
  • RULE-02 (MUST): Patch note must not exaggerate — Known-limitations is mandatory if any part is unfinished.
  • RULE-03 (MUST): Levels differ at the FINAL STEP, not in the checklist: every level goes through the health gate; they differ only in the final product (tag / release / PR / MR / merge). Don't tag when the user says "pr"/"mr"; don't open a PR when the user only says "push".
  • RULE-04 (MUST): medic --ci green does NOT prove the remote path works — that is the job of /fdk-uat. release/pr/mr with new capability MUST go through UAT phase 1 (canary) before proposing step 7; skip only when the diff confirms it adds no user-visible capability, and the reason must be recorded. Decision that actually burned on 2026-09-17: every prior push (including 6c839d8) went only through medic --ci/ci-local, never through real remote UAT.
  • RULE-05 (MUST): Level merge — TEST is a merge condition, not a formality: must pull the branch + run medic --ci + test FOR REAL before merging; if red, absolutely do NOT merge, leave it for the author. One-at-a-time, do not blindly batch-merge multiple PRs at once.
  • RULE-06 (MUST): PR/MR body follows the same patch note rules: user voice, Known-limitations mandatory if any part is half-done. No SHA/internal function names. NO Closes #N automatically.
  • RULE-07 (MUST): Side-effects need "yes": push/tag/release/PR/MR are hard-to-reverse (outward-facing) actions → always STOP, show the command, wait for approval; no commit/PR-body AI-attribution (per fdk).
  • RULE-08 (MUST): Do not self-install/auth gh/glab: if a tool is missing → STOP, tell the user; don't guess the host.
  • RULE-10 (MUST): Know which KIND of repo you're in before running any gate. The first line of the checklist is always 🏷 repo_role=<role> (khai báo | sổ máy | suy luận | ép tay). Source suy luận → ask the user to confirm, then record the label (repo_role.py . --set <role>; for foreign write to the MACHINE log, don't touch someone else's repo). Gates for this repo kind do NOT apply to other kinds: ci-local/capability-stamp/UAT only make sense in framework; running them in module/downstream is grading the wrong thing, omitting them in framework is a gap. Lesson 20/09/2026: /ship single-flow made shipping the engine repo require remembering a completely different process.
  • RULE-11 (MUST): READ the gate's rc before pushing. The push/tag command stands at a SEPARATE step after having printed and read rc=; do not chain gate with push using ; or pipe | tail (swallows rc). Two fires on the same day 20/09/2026: push c83b065 while medic was red, and tag v3.0.1 while install-test reported FAIL — both due to command chaining. In framework when the working tree has untracked files not yet committed (e.g. overwritten by another tool), run the gate on a CLEAN CHECKOUT of the commit (git worktree add --detach <tmp> HEAD) to avoid grading the wrong workflow.
  • RULE-12 (MUST): foreign = a guest in someone else's house. Level only pr/mr, do not push directly to the default branch; follow THEIR commit/CI rules (read CONTRIBUTING, do not apply R15 or overstack rules); do NOT install, do not write .overstack.yaml, do not add any of our config files to the repo.
  • RULE-09 (MUST): Compose, don't reinvent: use medic for health, git tag for version, gh/glab for PR/MR — this skill only coordinates the checklist.
  • Capabilities: read repo + run local gate; remote writes (push/tag/PR/MR/merge) ONLY via authenticated tool and after approval.

Failure boundaries

  • Gate red (medic --ci / ci-local / freshinstall) → blocked, print the gap + fix command, do not push.
  • UAT FAIL at any phase → failed, stop shipping, delete canary; phase 2 FAIL → remove commit from remote per /fdk-uat step 5.
  • Unsure whether the diff has "new capability" or version bump → clarify (ask user), do not decide yourself.
  • Missing gh/glab or not authenticated → blocked, tell user to install + login.
  • Level merge: PR red → do not merge that PR (partial for the whole batch), report the reason.

HOW

Main workflow

Step Type Inputs Action Outputs/exit Failure/next
W00 deterministic repo repo_role.py . --json → print 🏷 repo_role=…; source inferred then ask user + --set; choose the gate column in the "Flow by repo_role" table role + gate table invalid role → blocked
W01 deterministic repo Health gate medic --ci then python3 fdk/tools/ci-local.py (including probe freshinstall) rc 0 red → blocked
W02 effect diff, level UAT /fdk-uat phase 1 — only release/pr/mr has new capability (B02) PASS or skip reason FAIL → failed
W03 deterministic worktree Git clean: git status --short, untracked ephemeral junk clean dirty → clean then repeat W03
W04 deterministic diff Selftest/quick check of engines touched rc 0 red → blocked
W05 judgment nearest tag Version vX.Y.(Z+1) — only release (B01) suggested tag unsure of level → clarify
W06 judgment git log, scratch-log Honest Patch note / PR-MR body, Known-limitations mandatory if anything is half-done text —
W07 deterministic W01–W06 results Show checklist + proposed commands, STOP and wait for approval "yes" not approved → cancelled
W08 effect approved Execute per level; if W02 has run then UAT phase 2 right after side-effect + receipt phase 2 FAIL → remove commit

Details of each step (source of truth for W01–W08):

Describe the scope instead of remembering flags: "push" (push only) · "release" (push + tag + notes) · "pr" (push branch + GitHub Pull Request) · "mr" (push branch + GitLab Merge Request) · "merge" (gather PR/MR here → test → merge). Default = push.

Level push/release/pr/mr (PUSH OUT) runs steps 1-8 below. Level merge (GATHER IN) runs a separate branch at step 8 (see section "Merge level").

Steps 1, 3-4 apply to EVERY level. Step 2 (UAT) ONLY release/pr/mr. Step 5 (version tag) ONLY level release. Step 6 renames "written product": release→RELEASE-vX.Y.Z.md; pr/mr→ PR/MR body (same user-voice, same Known-limitations rule). push needs no text, only commit msg. Level merge writes no note (only report test results + merge/no-merge decision).

  1. HEALTH GATE — medic --ci (or python3 fdk/tools/medic.py --ci). FAIL → STOP, print the gap + fix command; do not push when red. Warn (known debt) → allow through but LIST in patch note.
    • Then python3 fdk/tools/ci-local.py (framework repo) — run ALL steps run: of every GitHub workflow locally (L4). medic is L2; there are gates ONLY in CI (search-index, skill-provenance, retrieval-eval…) — already burned 080926: medic green, push, CI red 2 jobs. Red → do not push.
    • Includes probe freshinstall (E2E): curl-install overstack into an ISOLATED EMPTY project (mktemp outside the repo) via working-tree → assert 3 pillars + harness bites + orchestration-ready. Red = the newcomer install path is broken → DO NOT push. Full version curl-github + live acceptance: bash harness/scripts/fresh-install-smoke.sh --remote.
  2. UAT gate — /fdk-uat (ONLY level release/pr/mr, NOT push as usual): medic --ci/ci-local in step 1 only installs via file:// working-tree — proves "the code on my machine works", NOT "a stranger can curl the remote and run it" (the GH#77 bug class: "docs promise what the user doesn't get", actually measured 2026-09-17 when pushing 6c839d8 without going through UAT at all).
    • Diff has NEW capability (new skill / new rule that can bite / new engine-tool) → MANDATORY run at minimum PHASE 1 (canary: push a temp branch, curl-install from that branch's own raw, verify the new capability is reachable) before moving to step 7. PHASE 2 (main-URL smoke, waiting for CDN) runs IMMEDIATELY after the user approves the real merge/tag at step 8 — not at proposal time.
    • Pure bugfix/internal-refactor diff, adds no capability the user can see → skip this step, record the reason explicitly in the step-7 checklist ("no new capability — skip UAT").
    • Unsure whether the diff counts as a "new capability" → ask the user, don't decide to skip on your own.
    • Pushing the canary is a real side-effect (pushes a temp branch to the remote) → STOP and ask the user before running, same side-effect rule as this skill. FAIL at any phase → stop shipping, report the specific error + delete the canary (not "later").
  3. Clean git: git status --short; make sure ephemeral junk (scratchpad/…) has been .gitignore + git rm -r --cached if accidentally tracked. Check that no secret/temp files slipped in.
  4. Selftest/quick check the engines touched (e.g. council.py selftest, tests related to the diff).
  5. Version: git tag --sort=-v:refname | head -1 → nearest tag vX.Y.Z → propose vX.Y.(Z+1) (patch) or minor/major if the diff warrants — ask the user if unsure of the level.
  6. HONEST patch note (USER-facing release-note voice — Claude Code style): write RELEASE-vX.Y.Z.md.
    • Format: header Version X.Y.Z: then a FLAT bullet list, one bullet per line, one idea each.
    • Voice: verb-first describing the change the USER SEES, don't dump commits/internals. Fixed <triệu chứng> — <giờ ra sao> · Added <khả năng> — <dùng để làm gì> · Removed/Changed …. Write from the reader's perspective ("you/your"), no SHA, no function names unless the user typed them directly.
    • Implicitly group by verb: Added/Changed first, Fixed after (like Claude release notes). NO group headings needed if the list is short.
    • Source: read git log <tag-cũ>..HEAD + phiên scratch-log → TRANSLATE technical commit into user-understandable sentences (1 commit may be merged/split into bullets by perceived value, not 1-1).
    • Known-limitations (MANDATORY if there is any half-done part — an advantage OVER Claude): proposal draft not yet impl, partial coverage, known medic warn → state clearly "in progress/known". Silence = exaggeration (council lesson 2026-07-03).
  7. Present checklist + propose commands to user (commit msg, push, tag/PR/MR, phase-1 UAT result or reason for skip). STOP and wait for approval.
  8. After user approval: execute according to the level. Do not run side-effect steps on your own before there is a "yes". If step 2 already ran phase-1 UAT (PASS) → after merge/tag/push, run phase-2 UAT IMMEDIATELY (main-URL smoke, wait for CDN sentinel) before telling the user "done"; if FAIL → remove the commit from remote per /fdk-uat step 5.
    • push: commit + git push.
    • release: commit + push + git tag vX.Y.Z + create 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>. Default base = repo's main branch (e.g. orca), ask if unsure.
    • mr (GitLab): commit + git push -u origin <nhánh> + glab mr create --source-branch <nhánh> --target-branch <base> --title "…" --description "…" (or -F <file>).
    • Choose tool by remote: git remote get-url origin contains github.com→gh, gitlab→glab. ship pr/ship mr forces the explicit tool; if the tool is not installed/authenticated (gh auth status / glab auth status) then STOP, tell the user to install+login (do not do it yourself).
    • Do NOT insert Closes #N/Fixes #N into the PR/MR body unless the user explicitly requests it — leave the user in control of closing issues manually.

Flow by repo_role (W00 chooses ONE column; W01–W08 above describe column framework)

Step framework (Rheinmir/setup) module (orca-graph, uiux-asset…) downstream (project with .llmwiki/) foreign (someone else's repo)
Gate medic --ci → ci-local (on a clean checkout if the tree has foreign files) commit first → ITS OWN test + eval + install-test (read each rc; install-test clones from HEAD so uncommitted means untested) project's tests + llmwiki-validate + medic (downstream mode) clean git + their test/CI
Remote UAT when the diff has new capability (B02) smoke install from remote after push (install.sh of the module into a temp HOME) no no
Version capability-stamp.py --update WHEN what reaches the client machine changes (hook, shim, installer, global tool) — even if the surface sha is unchanged it must still be bumped, otherwise a machine already on the current version will not refresh bump VERSION + constant in code + CHANGELOG per project per family
Final step push (· tag/PR by level) push → WAIT for green CI → tag + release → re-pin in framework (upstream_pin in .overstack.yaml: copy SKILL if changed → sync-skills.py → write commit/version to fdk/skills.provenance.json → ship framework) push / pr ONLY pr / mr
Forbidden installer writes to this repo (auto-reject rc 3) ci-local, capability-stamp push framework files, UAT, stamp install, write overstack config, AI-attribution against their rules

Branches

ID Kind Guard Behavior Skip / failure Rejoin
B01 conditional_required level = release W05 version + tag vX.Y.Z + release notes other level → skip W06
B02 conditional_required level ∈ {release, pr, mr} AND diff has new capability UAT phase 1 before W07, phase 2 after W08 internal bugfix/refactor → skip, write reason into checklist; unsure → clarify W03
B03 user_optional level = merge Separate GATHER BACK loop (section below), drop W02, W05–W06 Red PR → do not merge that PR summary report

Level merge (GATHER BACK — approve-then-merge incoming PR/MR)

Do not write note/tag. Skip steps 2, 5-6; replace with test-per-request loop:

  1. Choose tool by remote (as above): github.com→gh, gitlab→glab. Not authed → STOP and tell user.
  2. List open PR/MR of the repo:
    • GitHub: gh pr list --json number,title,headRefName,mergeable,isDraft
    • GitLab: glab mr list (or --output json if the version supports it). Show the list to user; if user specifies certain numbers then filter, otherwise ask whether to do all or select.
  3. For each PR/MR (one-at-a-time, no blind batching): a. Pull branch to a CLEAN LOCAL: GitHub gh pr checkout <n>; GitLab git fetch origin merge-requests/<n>/head:mr-<n> && git checkout mr-<n> (or glab mr checkout <n>). b. Run GATE + TEST on that branch: medic --ci + selftest/relevant tests for the PR diff. This is the merge condition — do NOT merge before running. c. Green → propose merge command, STOP and wait for approval, then merge: GitHub gh pr merge <n> --squash (or --merge/--rebase per repo); GitLab glab mr merge <n>. Red → do NOT merge; report the red spots + leave the PR as is for the author to fix. d. After merge: return to the original branch (git checkout <nhánh-cũ>), clean up temporary branch.
  4. Summary report: each PR/MR → merged / skipped-because-red (with reason) / skipped-because-user.

Validation and stopping

The condition to proceed is the tool's rc (medic, ci-local, fdk-uat, test), not the model's own assessment. All side-effects stop at W07 waiting for "yes"; the level merge stop waiting for approval per PR. Do not auto-retry push/tag on network error — notify the user.

Examples

  • Positive (module): in repo orca-graph type "ship release" → W00 prints 🏷 repo_role=module (khai báo) → commit → pytest tests rc 0 → evals/run.py rc 0 → tests/install-test.sh rc 0 → bump VERSION → STOP for approval → push → CI green → tag + release → remind the re-pin step at Rheinmir/setup per upstream_pin.
  • Boundary (foreign): in a repo with no stamp, no label → W00 prints 🏷 repo_role=foreign (suy luận: không có fdk/wiki, không có .harness-stamp) → ask the user to confirm → only propose ship pr, read their CONTRIBUTING, write no overstack files.
  • Positive: "ship push" after editing docs → W01 green, B02 skip (no new capability, record reason), W03–W04 green → checklist + git push → user "yes" → push.
  • Boundary/failure: "ship pr" has a new skill but ci-local red 1 job → blocked at W01, print the red job + fix command, do not push the branch, do not open a PR.
  • Boundary: "ship merge" has 2 PRs, PR #2 test red → merge #1 after approval, drop #2 with reason (partial).