| name | mega-ship |
| description | The fourth stage of the mega chain (mega-brainstorm → mega-plan → mega-build → mega-ship). Use AFTER a build is complete — same session or fresh — to take the branch from 'QA-passed' to 'shipped': live-test the running app, deploy to the dev environment, smoke-test the deployment, then dispose of the branch (solo-dev repo ⇒ merge to main and push; team repo ⇒ push branch and open a PR). Replaces mega-build's terminal branch-disposition question — arriving from mega-build close-out, this skill IS the disposition. Trigger on 'mega-ship', 'ship it', 'ship this', 'deploy and merge', 'take it to dev', arrival from mega-build. Do NOT trigger for production deploys (dev environment only — prod release is a human act), for builds whose QA gates have not passed, or for deploying someone else's uncommitted work. |
Mega-Ship: Live Test → Dev Deploy → Smoke → Merge or PR
Take a completed build across the last mile. Every stage is a gate: red anywhere means the branch does not move. The user sees one disposition decision, not a deploy log.
This skill instructs you to call the Workflow tool — that satisfies its opt-in requirement.
- NEVER ship a branch whose full test suite is red or whose working tree is dirty.
- NEVER invent a deploy command. Discovered and confirmed, or asked — no third option.
- NEVER merge or push past a failed dev smoke. A deploy that "probably works" is a halt, not a ship.
- NEVER push to a remote without one explicit user confirmation of the disposition (pre-authorization in the invocation — "ship it, no questions" — counts).
- NEVER deploy to anything that is not the dev environment. Prod is out of scope by construction.
Checklist
TodoWrite task per item, in order:
- Pre-flight — parallel gate fan-out (workflow below)
- Live test — run the actual app, drive real paths
- Discover deploy — find the dev-deploy command; confirm it
- Deploy to dev — inline, serial, watched
- Dev smoke — parallel smoke fan-out against the deployment
- Disposition — solo-dev detection → merge+push or branch+PR
- Close out — HUMAN_REVIEW.md entry, rollback note, cleanup
1. Pre-flight
Record BASE_SHA (merge-base with main) and HEAD. Then fan out read-only gates:
// args: { suiteCmd, lintCmd, baseSha }
const GATE = { type: 'object', required: ['pass', 'detail'], properties: {
pass: { type: 'boolean' }, detail: { type: 'string' } } }
const gates = await parallel([
() => agent(`Run the full test suite: ${args.suiteCmd}. Report pass/fail with failing test names.`,
{ label: 'gate:suite', phase: 'Pre-flight', schema: GATE, agentType: 'runner' }),
() => agent(`Run lint/typecheck: ${args.lintCmd}. Report pass/fail with first errors.`,
{ label: 'gate:lint', phase: 'Pre-flight', schema: GATE, agentType: 'runner' }),
() => agent(`Inspect the diff ${args.baseSha}..HEAD for accidental ship-blockers ONLY:
committed secrets/keys, debug flags left on, hardcoded localhost/dev URLs in runtime paths,
TODO-before-ship markers. Not a code review — mega-build already did QA. Refute-by-default.`,
{ label: 'gate:blockers', phase: 'Pre-flight', schema: GATE }),
() => agent(`Verify git state: working tree clean, current branch is not main/master,
all work committed. Report branch name and cleanliness.`,
{ label: 'gate:git', phase: 'Pre-flight', schema: GATE, agentType: 'runner' })])
return { failures: gates.filter(g => g && !g.pass).map(g => g.detail) }
Any failure → fix loop (max 2 attempts via dev agent), then HALT and surface. A dirty tree is surfaced verbatim, never auto-committed — those changes may not be yours to ship.
2. Live test
Unit-green is not alive. Run the actual app the way a user reaches it (dev server, CLI invocation, TUI — whatever the project is) and drive the paths this build touched plus one untouched control path. Prefer the project's run/verify skill if one exists.
Judge against the plan's acceptance criteria (.ai/plan/<name>/ if arriving from mega-build), not against "no stack trace." Broken → fix loop (max 2), then HALT. Record what was driven — it becomes the HUMAN_REVIEW entry.
3. Discover deploy
Look, in order: .ai/plan/<name>/*-context.md deploy notes → playbook (pb <topic> for this project/stack) → package.json scripts / Makefile / justfile targets matching deploy·dev·stage → CI configs (.github/workflows, etc.) for the dev-deploy job → project README.
- Exactly one candidate → state it and the target environment; proceed unless the user objects.
- Zero or several → AskUserQuestion with the candidates found. Never guess between two deploy commands.
- Deploy is CI-triggered on push → note it: deploy and disposition collapse into one step; smoke happens after the push, and the disposition confirmation (gate above) happens BEFORE it.
4. Deploy to dev
Inline and serial — deploys are state-changing and their failures need judgment, not retries. Run the confirmed command, watch the output, capture the deployed version/sha and the dev URL or endpoint. Before running, note the rollback path (previous version tag, rollback script, revert-and-redeploy). Deploy fails → diagnose inline; do not blind-retry a state-changing command.
5. Dev smoke
Fan out against the deployment, not the local checkout:
// args: { devUrl, deployedSha, flows: [{name, probe}] } — flows from the plan's acceptance criteria
const results = await parallel(args.flows.map(f => () =>
agent(`Smoke-test against the DEV deployment at ${args.devUrl} (expect version ${args.deployedSha}).
Flow: ${f.name} — ${f.probe}. Use real requests (curl / headless browser / CLI against dev).
Report pass/fail with the actual response observed.`,
{ label: `smoke:${f.name}`, phase: 'Smoke', schema: GATE, agentType: 'runner' })))
Always include: health/version endpoint confirms the new sha is what's serving; one core flow that predates this build (regression canary); each new flow this build added. Any failure → the branch does not move. Fix → redeploy → re-smoke (max 2 cycles), then HALT with the failing probe verbatim.
6. Disposition
Detect solo-dev — all three, cheap:
git shortlog -sn --since='6 months ago' → one human author (bots excluded)?
gh pr list --state merged --limit 5 → is there a live PR convention?
gh api repos/{owner}/{repo} --jq .permissions / branch protection on main?
One author + no PR convention + no protection ⇒ solo-dev: merge to main locally (--no-ff, message cites the plan name), push main, delete the branch. Otherwise ⇒ team: push the branch, gh pr create with a body of plan summary + verify commands + dev deployment evidence (sha, smoke results).
Signals conflicting ⇒ ask. Then ONE AskUserQuestion with the detected disposition as the recommended option (merge+push / branch+PR / stop here) — skipped only on explicit pre-authorization in the invocation. This is the last gate before the remote changes.
7. Close out
- HUMAN_REVIEW.md — feature, date, session-id, merge/PR ref, deployed sha + dev URL, the live-test paths driven, runnable smoke commands.
- Rollback note in the same entry — the exact command to restore the previous dev version.
- Cleanup — tasks.md final state if arriving from mega-build; local branch deleted (solo path);
todone done if the shipped task is tracked.
Halts
- Gate failure that survives 2 fixes → stop, surface the failing gate's output verbatim, offer resolutions via AskUserQuestion.
- Deploy target ambiguity → ask; never split the difference between environments.
- Smoke reveals a design-level fault (not a deploy artifact — the feature itself is wrong on real infrastructure) → this is a build problem wearing a ship costume: route back to mega-build with the evidence, or to intent-shape if the assumption underneath died.
Anti-patterns
- Smoke theater — probing localhost, or asserting only "HTTP 200" when the flow has observable behavior. Smoke hits the DEV deployment and asserts the thing the flow is for.
- Confirmation creep — asking at every stage. The gates are automatic; the ONE question is disposition.
- Optimistic merge — merging while a smoke failure is "probably flaky." Flaky is a halt with evidence, not a waiver.
- Deploy improvisation — assembling a deploy command from README fragments because discovery came up empty. Empty discovery is a question, not a puzzle.
- Scope inflation — "while we're shipping, prod too?" No. Dev is the ceiling; prod release is a human act outside this skill.