# Qshipmaster

> Epic-level orchestrator for qship. Takes a Jira Epic ID, builds a topologically-sorted wave plan from its children, spawns one qship-persist.sh per ticket per wave in parallel, merges each wave into a consolidated epic branch, runs a lightweight wave-gate after each wave (migration check + targeted tests + 2 bug hunters + qbcheck, blocks only on Critical) and ONE full epic-level Phase 2 review af…

- **Type:** Skill
- **Install:** `agentstack add skill-3awny-qship-qshipmaster`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [3awny](https://agentstack.voostack.com/s/3awny)
- **Installs:** 0
- **Category:** [Productivity](https://agentstack.voostack.com/c/productivity)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [3awny](https://github.com/3awny)
- **Source:** https://github.com/3awny/qship/tree/main/templates/skills/qshipmaster

## Install

```sh
agentstack add skill-3awny-qship-qshipmaster
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

> **Issue source — `tracker = {{TRACKER_TYPE}}`** (chosen at onboarding). Follow the issue-source protocol in `$SKILLS_ROOT/qship/references/tracker-contract.md` — it defines, per tracker, how to FETCH / CHILDREN / CREATE / TRANSITION / READ-TRD. For `none`: treat `$ARGUMENTS` as the spec (pasted text or a local file path) and skip all tracker MCP calls.

# qshipmaster — Epic-level qship orchestrator

`qship` ships one ticket. `qshipmaster` ships an Epic.

This skill codifies the manual layer above `qship`: dependency-wave planning, per-wave parallel ticket execution, wave-level merging into a consolidated epic branch, wave-level Phase 2 review, and ONE consolidated PR per repo at the end.

> **Multi-repo contract:** The set of repos this orchestrator coordinates across is `$SKILLS_ROOT/qship/repos.json`. The "one PR per repo" pattern below means one PR per entry in that list (or a subset of entries actually touched by the epic). Single-repo users see exactly one PR per epic. Multi-service monorepo users see N PRs, one per affected repo. Resolve the list at orchestrator startup:
>
> ```bash
> ALL_REPOS=$(jq -r '.[].name' "$SKILLS_ROOT/qship/repos.json")
> ```

## ⛔ When this skill applies

Invoke `qshipmaster` when:
- The argument is a Jira **Epic** (`issuetype.name == "Epic"`).
- You want fully unattended end-to-end Epic delivery.

Do NOT invoke for:
- Standalone tickets (use `qship` directly).
- A single Story under an Epic (use `qship` directly — the parent SKILL.md §Epic-Mode hooks will keep the worker from opening a per-ticket PR).
- Re-running specific stages on an already-shipped Epic — read state.json directly and call the helper scripts manually.

## ⛔ Composition philosophy — DO NOT duplicate qship

`qshipmaster` is a **thin** orchestrator. It must:

1. **Compose** existing primitives, never re-implement them:
   - `qship-persist.sh` runs the per-ticket pipeline (don't reinvent it).
   - `qship-compute-context.sh` classifies the diff (don't reinvent it).
   - `require-phase3-evidence.sh` / `require-pipeline-complete.sh` enforce gates (don't bypass them).
   - `qshipcheck` decides per-ticket completion (don't second-guess it).
   - `code-review:code-review` is the final-PR review skill (don't reinvent it).

2. **Add only what's epic-specific**:
   - Wave plan construction from Jira parent/Blocked-by graph.
   - Per-wave fan-out + barrier (block until all wave tickets PASSED).
   - Wave merge into the consolidated epic branch with additive conflict resolution.
   - Wave-level (not per-ticket) Phase 2 lint/test pass on the merged diff.
   - Wave N+1 base-branch swap so worktrees see prior waves.
   - One consolidated PR per repo + final review.

3. **Persist everything** to `{{STATE_ROOT}}/epic-/state.json` so re-running the skill resumes from the last completed step.

## ⛔ Pre-flight gates

Before doing anything:

1. Verify the parent qship skill exists and the post-{{JIRA_PROJECT_KEY}}-EX01 patches are applied. The skill assumes:
   - `~/.claude/skills/qship/hooks/qship-persist.sh` honors `EPIC_MODE=true` (workers don't push, don't `gh pr create`).
   - `~/.claude/skills/qship/hooks/require-pipeline-complete.sh` recognizes wave-level Phase 3 evidence (`{{STATE_ROOT}}/epic-/wave--phase3-evidence.md`) instead of demanding per-ticket evidence for every child.
   - `~/.claude/skills/qship/hooks/require-phase3-critic.sh` parses prose-wrapped JSON (the fallback chain documented in `{{STATE_ROOT}}/epic-{{JIRA_PROJECT_KEY}}-EX01/post-epic-patches.md` §4).

   If any of these are missing, **HALT** and tell the user: *"qshipmaster requires post-{{JIRA_PROJECT_KEY}}-EX01 qship patches. See {{STATE_ROOT}}/epic-{{JIRA_PROJECT_KEY}}-EX01/post-epic-patches.md and apply patches 1, 3, 4, 5, 6 before re-running."*

2. Verify `pyenv` shims are first on PATH (post-patch §8). If `python3 --version` is  {{STATE_ROOT}}/epic-{{JIRA_PROJECT_KEY}}-EX01/qshipmaster.log 2>&1 &
disown
```

Inside Claude Code (via `/qshipmaster {{JIRA_PROJECT_KEY}}-XXX [provider=claude|codex] [reviewer=claude|codex]`):

**Argument parsing.** Split `$ARGUMENTS` on whitespace. Extract any tokens matching `provider=(claude|codex)` or `reviewer=(claude|codex)` (case-insensitive on key, lowercase value) into `PROVIDER` / `REVIEWER` and remove them from the list. Reject duplicates or invalid values. The remaining single token is the `EPIC` id and must match `^[A-Z]+-\d+$`. Defaults: `PROVIDER=claude`, `REVIEWER=claude`.

**Provider selection — Step 7 implementer.**

- `PROVIDER=claude` (default): each per-ticket worker runs Step 7 as Claude TDD against `opus[1m]` at `medium` reasoning effort (override via `QSHIP_ITER_MODEL`/`QSHIP_ITER_EFFORT`).
- `PROVIDER=codex`: each per-ticket worker delegates Step 7's inner loop to `codex exec --model gpt-5.5 -c model_reasoning_effort=high` per task. Wave-gate, Phase 2 review (unless `REVIEWER=codex`), fix-worker dispatch, merge resolution, and final PR review remain in Claude — Codex never reviews its own work in a wave-gate. See [qship/step7-codex-override.md](../qship/step7-codex-override.md).

**Reviewer selection — Phase 2 reviewer (independent of `PROVIDER`).**

- `REVIEWER=claude` (default): Phase 2 (Steps 7.5, 8, 9, 10) runs as Claude Task subagents per the documented qship pipeline.
- `REVIEWER=codex`: inside each per-ticket worker, Step 6 Plan Review (`qplan`), 7.5, 8, 9, 10 delegate their analysis to `codex exec --model gpt-5.5 -c model_reasoning_effort=high` per slot. Step 11 (Fix), 11.5 (Verification), 11.6 (`/qe2etest`), 11.7 (`/qmemory`) and the **wave-gate + epic-end Phase 2 review** stay in Claude (the wave-gate's value is precisely the diversity-of-model second opinion — running both layers on Codex collapses that). See [qship/reviewer-codex-override.md](../qship/reviewer-codex-override.md).
- Recommended combo for epics where you want diversity-of-model coverage without giving up {{COMPANY_SLUG}} implementation taste: `provider=claude reviewer=codex`. Avoid `provider=codex reviewer=codex` — same-family review on same-family code collapses the signal.

**Skill access for Codex.** Codex sees the same skill catalog as Claude via `~/.codex/skills/` symlinks pointing at `~/.agent-skills/` (same target `~/.claude/skills` points at — single source of truth, see `~/.agent-skills/README.md`). Per the [Codex Agent Skills docs](https://developers.openai.com/codex/skills), Codex reads SKILL.md frontmatter the same way Claude does, so `qcheckt`, `qclean`, `qbug`, `qbcheck`, etc. are reachable via `/skills` or `$` mentions. Run `sync-agent-skills` after creating or deleting any skill to refresh the symlink farm.

When `PROVIDER=codex`, additionally run the [`/qship` Provider pre-flight](../qship/SKILL.md#provider-selection--claude-default-vs-codex) (codex CLI installed, authenticated, gpt-5.5 reachable) AND scan all epic children for carve-out triggers (`alembic`, `migration`, `enum`, `RLS`, `tenant`, `cross-repo`, `auth middleware`). If any child matches, surface options:
> "Epic  has N children that touch sensitive areas. Options:
>  a) Rerun without `provider=codex` (safest — Claude implements everything).
>  b) Split: run the codex-safe children via `/qshipmaster  provider=codex` and the sensitive children manually via `/qship `.
>  c) Proceed anyway — codex's per-task fallback (Claude takes over after 2 failures) handles the bumps, but expect slower throughput."

Default to (a) unless the user explicitly picks (b) or (c). Don't silently assume.

**The model MUST launch this via the Bash tool with `run_in_background: true`.** Compose the env-var prefix based on `PROVIDER` and `REVIEWER` (omit either block entirely when its value is `claude`):

```
ENV_PREFIX=""
if [ "$PROVIDER" = "codex" ]; then
  ENV_PREFIX+="QSHIP_IMPL_ENGINE=codex QSHIP_CODEX_MODEL=gpt-5.5 QSHIP_CODEX_EFFORT=${QSHIP_CODEX_EFFORT:-high} "
fi
if [ "$REVIEWER" = "codex" ]; then
  ENV_PREFIX+="QSHIP_REVIEW_ENGINE=codex QSHIP_CODEX_REVIEWER_MODEL=gpt-5.5 QSHIP_CODEX_REVIEWER_EFFORT=${QSHIP_CODEX_REVIEWER_EFFORT:-high} "
fi

Bash(
  command: "mkdir -p {{STATE_ROOT}}/epic-/logs && ${ENV_PREFIX}nohup bash ~/.claude/skills/qshipmaster/hooks/qshipmaster-run.sh  > {{STATE_ROOT}}/epic-/qshipmaster.log 2>&1 & disown; echo started",
  run_in_background: true,
  description: "Launch qshipmaster orchestrator detached"
)
```

Concrete examples:

```bash
# /qshipmaster {{JIRA_PROJECT_KEY}}-EX01                           — all Claude (default)
nohup bash …/qshipmaster-run.sh {{JIRA_PROJECT_KEY}}-EX01 …

# /qshipmaster {{JIRA_PROJECT_KEY}}-EX01 provider=codex            — codex implements
QSHIP_IMPL_ENGINE=codex QSHIP_CODEX_MODEL=gpt-5.5 QSHIP_CODEX_EFFORT=high nohup …

# /qshipmaster {{JIRA_PROJECT_KEY}}-EX01 reviewer=codex            — claude implements, codex reviews Phase 2
QSHIP_REVIEW_ENGINE=codex QSHIP_CODEX_REVIEWER_MODEL=gpt-5.5 QSHIP_CODEX_REVIEWER_EFFORT=high nohup …

# /qshipmaster {{JIRA_PROJECT_KEY}}-EX01 provider=codex reviewer=codex     — discouraged (see "Reviewer selection")
QSHIP_IMPL_ENGINE=codex … QSHIP_REVIEW_ENGINE=codex … nohup …
```

The env vars travel through `nohup` → `qshipmaster-run.sh` → its inner `claude --print` worker invocations → into each `qship-persist.sh` child. `~/.claude/agents/qship-worker.md` §Step 7 reads `$QSHIP_IMPL_ENGINE` (routes to `~/.claude/skills/qship/step7-codex-override.md`), and the reviewer-engine block reads `$QSHIP_REVIEW_ENGINE` (routes Steps 6, 7.5, 8, 9, 10 to `~/.claude/skills/qship/reviewer-codex-override.md`). No change to the shell scripts is required — environment inheritance handles it.

Why this matters: qshipmaster orchestrates 6-wave epics over ~10-15 hours. Foreground execution pins the entire user session for that duration — the Bash tool's 10-minute timeout fires before the first wave's worker finishes, and even if a hook bumps the timeout, the user can't reclaim their conversation slot. The first qshipmaster v2 deployment shipped without this rule and bit {{JIRA_PROJECT_KEY}}-EX07's first launch in May 2026 — see [qship memory: feedback_qshipmaster_must_background](file://{{USER_HOME}}/.claude/projects/-Users-{{LOCAL_DB_USER}}-work-{{GH_ORG}}-{{COMPANY_SLUG}}-codebase/memory/feedback_qshipmaster_must_background.md).

After launch, the model polls `{{STATE_ROOT}}/epic-/state.json` periodically (via `/loop` or `ScheduleWakeup`) for `status: shipped` or `status: blocked` — never via `tail -f` or a blocking wait.

## Model + effort env vars — single reference

Every `claude --print` and `codex exec` dispatch in qship / qshipmaster can be tuned via env vars. The defaults below were chosen to follow one rule of thumb: **plan/design = `xhigh`, review = `high`, mechanical work = `medium`, narrow text ops = the model's own default**. Higher leverage on a single decision → stronger model + more reasoning depth.

### Per-ticket pipeline (qship — per-ticket worker)

| Role | Site | Model var | Default model | Effort var | Default effort |
|---|---|---|---|---|---|
| Step 5 — Plan writing (`superpowers:writing-plans` subprocess) | `qship-worker.md` §5 | `QSHIP_PLAN_MODEL` | `opus[1m]` | `QSHIP_PLAN_EFFORT` | `xhigh` |
| Step 6 — Plan review (`qplan` subprocess, when `reviewer=claude`) | `qship-worker.md` §6 | `QSHIP_PLAN_REVIEW_MODEL` | `opus[1m]` | `QSHIP_PLAN_REVIEW_EFFORT` | `high` |
| Steps 7–7.5 — Implementation / cleanup / simplify (worker iter loop) | `qship-persist.sh:162-163` | `QSHIP_ITER_MODEL` | `opus[1m]` | `QSHIP_ITER_EFFORT` | `medium` |
| `/qshipcheck` verdict reader | `qship-persist.sh:177` | `QSHIP_CHECK_MODEL` | `claude-haiku-4-5-20251001` | n/a | n/a |
| Step 7 — Implementation **with `provider=codex`** (Codex CLI subprocess per task) | `step7-codex-override.md` | `QSHIP_CODEX_MODEL` | `gpt-5.5` | `QSHIP_CODEX_EFFORT` | `high` |
| Phase 2 review **with `reviewer=codex`** (Steps 6 plan-review, 7.5 simplify, 8 reviewers, 9 hunters, 10 qbcheck via Codex) | `reviewer-codex-override.md` | `QSHIP_CODEX_REVIEWER_MODEL` | `gpt-5.5` | `QSHIP_CODEX_REVIEWER_EFFORT` | `high` |

### Epic pipeline (qshipmaster)

| Role | Site | Model var | Default model | Effort var | Default effort |
|---|---|---|---|---|---|
| Wave-plan construction (Jira fetch + DAG build) | `qshipmaster-plan.sh:52` | `QSHIP_PLAN_MODEL`* | `opus[1m]` | `QSHIP_PLAN_EFFORT`* | `xhigh` |
| Wave-batch + epic Phase 2 review (consolidated review across merged tickets) | `qshipmaster-run.sh:443` | `QSHIP_PHASE2_REVIEW_MODEL` | `opus[1m]` | `QSHIP_PHASE2_REVIEW_EFFORT` | `high` |
| Phase 2 fix iterations (apply MUST-FIX findings, black/isort/flake8/pytest) | `qshipmaster-run.sh:642, 734` | `QSHIP_FIX_MODEL` | `opus[1m]` | `QSHIP_FIX_EFFORT` | `medium` |
| Epic-end Phase 3 scenario matrix design (`superpowers:brainstorming`) | `qshipmaster-deliver.sh:321` | `QSHIP_EPIC_PHASE3_DESIGN_MODEL` | `opus[1m]` | `QSHIP_EPIC_PHASE3_DESIGN_EFFORT` | `xhigh` |
| Epic-end Phase 3 execution (live `/qe2etest` against scenario matrix) | `qshipmaster-deliver.sh:359` | `QSHIP_EPIC_PHASE3_EXEC_MODEL` | `opus[1m]` | `QSHIP_EPIC_PHASE3_EXEC_EFFORT` | `high` |
| Step 13 PR primary review (`code-review:code-review` skill on the consolidated PR) | `qshipmaster-deliver.sh:161` | `QSHIP_PR_REVIEW_MODEL` | `opus[1m]` | `QSHIP_PR_REVIEW_EFFORT` | `high` |
| Step 13 PR external-family critic (engine selection) | `qshipmaster-deliver.sh:165` | `QSHIP_CRITIC_ENGINE` | (gated by `QSHIP_REVIEW_ENGINE`) | — | — |
| Step 13 critic — codex branch (only when `reviewer=codex` opted in) | `qshipmaster-deliver.sh:230` | `QSHIP_CODEX_CRITIC_MODEL` | `gpt-5.5` | `QSHIP_CODEX_CRITIC_EFFORT` | `high` |
| Non-additive merge auto-resolver | `qshipmaster-merge-wave.sh:196, 205` | (hardcoded) | `sonnet` | (none) | (default) |
| Cross-epic memory extractor (3-line `ROOT_CAUSE`/`FIX`/`RULE` distillation) | `qshipmaster-learn.sh:46` | (hardcoded) | `haiku` | (none) | (default) |

*`QSHIP_PLAN_MODEL` / `QSHIP_PLAN_EFFORT` are shared between the per-ticket Step 5 plan subprocess (worker side) and the qshipmaster wave-plan construction (orchestrator side). Same operation type (planning), same defaults, one set of knobs.

### Engine-selection flags (boolean opt-ins, not model/effort)

| Flag | Default | Effect |
|---|---|---|
| `QSHIP_IMPL_ENGINE=codex` | unset | Step 7 implementation routes to `codex exec` instead of Claude TDD. Set automatically when user passes `provider=codex` to `/qship` or `/qshipmaster`. |
| `QSHIP_REVIEW_ENGINE=codex` | unset | Phase 2 review (Steps 6, 7.5, 8, 9, 10) routes to `codex exec`. Set automatically when user passes `reviewer=codex`. ALSO gates the Step 13 critic to use codex. |
| `QSHIP_CRITIC_ENGINE={codex,sonnet}` | unset | Forces the Step 13 critic engine regardless of `QSHIP_REVIEW_ENGINE`. Use to explicitly pin one engine for the critic step. |

### When to override

- **Cost-conscious dev runs:** set `QSHIP_ITER_EFFORT=low` and `QSHIP_PLAN_EFFORT=high` (down from xhigh) for cheap iteration. Bump back to defaults before the run that actually ships.
- **Particularly twisted epic dependency graph:** keep `QSHIP_PLAN_EFFORT=xhigh` (default) but consider `QSHIP_PHASE2_REVIEW_EFFORT=xhigh` if early waves shipped subtle cross-wave bugs.
- **Codex CLI unavailable but you want different-family review:** keep the defaults — sonnet is the fallback for both Phase 2 review and the Step 13 critic.

## Invariants (formal, hook-enforceable)

These are the contract-level invariants the supervisor and orchestrator both enforce. Encoded here so future changes to either layer can grep-verify they're not silently relaxed. Each invariant maps to a concrete check; the FINAL VERIFICATION step (supervisor step 7) re-checks all of them on `status: shipped`.

| # | Invariant | Concrete check |
|---|---|---|
| I1 | Wave N+1 MUST NOT spawn workers until Wave N's `wave-N-phase23-evidence.md` exists AND contains all 4 marker words (qsimplify, qcheck, qbug, qbcheck) AND contains a `## Phase 3 — /qe2etest evidence` section with a `/qe2etest` PASS verdict

…

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [3awny](https://github.com/3awny)
- **Source:** [3awny/qship](https://github.com/3awny/qship)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** yes
- **Filesystem access:** yes
- **Shell / process execution:** yes
- **Environment & secrets:** yes
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-3awny-qship-qshipmaster
- Seller: https://agentstack.voostack.com/s/3awny
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
