---
name: setup-ramstack
description: Configure which models ramstack uses per role, for the host you're running in (Claude Code, Codex, or pi). Detects your available models and writes your host's section of the shared config file. Also binds this repo's capture inbox, where playbooks park out-of-scope finds, and offers to seed the repo glossary. Use for /setup-ramstack, "configure ramstack models", "where do captures go", "seed the glossary", or changing ramstack's model choices.
---

# Setup ramstack

Write your host's section of `~/.agents/ramstack-models.md`, a config file that sets ramstack's model per role. The skills read it at run time and fall back to their inline defaults when a section or line is absent, so this is an override layer, not a requirement.

The file is shared across hosts on purpose. Model slugs differ per host (`sonnet` means something in Claude Code and nothing in Codex or pi), so the file holds one `## <host>` section per tool, and every skill reads only the section for the host it is running in. Someone who switches between Claude Code, Codex, and pi runs this skill once in each and the tools stop stepping on each other.

## Steps

### 1. Identify the host and detect available models

Identify which host you are running in from your own environment (your system prompt names it). Section labels: `claude-code`, `codex`, `pi`; for any other host, a short kebab-case name of the tool.

Then enumerate the model slugs you can pass to a subagent in this session; that is the dependable source.

- **Claude Code**: the `model` values the Agent tool accepts (typically `fable`, `opus`, `sonnet`, `haiku`).
- **Codex**: the models the CLI exposes.
- **pi**: the models the user has actually set up, not pi's full catalog. Enumerate authenticated providers and their models from pi's config (`~/.pi/agent/`, including `models.json` and custom entries) or the `/model` picker. The set is whatever the user configured, so always show what you found and confirm before writing. pi is the one host that can run genuinely cross-vendor panels; when several vendors are authenticated, default each panel list to one model per vendor.

If the host has a models API or CLI that lists the user's entitled models, prefer it for completeness. If you cannot detect any, ask the user to paste the slugs they have access to. Never write a real slug you have not confirmed is available. The aliases `inherit-parent` and `auto` are always valid even though they are not detected slugs.

### 2. Load current state

If `~/.agents/ramstack-models.md` exists and has a section for this host, read it and treat its values as the current choices. Otherwise start from the defaults in step 5. Never treat another host's section as current state; its slugs are not valid here.

### 3. Map and confirm

Show every role with its current model, marking any real slug not in the detected set as needing a choice. Ask whether to accept as-is or change specific roles, offering the detected models plus `inherit-parent` and `auto` (both mean: this role runs on the parent chat model) as the options. Prefer a structured question tool over free text when the host has one. For panel roles (how critics, arena runners, architect runners, interrogate reviewers) the value is a list, and one subagent runs per entry, alias entries included, so the list length sets the count. `arena cross-judge pool` is also a list, but Arena selects one value from it whose model family differs from the parent's when possible; on a single-vendor host, a different model tier counts as a different family. `swarm workers` is the default model for every worker unless a race or comparison assigns another model per arm.

### 4. Validate

Every real slug written must be in the detected set; `inherit-parent` and `auto` always pass. If a chosen real slug is not available, stop and ask again. A config pointing at a model the user cannot use breaks every delegation that reads it.

### 5. Write the config

Rewrite this host's `## <host>` section of `~/.agents/ramstack-models.md` with one line per role, using the same labels ram-mode uses. Preserve every other host's section byte for byte; create the file with the header comment below if it doesn't exist. Re-runs stay idempotent by replacing the whole section.

Shape, with the Claude Code defaults filled in (another host substitutes its own detected slugs under its own heading, keeping the same roles):

```
# ramstack model configuration. One `## <host>` section per tool; skills read only
# the section for the host they run in. One line per role. Delete a line (or a
# section) to fall back to the skill defaults.
# `inherit-parent` or `auto` as a value: the role runs on the parent chat model
# (omit the subagent model param). Alias entries in a panel list still count
# toward its fan-out.

## claude-code
feature, refactoring: sonnet
bug-fix: opus
perf-issue: opus
hillclimb: opus
judgment and prose: fable
hardest tasks: fable
how explorer: sonnet
how explainer: fable
how critics: fable, opus, sonnet
why investigators: sonnet
why synthesizer: fable
reflect tooling: opus
reflect judgment, divergent, synthesizer: fable
arena runners: fable, opus, sonnet
arena cross-judge pool: fable, opus, sonnet
swarm workers: sonnet
architect runners: fable, opus, sonnet
interrogate reviewers: fable, opus, sonnet
```

The role split follows the upstream design: fast mechanical code goes to the fast tier, precisely-specified code to the strong coding tier, and prose and judgment to the highest-reasoning tier. On Claude Code that is `sonnet` / `opus` / `fable`. On a host with cross-vendor model access (pi), put one model per vendor in each panel list; cross-vendor disagreement is the point of a panel.

### 6. Confirm

Tell the user which host section was written and that skills read it on their next run. If the file has sections for other hosts, say so; if it doesn't, suggest running `/setup-ramstack` inside each other tool they use so every host gets valid slugs.

### 7. Offer a verification skill (optional)

Check whether the project has a way to drive the real app for proof (a `verify-*` skill, or an existing harness). If not, offer once: "want a project-local verification skill, so agents can drive the app the way a user does and prove changes work? I can generate one with /create-verification-skill." On yes, invoke `/create-verification-skill` (resolves wherever ramstack is installed — workspace, user, or plugin). On no, move on without pushing.

### 8. Bind the capture inbox (optional)

ram-mode playbooks tell you to park an out-of-scope discovery in follow-ups without saying where they live. The binding says where. It is a per-repo fact, unlike the model config, so it goes in the repo at `.ramstack/inbox.md` and gets committed.

Check that it can be: `git check-ignore -q .ramstack/inbox.md` succeeding means the repo ignores the path, and an inbox nobody else can see breaks on the next clone. Some repos ignore `.ramstack/` wholesale rather than just the installer's `config.local.json`. When it is ignored, say so and offer either a narrower ignore rule or a different path; never report the file as committed when it is not.

Skip this section when you are not inside a git repo. If `.ramstack/inbox.md` already exists, say so and move on; re-run only to switch backends.

**Detect.** Read `git remote -v` and take the hostname from the remote's URL. Check that host specifically: `gh auth status --hostname <host>`. A bare `gh auth status` tests every host it knows and exits non-zero when any account on any of them has a problem, so an expired credential for some unrelated enterprise host would push you to a local file, and being signed in to one host says nothing about the host this remote points at. `glab auth status --hostname <host>` for GitLab. Then list connected MCP servers for an issue tracker (Linear, Jira, Plane, Shortcut).

**Recommend one and let a single word accept it.** Ask nothing when detection settles it:

- GitHub remote with `gh` authenticated: GitHub issues.
- GitLab remote with `glab` authenticated: GitLab issues.
- A tracker MCP connected and no code-host remote: that tracker.
- No remote, or nothing authenticated: a local file.

Offer the other backends only when two are plausible, or when the user asks. A tracker MCP alongside a GitHub remote is the one real fork: ask which one they actually track work in.

**Write** `.ramstack/inbox.md` from the matching template, filling in the concrete values you detected rather than leaving placeholders:

- [references/inbox-local.md](references/inbox-local.md): a TSV committed to the repo
- [references/inbox-gh.md](references/inbox-gh.md): GitHub issues via `gh` (adapt for GitLab and `glab`)
- [references/inbox-mcp.md](references/inbox-mcp.md): a tracker MCP, with the server's real tool names written in

For a backend none of these cover, write the file from the user's description in their words, keeping the three verb headings intact. The headings are the contract; the prose under them is whatever the backend needs.

**Confirm.** Name the file, the backend, and the fact that a capture is one command that does not reopen the work you parked it from.

The binding is optional here because capture writes it on first use in an unbound repo. Running it now just means the first capture asks nothing.

### 9. Seed the glossary (optional)

Shared understanding of terms is the **align-on-intent** principle skill's contract, and the repo glossary is where the terms half lives. Skip this section when you are not inside a git repo. Check for a `CONTEXT.md` with a glossary section in the repo root; when one exists, say so and move on. Re-runs never overwrite an existing glossary.

When absent, offer once: "want a seeded glossary, so agents and humans share one meaning per term? I can draft one from the repo's own vocabulary." On no, move on without pushing; the **define-the-terms** principle skill still triggers on first ambiguity.

On yes:

- When a domain-modeling skill is installed, invoke it. It builds the model, catches assumptions, and records ADRs; the glossary falls out of that work.
- Otherwise scan the repo for load-bearing terms doing double duty (`tool`, `config`, `mode`, `service`, and the repo's own recurring nouns), draft a one-line definition with an Avoid list for each, and confirm every definition with the user before writing. The glossary is a shared-understanding contract; an agent-invented definition the user never saw is not shared.
- Write the confirmed entries into `CONTEXT.md` (create it with a `## Language` section when absent) and commit it like the inbox binding.
