Reference
Configuration.
Quase tudo que muda o comportamento da fábrica está no t25.yaml da raiz —
roteamento de agentes, limites, risco, GitHub, autenticação. Esta página é o mapa das
seções; a referência campo a campo é
docs/CONFIGURATION.md.
Shallow merging happens by section, not by nested key. A section present in YAML replaces the default at that level. It is not deep-merged. Declared routing? Declare the roles you want, because missing roles do not come back from the default.
Secrets do not belong in versioned YAML. The database URL comes from DATABASE_URL, the worker credential comes from FACTORY_WORKER_CREDENTIAL and OAuth secrets come from the environment. A real value committed to the repository is an incident, not a typo.
The sections
| Section | What for |
|---|---|
factory | Name, state directory, worktrees directory, maximum time per task, retries, whether plan approval is required. |
repository | The repository the factory operates on and the default branch worktrees are cut from. |
projects | Other local checkouts registered, to operate more than one repository. |
routing | Pipeline role → chain of CLIs, in order of preference. |
skills | Replaces the skills list of a specific role. |
timeouts | Minute limit per role; any role left out uses the global limit. |
limits | Guardrails against loops and runaway agents. |
risk | Risk level → how much the factory automates. |
sandbox_image | The Docker image for the dev roles when the level calls for a sandbox. |
github | Issue import and pull request creation. |
server | Port, API keys and, optionally, login through GitHub or OIDC. |
cost and observability | Cost accounting per run and telemetry. |
control_plane | Database and artifact store. The URL always comes from the environment. |
Routing: a chain, not a fixed CLI
This is the concept most likely to cause confusion. Each role receives an ordered list, and T25 uses the first CLI available on the machine. It is not a quality choice or a lottery: it is the first door that opens.
routing: triage: [kimi, claude, codex] planner: [claude, codex, kimi] research: [kimi, claude] dev-frontend: [claude, kimi, codex] dev-backend: [codex, claude, kimi] qa-frontend: [claude, kimi] qa-backend: [codex, claude, kimi] reviewer: [claude, codex, kimi] security: [claude, codex] docs: [kimi, claude, codex] release: [claude, codex]
There are eleven roles, and every list must be a non-empty array. An empty list or the wrong type is rejected at load time, not discovered during execution. The adapters available today are claude, codex, kimi, gemini, opencode, cursor, pi, vibe and mock.
Risk: how far it runs on its own
risk:
low: { approval: none, sandbox: none }
medium: { approval: plan, sandbox: none }
high: { approval: plan_and_pr, sandbox: none }
critical: { approval: human_required, sandbox: none }
| Level | What changes |
|---|---|
low | Opens the pull request without a plan gate. |
medium | Requires plan approval. |
high | Requires plan and pull request approval. |
critical | Always requires human intervention. |
No level automates the merge. The risk configuration controls how far the factory goes without asking before the pull request. The merge is always yours, through the cockpit or CLI. Briefing approval at SPEC is mandatory at every level; no setting turns it off.
A chore task without an explicit --risk uses low. This is the deliberate adoption path: upgrades, CVEs and lint, with verifiable criteria and a low cost of error.
Limits: the brake
limits: max_runtime_minutes: 60 max_queue_attempts: 5 max_failed_commands: 8 max_same_error_retries: 2 max_files_changed: 40 max_diff_lines: 2000 max_duplicate_line_ratio: 0.5
The first two in the second half are the guardrail against an agent that decides to rewrite the world: limits on changed files and diff lines, checked after implementation. If either is exceeded, the task fails. max_duplicate_line_ratio catches excessive copy-paste and is the only one that turns itself off in bootstrap mode, where legitimate repetition would create a false positive.
Authentication
API keys work without extra configuration and are the path for scripts and the CLI. Human login through GitHub or OIDC is optional: when enabled, it requires a session secret and the complete configuration for one of the two providers. Authorized users start declared in YAML and move to a local overlay after the first cockpit edit. There is no user database. A GitHub access token is never persisted, and removing someone from the list revokes their session on the next request.
Before you change anything
- Run
npm run t25 -- doctor: it checks the environment and exits with an error if anything is broken. - A reference to a role or skill that does not exist is rejected at load time. The error appears on startup, not in the middle of a task.
- No secrets in versioned YAML. None.