---
name: stage
description: Run a local test stage or personal cloud dev stage with --live.
---

**Host-native invocation:** Claude `/mmi:stage` · Codex `$mmi:stage` · jervcode `/stage` · Hermes skill_view. A backticked `/name` in this doc names the matching workflow (this skill or a sibling), not a literal command.

# /stage — local test environment

A throwaway **local** environment (dev server or local stack, plus Playwright where used) for the current branch. Off the promotion train: no version effect, no deploy. It lives in a gitignored workspace, force-kills the previous stage in this worktree before starting, and is decommissioned when done.

`/stage` is the normal path for previews, smoke tests and Playwright targets; a request to run or preview the app is enough to start it. A manual dev-server command is fine for a bounded diagnostic or a requested bypass; say why. If the stage path fails, diagnose from `mmi-cli stage --json`, `tmp/stage/state.json` and process/port/container evidence, and file Hub/org-default friction instead of silently working around it.

A `tenant-container` repo with `docker-compose.yml` and a Hub registry `portRange` needs no committed config: `mmi-cli stage` derives `docker compose build --no-cache`, `docker compose up -d`, a free port from the range, and the local URL (e.g. `http://127.0.0.1:3700/`). Board, deploy, secret and project facts live in the Hub registry, not a repo file. For vault/env passthrough or build-time secrets, read [reference.md](reference.md).

## Step 0 — inspect the plan

```bash
mmi-cli stage --json
```

`source` is `derived`/`local`/`none`; when derived, `url` is the local URL. `none` means no usable recipe or derivable default; the message names the missing fact (deployModel, `docker-compose.yml`, or registry `portRange`; `.env.example` is not required). A missing `portRange` adds `recovery` with `mmi-cli stage port-range <owner/repo>`: assign the block, re-run `/stage` (the Hub registry itself is fine; stage just cannot pick a collision-safe port).

On `deployModel: vercel` the receipt carries `preview` (latest Vercel Preview `state`, `url` from GitHub Deployments); report that URL as the branch preview. No `preview.deployment` = branch unpushed or Vercel GitHub app not connected. There is no box stage on vercel: `--live` refuses.

## Step 1 — run

A stage is per worktree: the CLI stops this worktree's previous stage, runs `stage.build`, starts `stage.up`, records `tmp/stage/state.json` (cwd, branch, commit), picks a free port from the registry range (skipping sibling worktrees' ports), and polls `stage.healthUrl` if set. Sibling worktrees keep their own stages; no need to stop one first. Recipes run in Bash (Git Bash on Windows, or an absolute `SHELL` path to its `bash.exe`; no cmd fallback), so convert `set VAR=value` or `$env:VAR` recipes to Bash or Node. For `jervaise`, continuity keys on branch; use a distinct North Star slug per parallel grind.

```bash
mmi-cli stage run --apply
mmi-cli stage run --apply --port 5180            # pin a port
mmi-cli stage run --apply --timeout-ms 120000    # slow stacks
```

All artifacts (build output, screenshots, traces, local DB files) stay under untracked `tmp/stage/`. When grinding or issue acceptance criteria exist, read [smoke.md](smoke.md) and run its post-smoke panel before teardown.

## Step 2 — stop when done

```bash
mmi-cli stage stop --apply
```

Stop when work is done, before switching context, or before another stage; leave it up if the user wants the preview, and report that. For the Docker Compose default, stop runs `docker compose down` from the original working directory, re-fetching the declared dev runtime secrets so `${POSTGRES_PASSWORD:?}` and `${PORT:?}` interpolate (secrets never come from the state file); a vault-native repo with no `.env` gets `PORT` defaulted to the bound port.

For a personal cloud dev stage (`--live`), read [live.md](live.md) before offering, applying or tearing it down.

## Step 3 — report

Stage URL, what's running, workspace path (`tmp/stage/`), teardown command. For Playwright output placement, extra services, or stale Docker/env troubleshooting, read [reference.md](reference.md) Notes.

## Retro

If this skill's instructions misfired (process only, e.g. a teardown that left a port bound), file one lesson (one per run; if the call fails, note it and continue):
`mmi-cli learning skill-lesson --skill stage --title "<what misfired>" --body "<what; evidence; proposed amendment>"`
