Factories > Factory configuration
Factory definition syntax
# Factory definition syntax A factory definition is a versioned tree of YAML and Markdown files rooted at `factory.yaml`. It can define agents, automations, runners, model routers, benchmarks, scorers, skills, and webhooks. Keys are case-sensitive, and Warp applies file changes automatically. For working definitions you can copy, see [warp-factory-examples](https://github.com/warpdotdev/warp-factory-examples). ## Where the definition lives Choose where to host the definition when you create a factory: * **Warp-managed (default)** - Edit the definition in the [Warp Factories web app](/factories/factory-dashboard/). Warp validates, commits, and applies changes; its repository stays hidden. * **GitHub** - On a paid plan, keep the definition in your own repository. The web app links to the files in a read-only view. Merges to the production branch (`main` by default) update the factory. Both modes share the file format. You can link a Warp-managed factory to GitHub later. Work items, runs, and metrics live in the web app, not in the definition. ## Validate a definition Warp validates syntax, required fields, and resource access before applying a definition: on save for a Warp-managed factory, and in pull requests to a GitHub-backed factory's production branch. ### Pull request checks Every pull request to the production branch gets a **warp/factory-config** check. It reports errors by file and line or summarizes the resources a valid change will create, update, or delete. Pull requests that don't change the definition pass immediately. Require the check in branch protection to block invalid definitions. Warp applies a definition as one unit. If validation fails, the factory keeps its last valid definition. For subdirectory check names and troubleshooting, see [factory-definition pull request checks](/factories/integrations/github/#factory-definition-pull-request-checks). ### Validate locally or in CI Run [`validate_factory_files.py`](https://github.com/warpdotdev/warp-factory-examples/blob/main/scripts/validate_factory_files.py) before opening a pull request or in CI. It requires Python 3, but no Warp login or existing factory. ```bash python3 scripts/validate_factory_files.py path/to/factory-root ``` Pass the factory root to check cross-file references. The script reports errors by file and line. The GitHub check also validates team- and factory-dependent settings. For a CI job built on the script, see the example repository's [validation workflow](https://github.com/warpdotdev/warp-factory-examples/blob/main/.github/workflows/validate.yml). ### Validate with a coding agent * **Warp Agent** - Ask the agent to change or check the definition. Its `factory-files` skill validates before opening a pull request. For example: "Add a nightly dependency-audit automation and validate the definition." * **Factory MCP** - Connect another coding agent to [Factory MCP](/factories/factory-mcp/) for schema and validation tools. * **Other agents** - Have the agent run the [validator script](#validate-locally-or-in-ci). ## JSON Schema Warp publishes unauthenticated JSON Schemas for editor completion and validation. They describe each field and reject unknown keys. * `https://app.warp.dev/api/v1/factory-files/schemas` - Lists supported versions and the current version. * `https://app.warp.dev/api/v1/factory-files/schemas/v1alpha1` - Returns all `v1alpha1` documents, keyed by document name. * `https://app.warp.dev/api/v1/factory-files/schemas/v1alpha1/<document>` - Returns one document for use as a schema reference. Documents include `factory.schema.json` for `factory.yaml`; `agent.schema.json`, `automation.schema.json`, and `scorer.schema.json` for Markdown frontmatter; `runner.schema.json`, `router.schema.json`, `webhook.schema.json`, `benchmark_suite.schema.json`, and `benchmark_suite_task.schema.json` for YAML resources; and `common.schema.json` for shared definitions. For completion and inline validation in the VS Code YAML extension, add the document URL on the first line: ```yaml title="factory.yaml" # yaml-language-server: $schema=https://app.warp.dev/api/v1/factory-files/schemas/v1alpha1/factory.schema.json schemaVersion: v1alpha1 name: payments-factory ``` YAML schemas don't apply to Markdown frontmatter. Use one of the [definition validators](#validate-a-definition) for Markdown files. ## Directory structure Each resource takes its name from its path: `agents/reviewer/agent.md` defines an agent named `reviewer`. ```text factory.yaml agents/ foreman/ agent.md skills/ incident-triage/ SKILL.md reviewer/ agent.md automations/ labeled-issue/ automation.md runners/ linux-build.yaml routers/ by-task.yaml benchmarks/ pull-request-review/ suite.yaml tasks/ broken-doc-link.yaml scorers/ tests-run/ scorer.md skills/ repository-conventions/ SKILL.md webhooks/ internal-ci.yaml ``` See the [example factory definition](#example-factory-definition), the minimal [`01-single-repo-quickstart`](https://github.com/warpdotdev/warp-factory-examples/tree/main/examples/01-single-repo-quickstart), or the full [`02-sdlc-issue-to-pr`](https://github.com/warpdotdev/warp-factory-examples/tree/main/examples/02-sdlc-issue-to-pr). ## `factory.yaml` **Required resource.** The root document names the factory, scopes it to repositories, and sets execution defaults. ```yaml title="factory.yaml" schemaVersion: v1alpha1 name: payments-factory repositories: - owner: acme name: payments-service agentDefaults: model: auto ``` ### `schemaVersion` **Required.** Every definition sets `schemaVersion: v1alpha1`. ### `name` **Required.** The factory's name. ### `description` **Optional.** What the factory is for. ### `alias` **Optional.** The handle used to @-mention the foreman on platforms such as Slack and Linear. The factory dashboard labels it **Foreman name**. It accepts up to 60 letters, numbers, spaces, `.`, `_`, and `-`, and is case-insensitively unique in the workspace. ### `credentialStrategy` **Optional.** Whose credentials runs use: `EXECUTOR` for the executing principal, or `CREATOR` for the user who created the run. `CREATOR` requires a paid plan. Omit the key to preserve the setting; otherwise, it defaults to `EXECUTOR`. Agents can override it by role. ### `codeForges` **Optional.** The enabled code hosts: `GITHUB`, `GITLAB`, and `AZURE_DEVOPS`. Omit the key to preserve them. With multiple hosts, set `codeForge` on every repository. An empty `codeForges` list requires empty `repositories` and configures no code host. ### `repositories` **Required.** The factory's repositories. The list can be empty. Each entry requires `owner` and `name`; optional `codeForge` selects `GITHUB`, `GITLAB`, or `AZURE_DEVOPS`. With multiple [`codeForges`](#codeforges), every repository requires `codeForge`. Optional `deferred` defaults to `false`. Set it to `true` to attach a repository without preparing it for every run. Warp prepares it when an agent or automation lists it in `required_repos`, or a run adds it. ```yaml codeForges: - GITHUB - GITLAB repositories: - codeForge: GITHUB owner: acme name: payments-service - codeForge: GITLAB owner: acme/platform name: deployment-config ``` ### `benchmarkRepoSubstitutions` **Optional.** Repository substitutions for benchmark starting states. Each entry requires `source` and `target` objects, each with `codeForge`, `owner`, and `name`. Both `codeForge` values must be `GITHUB`; the source must belong to the factory, and the target must not. ### `secrets` **Optional.** Names of [managed secrets](/platform/secrets/) granted to every agent, in addition to secrets declared by an agent. ### `mcpServers` **Optional.** [MCP servers](/platform/mcp/) granted to every agent, keyed by the name shown to the agent. Each entry selects exactly one transport: * `warpId` - A Warp-managed MCP server ID. * `command` - A stdio command. Optional `args` is a list of strings, and optional `env` maps names to string values. * `url` - An absolute HTTP or HTTPS URL. Optional `headers` maps header names to string values. Don't put credentials in `env` or `headers`. Reference a [managed secret](/platform/secrets/) as `{{SECRET_NAME}}`, or use `warpId` for a [managed MCP installation](/platform/mcp/#oauth-authentication). ```yaml mcpServers: sentry: warpId: SENTRY_MCP_SERVER_ID ``` ### `cloudProviders` **Optional.** Cloud-provider identity federation for agent runs: * `cloudProviders.gcp` configures Google Cloud. It requires `cloudProviders.gcp.projectNumber`, `cloudProviders.gcp.workloadIdentityFederationPoolId`, and `cloudProviders.gcp.workloadIdentityFederationProviderId`. Quote `projectNumber` so YAML keeps it as a string. Optional `cloudProviders.gcp.serviceAccountEmail` selects a service account. * `cloudProviders.aws.roleArn` configures AWS and is required for that provider. ```yaml cloudProviders: aws: roleArn: arn:aws:iam::123456789012:role/warp-factory ``` ### `integrations` **Optional.** The integration providers attached to the factory: `slack`, `microsoft-teams`, `linear`, and `jira`. Each entry requires `type`. Declare at most one issue tracker because `linear` and `jira` are mutually exclusive. Code-forge access comes from `repositories`, not this list. Omit `integrations` to preserve the currently attached providers. Set it to an empty list to detach every provider. ```yaml integrations: - type: slack - type: linear ``` For Slack and Microsoft Teams, `slack.autoRespondToThreadReplies` and `microsoft-teams.autoRespondToThreadReplies` control whether eligible plain replies in an existing factory thread can continue work without another mention. The Slack setting defaults to `true`. The Microsoft Teams setting defaults to `true` when the shared per-factory reply setting is enabled. ```yaml integrations: - type: slack slack: autoRespondToThreadReplies: false ``` `integrations[].linear.teamIds` and `integrations[].jira.projectKeys` are accepted for compatibility but don't control issue discovery or routing. Warp omits them when rewriting the definition. Use automation filters such as `team_ids` and `project_keys`. ### `providers` **Optional.** Accepted as a legacy alias for [`cloudProviders`](#cloudproviders) with the same keys. Use `cloudProviders` in new files. Warp writes the canonical key when it updates an older definition. ### `scorerDefaults` **Optional.** Sets `runner`, `secrets`, and `mcpServers` for file-defined scorers. A scorer can override each value. The `mcpServers` map uses the [factory-level transport syntax](#mcpservers). ### `selfImprovement` **Optional.** Configures scheduled self-improvement for a GitHub-backed factory: * `failedRunThreshold` - Distinct scored failures per agent required before a scheduled self-improvement run. Use a value from 1 through 50, or omit it for the server default. * `reviewerType` - The pool used to request one reviewer: `admins` (the default), `team`, `custom`, or `none`. * `reviewerEmails` - Required when `reviewerType` is `custom` and invalid otherwise. Values must be active members of the factory's team. ### `agentDefaults` **Required.** Execution defaults inherited by every agent. Declare exactly one of `model` or `harness`. Agents can override these defaults. ```yaml agentDefaults: model: auto runner: linux-build environmentId: PAYMENTS_ENVIRONMENT_ID ``` ### `agentDefaults.model` **Conditionally required.** Set exactly one of `model` or `harness`. The `model_id` used for runs. See [model choice for agents](/agents/inference/model-choice/). `model` is shorthand for the Warp Agent harness: ```yaml model: auto ``` is equivalent to: ```yaml harness: type: oz model: auto ``` `model` and `harness` are mutually exclusive everywhere they appear. ### `agentDefaults.harness` **Conditionally required.** Set exactly one of `model` or `harness`. The run harness and model. The object requires `type` and `model`. `type` accepts `oz`, `claude`, `codex`, or `claude-code` (an alias for `claude`). Prefer the canonical [harness identifier](/platform/harnesses/#harness-identifiers) used by the CLI and the Warp Platform API. See [supported harnesses](/platform/harnesses/) for availability and behavior. ```yaml harness: type: codex model: gpt-5.3-codex reasoningLevel: high auth: source: managedSecret secretName: CODEX_API_KEY ``` Optional `auth` requires `source`. `managedSecret` also requires `agentDefaults.harness.auth.secretName`; `workerEnvironment` rejects it and requires a self-hosted `workerHost`. Set the source with `agentDefaults.harness.auth.source`. The `oz` harness supplies its own credentials and rejects `auth` and `reasoningLevel`. Third-party harnesses accept optional `reasoningLevel`. For per-agent harnesses and managed-secret authentication, see [`03-multi-harness`](https://github.com/warpdotdev/warp-factory-examples/tree/main/examples/03-multi-harness). To use the dashboard instead, see [configuring a third-party harness](/factories/factory-agents/#configuring-a-third-party-harness). ### `agentDefaults.runner` **Optional.** The name of a runner defined under [`runners/`](#runnersnameyaml) that provides the compute for runs. ### `agentDefaults.environmentId` **Optional.** The ID of an existing [environment](/platform/environments/) for runs. Omit it to let Warp manage the workspace from the factory's repositories. ### `agentDefaults.secrets` **Optional.** Managed secrets inherited by agents without their own `secrets` list. An agent-level list replaces this one; factory-wide [`secrets`](#secrets) still apply. ### `agentDefaults.mcpServers` **Optional.** MCP servers inherited by agents without their own map, using the [`mcpServers`](#mcpservers) syntax. An agent-level map replaces this one; factory-wide servers still apply. ### `agentDefaults.workerHost` **Optional.** Where runs execute: `warp` for Warp-hosted compute, or the ID of a connected [self-hosted worker](/factories/self-hosting/). Omit the key for the workspace default. At the agent or automation level, use `null` or an empty string to clear an inherited host. Configure the backend on the worker; the definition selects only the worker and runner. ### `agentDefaults.computerUseModel` **Optional.** The `model_id` used by Computer Use. Omit it for automatic selection. ```yaml agentDefaults: model: auto computerUseModel: claude-5-sonnet-high ``` Use `computer-use-agent-auto` for automatic selection. A model suffix selects its effort level; `thinking` enables thinking, and `xhigh-fast` selects fast mode. | Model | Supported values | | --- | --- | | Auto | `computer-use-agent-auto` | | Claude Sonnet 5 | `claude-5-sonnet-low`, `claude-5-sonnet-medium`, `claude-5-sonnet-high`, `claude-5-sonnet-xhigh`, `claude-5-sonnet-max` | | Claude Opus 5 | `claude-5-opus-low`, `claude-5-opus-medium`, `claude-5-opus-high`, `claude-5-opus-xhigh`, `claude-5-opus-xhigh-fast`, `claude-5-opus-max` | | Claude Fable 5.1 | `claude-5-1-fable-low`, `claude-5-1-fable-medium`, `claude-5-1-fable-high`, `claude-5-1-fable-xhigh`, `claude-5-1-fable-max` | | Claude Fable 5 | `claude-5-fable-low`, `claude-5-fable-medium`, `claude-5-fable-high`, `claude-5-fable-xhigh`, `claude-5-fable-max` | | Claude Opus 4.8 | `claude-4-8-opus-low`, `claude-4-8-opus-medium`, `claude-4-8-opus-high`, `claude-4-8-opus-xhigh`, `claude-4-8-opus-xhigh-fast`, `claude-4-8-opus-max` | | Claude Opus 4.7 | `claude-4-7-opus-high`, `claude-4-7-opus-xhigh`, `claude-4-7-opus-max` | | Claude Opus 4.6 | `claude-4-6-opus-high`, `claude-4-6-opus-max` | | Claude Sonnet 4.6 | `claude-4-6-sonnet-high`, `claude-4-6-sonnet-max` | | Claude Opus 4.5 | `claude-4-5-opus`, `claude-4-5-opus-thinking` | | Claude Sonnet 4.5 | `claude-4-5-sonnet`, `claude-4-5-sonnet-thinking` | | Claude Haiku 4.5 | `claude-4-5-haiku` | The value must be available to your plan and workspace. See [model choice for agents](/agents/inference/model-choice/) for availability and data retention. Agents and automations can override `computerUseModel`. An omitted or `null` agent value inherits `agentDefaults.computerUseModel`; an automation inherits the selected agent's effective value. The setting applies only to Computer Use on the Warp Agent harness (`type: oz`). Warp preserves but ignores it otherwise. It can appear with `model` or `harness` because it doesn't select the main model. ## `agents/<name>/agent.md` **Required resource.** Every definition includes at least one agent file. Each agent has one file. The directory names the agent, the YAML frontmatter configures it, and the Markdown body contains its instructions. ```markdown title="agents/reviewer/agent.md" --- description: Reviews factory-produced pull requests agentType: REVIEW --- Review each pull request against the repository's standards. Request changes when tests are missing; never approve your own edits. ``` All frontmatter keys are optional: * `description` - What the agent does. * [`agentType`](#agenttype) - The agent's role. * `credentialStrategy` - Overrides the factory-level [`credentialStrategy`](#credentialstrategy). Omit it to keep the agent's current setting. * `spawnableBy` - Agents allowed to start this agent. Omit it to allow only the foreman, use an empty list to allow none, or list exact agent names. * `model` or `harness`, `runner`, `environmentId`, `secrets`, `mcpServers`, `workerHost`, `computerUseModel` - Override the corresponding [`agentDefaults`](#agentdefaults). * `idleTimeoutMinutes` - Keeps a completed session available for follow-up for 1 through 60 minutes. Omit it or use `null` to inherit. Without an inherited or run-level value, Warp uses 10 minutes, or 60 minutes for an orchestrated child run. * `required_repos` - Repositories prepared for every run by this agent. Each item requires `required_repos[].owner` and `required_repos[].name`. Use `required_repos[].codeForge` to distinguish the same repository across hosts. An agent's `harness` object is a sparse override of [`agentDefaults.harness`](#agentdefaultsharness). Set `auth` to `null` to clear inherited authentication. Agent-level `mcpServers` entries use the same transport keys as the factory-level [`mcpServers`](#mcpservers) map. ### `agentType` **Optional.** The agent's role: `CUSTOM` (default), `FOREMAN` (alias `MAIN`), `TRIAGE`, `SPEC`, `IMPLEMENT`, `REVIEW`, or `VERIFY`. Every factory has one foreman, which serves as its entry point and the default automation target. See [factory agents](/factories/factory-agents/) for role behavior. ## `automations/<name>/automation.md` **Optional resource.** Each automation has one file. The directory names the automation, the frontmatter defines its triggers and execution settings, and the Markdown body contains the starting prompt. ```markdown title="automations/labeled-issue/automation.md" --- 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. Return unresolved product questions to a human. ``` ### `enabled` **Optional.** Turns the automation on or off. Defaults to `true`. ### `agent` **Optional.** The agent that handles the automation's runs. Defaults to the foreman. ### `triggers` **Required.** One or more events that start runs. Every automation requires `triggers`. Each trigger declares `provider` and `event`, and can include `filter` or, for scheduled runs, `schedule`. The providers and their events: * `azure_devops` - `pull_request_closed`, `pull_request_commented`, `pull_request_created`, `pull_request_mentioned`, `pull_request_merged`, `pull_request_updated`, `push`, `work_item_assigned`, `work_item_created`, `work_item_labeled`, `work_item_mentioned` * `github` - `check_run_rerequested`, `check_suite_completed`, `check_suite_rerequested`, `issue_assigned`, `issue_commented`, `issue_created`, `issue_labeled`, `issue_mentioned`, `pull_request_assigned`, `pull_request_closed`, `pull_request_commented`, `pull_request_labeled`, `pull_request_mentioned`, `pull_request_merged`, `pull_request_opened`, `pull_request_ready`, `pull_request_reopened`, `pull_request_review_requested`, `pull_request_review_submitted`, `pull_request_synchronized`, `push`, `workflow_run_completed` * `gitlab` - `bot_mentioned`, `merge_request`, `push` * `linear` - `agent_session_created`, `comment_created`, `issue_assigned`, `issue_created`, `issue_labeled`, `issue_state_changed` * `jira` - `agent_session_created`, `issue_created`, `issue_labeled`, `status_changed` * `slack` - `app_mention`, `member_joined_channel`, `message_dm`, `message_im`, `message_mpim`, `message_posted`, `reaction_added` * `teams` - `app_mention`, `message_posted` * `schedule` - `cron_fired` * `webhook` - `received` * `factory` - `work_item_stage_changed` Slack, Microsoft Teams, Linear, and Jira triggers require the matching [integration](/platform/integrations/) to be connected. Code-forge triggers use the factory's repositories and provider connection; see the [GitHub](/factories/integrations/github/), [GitLab](/factories/integrations/gitlab/), and [Azure DevOps](/factories/integrations/azure-devops/) integration guides. `webhook` triggers listen to [custom webhooks](/factories/webhooks/) declared under [`webhooks/`](#webhooksnameyaml). ### `triggers[].filter` **Conditionally required.** Required for `webhook` / `received`; optional for other triggers. Narrows which events start runs. Available keys depend on the provider and event, such as `repos`, `labels`, and `authors` for GitHub or `channels`, `users`, and `keywords` for Slack. Keys combine with AND. Within a key's list, any value can match. An omitted key matches everything. Most canonical keys accept matcher objects with `in` and `not_in`. The name-based aliases `issues`, `projects`, `states`, `teams`, `channels`, `users`, and `itemUsers` take plain lists; Warp resolves their values to IDs. A `webhook` trigger for `received` requires `webhook_ids`: a one-item list with one webhook UID. It supports `in` only and doesn't accept a file name. To listen to multiple webhooks, add one trigger per UID. The optional `payload` pattern matches against the delivery's JSON body. See [webhook payload filters](/factories/automations/#payload-filters-for-webhook-triggers) for the pattern syntax. Filter keys by provider: * Factory: `stages`. * Azure DevOps: `assignees`, `authors`, `base_branches`, `branches`, `labels`, `mentioned`, `repos`, `source_repos`, and `work_item_types`. * GitHub: `assignees`, `authors`, `baseBranches`, `base_branches`, `branches`, `conclusions`, `keywords`, `labels`, `mentioned`, `paths`, `prNumbers`, `pr_numbers`, `repos`, `review_states`, `reviewer_teams`, `reviewers`, and `workflows`. * GitLab: `actions`, `base_branches`, `branches`, `mentioned`, and `repos`. * Jira: `keywords`, `labels`, `project_keys`, and `status_ids`. * Linear: `assignee_ids`, `creator_ids`, `issue_ids`, `issues`, `keywords`, `labels`, `mentioned_user_ids`, `project_ids`, `projects`, `state_ids`, `states`, `team_ids`, and `teams`. * Schedule: `schedule_ids` is server-managed and cannot be set in a factory definition. * Slack: `channel_ids`, `channels`, `emojis`, `itemUsers`, `item_user_ids`, `keywords`, `user_ids`, and `users`. * Microsoft Teams: `channel_ids`, `keywords`, `team_ids`, and `user_ids`. * Webhook: `payload` and `webhook_ids`. Matcher objects use `in` to include values and `not_in` to exclude them. Webhook `payload` also accepts `exists`. Microsoft Teams `team_ids` and `channel_ids` support only `in`. For Microsoft Teams, `team_ids` contains exactly one Microsoft Graph team UUID, and `channel_ids` contains at least one channel ID. `baseBranches` and `prNumbers` are authoring aliases for `base_branches` and `pr_numbers`. `teams`, `projects`, `states`, `issues`, `channels`, `users`, and `itemUsers` are name-based aliases for their `_ids` counterparts. An alias and its canonical key are mutually exclusive. ```yaml triggers: - provider: webhook event: received filter: webhook_ids: [WEBHOOK_UID] payload: status: [failed] ``` ### `triggers[].schedule` **Conditionally required.** Required for `schedule` / `cron_fired` and invalid for other triggers. Defines an inline UTC schedule for a `schedule` / `cron_fired` trigger. The object requires `cron`, which accepts a five-field expression or a descriptor such as `@daily` or `@every 1h`. Use optional `name` to distinguish multiple schedules; at most one can omit it. Changing only `cron` updates a schedule, while changing `name` replaces it. ```yaml triggers: - provider: schedule event: cron_fired schedule: name: weekday-mornings cron: "0 9 * * 1-5" ``` ### Execution overrides **Optional.** An automation can declare `displayName`, plus `model` or `harness`, `runner`, `environmentId`, `secrets`, `mcpServers`, `workerHost`, `computerUseModel`, `idleTimeoutMinutes`, and `required_repos`. Use `null` to clear `displayName`. Execution settings override the target agent for runs from this automation. Automation `required_repos` entries extend the target agent's list. Each item requires `required_repos[].owner` and `required_repos[].name`; use `required_repos[].codeForge` to distinguish the same repository across hosts. The `harness` object uses the same sparse override as an agent. Automation-level `mcpServers` use the [factory-level transport syntax](#mcpservers). Omit `idleTimeoutMinutes`, or set it to `null`, to inherit the target agent's value. ## `runners/<name>.yaml` **Optional resource.** Runner files define compute. Agents and automations select a file by name with `runner`. See [cloud agent runners](/factories/runners/) for runtime behavior and [`02-sdlc-issue-to-pr`](https://github.com/warpdotdev/warp-factory-examples/tree/main/examples/02-sdlc-issue-to-pr) for Linux and macOS examples. ```yaml title="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 ``` ### `description` **Optional.** A description of the runner. ### `setupCommands` **Optional.** Shell commands that run in order while the sandbox is prepared. ### `instanceShape` **Optional.** The compute size. When set, `instanceShape` requires both `vcpus` and `memoryGb`. Omit it for the workspace default. Linux and Windows require powers of two. macOS accepts 4 vCPUs with 7 GB, 6 vCPUs with 14 GB, 8 vCPUs with 14 GB, 12 vCPUs with 28 GB, or 12 vCPUs with 56 GB. ### `platform` **Required.** The operating system and architecture. `os` accepts `linux` (default), `macos`, or `windows`. `arch` accepts `x86_64` (the Linux default and only Windows option) or `aarch64` (supported on Linux and required on macOS). Linux runners require `platform.linux.dockerImage`. For macOS, `platform.mac.version` accepts `"14"`, `"15"`, `"26"`, or `"27"`. Quote the version; omitting `platform.mac` uses `"26"`. For a private Linux image, set `linux.registryCredentialSecretName` to the name of a managed Docker registry (`docker_registry`) or AWS ECR (`aws_ecr_credential`) credential. The credential's registry host must match the host in `linux.dockerImage`. ### `failureSessionRetentionMinutes` **Optional.** Keeps a failed session open for inspection for 1 through 60 minutes. Omit it to use the environment setting. ## `routers/<name>.yaml` **Optional resource.** Router files define factory-owned custom model routers. Use the file name anywhere the definition accepts a model. | Field | Requirement | Description | | --- | --- | --- | | `name` | Optional | Display label. | | `type` | Required | `complexity` or `prompt`. | | `default` | Required | Concrete model used when no route matches. | | `routing` | Optional | Type-specific routing rules. | ```yaml title="routers/by-task.yaml" name: By task type: prompt default: claude-4-6-sonnet-high routing: - description: Routine documentation changes model: claude-4-5-haiku - description: Complex implementation or debugging model: claude-4-8-opus-high ``` For `type: complexity`, optional `routing.easy`, `routing.medium`, and `routing.hard` map complexity levels to concrete models. For `type: prompt`, `routing` is an ordered list of `routing.description` and `routing.model` pairs. Each pair requires both fields. `routing` is optional for either type. Targets must be concrete supported models, not Auto models or other routers. See [custom model routers](/agents/inference/custom-routers/) for routing behavior. Factory members who can access the router can also select it from model catalogs in the factory dashboard, including agent settings and benchmark configurations. ## `benchmarks/<suite-slug>/suite.yaml` **Optional resource.** Benchmark suite files define trials for one agent, with reusable configurations and an ordered task list. The directory slug is the suite's stable identity; changing `name` doesn't move the file. See [benchmarks](/factories/benchmarks/) for how to run a suite. ```yaml title="benchmarks/pull-request-review/suite.yaml" name: Pull request review description: Compare configurations for the review agent. agent: reviewer configurations: - name: Baseline agents: - agent: reviewer model: auto - name: Candidate agents: - agent: reviewer model: auto-efficient tasks: - broken-doc-link ``` ### `name` **Required.** The suite display name, which must be unique in the factory. ### `description` **Optional.** A short summary of what the suite measures. ### `agent` **Required.** The factory agent used for every task in the suite. ### `configurations` **Optional.** One to six reusable configurations. Warp uses these presets when a benchmark run doesn't supply configurations. Each configuration requires a unique `name`. Optional `role` is deprecated metadata. Warp ignores it and omits it when rewriting the suite. The optional `agents` list pins factory agents to models and harnesses for the configuration's trials. Each `configurations[].agents[]` item names an `agent` and includes exactly one of `model` or `harness`. A `harness` requires `type` and `model`; `type` accepts `oz`, `claude`, `claude-code`, and `codex`. Optional `auth` follows the [harness authentication rules](#agentdefaultsharness). List an agent once per configuration. Omitted agents use their settings at launch time. ### `tasks` **Optional.** An ordered list of unique task slugs. Each slug matches one file under `benchmarks/<suite-slug>/tasks/`, and every task file appears once. A suite without tasks can be saved but not run. ## `benchmarks/<suite-slug>/tasks/<task-slug>.yaml` **Optional resource.** Each task file belongs to its parent suite. The file name without `.yaml` is the stable task slug. ```yaml title="benchmarks/pull-request-review/tasks/broken-doc-link.yaml" title: Fix a broken documentation link prompt: Find the broken internal documentation link and update it. successCriteria: The destination resolves and the link text names the destination. startingRepoRefs: - github.com:acme/payments-docs@0123456789abcdef0123456789abcdef01234567 ``` ### `title` **Required.** The task display name. It doesn't need to match the task slug. ### `prompt` **Required.** The instructions sent to the agent. ### `successCriteria` **Required.** The Correctness Scorer's evaluation criteria. ### `sourceRunId` **Optional.** The ID of the prior run that produced the task. This records provenance and can refer to a deleted run. ### `tags` **Optional.** An ordered list of task labels. ### `linearSeed` **Optional.** JSON-compatible starting state for the trial's isolated Linear workspace. ### `startingRepoRefs` **Optional.** The GitHub or GitLab repositories and commits used as the task's starting state. Each entry accepts `github.com:OWNER/REPO@COMMIT_SHA`, `gitlab.com:OWNER/REPO@COMMIT_SHA`, or an object with `codeForge` (`GITHUB` or `GITLAB`), `owner`, `repo`, and `ref`. All four object fields are required. `COMMIT_SHA` and `ref` must be full 40-character commit SHAs, not branches or tags. Omit the key to use the agent's checkout defaults. ## `scorers/<name>/scorer.md` **Optional resource.** Scorer files define LLM judges that classify sampled runs against a rubric. The directory is a stable slug; `name` identifies the scorer. Frontmatter defines the classification contract, and the Markdown body holds the rubric. See [configuring scorers](/factories/measure-and-improve/scorers/) for how scores are used. ```markdown title="scorers/tests-run/scorer.md" --- name: tests-run description: Checks whether implementation runs include test evidence. agents: - reviewer labels: - value: tests_run description: The transcript contains a test command and its result. score: 1 - value: tests_skipped score: 0 passingScore: 1 samplingRate: 25 model: claude-4-5-haiku --- Evaluate whether the agent ran the relevant tests before finishing. Return exactly one declared label. ``` ### `name` **Required.** The scorer's identity. Changing it doesn't move the directory. ### `description` **Optional.** A short summary of what the scorer checks. ### `agents` **Required.** The agents whose runs the scorer evaluates. A string names one agent and scores only that run. To include child runs as evidence, use an object with required `name` and optional `includeDescendants: true`. ```yaml agents: - name: foreman includeDescendants: true ``` ### Scorer execution settings **Optional.** `runner`, `secrets`, and `mcpServers` override the factory's `scorerDefaults` for this scorer. Scorer-level `mcpServers` use the [factory-level transport syntax](#mcpservers). Set shared values under `scorerDefaults` in `factory.yaml`. ### `output` **Optional.** The scorer output form. `classification` is the supported value. ### `labels` **Required.** One to 20 classifications. Each label requires a unique `value` and a `score` from 0 through 1; `description` is optional. At least one label must meet `passingScore`, and at least one must fall below it. ### `passingScore` **Required.** The passing threshold, from 0 through 1. ### `samplingRate` **Optional.** The percentage of eligible runs to score, from 0 through 100. It defaults to 25, rounds to two decimal places, and disables automatic scoring at 0. ### `model` **Required.** The model that judges runs. ### `selfImprovement` **Optional.** When `true`, failing scores can feed the self-improvement flow, which proposes definition changes in pull requests. Defaults to `false`. ## `webhooks/<name>.yaml` **Optional resource.** Webhook files define [authenticated URLs](/factories/webhooks/) for JSON POST requests. Automation `webhook` triggers subscribe to them; the file name names the webhook. `secretName` references an existing [managed secret](/platform/secrets/), not secret material. ```yaml title="webhooks/internal-ci.yaml" authMode: token secretName: INTERNAL_CI_WEBHOOK_SECRET deliveryIdHeader: X-CI-Run-Id enabled: true ``` ### `authMode` **Optional.** How deliveries authenticate: `token` (default, using an `Authorization: Bearer` header), `url_token` (secret in the URL path), or `signature` (the provider's signature scheme). See [webhook authentication modes](/factories/webhooks/#authentication-modes). ### `signatureScheme` **Conditionally required.** Required for `authMode: signature` and invalid otherwise. The provider signature to verify: `github`, `pagerduty`, `sentry`, `standard_webhooks`, `stripe`, or `vercel`. ### `secretName` **Required.** The managed secret containing the bearer token, URL token, or provider signing secret. A `url_token` secret becomes part of the ingress URL and accepts only letters, digits, `-`, `.`, `_`, and `~`. ### `deliveryIdHeader` **Optional.** The sender's delivery ID header, used to deduplicate retries. It accepts up to 64 characters and must be a valid HTTP header name. Credential-bearing headers such as `Authorization`, `Cookie`, and provider signature headers are rejected. ### `enabled` **Optional.** Whether the webhook accepts deliveries. Defaults to `true`. Use `false` to stop deliveries immediately without deleting the webhook, or to create it before the provider issues a signing secret. See [setting up a Vercel webhook](/factories/webhooks/vercel/). On a Warp-managed factory, creating a webhook in the dashboard writes this file for you and stores the secret under the name you enter in the "Secret name" field. You can't change `authMode` or `signatureScheme` on an existing webhook. Delete and recreate the webhook, or create the replacement under a different name. ## Skills **Optional resource.** A skill is a directory containing `SKILL.md`, not a YAML key. Put shared skills under `skills/` and agent-specific skills under `agents/<name>/skills/`. See [factory skills](/factories/factory-skills/) for placement and [Skills](/agents/capabilities/skills/) for the file format. ## Example factory definition This definition includes one repository, a foreman, an automation triggered by a GitHub label, and a Linux runner. Replace `PAYMENTS_ENVIRONMENT_ID` and `SENTRY_MCP_SERVER_ID` with existing resource IDs. For more complete definitions, see [warp-factory-examples](https://github.com/warpdotdev/warp-factory-examples). ```yaml title="factory.yaml" schemaVersion: v1alpha1 name: payments-factory description: Processes approved work for the payments service alias: payments repositories: - owner: acme name: payments-service agentDefaults: model: auto runner: linux-build environmentId: PAYMENTS_ENVIRONMENT_ID ``` ```markdown title="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. ``` ```markdown title="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. ``` ```yaml title="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 ``` ### Routing to a self-hosted worker To use a [managed self-hosted worker](/factories/infrastructure-and-security/#choose-an-execution-host), set `agentDefaults.workerHost` to the worker ID. Agents and automations can override it. ```yaml title="factory.yaml" agentDefaults: model: auto runner: linux-build workerHost: SELF_HOSTED_WORKER_ID ``` Pair `workerHost` with a runner whose `platform` matches the worker. Follow the [self-hosting quickstart](/factories/self-hosting/quickstart/) to connect a worker, or copy [`07-self-hosted-worker`](https://github.com/warpdotdev/warp-factory-examples/tree/main/examples/07-self-hosted-worker). ## Related pages * [**Factory MCP for coding agents**](/factories/factory-mcp/) - Read the schema and validate a tree from any coding agent, and send work to a factory. * [**GitHub integration**](/factories/integrations/github/#factory-definition-pull-request-checks) - How the **warp/factory-config** check appears on pull requests, and what to check when it doesn't. * [**Factory dashboard**](/factories/factory-dashboard/#edit-definitions-in-the-factory-definition-tab) - Where a Warp-managed definition is edited and validated on save. * [**warp-factory-examples**](https://github.com/warpdotdev/warp-factory-examples) - Complete definitions to copy, plus the validator script and a CI workflow that runs it.Tell me about this feature: https://docs.warp.dev/factories/factory-as-code/Look up the files and public keys in a factory definition: factory.yaml, agents, automations, runners, routers, benchmarks, scorers, skills, and webhooks.
A factory definition is a versioned tree of YAML and Markdown files rooted at factory.yaml. It can define agents, automations, runners, model routers, benchmarks, scorers, skills, and webhooks. Keys are case-sensitive, and Warp applies file changes automatically.
For working definitions you can copy, see warp-factory-examples.
Where the definition lives
Section titled “Where the definition lives”Choose where to host the definition when you create a factory:
- Warp-managed (default) - Edit the definition in the Warp Factories web app. Warp validates, commits, and applies changes; its repository stays hidden.
- GitHub - On a paid plan, keep the definition in your own repository. The web app links to the files in a read-only view. Merges to the production branch (
mainby default) update the factory.
Both modes share the file format. You can link a Warp-managed factory to GitHub later.
Work items, runs, and metrics live in the web app, not in the definition.
Validate a definition
Section titled “Validate a definition”Warp validates syntax, required fields, and resource access before applying a definition: on save for a Warp-managed factory, and in pull requests to a GitHub-backed factory’s production branch.
Pull request checks
Section titled “Pull request checks”Every pull request to the production branch gets a warp/factory-config check. It reports errors by file and line or summarizes the resources a valid change will create, update, or delete. Pull requests that don’t change the definition pass immediately.
Require the check in branch protection to block invalid definitions.
Warp applies a definition as one unit. If validation fails, the factory keeps its last valid definition.
For subdirectory check names and troubleshooting, see factory-definition pull request checks.
Validate locally or in CI
Section titled “Validate locally or in CI”Run validate_factory_files.py before opening a pull request or in CI. It requires Python 3, but no Warp login or existing factory.
python3 scripts/validate_factory_files.py path/to/factory-rootPass the factory root to check cross-file references. The script reports errors by file and line. The GitHub check also validates team- and factory-dependent settings.
For a CI job built on the script, see the example repository’s validation workflow.
Validate with a coding agent
Section titled “Validate with a coding agent”- Warp Agent - Ask the agent to change or check the definition. Its
factory-filesskill validates before opening a pull request. For example: “Add a nightly dependency-audit automation and validate the definition.” - Factory MCP - Connect another coding agent to Factory MCP for schema and validation tools.
- Other agents - Have the agent run the validator script.
JSON Schema
Section titled “JSON Schema”Warp publishes unauthenticated JSON Schemas for editor completion and validation. They describe each field and reject unknown keys.
https://app.warp.dev/api/v1/factory-files/schemas- Lists supported versions and the current version.https://app.warp.dev/api/v1/factory-files/schemas/v1alpha1- Returns allv1alpha1documents, keyed by document name.https://app.warp.dev/api/v1/factory-files/schemas/v1alpha1/<document>- Returns one document for use as a schema reference.
Documents include factory.schema.json for factory.yaml; agent.schema.json, automation.schema.json, and scorer.schema.json for Markdown frontmatter; runner.schema.json, router.schema.json, webhook.schema.json, benchmark_suite.schema.json, and benchmark_suite_task.schema.json for YAML resources; and common.schema.json for shared definitions.
For completion and inline validation in the VS Code YAML extension, add the document URL on the first line:
# yaml-language-server: $schema=https://app.warp.dev/api/v1/factory-files/schemas/v1alpha1/factory.schema.jsonschemaVersion: v1alpha1name: payments-factoryYAML schemas don’t apply to Markdown frontmatter. Use one of the definition validators for Markdown files.
Directory structure
Section titled “Directory structure”Each resource takes its name from its path: agents/reviewer/agent.md defines an agent named reviewer.
factory.yamlagents/ foreman/ agent.md skills/ incident-triage/ SKILL.md reviewer/ agent.mdautomations/ labeled-issue/ automation.mdrunners/ linux-build.yamlrouters/ by-task.yamlbenchmarks/ pull-request-review/ suite.yaml tasks/ broken-doc-link.yamlscorers/ tests-run/ scorer.mdskills/ repository-conventions/ SKILL.mdwebhooks/ internal-ci.yamlSee the example factory definition, the minimal 01-single-repo-quickstart, or the full 02-sdlc-issue-to-pr.
factory.yaml
Section titled “factory.yaml”Required resource. The root document names the factory, scopes it to repositories, and sets execution defaults.
schemaVersion: v1alpha1name: payments-factoryrepositories: - owner: acme name: payments-serviceagentDefaults: model: autoschemaVersion
Section titled “schemaVersion”Required.
Every definition sets schemaVersion: v1alpha1.
Required. The factory’s name.
description
Section titled “description”Optional. What the factory is for.
Optional.
The handle used to @-mention the foreman on platforms such as Slack and Linear. The factory dashboard labels it Foreman name. It accepts up to 60 letters, numbers, spaces, ., _, and -, and is case-insensitively unique in the workspace.
credentialStrategy
Section titled “credentialStrategy”Optional.
Whose credentials runs use: EXECUTOR for the executing principal, or CREATOR for the user who created the run. CREATOR requires a paid plan. Omit the key to preserve the setting; otherwise, it defaults to EXECUTOR. Agents can override it by role.
codeForges
Section titled “codeForges”Optional.
The enabled code hosts: GITHUB, GITLAB, and AZURE_DEVOPS. Omit the key to preserve them. With multiple hosts, set codeForge on every repository. An empty codeForges list requires empty repositories and configures no code host.
repositories
Section titled “repositories”Required.
The factory’s repositories. The list can be empty. Each entry requires owner and name; optional codeForge selects GITHUB, GITLAB, or AZURE_DEVOPS. With multiple codeForges, every repository requires codeForge.
Optional deferred defaults to false. Set it to true to attach a repository without preparing it for every run. Warp prepares it when an agent or automation lists it in required_repos, or a run adds it.
codeForges: - GITHUB - GITLABrepositories: - codeForge: GITHUB owner: acme name: payments-service - codeForge: GITLAB owner: acme/platform name: deployment-configbenchmarkRepoSubstitutions
Section titled “benchmarkRepoSubstitutions”Optional.
Repository substitutions for benchmark starting states. Each entry requires source and target objects, each with codeForge, owner, and name. Both codeForge values must be GITHUB; the source must belong to the factory, and the target must not.
secrets
Section titled “secrets”Optional. Names of managed secrets granted to every agent, in addition to secrets declared by an agent.
mcpServers
Section titled “mcpServers”Optional. MCP servers granted to every agent, keyed by the name shown to the agent. Each entry selects exactly one transport:
warpId- A Warp-managed MCP server ID.command- A stdio command. Optionalargsis a list of strings, and optionalenvmaps names to string values.url- An absolute HTTP or HTTPS URL. Optionalheadersmaps header names to string values.
Don’t put credentials in env or headers. Reference a managed secret as {{SECRET_NAME}}, or use warpId for a managed MCP installation.
mcpServers: sentry: warpId: SENTRY_MCP_SERVER_IDcloudProviders
Section titled “cloudProviders”Optional. Cloud-provider identity federation for agent runs:
cloudProviders.gcpconfigures Google Cloud. It requirescloudProviders.gcp.projectNumber,cloudProviders.gcp.workloadIdentityFederationPoolId, andcloudProviders.gcp.workloadIdentityFederationProviderId. QuoteprojectNumberso YAML keeps it as a string. OptionalcloudProviders.gcp.serviceAccountEmailselects a service account.cloudProviders.aws.roleArnconfigures AWS and is required for that provider.
cloudProviders: aws: roleArn: arn:aws:iam::123456789012:role/warp-factoryintegrations
Section titled “integrations”Optional.
The integration providers attached to the factory: slack, microsoft-teams, linear, and jira. Each entry requires type. Declare at most one issue tracker because linear and jira are mutually exclusive. Code-forge access comes from repositories, not this list.
Omit integrations to preserve the currently attached providers. Set it to an empty list to detach every provider.
integrations: - type: slack - type: linearFor Slack and Microsoft Teams, slack.autoRespondToThreadReplies and microsoft-teams.autoRespondToThreadReplies control whether eligible plain replies in an existing factory thread can continue work without another mention. The Slack setting defaults to true. The Microsoft Teams setting defaults to true when the shared per-factory reply setting is enabled.
integrations: - type: slack slack: autoRespondToThreadReplies: falseintegrations[].linear.teamIds and integrations[].jira.projectKeys are accepted for compatibility but don’t control issue discovery or routing. Warp omits them when rewriting the definition. Use automation filters such as team_ids and project_keys.
providers
Section titled “providers”Optional.
Accepted as a legacy alias for cloudProviders with the same keys. Use cloudProviders in new files. Warp writes the canonical key when it updates an older definition.
scorerDefaults
Section titled “scorerDefaults”Optional.
Sets runner, secrets, and mcpServers for file-defined scorers. A scorer can override each value. The mcpServers map uses the factory-level transport syntax.
selfImprovement
Section titled “selfImprovement”Optional. Configures scheduled self-improvement for a GitHub-backed factory:
failedRunThreshold- Distinct scored failures per agent required before a scheduled self-improvement run. Use a value from 1 through 50, or omit it for the server default.reviewerType- The pool used to request one reviewer:admins(the default),team,custom, ornone.reviewerEmails- Required whenreviewerTypeiscustomand invalid otherwise. Values must be active members of the factory’s team.
agentDefaults
Section titled “agentDefaults”Required.
Execution defaults inherited by every agent. Declare exactly one of model or harness. Agents can override these defaults.
agentDefaults: model: auto runner: linux-build environmentId: PAYMENTS_ENVIRONMENT_IDagentDefaults.model
Section titled “agentDefaults.model”Conditionally required. Set exactly one of model or harness.
The model_id used for runs. See model choice for agents. model is shorthand for the Warp Agent harness:
model: autois equivalent to:
harness: type: oz model: automodel and harness are mutually exclusive everywhere they appear.
agentDefaults.harness
Section titled “agentDefaults.harness”Conditionally required. Set exactly one of model or harness.
The run harness and model. The object requires type and model. type accepts oz, claude, codex, or claude-code (an alias for claude). Prefer the canonical harness identifier used by the CLI and the Warp Platform API. See supported harnesses for availability and behavior.
harness: type: codex model: gpt-5.3-codex reasoningLevel: high auth: source: managedSecret secretName: CODEX_API_KEYOptional auth requires source. managedSecret also requires agentDefaults.harness.auth.secretName; workerEnvironment rejects it and requires a self-hosted workerHost. Set the source with agentDefaults.harness.auth.source.
The oz harness supplies its own credentials and rejects auth and reasoningLevel. Third-party harnesses accept optional reasoningLevel.
For per-agent harnesses and managed-secret authentication, see 03-multi-harness. To use the dashboard instead, see configuring a third-party harness.
agentDefaults.runner
Section titled “agentDefaults.runner”Optional.
The name of a runner defined under runners/ that provides the compute for runs.
agentDefaults.environmentId
Section titled “agentDefaults.environmentId”Optional. The ID of an existing environment for runs. Omit it to let Warp manage the workspace from the factory’s repositories.
agentDefaults.secrets
Section titled “agentDefaults.secrets”Optional.
Managed secrets inherited by agents without their own secrets list. An agent-level list replaces this one; factory-wide secrets still apply.
agentDefaults.mcpServers
Section titled “agentDefaults.mcpServers”Optional.
MCP servers inherited by agents without their own map, using the mcpServers syntax. An agent-level map replaces this one; factory-wide servers still apply.
agentDefaults.workerHost
Section titled “agentDefaults.workerHost”Optional.
Where runs execute: warp for Warp-hosted compute, or the ID of a connected self-hosted worker. Omit the key for the workspace default. At the agent or automation level, use null or an empty string to clear an inherited host. Configure the backend on the worker; the definition selects only the worker and runner.
agentDefaults.computerUseModel
Section titled “agentDefaults.computerUseModel”Optional.
The model_id used by Computer Use. Omit it for automatic selection.
agentDefaults: model: auto computerUseModel: claude-5-sonnet-highUse computer-use-agent-auto for automatic selection. A model suffix selects its effort level; thinking enables thinking, and xhigh-fast selects fast mode.
| Model | Supported values |
|---|---|
| Auto | computer-use-agent-auto |
| Claude Sonnet 5 | claude-5-sonnet-low, claude-5-sonnet-medium, claude-5-sonnet-high, claude-5-sonnet-xhigh, claude-5-sonnet-max |
| Claude Opus 5 | claude-5-opus-low, claude-5-opus-medium, claude-5-opus-high, claude-5-opus-xhigh, claude-5-opus-xhigh-fast, claude-5-opus-max |
| Claude Fable 5.1 | claude-5-1-fable-low, claude-5-1-fable-medium, claude-5-1-fable-high, claude-5-1-fable-xhigh, claude-5-1-fable-max |
| Claude Fable 5 | claude-5-fable-low, claude-5-fable-medium, claude-5-fable-high, claude-5-fable-xhigh, claude-5-fable-max |
| Claude Opus 4.8 | claude-4-8-opus-low, claude-4-8-opus-medium, claude-4-8-opus-high, claude-4-8-opus-xhigh, claude-4-8-opus-xhigh-fast, claude-4-8-opus-max |
| Claude Opus 4.7 | claude-4-7-opus-high, claude-4-7-opus-xhigh, claude-4-7-opus-max |
| Claude Opus 4.6 | claude-4-6-opus-high, claude-4-6-opus-max |
| Claude Sonnet 4.6 | claude-4-6-sonnet-high, claude-4-6-sonnet-max |
| Claude Opus 4.5 | claude-4-5-opus, claude-4-5-opus-thinking |
| Claude Sonnet 4.5 | claude-4-5-sonnet, claude-4-5-sonnet-thinking |
| Claude Haiku 4.5 | claude-4-5-haiku |
The value must be available to your plan and workspace. See model choice for agents for availability and data retention.
Agents and automations can override computerUseModel. An omitted or null agent value inherits agentDefaults.computerUseModel; an automation inherits the selected agent’s effective value. The setting applies only to Computer Use on the Warp Agent harness (type: oz). Warp preserves but ignores it otherwise. It can appear with model or harness because it doesn’t select the main model.
agents/<name>/agent.md
Section titled “agents/<name>/agent.md”Required resource. Every definition includes at least one agent file. Each agent has one file. The directory names the agent, the YAML frontmatter configures it, and the Markdown body contains its instructions.
---description: Reviews factory-produced pull requestsagentType: REVIEW---
Review each pull request against the repository's standards. Requestchanges when tests are missing; never approve your own edits.All frontmatter keys are optional:
description- What the agent does.agentType- The agent’s role.credentialStrategy- Overrides the factory-levelcredentialStrategy. Omit it to keep the agent’s current setting.spawnableBy- Agents allowed to start this agent. Omit it to allow only the foreman, use an empty list to allow none, or list exact agent names.modelorharness,runner,environmentId,secrets,mcpServers,workerHost,computerUseModel- Override the correspondingagentDefaults.idleTimeoutMinutes- Keeps a completed session available for follow-up for 1 through 60 minutes. Omit it or usenullto inherit. Without an inherited or run-level value, Warp uses 10 minutes, or 60 minutes for an orchestrated child run.required_repos- Repositories prepared for every run by this agent. Each item requiresrequired_repos[].ownerandrequired_repos[].name. Userequired_repos[].codeForgeto distinguish the same repository across hosts.
An agent’s harness object is a sparse override of agentDefaults.harness. Set auth to null to clear inherited authentication. Agent-level mcpServers entries use the same transport keys as the factory-level mcpServers map.
agentType
Section titled “agentType”Optional.
The agent’s role: CUSTOM (default), FOREMAN (alias MAIN), TRIAGE, SPEC, IMPLEMENT, REVIEW, or VERIFY. Every factory has one foreman, which serves as its entry point and the default automation target. See factory agents for role behavior.
automations/<name>/automation.md
Section titled “automations/<name>/automation.md”Optional resource. Each automation has one file. The directory names the automation, the frontmatter defines its triggers and execution settings, and the Markdown body contains the starting prompt.
---agent: foremantriggers: - provider: github event: issue_labeled filter: repos: [acme/payments-service] labels: [factory-ready]---
Review the labeled issue and decide the next required stage. Returnunresolved product questions to a human.enabled
Section titled “enabled”Optional.
Turns the automation on or off. Defaults to true.
Optional. The agent that handles the automation’s runs. Defaults to the foreman.
triggers
Section titled “triggers”Required.
One or more events that start runs. Every automation requires triggers. Each trigger declares provider and event, and can include filter or, for scheduled runs, schedule.
The providers and their events:
azure_devops-pull_request_closed,pull_request_commented,pull_request_created,pull_request_mentioned,pull_request_merged,pull_request_updated,push,work_item_assigned,work_item_created,work_item_labeled,work_item_mentionedgithub-check_run_rerequested,check_suite_completed,check_suite_rerequested,issue_assigned,issue_commented,issue_created,issue_labeled,issue_mentioned,pull_request_assigned,pull_request_closed,pull_request_commented,pull_request_labeled,pull_request_mentioned,pull_request_merged,pull_request_opened,pull_request_ready,pull_request_reopened,pull_request_review_requested,pull_request_review_submitted,pull_request_synchronized,push,workflow_run_completedgitlab-bot_mentioned,merge_request,pushlinear-agent_session_created,comment_created,issue_assigned,issue_created,issue_labeled,issue_state_changedjira-agent_session_created,issue_created,issue_labeled,status_changedslack-app_mention,member_joined_channel,message_dm,message_im,message_mpim,message_posted,reaction_addedteams-app_mention,message_postedschedule-cron_firedwebhook-receivedfactory-work_item_stage_changed
Slack, Microsoft Teams, Linear, and Jira triggers require the matching integration to be connected. Code-forge triggers use the factory’s repositories and provider connection; see the GitHub, GitLab, and Azure DevOps integration guides. webhook triggers listen to custom webhooks declared under webhooks/.
triggers[].filter
Section titled “triggers[].filter”Conditionally required. Required for webhook / received; optional for other triggers.
Narrows which events start runs. Available keys depend on the provider and event, such as repos, labels, and authors for GitHub or channels, users, and keywords for Slack. Keys combine with AND. Within a key’s list, any value can match. An omitted key matches everything.
Most canonical keys accept matcher objects with in and not_in. The name-based aliases issues, projects, states, teams, channels, users, and itemUsers take plain lists; Warp resolves their values to IDs.
A webhook trigger for received requires webhook_ids: a one-item list with one webhook UID. It supports in only and doesn’t accept a file name. To listen to multiple webhooks, add one trigger per UID. The optional payload pattern matches against the delivery’s JSON body. See webhook payload filters for the pattern syntax.
Filter keys by provider:
- Factory:
stages. - Azure DevOps:
assignees,authors,base_branches,branches,labels,mentioned,repos,source_repos, andwork_item_types. - GitHub:
assignees,authors,baseBranches,base_branches,branches,conclusions,keywords,labels,mentioned,paths,prNumbers,pr_numbers,repos,review_states,reviewer_teams,reviewers, andworkflows. - GitLab:
actions,base_branches,branches,mentioned, andrepos. - Jira:
keywords,labels,project_keys, andstatus_ids. - Linear:
assignee_ids,creator_ids,issue_ids,issues,keywords,labels,mentioned_user_ids,project_ids,projects,state_ids,states,team_ids, andteams. - Schedule:
schedule_idsis server-managed and cannot be set in a factory definition. - Slack:
channel_ids,channels,emojis,itemUsers,item_user_ids,keywords,user_ids, andusers. - Microsoft Teams:
channel_ids,keywords,team_ids, anduser_ids. - Webhook:
payloadandwebhook_ids.
Matcher objects use in to include values and not_in to exclude them. Webhook payload also accepts exists. Microsoft Teams team_ids and channel_ids support only in.
For Microsoft Teams, team_ids contains exactly one Microsoft Graph team UUID, and channel_ids contains at least one channel ID.
baseBranches and prNumbers are authoring aliases for base_branches and pr_numbers. teams, projects, states, issues, channels, users, and itemUsers are name-based aliases for their _ids counterparts. An alias and its canonical key are mutually exclusive.
triggers: - provider: webhook event: received filter: webhook_ids: [WEBHOOK_UID] payload: status: [failed]triggers[].schedule
Section titled “triggers[].schedule”Conditionally required. Required for schedule / cron_fired and invalid for other triggers.
Defines an inline UTC schedule for a schedule / cron_fired trigger. The object requires cron, which accepts a five-field expression or a descriptor such as @daily or @every 1h. Use optional name to distinguish multiple schedules; at most one can omit it. Changing only cron updates a schedule, while changing name replaces it.
triggers: - provider: schedule event: cron_fired schedule: name: weekday-mornings cron: "0 9 * * 1-5"Execution overrides
Section titled “Execution overrides”Optional.
An automation can declare displayName, plus model or harness, runner, environmentId, secrets, mcpServers, workerHost, computerUseModel, idleTimeoutMinutes, and required_repos. Use null to clear displayName. Execution settings override the target agent for runs from this automation.
Automation required_repos entries extend the target agent’s list. Each item requires required_repos[].owner and required_repos[].name; use required_repos[].codeForge to distinguish the same repository across hosts.
The harness object uses the same sparse override as an agent. Automation-level mcpServers use the factory-level transport syntax. Omit idleTimeoutMinutes, or set it to null, to inherit the target agent’s value.
runners/<name>.yaml
Section titled “runners/<name>.yaml”Optional resource.
Runner files define compute. Agents and automations select a file by name with runner. See cloud agent runners for runtime behavior and 02-sdlc-issue-to-pr for Linux and macOS examples.
description: Linux runner for payments builds and testssetupCommands: - corepack enableinstanceShape: vcpus: 4 memoryGb: 8platform: os: linux arch: x86_64 linux: dockerImage: ubuntu:22.04description
Section titled “description”Optional. A description of the runner.
setupCommands
Section titled “setupCommands”Optional. Shell commands that run in order while the sandbox is prepared.
instanceShape
Section titled “instanceShape”Optional.
The compute size. When set, instanceShape requires both vcpus and memoryGb. Omit it for the workspace default. Linux and Windows require powers of two. macOS accepts 4 vCPUs with 7 GB, 6 vCPUs with 14 GB, 8 vCPUs with 14 GB, 12 vCPUs with 28 GB, or 12 vCPUs with 56 GB.
platform
Section titled “platform”Required.
The operating system and architecture. os accepts linux (default), macos, or windows. arch accepts x86_64 (the Linux default and only Windows option) or aarch64 (supported on Linux and required on macOS).
Linux runners require platform.linux.dockerImage. For macOS, platform.mac.version accepts "14", "15", "26", or "27". Quote the version; omitting platform.mac uses "26".
For a private Linux image, set linux.registryCredentialSecretName to the name of a managed Docker registry (docker_registry) or AWS ECR (aws_ecr_credential) credential. The credential’s registry host must match the host in linux.dockerImage.
failureSessionRetentionMinutes
Section titled “failureSessionRetentionMinutes”Optional. Keeps a failed session open for inspection for 1 through 60 minutes. Omit it to use the environment setting.
routers/<name>.yaml
Section titled “routers/<name>.yaml”Optional resource. Router files define factory-owned custom model routers. Use the file name anywhere the definition accepts a model.
| Field | Requirement | Description |
|---|---|---|
name | Optional | Display label. |
type | Required | complexity or prompt. |
default | Required | Concrete model used when no route matches. |
routing | Optional | Type-specific routing rules. |
name: By tasktype: promptdefault: claude-4-6-sonnet-highrouting: - description: Routine documentation changes model: claude-4-5-haiku - description: Complex implementation or debugging model: claude-4-8-opus-highFor type: complexity, optional routing.easy, routing.medium, and routing.hard map complexity levels to concrete models. For type: prompt, routing is an ordered list of routing.description and routing.model pairs. Each pair requires both fields. routing is optional for either type. Targets must be concrete supported models, not Auto models or other routers. See custom model routers for routing behavior.
Factory members who can access the router can also select it from model catalogs in the factory dashboard, including agent settings and benchmark configurations.
benchmarks/<suite-slug>/suite.yaml
Section titled “benchmarks/<suite-slug>/suite.yaml”Optional resource.
Benchmark suite files define trials for one agent, with reusable configurations and an ordered task list. The directory slug is the suite’s stable identity; changing name doesn’t move the file. See benchmarks for how to run a suite.
name: Pull request reviewdescription: Compare configurations for the review agent.agent: reviewerconfigurations: - name: Baseline agents: - agent: reviewer model: auto - name: Candidate agents: - agent: reviewer model: auto-efficienttasks: - broken-doc-linkRequired. The suite display name, which must be unique in the factory.
description
Section titled “description”Optional. A short summary of what the suite measures.
Required. The factory agent used for every task in the suite.
configurations
Section titled “configurations”Optional.
One to six reusable configurations. Warp uses these presets when a benchmark run doesn’t supply configurations. Each configuration requires a unique name.
Optional role is deprecated metadata. Warp ignores it and omits it when rewriting the suite.
The optional agents list pins factory agents to models and harnesses for the configuration’s trials. Each configurations[].agents[] item names an agent and includes exactly one of model or harness. A harness requires type and model; type accepts oz, claude, claude-code, and codex. Optional auth follows the harness authentication rules. List an agent once per configuration. Omitted agents use their settings at launch time.
Optional.
An ordered list of unique task slugs. Each slug matches one file under benchmarks/<suite-slug>/tasks/, and every task file appears once. A suite without tasks can be saved but not run.
benchmarks/<suite-slug>/tasks/<task-slug>.yaml
Section titled “benchmarks/<suite-slug>/tasks/<task-slug>.yaml”Optional resource.
Each task file belongs to its parent suite. The file name without .yaml is the stable task slug.
title: Fix a broken documentation linkprompt: Find the broken internal documentation link and update it.successCriteria: The destination resolves and the link text names the destination.startingRepoRefs: - github.com:acme/payments-docs@0123456789abcdef0123456789abcdef01234567Required. The task display name. It doesn’t need to match the task slug.
prompt
Section titled “prompt”Required. The instructions sent to the agent.
successCriteria
Section titled “successCriteria”Required. The Correctness Scorer’s evaluation criteria.
sourceRunId
Section titled “sourceRunId”Optional. The ID of the prior run that produced the task. This records provenance and can refer to a deleted run.
Optional. An ordered list of task labels.
linearSeed
Section titled “linearSeed”Optional. JSON-compatible starting state for the trial’s isolated Linear workspace.
startingRepoRefs
Section titled “startingRepoRefs”Optional.
The GitHub or GitLab repositories and commits used as the task’s starting state. Each entry accepts github.com:OWNER/REPO@COMMIT_SHA, gitlab.com:OWNER/REPO@COMMIT_SHA, or an object with codeForge (GITHUB or GITLAB), owner, repo, and ref. All four object fields are required. COMMIT_SHA and ref must be full 40-character commit SHAs, not branches or tags. Omit the key to use the agent’s checkout defaults.
scorers/<name>/scorer.md
Section titled “scorers/<name>/scorer.md”Optional resource.
Scorer files define LLM judges that classify sampled runs against a rubric. The directory is a stable slug; name identifies the scorer. Frontmatter defines the classification contract, and the Markdown body holds the rubric. See configuring scorers for how scores are used.
---name: tests-rundescription: Checks whether implementation runs include test evidence.agents: - reviewerlabels: - value: tests_run description: The transcript contains a test command and its result. score: 1 - value: tests_skipped score: 0passingScore: 1samplingRate: 25model: claude-4-5-haiku---Evaluate whether the agent ran the relevant tests before finishing. Returnexactly one declared label.Required. The scorer’s identity. Changing it doesn’t move the directory.
description
Section titled “description”Optional. A short summary of what the scorer checks.
agents
Section titled “agents”Required.
The agents whose runs the scorer evaluates. A string names one agent and scores only that run. To include child runs as evidence, use an object with required name and optional includeDescendants: true.
agents: - name: foreman includeDescendants: trueScorer execution settings
Section titled “Scorer execution settings”Optional.
runner, secrets, and mcpServers override the factory’s scorerDefaults for this scorer. Scorer-level mcpServers use the factory-level transport syntax. Set shared values under scorerDefaults in factory.yaml.
output
Section titled “output”Optional.
The scorer output form. classification is the supported value.
labels
Section titled “labels”Required.
One to 20 classifications. Each label requires a unique value and a score from 0 through 1; description is optional. At least one label must meet passingScore, and at least one must fall below it.
passingScore
Section titled “passingScore”Required. The passing threshold, from 0 through 1.
samplingRate
Section titled “samplingRate”Optional. The percentage of eligible runs to score, from 0 through 100. It defaults to 25, rounds to two decimal places, and disables automatic scoring at 0.
Required. The model that judges runs.
selfImprovement
Section titled “selfImprovement”Optional.
When true, failing scores can feed the self-improvement flow, which proposes definition changes in pull requests. Defaults to false.
webhooks/<name>.yaml
Section titled “webhooks/<name>.yaml”Optional resource.
Webhook files define authenticated URLs for JSON POST requests. Automation webhook triggers subscribe to them; the file name names the webhook. secretName references an existing managed secret, not secret material.
authMode: tokensecretName: INTERNAL_CI_WEBHOOK_SECRETdeliveryIdHeader: X-CI-Run-Idenabled: trueauthMode
Section titled “authMode”Optional.
How deliveries authenticate: token (default, using an Authorization: Bearer header), url_token (secret in the URL path), or signature (the provider’s signature scheme). See webhook authentication modes.
signatureScheme
Section titled “signatureScheme”Conditionally required. Required for authMode: signature and invalid otherwise.
The provider signature to verify: github, pagerduty, sentry, standard_webhooks, stripe, or vercel.
secretName
Section titled “secretName”Required.
The managed secret containing the bearer token, URL token, or provider signing secret. A url_token secret becomes part of the ingress URL and accepts only letters, digits, -, ., _, and ~.
deliveryIdHeader
Section titled “deliveryIdHeader”Optional.
The sender’s delivery ID header, used to deduplicate retries. It accepts up to 64 characters and must be a valid HTTP header name. Credential-bearing headers such as Authorization, Cookie, and provider signature headers are rejected.
enabled
Section titled “enabled”Optional.
Whether the webhook accepts deliveries. Defaults to true. Use false to stop deliveries immediately without deleting the webhook, or to create it before the provider issues a signing secret. See setting up a Vercel webhook.
On a Warp-managed factory, creating a webhook in the dashboard writes this file for you and stores the secret under the name you enter in the “Secret name” field.
You can’t change authMode or signatureScheme on an existing webhook. Delete and recreate the webhook, or create the replacement under a different name.
Skills
Section titled “Skills”Optional resource.
A skill is a directory containing SKILL.md, not a YAML key. Put shared skills under skills/ and agent-specific skills under agents/<name>/skills/. See factory skills for placement and Skills for the file format.
Example factory definition
Section titled “Example factory definition”This definition includes one repository, a foreman, an automation triggered by a GitHub label, and a Linux runner. Replace PAYMENTS_ENVIRONMENT_ID and SENTRY_MCP_SERVER_ID with existing resource IDs.
For more complete definitions, see warp-factory-examples.
schemaVersion: v1alpha1name: payments-factorydescription: Processes approved work for the payments servicealias: paymentsrepositories: - owner: acme name: payments-serviceagentDefaults: model: auto runner: linux-build environmentId: PAYMENTS_ENVIRONMENT_ID---description: Routes approved payments work through the factoryagentType: FOREMANsecrets: - SENTRY_AUTH_TOKENmcpServers: sentry: warpId: SENTRY_MCP_SERVER_ID---
Own each work item from intake through human handoff.
Confirm the request is ready before dispatching implementation. Requirerepository validation and independent review before marking work complete.---enabled: trueagent: foremantriggers: - provider: github event: issue_labeled filter: repos: [acme/payments-service] labels: [factory-ready]---
Review the labeled issue and decide the next required stage. Preserve theissue's acceptance criteria and return unresolved product questions to a human.description: Linux runner for payments builds and testssetupCommands: - corepack enableinstanceShape: vcpus: 4 memoryGb: 8platform: os: linux arch: x86_64 linux: dockerImage: ubuntu:22.04Routing to a self-hosted worker
Section titled “Routing to a self-hosted worker”To use a managed self-hosted worker, set agentDefaults.workerHost to the worker ID. Agents and automations can override it.
agentDefaults: model: auto runner: linux-build workerHost: SELF_HOSTED_WORKER_IDPair workerHost with a runner whose platform matches the worker. Follow the self-hosting quickstart to connect a worker, or copy 07-self-hosted-worker.
Related pages
Section titled “Related pages”- Factory MCP for coding agents - Read the schema and validate a tree from any coding agent, and send work to a factory.
- GitHub integration - How the warp/factory-config check appears on pull requests, and what to check when it doesn’t.
- Factory dashboard - Where a Warp-managed definition is edited and validated on save.
- warp-factory-examples - Complete definitions to copy, plus the validator script and a CI workflow that runs it.