---
name: bootstrap
description: Provision an org repo with board, registry, rules, and plugin setup.
---

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

# /bootstrap — provision a repo into the org

One-time onboarding, run from `MMI-Hub` by the master (who holds the GitHub App key). It uses the App installation token, no per-repo checkout. The repo must already be named `<CATEGORY>-<PascalName>`.

Read [reference.md](reference.md) for create vs upgrade, seed refresh, propagation rollback, or new topology values.

## Step 0 — confirm the four axes before any mutation

Before Step 0a, state a recommended default per axis and confirm all four with Jervaise through the orchestrator; never default silently.

- **`class`** — `deployable` (full or direct train) · `content` (trunk, `main` only); sets the branch model.
- **`project-type`** — `web-app`, `cli-tool`, `worker`, `desktop-app`, `desktop-game`, `mobile-app`, `content`…; sets Hub services.
- **`deploy-model`** — `tenant-container`, `none`, `content`…; sets the deploy path.
- **`release-track`** — `full` (development·rc·main) · `direct` (development·main) · `trunk` (`main`); sets the branch set.

A **deployable** repo also needs gate runtime (`node` default, `python` for a Python app), check command and working directory: `--var GATE_RUNTIME=`, `GATE_CMD=`, `GATE_WORKDIR=`, and `GATE_CACHE_DEP_PATH=` for a non-root Node lockfile.

**Content/trunk**: `main` only, no `rc`, no `gate.yml`, no product required-check ruleset, `projects.json` entry with `branch: main`.

Apply flags carry the confirmed values; Step 0b creates the repo on the track's default branch.

## Step 0a — no-mutation verifier

```bash
mmi-cli devops bootstrap verify "$OWNER/$REPO" --class deployable --json   # or --class content
```

Re-run after Step 7. Ready = all green, or a named manual-only item Jervaise accepted. A deployable report ends with the train doctor verdict per lane (`release`, plus `rcand` on full track); the lane you are not standing on reports `branch-mismatch`; if that is its ONLY finding, verify prints `NOT EVALUATED from this branch` and passes: run `mmi-cli devops train doctor --lane <lane> --json` from that lane's branch. Any other blocker, or an unread origin, is red.

Two FAILs are unrun steps or API lag, never acceptable end states:
- `branch protection exists` / `push allowlist configured` — `bootstrap apply --execute` applies the allowlist (Step 2b). Security controls: green, or an accepted manual item, before the bootstrap is complete.
- `README has Agent context section — README.md not readable via API` on a README that has it — API lag after a merge; re-run.

For board selection/creation, access, gate setup or manual provisioning of a new repo, read [reference.md](reference.md) Steps 0b–5; upgrades use the apply path below.

## Step 6 — register Hub META

No product repo control-plane file; `mmi-cli` resolves state from the Hub registry. For flag combinations or an MM-Work module, read [reference.md](reference.md) first. Apply with the board variables discovered earlier (or `mmi-cli oracle org project set`):

```bash
mmi-cli devops bootstrap apply "$OWNER/$REPO" --class deployable \
  --project-type web-app --deploy-model tenant-container --execute \
  --var PROJECT_OWNER="$PROJECT_OWNER" --var PROJECT_NUMBER="$PROJECT_NUMBER" \
  --var PROJECT_ID="$PROJECT_ID" --var STATUS_FIELD_ID="$STATUS_FIELD_ID" \
  --var STATUS_TODO="$STATUS_TODO" --var STATUS_IN_PROGRESS="$STATUS_IN_PROGRESS" \
  --var STATUS_IN_REVIEW="$STATUS_IN_REVIEW" --var STATUS_DONE="$STATUS_DONE"
```

`tenant-container` repos need a `docker-compose.yml` and Dockerfile building from the shipped source archive (no prebuilt `dist/`); bootstrap seeds both from `skills/bootstrap/seeds/`. The seeded compose is fileless: label `mmi.runtime-env: "true"`, no `env_file`, loopback-only port; deploy injects the stage's vault values (`DEPLOY#<stage>.noEnvFile: true`), so the app reads plain env vars, never self-loads SSM, never ships a `.env`. For an MM-Work module or non-suite web-app with OAuth META, read [reference.md](reference.md) before the first CI/deploy or OAuth provisioning.

**Stage port block:** `tenant-container` and `solo-container` need Hub registry `portRange` (`bootstrap verify` fails without it). `bootstrap apply --execute` assigns it; for older META run `mmi-cli stage port-range <Repo>` (idempotent). Use `$STAGE_PORT` in `stage.up`/`healthUrl`.

## Step 7 — org-managed .gitignore block

The `managed-block` seed (`skills/bootstrap/seeds/manifest.json`) merges org-universal ignores into `.gitignore` in place, keeping the repo's own lines.

## Step 8 — report

Repo, default branch, ruleset, push allowlist, Environments per track, project (info, Status lanes, Labels field verified), secrets set (names only), access, plugin, docs, registry META, issue templates, org App credentials, `.gitignore` block, the final `bootstrap verify` result, and for a deployable repo the train door from the repo's checkout on `development`:

```bash
mmi-cli devops train doctor --lane release --repo "$OWNER/$REPO" --json   # full track: also --lane rcand
```

`ready: true` is the train-readiness proof (findings: `docs/Guides/train-troubleshooting.md#<code>`). A `bootstrap-gap` finding names the missing apply row (blocker: train branch absent on origin; warning: stage with no required status check). Read warnings too: `ready: true` alone does not prove the product ruleset is active.

## Retro

If this skill's instructions misfired (process only), file one lesson (one per run; if the call fails, note it and continue):
`mmi-cli learning skill-lesson --skill bootstrap --title "<what misfired>" --body "<what; evidence; proposed amendment>"`
