Team per repo and per request
Updated 2026-10-07
Read https://www.ghosty.studio/en/docs/factory/team-per-repo.md and create this repo's `.ghosty/factory.md` with the conventions you see in the code.
Who plays each role is decided at three levels. The most specific wins:
message > the repo's .ghosty/factory.md > workspace team
Workspace team
In /factory → "Workspace team" (owner only): which Studio agent is @plan, @build and @check by default, plus the optional @eval. Every repo that doesn't say otherwise uses it.
From the CLI: ghosty agents teams on <id> <workspace> --factory plan,build,check gives those roles to an agent (each role keeps its name and avatar). ghosty agents teams ls <id> shows which roles it holds in each workspace.
If nobody asks for a model, @plan and @check run on Opus 5.5 when their agent is a Claude one; @build uses its agent's model. On another engine, each role uses its agent's model.
.ghosty/factory.md in the repo
A file in the repo with frontmatter per role and, below it, the conventions all three roles must know:
agent: name or id of a Studio agent in your workspace.model: alias (opus,sonnet,fable,pro,flash,sol,terra,luna) or full id. It must belong to that agent's engine: changing engine means changing agent.- A role that isn't listed uses the workspace's. The body travels with every factory turn and overrides the generic rules.
- A
## @plan,## @buildor## @checksection goes only to that role: that's where this repo's review rules go, for example. It ends at the next##. - It's read with a 5-minute cache; in
/factory, "Team in this repo" → ↻ refreshes it and shows where each role comes from ("from the repo" or "from the workspace").
Test environment: setup:
If the repo's tests need a database, Redis or variables, declare it in the same frontmatter. @build and @check get the exact call that prepares their work box before every run:
services:postgresandredis(installed and stopped in thedevbox). Anything else is ignored.db: name of the database and its user (the password is the same name). It's dropped and recreated on every run, so the suite always starts with an empty database. The connection arrives asDATABASE_URL; Redis asREDIS_URL.env: test variables, the same ones your CI uses. Never real secrets: the repo's secrets stay in the vault.script: runs from the repo root with that env loaded (migrations, seeds).- If the repo doesn't have it and the request touches tests with a database,
@planproposes it from theservices:in.github/workflows/.
A box per run
Each run gets its own computer (4 GB) from the moment you sign the plan until it's merged or cancelled: @build builds there, @check tests there (on a clean clone of the PR) and the preview runs there. Idle, it sleeps; when the run closes, it's deleted. Your factory plan has execution slots (F1: 2, F2: 4, F3: 6) shared by runs and by previews of PRs without a run. A new run displaces a loose preview; a new loose preview replaces the oldest one; if every slot is a run in progress, the run or preview waits ("Waiting for a slot") and starts on its own as soon as one frees up.
In the message
The keywords stay in Spanish (con = with, en = in):
- "con <model>" changes that role's model in that thread: later hand-offs of the same request inherit it.
- "en <repo>" picks the repo when the room has several.
- A model from another engine or an agent that doesn't exist won't run: the thread says why.
Each reply's footer shows the model that ran that turn, not just the configured one.