---
description: "First-run setup wizard: keychain token discovery, Git Identity onboarding, and pipeline preparation. Use when the pipeline is being set up for the first time, or tokens and git identity need onboarding."
description-tr: "İlk kurulum sihirbazı: keychain token keşfi, Git Identity kaydı ve pipeline hazırlığı."
argument-hint: "[jira-keys | hosts | accounts]  -  optional; no argument runs the whole onboarding"
parameters: [{"name":"section","kind":"enum","enum":["jira-keys","hosts","accounts"]}]
gui: form
destructive: false
confirm: none
allowed-tools: Bash, Read, Write, AskUserQuestion, WebFetch
---

## Gotchas

- A token is read and written only through `~/.claude/lib/credential-store.sh`. Never echo it, never pass it on argv, never paste it back to the user.
- A mapping in `keychainMapping` with no value in the store is not onboarded: offer the Token Save Flow, do not ask for the secret in chat.
- Hosts are stored without a scheme (`jira.example.com`); the callers add `https://`.
- Publishing tokens differ by registry: npmjs takes an npm token, GitHub Packages a classic PAT with `write:packages` from the account that owns the scope.

## Step 0 - What is actually wrong

```bash
node "$HOME/.claude/scripts/doctor.mjs"
```

Run it before the first question and again at the end. The first run turns setup from a fixed script into a targeted one: there is no point asking for a token that is already mapped and answering. The second run is the only honest way to end - "setup complete" is a claim, and the doctor's exit code is the evidence for or against it. Report both in `outputLanguage`, and if the second run still shows a BLOCK, say so plainly rather than closing on the word "complete".

## Setup (Credential Store + Git Identity Onboarding)

Uses `$HOME/.claude/lib/credential-store.sh` to read/write secrets in the macOS Keychain (`security`, built in). The pipeline is macOS only (ADR-0012).

Run `~/.claude/lib/credential-store.sh doctor` first  -  it prints the platform and whether the backend is usable.

The shell driver auto-delegates `get`/`set`/`delete` to the deterministic Python helper at `$HOME/.claude/scripts/keychain.py` (Python 3 stdlib only, no external deps). The Python path writes both `-l` (label) and `-s` (service) attributes so items are findable regardless of how callers look them up. Set `KEYCHAIN_DELEGATE=0` to force the raw shell path.

### Step 0  -  Language Selection

Ask BEFORE anything else, so every subsequent setup prompt and the rest of the pipeline honour the choice. The pipeline has two language axes:

| Axis | What it controls | Configurable? |
|---|---|---|
| `promptLanguage` | Picker chrome only: the `AskUserQuestion` `header` chip, host error UI, internal contract identifiers | **No  -  fixed to `en`.** The chip is capped at 12 chars, which most Turkish equivalents overflow. |
| `outputLanguage` | The assistant's non-interactive explanations, status updates, error messages, and pipeline-generated reports rendered to the user | Yes  -  set here and changeable later via `/multi-agent:language <en\|tr>` |

`promptLanguage` is seeded as `"en"` and never offered to the user. **External payloads always stay English** (commits, PR titles/bodies, Jira comments, wiki content, reviewer/triage prompts, agent-log.md).

#### Step 0 prompt  -  `outputLanguage`

The setup wizard asks one question (English UI per skill-prompt rules):

```
Which language should the assistant use for ITS OWN explanations,
status updates, and pipeline-generated reports?

  1) English
  2) Türkçe

Select (1-2):
```

**Rules:**

- **Already set in prefs** → skip silently. User can change later with `/multi-agent:language <en|tr>` or `/multi-agent:language output <en|tr>`.
- **New value** → validate against the schema enum (`en`, `tr`), write `prefs.global.outputLanguage` via atomic rename, force `prefs.global.promptLanguage = "en"`, then echo a confirmation in the just-chosen `outputLanguage`:
  - `en`: `outputLanguage=<Y>. promptLanguage stays "en". External payloads (PR bodies, Jira comments, reviewer prompts) stay English regardless.`
  - `tr`: `outputLanguage=<Y>. promptLanguage "en" sabit. Dış çıktılar (PR açıklamaları, Jira yorumları, review istemleri) her durumda İngilizce kalır.`
- **Unknown input** → re-ask once, then abort setup with a hint pointing to `/multi-agent:language`.

From this point forward, every prompt in Steps 1-6 below follows the canonical
per-field matrix in `$HOME/.claude/multi-agent-refs/rules.md` ("Language Application"):
`question`, `label` and `description` render in `outputLanguage`; `header` stays
English. Wizard status and the post-setup summary follow `outputLanguage`. External
payloads remain English.

> `promptLanguage` governs only the button and chip chrome, never the question a
> user reads. Rendering a whole prompt in English "per the fixed
> `promptLanguage`" contradicts the matrix above and produces half-English
> pickers on Turkish runs.

### Step 0.5  -  Dependency check

```bash
~/.claude/lib/credential-store.sh doctor
command -v pdftotext >/dev/null 2>&1 || echo "pdftotext: MISSING"
```

| Output | Action |
|--------|--------|
| `Backend: ✓` | Continue to Step 1 |
| Platform `unknown` or `ERR: macOS only` | Halt  -  the pipeline runs on macOS only (ADR-0012). |
| `pdftotext: MISSING` | Advisory. Print `brew install poppler`, continue. `.docx` needs nothing. |

### Credential Key Naming Rule

- **New token** (first-time creation in Step 3): ALWAYS use the standard key name (`${USER}_Jira_Access_Token`, etc.). This ensures cross-machine consistency.
- **Existing token** (discovered in Step 1): NEVER rename or migrate. Map the discovered key name as-is into `keychainMapping`. The mapping layer abstracts the actual key name  -  the pipeline never reads the credential store directly by standard name.

### Step 1  -  Dynamic Credential Discovery

Full procedure: `$HOME/.claude/multi-agent-refs/setup/discovery.md`. Read it for Step 1.

### Step 2  -  Show Discovery Summary + Save Mapping

Show results grouped by status:

```
Keychain Token Discovery (${USER}):

  Jira               -> ${USER}_Jira_Access_Token
  GitHub             -> ${USER}_Github
  Figma              -> ${USER}_Figma_Access_Token
  Firebase           -> ${USER}_Firebase_Access_Json
  Confluence         -> MISSING
  Jenkins            -> MISSING
  ---
  Git identities: check preferences file (see Step 3)

  Mapped: 8 | Missing: 4
```

Non-standard key names are perfectly valid  -  the mapping handles resolution. No rename or migration is offered.

Save the resolved mapping to `prefs.global.keychainMapping`  -  every service ID gets an entry, the discovered key name verbatim or `null` when nothing was found:

```json
{ "jira": "${USER}_Jira_Access_Token", "github": "${USER}_Github", "confluence": null, "...": "..." }
```

Full key list and shape: `$HOME/.claude/multi-agent-refs/keychain.md`.

`null` = not mapped (missing or skipped). Pipeline phases read this mapping to retrieve tokens dynamically  -  never hardcoded key names.

### Step 2.7  -  Operational reporting

Ask (in `outputLanguage`), and proceed only on an explicit yes:

```
Do you have an operational-reporting token from your admin?
[ Paste token / Skip ]
```

On paste, store it in the credential store ONLY - never in a file, prefs value,
git or any synced tree - under the standard per-user name, so it is revocable on
its own:

```bash
pbpaste | ~/.claude/lib/credential-store.sh set "${USER}_Usage_Ingest_Token" -
pbcopy < /dev/null
```

Then, **whether they pasted or skipped**, run:

```bash
node "$HOME/.claude/scripts/usage-register.mjs" --json
```

If its JSON line says `"needsPersonalAccount":true`, offer once: `gh auth login`,
or an SSH key on the personal account (the "Personal account" step in
`$HOME/.claude/multi-agent-refs/features/usage-reporting.md`).

It maps whatever token exists and switches reporting on, and requests a
per-machine write-only one when none resolves, so a machine that runs setup and
never runs update still reports. What is sent, what never is, and
`usageLog.optOut`:
`$HOME/.claude/multi-agent-refs/features/usage-reporting.md`.

### Auto-learned fields (no setup step needed)

**Jira Project Key**: auto-learned from pipeline usage. User runs `/multi-agent ABC-123` → `ABC` is extracted and saved to `prefs.global.defaultJiraKey` (first ever) and `prefs.projects[{project}].jiraProjectKeys` (per-project). Multiple keys accumulate over time  -  most recent first, deduped. Phase 0 Step 1 (Parse Input) handles extraction.

**Git Identity**: auto-learned from token onboarding. Each token saved in Step 3 triggers an identity prompt (see Token Save Flow Step C). No separate identity setup step.

### Step 3  -  Interactive token onboarding (for missing tokens)

Git identities are NOT asked as a separate step. They are learned when tokens are added via the Token Save Flow below. Each token save triggers an identity prompt:

```
Token saved. Which git identity uses this token?

  Existing identities:
    1. Ada Lovelace <ada@example.com>
    2. Ada Lovelace <ada@personal.com>
    n. Create new identity

  Select:
```

- First token ever → no existing identities → asks name + email → creates identity → maps token
- Subsequent tokens → pick existing or create new → maps token to that identity's `servicePatMap`
- Multiple accounts per platform supported (e.g. two GitHub tokens, each mapped to a different identity)
- Identity is stored in `prefs.global.identities[]`, token-to-identity binding in `identity.servicePatMap`

**Legacy compatibility**: If `prefs.global.gitIdentities` (deprecated) is present, `migrate-prefs.mjs` renames it to `identities` automatically.

For each MISSING service, run the **Token Save Flow** below. When creating new tokens, use the **standard key name** from Step 1b table.

#### Sequential onboarding loop (strict)

The Step 2 discovery summary is never the end of setup. Immediately after showing it, walk the missing services ONE BY ONE in this fixed order and run the Token Save Flow for each:

1. `jira`
2. `bitbucket_token` (then `bitbucket_user` right after, if missing)
3. `github`
4. `confluence`
5. `figma`  -  Figma Personal Access Token (Tier 2, REST)
6. `figma_mcp`  -  Figma MCP auth (Tier 1); its own prompt, never folded into the PAT prompt
7. `fortify`
8. `graylog`
9. `firebase`
10. `jenkins`
11. App Store Connect block (Step 3b; only when the target repo is iOS)
12. Google Play block (Step 3d; only when the target repo is Android)

Loop rules:

- **One prompt per service.** Never collapse the list into a single "add missing tokens now?" yes/no, and never offer one multi-select covering all services: each service has its own source URL, key name, identity binding and host prompt, so each gets its own Token Save Flow pass.
- **Each service pass asks, in order: token → author → host.** Step A/B collect the secret, Step C binds the git identity (author)  -  Bitbucket and GitHub included; every saved token gets an author  -  and Step 3.5 asks the host domain inline for hosted services (jira, confluence, bitbucket, fortify, graylog) - plus the Fortify project versions and the optional Graylog test instance. GitHub and Figma skip the host question (fixed domains); `bitbucket_user` skips author binding (username, not a PAT). Never end a service pass with the token saved but the author or a required host unasked.
- **Skip is per-service.** A Skip answer leaves that service's `keychainMapping` at `null` and the loop continues with the next service. Skips never abort the loop.
- **`figma` and `figma_mcp` are distinct credentials for distinct tiers  -  ask both.** Skipping the PAT does not imply skipping MCP, and vice versa. The `figma_mcp` pass opens with a Remote / Local mode question instead of a clipboard paste (see "Figma MCP Setup" below): Remote generates a `figu_` OAuth token for the current user, Local wires the PAT-based local server.
- The loop ends only when every missing service has been asked exactly once; then continue to Step 4 (Verify all).

---

### Token Save Flow (reusable)

Full procedure: `$HOME/.claude/multi-agent-refs/setup/token-save-flow.md`. Read it for every token prompt (Steps 3, 3b, 3c and any command that saves a token).

### Step 3b  -  App Store Connect onboarding (iOS only, optional)

Runs inside Step 3. Every part of the API key lives in the Keychain, the `.p8` included: ask for the `.p8` as a path, validate it BEFORE saving with `node "$HOME/.claude/scripts/probe-store-key.mjs" --asc ...` (exit 0 only), map `appstore_connect_private_key`, store it from the file with `credential-store.sh set appstore_connect_private_key - < <AuthKey_<keyId>.p8>`, run `node "$HOME/.claude/scripts/write-store-config.mjs"`, then offer (picker, default keep) to delete the file. `store_asc_*` and `ios_testflight_validate` then read the key from the Keychain. The five entries, the tier picker and the probes: `$HOME/.claude/multi-agent-refs/setup/app-store-connect.md`. On Skip, nothing is written.

### Step 3c  -  Firebase / Crashlytics onboarding (optional)

Runs inside Step 3. Measure first  -  `bash "$HOME/.claude/lib/fetch-crashlytics.sh" --probe` answers `tier-1-ready` / `tier-1-no-grant` / `malformed` / `unreachable`  -  then ask by that answer, never blind. Store the JSON as issued; never base64 it. Skip writes nothing. Then offer appId discovery: `bash "$HOME/.claude/scripts/firebase-app-discovery.sh" <repo> --json` reads the pairs the repo already carries, for `firebase.accounts[].apps[]`  -  it saves a round trip per run; skipping costs nothing. The picker, both tiers, the role-request wording and the v1alpha caveat: `$HOME/.claude/multi-agent-refs/setup/firebase.md`.

### Step 3d  -  Google Play onboarding (Android only, optional)

Runs inside Step 3, only when the target repo is Android. One entry, `google_play`: the service-account JSON the toolkit's `store_play_*` tools use, which lets `/multi-agent:store-ready` run Android Gate 2. Ask for the JSON's path, validate BEFORE saving with `node "$HOME/.claude/scripts/probe-store-key.mjs" --play --service-account <path>`, map `google_play`, then `credential-store.sh set google_play - < <path>` and `write-store-config.mjs`. Account prerequisites, the picker and the probe hints: `$HOME/.claude/multi-agent-refs/setup/google-play.md`. Skip writes nothing.

### Step 3.5  -  Host Prompt (embedded in Token Save Flow)

Full procedure: `$HOME/.claude/multi-agent-refs/setup/token-save-flow.md`. Read it for the host question inside the Token Save Flow.

### Step 3.6  -  Per-account host overrides (optional)

**Runs only when** `~/.claude/lib/account-resolver.sh` returns **more than one** account AND at least one account has Jira or Bitbucket tokens.

Use case: a single user with two corporate identities (e.g. agency + client). Each account points at its own Jira host  -  `prefs.global.hosts.jira` can hold only one default, so per-account overrides win for the rest.

For each non-default account, ask once:

```
Account {label} has Jira/Bitbucket tokens but no host override yet.
Use the global default ({hosts.jira}) or set a per-account host?

  1) Use global default
  2) Set per-account host
```

If `2`, prompt for `jiraHost` / `bitbucketHost` / `confluenceHost` (each optional). Save to `prefs.global.accounts[]`:

```json
{
  "global": {
    "accounts": [
      { "id": "personal", "jiraHost": "personal.atlassian.net" },
      { "id": "client-x", "jiraHost": "client-x.atlassian.net", "bitbucketHost": "bitbucket.client-x.com" }
    ]
  }
}
```

`account-resolver.sh` reads this on every invocation; per-account override wins over `global.hosts.*`. Skip this step on autopilot  -  `accounts[]` stays empty until the user opts in via `/multi-agent:setup accounts`.

**Re-run / update**: `/multi-agent:setup accounts` opens the editor for this block without re-running token discovery.

---

### Step 4  -  Verify all

Re-run scan from Step 1. Show final status:
```
All tokens present. Pipeline ready to use.

Optional per-project features (configured on first use, nothing to do now):
  • Phase 5 Report Step 2 Wiki  -  auto-generates component wiki pages + Figma
    screenshots. Activates when (a) task is a component AND (b) a Figma token
    is in Keychain. Four adapters supported: submodule / in-repo / github-wiki
    / separate-repo. First run asks: use auto-detected path, use a custom
    path, skip once, or disable for this project (persisted).
  • channels  -  post-hoc multi-channel reporter (Jira/Confluence/Wiki/PR), works on any branch with an open PR.
  • Default reviewers  -  auto-fetched from Bitbucket default-reviewers endpoint
    or GitHub CODEOWNERS on first PR.

Next step:
  /multi-agent "PROJ-12345"              -> start your first task
  /multi-agent help                      -> full usage guide
```

If still missing, show which ones and let user skip (pipeline will re-ask for any needed token at Phase 0).

### Step 5  -  Repo Discovery (optional)

Pre-populates the Phase 0 project picker with repos the user is active in. Three independent sources merge into one flat list: local `$HOME` scan (depth 3, repo markers), Bitbucket (last 90 days, token-gated), GitHub (owner + collaborator, push in last 90 days, token-gated). Any source failing skips that source only, is reported (never swallowed), and discovery is never destructive and idempotent.

```
Step 5  -  Repo Discovery (optional)
Scan for recent repos now to pre-populate the Phase 0 picker?

  y  -  all three (local + Bitbucket + GitHub, ~10-30s)
  l  -  local scan only (fastest, no network)
  n  -  skip (Phase 0 will prompt for repo path manually)
```

The scan commands, merge-by-origin dedup, the multi-select picker, the `recentProjects` / `serviceStatus` prefs shapes and the skip / degrade rules live in `$HOME/.claude/multi-agent-refs/setup/repo-discovery.md`  -  read that file when the user opts in.

### Step 6  -  Remember as Multi-Repo Group (optional)

After Step 5, if the user picked **2 or more** repos, offer to remember the combination as a named group. Phase 0's project picker surfaces saved groups at the top, so a multi-repo task ("update token resolver in `common` + `uicomponents`") becomes a single keypress next time.

Auto-skipped if Step 5 was skipped or fewer than 2 repos were selected.

**Prompt:**
```
Step 6  -  Remember as a multi-repo group (optional)
You picked 2 repos: Checkout, UIComponents.

Save this combo for one-tap selection in Phase 0?
  Group name (Enter for auto): [Checkout + UIComponents]
  Skip with 'n'.
```

**Auto-name heuristic** (suggested but editable):
- 2 repos    → `"<repoA> + <repoB>"`
- 3-4 repos  → `"<repoA>, <repoB>, <repoC>(+1)"`
- 5+ repos   → `"<repoA> + <count-1> more"`

Repo identifiers in the label are the human label from `recentProjects` (basename of the path, not the full path), so groups stay readable.

**Save** (matches schema `global.recentGroups[]` shape  -  `repos` required, `label` / `count` / `lastUsed` optional):

```json
{
  "global": {
    "recentGroups": [
      {
        "label": "Checkout + UIComponents",
        "repos": ["~/dev/Checkout", "~/dev/UIComponents"],
        "count": 1,
        "lastUsed": "2026-04-15T21:08:00Z"
      }
    ]
  }
}
```

**LRU + dedup rules:**
- New group → unshift to front of `recentGroups`.
- Same set of `repos` already exists (order-independent compare) → bump existing entry to front, increment its `count`, update `lastUsed`. Do NOT create a duplicate.
- Schema cap is 10 entries; oldest LRU entries past the cap are dropped.

**Skip rules:**
- Single-repo selection → step is a no-op (no group needed for one repo).
- User answers `n` → not saved; the picker still works for one-time use, and a future Phase 0 selection of the same combo will re-prompt.
- Step 5 skipped → Step 6 is also skipped (no selection to remember).

### Step 7  -  Platform Identity Routing (optional)

Full procedure: `$HOME/.claude/multi-agent-refs/setup/identity-routing.md`. Read it for Step 7.

### Cross-Platform Notes (Step 1-9)

Every read and write goes through `~/.claude/lib/credential-store.sh`, which wraps the macOS Keychain; stay on the helper rather than calling `security` directly. The clipboard handling and what happens when no backend exists: `$HOME/.claude/multi-agent-refs/keychain.md` "Credential store mechanics".

### Token -> Source Mapping

Standard key names are a convention for NEW tokens; discovery may find existing keys under other names, and the mapping in preferences handles that. The key names, the token types and where to generate each one all live in one table: `$HOME/.claude/multi-agent-refs/keychain.md` "Standard key names". Git identities are stored in preferences, never in the credential store.

### Inline Token Save Pattern

All tokens go through `~/.claude/lib/credential-store.sh`, which auto-delegates to the deterministic Python helper (`~/.claude/scripts/keychain.py`). The Python path writes both `-l` (label) and `-s` (service) attributes so existing manually-added entries with either convention remain findable.

```bash
# PAT / API Key / JSON contents (from clipboard)
pbpaste | ~/.claude/lib/credential-store.sh set "<SERVICE_NAME>" -
pbcopy < /dev/null  # clear clipboard

# Non-secret value typed inline (a secret on argv is visible to ps and lands in shell history)
~/.claude/lib/credential-store.sh set "<SERVICE_NAME>" "<VALUE>"

# Key file from disk (the .p8, the Google Play JSON; or when the clipboard is unavailable)
~/.claude/lib/credential-store.sh set "<SERVICE_NAME>" - < /path/to/file.json

# Read  -  a JSON value comes back exactly as it was stored, newlines included
~/.claude/lib/credential-store.sh get "<SERVICE_NAME>"
```

For maximum stdin hygiene (the secret never lands on argv / shell history), use the Python helper directly with the `-` sentinel:

```bash
pbpaste | ~/.claude/scripts/keychain.py set "<SERVICE_NAME>" -
```

### Figma MCP Setup (Remote / Local question)

Full procedure: `$HOME/.claude/multi-agent-refs/setup/figma.md`. Read it for the Figma MCP question.

### Security Rules

- Never paste tokens into terminal or chat  -  use `pbpaste` for input
- Never hardcode tokens in source code
- Never commit tokens to git history
- Clear clipboard immediately: `pbcopy < /dev/null`
- `2>/dev/null` suppresses stderr (prevents metadata leakage)

### Setup from Scratch Summary

To set up multi-agent on a new machine:

```
1. Install the toolkit:
   npx @{npm-scope}/multi-agent-pipeline install

2. Start setup:
   /multi-agent setup

3. Interactive flow:
   -> Token scan (shows what is missing)
   -> Git Identity creation (name + email)
   -> Inline commands for missing tokens
   -> Final verification

4. Ready:
   /multi-agent "PROJ-12345"
   /multi-agent "https://github.com/.../issues/42"
   /multi-agent "bug description"
```

All tokens are optional in the sense that every service can be answered with Skip  -  but the ASKING is not optional: the Step 3 sequential loop still walks every missing service one by one (token → author → host). Phase 0 re-asks at runtime only for tokens the user skipped here.

### Step 8  -  Enforcement hooks (optional, Claude Code)

Offer to merge `$HOME/.claude/templates/claude-hooks.json`: three `PreToolUse` gates that block on a non-zero exit (secret scan, agent-guard, read-size) plus three capture hooks that block nothing (`PreCompact`, `SessionEnd`, `SessionStart`). What each does: `$HOME/.claude/multi-agent-refs/picker-contract.md`.

- Ask (picker): "Install the pipeline's hooks into `~/.claude/settings.json`?" Default Yes.
- On Yes, deep-merge EVERY event in the template's `hooks` object, not `PreToolUse` alone - merging one event silently drops the capture hooks, and a run killed before Phase 5 then loses its findings exactly as it did before they existed. Preserve existing hooks; never duplicate a matcher already calling the same script.
- Say what the merge does NOT cover: only the three gates need no run-specific arguments, so only they are hookable; the rest are phase-enforced.
- Say what it does not turn on: the read-size gate is inert until `prefs.global.bulkRead.mode` is set. Recommend `observe` first. Why, and the Phase 3 exemption: `$HOME/.claude/multi-agent-refs/picker-contract.md`.

### Step 9  -  Default stack plugin enablement

Stack skills ship as versioned plugins in the `{owner}/multi-agent-plugins` marketplace. On first setup, wire the stack so the pipeline works out of the box.

1. Ensure the marketplace is known (idempotent):
   ```bash
   bash "$HOME/.claude/scripts/plugin-refresh.sh" {owner} --add-only
   ```
2. Ask the detector, then derive. No marker list here: a second list is a second
   answer, and this one defaulted to `ai-ios-toolkit` when nothing matched - how
   a Next.js site and several Node CLIs ended up with the iOS toolkit.

   ```bash
   eval "$(bash $HOME/.claude/lib/stack-detect.sh "$PROJECT_ROOT")"   # MA_STACKS, MA_STACK_WHY
   node -e 'import(process.env.HOME+"/.claude/scripts/_stack-routing.mjs").then(m=>
     console.log(m.pluginsForStacks(process.argv[1].split(" ").filter(Boolean)).plugins.join(" ")))' "$MA_STACKS"
   ```

   Report `MA_STACK_WHY` with the result. `ai-common-toolkit` and
   `ai-analyst-toolkit` are in every answer, the empty one included: neither is
   stack-specific. **No marker matched is an answer** - those two, not a guess.
   A name the marketplace does not carry is dropped with `dropped[]` naming it,
   so a toolkit that was never shipped is caught before it fails to load.
3. Report the enabled set. To change later, run `/multi-agent:stack <ios|android|web|backend|...>` in the repo. Pipeline Phase 1 auto-detects the stack for its own routing regardless of enablement.

The marketplace repo name (`multi-agent-plugins`) is generic; a different org points `{owner}` at its own fork - nothing in the pipeline is coupled to a specific account.
