Skip to content

Configuration

Developer reads its config from a developer.yaml file. Copy example.developer.yaml to developer.yaml and customize it — developer.yaml is gitignored. This file defines which repos it manages, how to set them up locally, and what quality tools to run.

Where Developer looks

The config file is the first of these:

  1. --config PATH, given before the command (developer --config ~/developer/developer.yaml review myrepo 5);
  2. the DEVELOPER_CONFIG environment variable;
  3. developer.yaml in the current directory;
  4. developer.yaml at the root of the Developer checkout.

Developer keeps its clones (repos/) and a record of every run (runs/), and reads its GitHub App credentials (.env), in its home directory. That is the directory holding developer.yaml, unless DEVELOPER_HOME names another one. Running from a checkout, all three live at the project root, as before. An installed developer works from any directory that holds a developer.yaml.

Format

repos:
  assistant:
    github:
      owner: gregology
      repo: assistant
    testing_philosophy: >-
      Test rigor is proportional to irreversibility.
      Dispatch, provenance, and non-undoable actions need thorough tests.
    setup:
      - uv sync --all-extras
    quality_tools:
      - name: mypy
        cmd: [uv, run, mypy, app/, --ignore-missing-imports]
      - name: pytest
        cmd: [uv, run, pytest]
        timeout: 600

Fields

claude (optional)

How Developer runs Claude Code. Every setting is optional. Anything left out uses Claude Code's own default, except max_turns, which is 50.

claude:
  cli_path: null          # a claude binary; null uses the one bundled with the SDK
  model: sonnet           # an alias such as opus, sonnet or haiku, or a full model ID
  effort: high            # low, medium, high, xhigh or max
  max_budget_usd: 5       # per agent run; the run stops if it costs more
  max_turns: 50           # per agent run; the run stops if the agent needs more
  stages:                 # overrides for particular stages
    craft_pr: {effort: low, max_turns: 15}
    implement_step: {model: opus, max_budget_usd: 20}

stages takes the stage names from the pipeline docs, plus implement_step (every implementation step in resolve), audit (every audit) and investigate (the add command's agent). A stage name both resolve and address use, such as quality_fix, applies to both. An unknown stage name is an error.

A stage that uses all its turns before it finishes stops the run, with an error that names the setting to raise. The run's transcript in runs/ still shows what the stage cost.

DEVELOPER_CLAUDE_CLI in the environment overrides cli_path.

repos (required)

Top-level key. Each entry underneath is a repo, keyed by whatever name you want to use on the command line.

github (required)

GitHub coordinates:

github:
  owner: gregology
  repo: assistant

Both owner and repo are required. Developer uses these to construct API URLs, clone URLs, and the bot's commit identity.

env (optional)

Environment variables for the repo's setup and teardown commands, its quality tools, and the agent that works on it. They're added to Developer's own environment.

env:
  PATH: ${HOME}/.local/share/mise/shims:${PATH}
  RAILS_ENV: test

$VAR and ${VAR} take a variable's value from Developer's environment when a run starts, and $$ stands for a $. A run stops if a variable it names isn't set.

This is the place for facts about the machine, such as where a version manager keeps the repo's tools. A version manager's shell hook, like mise activate or direnv, doesn't run for the commands Developer starts, so they only find those tools if env puts them on PATH.

Developer keeps GitHub credentials away from the agent, so GITHUB_APP_ID, GITHUB_PRIVATE_KEY, GITHUB_TOKEN and GH_TOKEN can't be set here.

setup (optional)

List of shell commands that prepare a fresh checkout. They run inside each run's own worktree, before the agent starts.

setup:
  - uv sync
  - npm install
  - bundle install

Commands run with shell=True, so pipes and redirects work. They run in order, and each can rely on the ones before it. If one fails, the rest are skipped and the run stops before the agent starts. validate reports each command's result, including the ones a failure skipped.

teardown (optional)

List of shell commands that stop whatever setup started outside the worktree, such as containers or background services. They run in the worktree when the run ends, however it ends, including when setup failed partway.

setup:
  - docker compose up --detach --wait db
teardown:
  - docker compose down --volumes

Every command runs, even after one fails, and a failure is logged as a warning. validate counts a failed teardown command as a failure.

Each run's worktree is a new directory with a name of its own. Tools that name what they create after the directory, as Docker Compose does with its projects, keep each run's services apart. Fixed host ports are still shared, so two runs of a repo that publishes a fixed port can't set up at the same time.

quality_tools (optional)

List of tools that check code quality. Each needs a name and a cmd (as a list of strings). timeout is optional: the number of seconds a tool may run before it counts as failed, 120 by default.

quality_tools:
  - name: ruff
    cmd: [uv, run, ruff, check, src/, tests/]
  - name: mypy
    cmd: [uv, run, mypy, --ignore-missing-imports]

Quality tools run during the resolve and address pipelines (after implementation, before opening a PR). They also run during audit refactor as signal for the agent. If a tool fails, the agent gets up to three attempts to fix the issues.

Removed: provider and providers

Developer only runs Claude, so these keys were removed. provider: claude is still accepted with a warning. Any other provider value, or a providers block, is an error.

sandbox (optional)

What the agent's Bash commands may reach beyond the worktree. Commands always run in Claude Code's sandbox: by default they can write only inside the worktree and the temp directory, can't use the network, and can't read credential files such as ~/.ssh, ~/.config/gh or Developer's .env.

sandbox:
  allowed_domains: [pypi.org, files.pythonhosted.org]
  allow_write: [~/.cache/uv]
  • allowed_domains -- hosts commands may connect to, for example package registries the test suite needs.
  • allow_write -- extra paths commands may write to, for example a package manager's cache.

On Linux the sandbox needs bubblewrap and socat. Ubuntu 24.04 and later also need an AppArmor profile for bwrap; see Claude Code's sandbox docs.

testing_philosophy (optional)

Free-text description of the repo's testing approach. This gets injected into audit prompts so the agent understands what kind of test coverage the project expects.

testing_philosophy: >-
  Real user scenarios, no mocks, no private function tests.

Validation

Developer validates config on every run. Unknown keys are errors, so a typo can't be silently ignored. If something is wrong, you get an error naming each setting at fault:

Error: /home/you/developer/developer.yaml is invalid:
  repos.assistant.github.owner: Field required
  repos.assistant.quality_tool: Extra inputs are not permitted

You can also validate that a repo's full config works from scratch:

developer validate assistant
developer validate --all

This clones into a temp directory, sets up a fresh worktree exactly as a run does, runs every quality tool in it, and reports pass/fail for each step. It proves the config actually works, not just that it parses.

Adding a repo

The quickest way is to let Developer discover the config automatically:

developer add myorg/my-new-repo

This clones the repo, runs an investigation agent to discover setup and teardown commands, testing philosophy, and quality tools, then writes the result to developer.yaml. Use --dry-run to preview without saving. The same operation is available via the API (POST /repos).

To add a repo manually, add a block under repos in your developer.yaml:

repos:
  my-new-repo:
    github:
      owner: myorg
      repo: my-new-repo
    setup:
      - npm install
    quality_tools:
      - name: eslint
        cmd: [npx, eslint, src/]

Developer clones it on first run. No other setup needed.