Skip to content

Factories > Configure

Factory definitions as code

Open in ChatGPT ↗
Ask ChatGPT about this page
Open in Claude ↗
Ask Claude about this page
Copied!

Define a factory's agents, automations, runners, skills, and defaults as version-controlled, validated files.

Factory definitions as code let you manage a factory’s entire configuration as files in a Git repository. The files describe the factory’s repositories, agents, automations, runners, skills, and execution defaults, and they are the source of truth: when the files change, Warp updates the factory to match. Because the definition is version-controlled, every change to the factory gets the same treatment as a code change, with review, history, and rollback.

Every factory manages its configuration in one of two ways:

  • Live-managed - The configuration lives in the control room, and you edit it there directly. There are no definition files.
  • File-managed - The configuration lives in definition files in a Git repository, and the files are the source of truth. The control room reflects what the files say.

A file-managed factory keeps its definition in one of two places:

  • GitHub-backed - The definition lives in a directory you register in a GitHub repository you own. You change the factory the way you change code: open a pull request, let Warp’s check validate it, and merge.
  • Warp-managed - The definition lives in a repository that Warp hosts for you. You edit it in the control room, and each save commits directly.

A factory can be created in either mode, and a live-managed factory becomes file-managed when you link a definition source. In every mode, the definition files own configuration only; the factory’s operational state stays in the control room.

ModeSource of truthWhere you editHow changes are reviewed and applied
Live-managedControl-room stateControl roomEdits take effect directly in the control room. There are no files to sync until you link a definition source.
GitHub-backedThe registered directory on the production branch of your repositoryYour GitHub repository; control-room settings are read-only and link to the filesPull requests receive a validation check, and pushes to the production branch sync the factory. An admin can unlink the source to return the factory to live-managed.
Warp-managedThe Warp-hosted factory repositoryThe control room’s Code tab and supported control-room editorsEach edit validates, commits, and syncs in one step. The source cannot be unlinked or switched. A failed sync keeps the last successful definition active.

For a Warp-managed source, the Code tab in the control room edits the definition files directly. Saves are safe against concurrent edits: if someone else committed a change after you loaded the files, Warp reports a conflict instead of overwriting the newer commit. Every save validates the whole definition and reports problems with the file and line where they occur.

For a GitHub-backed source, the control room does not provide an editor. It links to the registered directory in your repository instead.

A definition is a small tree of YAML and Markdown files. Each resource takes its name from its path: agents/reviewer/agent.md defines an agent named reviewer, and runners/linux-build.yaml defines a runner named linux-build. Files never declare kind or apiVersion fields.

factory.yaml
agents/
foreman/
agent.md
skills/
incident-triage/
SKILL.md
reviewer/
agent.md
automations/
labeled-issue/
automation.md
runners/
linux-build.yaml
skills/
repository-conventions/
SKILL.md

Skills live in two places: skills/ applies to the whole factory, while agents/<name>/skills/ applies only to that agent. A skill is a directory containing a SKILL.md, not a YAML field; see Skills for agents.

YAML keys are case-sensitive.

factory.yaml names the factory and sets everything shared across it: the repositories it works in, factory-wide access, and the execution defaults agents inherit.

FieldPurposeRules
schemaVersionDeclares the definition schema.Required. Must be v1alpha1.
nameNames the factory.Required.
descriptionDescribes the factory’s purpose.Optional.
aliasSets a display alias.Optional. Must be unique in the workspace (case-insensitive).
credentialStrategyChooses whose credentials runs receive.EXECUTOR uses the principal executing the run; CREATOR uses the user who created the run. Defaults to EXECUTOR.
repositoriesLists the GitHub repositories the factory works in, as owner and name pairs.Required and non-empty.
secretsLists Warp-managed secret names granted to every agent.Optional.
mcpServersMaps server names to Warp MCP server warpId values, granted to every agent.Optional.
cloudProvidersConfigures GCP or AWS access.GCP accepts projectNumber, workloadIdentityFederationPoolId, workloadIdentityFederationProviderId, and serviceAccountEmail; AWS accepts roleArn.
integrationsDeclares connected factory integrations.Optional. type accepts slack, linear, or jira. Declare at most one issue tracker: linear and jira are mutually exclusive, and omitting a tracker is valid. GitHub is not declared here; repository access comes from repositories and the connected GitHub App.
agentDefaultsSets the execution defaults agents inherit: shared model or harness, runner, environmentId, secrets, mcpServers, and workerHost.Required. Agents inherit any execution field they omit.
agentDefaults.workerHostSets the factory’s default execution host.Optional. A non-empty value becomes the factory default; omitting or clearing it defers to the workspace default.

Warp still parses the legacy providers key. The next time a Warp-managed edit rewrites the configuration, Warp saves it as cloudProviders.

In the control room, Settings lets you edit cloud providers for Warp-managed sources. For GitHub-backed sources, cloud provider settings are read-only and link to factory.yaml in the registered repository directory.

Two different rules decide what an agent ends up with:

  • Factory-wide access is additive. Top-level secrets and mcpServers in factory.yaml are granted to every agent. An agent cannot opt out of them.
  • Defaults are replaceable. Values in agentDefaults apply only when an agent omits the field. An agent that sets its own secrets or mcpServers replaces the agentDefaults value, but the factory-wide entries still apply. Every other omitted execution field inherits from agentDefaults.

workerHost follows the same three-way rule wherever it appears:

  • Set a value to choose a host: warp for Warp-hosted execution, or the ID of a connected self-hosted worker.
  • Omit the field to inherit from the level above.
  • Set an empty or null value to skip inheritance and use the workspace default.

Fields that accept a model or harness take one of two mutually exclusive forms. model on its own is shorthand for the Warp Agent harness, serialized as type oz:

model: auto

The shorthand is equivalent to:

harness:
type: oz
model: auto

Use the harness form for a third-party harness or advanced settings:

harness:
type: codex
model: gpt-5.3-codex
reasoningLevel: high
auth:
source: managedSecret
secretName: CODEX_API_KEY

A harness mapping accepts type, model, reasoningLevel, and auth. For auth, set source: managedSecret with a secretName, or source: workerEnvironment with no secretName; workerEnvironment requires that the effective workerHost is a self-hosted worker. Type oz does not accept explicit auth or reasoningLevel. See supported harnesses and cloud agent secrets.

An agent file combines YAML frontmatter with a Markdown body. The frontmatter configures how the agent runs; the body is the prompt that carries the role’s durable instructions.

FieldPurposeRules
descriptionDescribes the role.Optional.
agentTypeClassifies the role.CUSTOM, FOREMAN, TRIAGE, SPEC, IMPLEMENT, REVIEW, or VERIFY. MAIN is an alias for FOREMAN.
credentialStrategyChooses whose credentials this agent’s runs receive.Overrides the factory-level strategy.
model or harnessSelects the runtime and model.Mutually exclusive. Overrides agentDefaults.
runnerNames a runner defined under runners/ or an existing runner.Overrides agentDefaults.runner.
environmentIdReferences an existing environment.Overrides agentDefaults.environmentId.
secretsGrants role-specific secrets.Replaces agentDefaults.secrets. Factory-wide secrets from factory.yaml still apply.
mcpServersGrants role-specific MCP servers.Replaces agentDefaults.mcpServers. Factory-wide servers from factory.yaml still apply.
workerHostSelects this agent’s execution host.Set a value to override, omit to inherit agentDefaults.workerHost, or clear to use the workspace default.

A valid definition contains exactly one foreman: an agent with agentType: FOREMAN or its alias MAIN. The foreman is the factory’s entry point and the default target for automations that omit agent. Validation fails if a definition declares no foreman or more than one.

An automation file also combines YAML frontmatter with a Markdown body. The frontmatter declares when runs start and how they execute; the body is the run prompt.

FieldPurposeRules
enabledTurns the automation on or off.Optional.
agentNames the agent that handles runs.Optional. Must name a declared agent. Defaults to the foreman.
model or harnessSelects execution for automation runs.Mutually exclusive. Overrides the target agent.
runnerSelects compute for automation runs.Overrides the target agent’s runner.
environmentIdSelects the environment for automation runs.Overrides the target agent’s environment.
secretsSelects secrets for automation runs.Overrides the target agent’s secret list.
mcpServersSelects MCP servers for automation runs.Overrides the target agent’s MCP map.
workerHostSelects the execution host for automation runs.Set a value to override, omit to inherit from the target agent, or clear to use the workspace default.
triggersDeclares the events or schedules that start runs.Required and non-empty. Each entry uses provider, event, an optional filter, and an optional schedule with name and cron.

See triggers and integrations for event sources.

A runner file defines compute, not agent behavior.

FieldPurposeRules
descriptionDescribes the workload the runner supports.Optional.
setupCommandsCommands that initialize the sandbox.Ordered list.
instanceShapeSets compute capacity.Uses vcpus and memoryGb.
platformSets the operating system and architecture.Uses os and arch. Linux adds linux.dockerImage; macOS adds mac.version.

The control room’s Runners page lists the effective runners in every mode. For a Warp-managed source, creating or editing a runner there writes runners/*.yaml for you. For a GitHub-backed source, runner controls are read-only and link to the runner directory in your repository. See cloud agent runners and cloud agent environments for execution behavior.

This example defines a small factory: one repository, a foreman, an automation triggered by a GitHub label, and a Linux runner.

factory.yaml
schemaVersion: v1alpha1
name: payments-factory
description: Processes approved work for the payments service
alias: payments
credentialStrategy: EXECUTOR
repositories:
- owner: ACME
name: PAYMENTS_SERVICE
agentDefaults:
model: auto
runner: linux-build
environmentId: PAYMENTS_ENVIRONMENT_ID

ACME is the GitHub organization, PAYMENTS_SERVICE is the repository name, and PAYMENTS_ENVIRONMENT_ID is the ID of an existing environment.

agents/foreman/agent.md
---
description: Routes approved payments work through the factory
agentType: FOREMAN
secrets:
- SENTRY_AUTH_TOKEN
mcpServers:
sentry:
warpId: SENTRY_MCP_SERVER_ID
---
Own each work item from intake through human handoff.
Confirm the request is ready before dispatching implementation. Require
repository validation and independent review before marking work complete.

The foreman inherits model, runner, and environmentId from agentDefaults. Its Sentry secret and MCP server are role-specific; moving them to factory.yaml would grant them to every agent in the factory.

automations/labeled-issue/automation.md
---
enabled: true
agent: foreman
triggers:
- provider: github
event: issue_labeled
filter:
repos: [ACME/PAYMENTS_SERVICE]
labels: [factory-ready]
---
Review the labeled issue and decide the next required stage. Preserve the
issue's acceptance criteria and return unresolved product questions to a human.
runners/linux-build.yaml
description: Linux runner for payments builds and tests
setupCommands:
- corepack enable
instanceShape:
vcpus: 4
memoryGb: 8
platform:
os: linux
arch: x86_64
linux:
dockerImage: ubuntu:22.04

Warp treats the definition as a single unit: it parses, validates, and resolves a change as a whole, and only a fully valid tree becomes the active definition. If any step fails, the factory keeps running on the last successful definition. An invalid change never partially applies.

flowchart LR
Change["Definition change"] --> Parse["Parse and validate"]
Parse -->|Valid| Resolve["Resolve dependencies"]
Resolve -->|Valid| Apply["Apply desired state"]
Apply -->|Success| Active["Active definition"]
Parse -->|Failure| Last["Keep last successful definition"]
Resolve -->|Failure| Last
Apply -->|Failure| Last

Validation rejects:

  • Unknown fields, duplicate YAML keys, unsupported file paths, and malformed frontmatter.
  • YAML anchors, aliases, and explicit tags.
  • A schemaVersion other than v1alpha1.
  • A missing repositories list or agentDefaults block, an automation without triggers, or a definition without exactly one foreman.
  • References that do not resolve, including agents, runners, environments, secrets, MCP servers, models, and harness settings.

Every diagnostic identifies the source file and line that caused it.

For GitHub-backed sources, every pull request that targets the production branch receives a warp/factory-config (<directory>) check for each registered path. The check annotates invalid fields or references and summarizes the changes it would apply. A push to the production branch starts synchronization.

For Warp-managed sources, supported control-room edits commit directly to the Warp-hosted repository, then validate and sync; there is no separate pull request step. Branch-based review gating is limited and is not a general workflow for these edits. If synchronization fails, the commit remains in the repository, and the factory keeps running on the last successful definition while you repair it.