Skip to content

Configuration reference

← Overview · Get started · Self-hosting · Use cases

Store the task, agent, editable paths and checks in .maintainer.yml. Keys belong in the worker environment or Actions secrets. Unknown fields, duplicate keys, unsafe paths and excessive budgets fail validation.

A repository task

version: 2
name: Application maintenance
agent:
  runner: codex
  allow_paid: true
instructions: |
  Fix one reproducible bug, preserve public behavior and add a regression test.
editable:
  source_dirs: [src, tests]
  extensions: [.ts, .tsx, .js, .md, .json]
validation:
  profile: custom
  checks:
    - name: tests
      command: [npm, test]

This example expects an npm test script and Node/npm on the worker. Use the language examples for a starting point; set the editable paths to the files you want maintained.

Discovery checks .maintainer.yml, .maintainer.yaml, .github/maintainer.yml, .github/maintainer.yaml and .github/maintainer.json, in that order. --config overrides discovery. Version-1 JSON is supported with the same fields. The shared workflow retains the legacy .github/maintainer.json default; explicitly pass config_path: .maintainer.yml for YAML. Config files are limited to 256 KB and YAML alias expansion is bounded.

Choose a coding agent

Field Schema default Meaning
agent.runner codex in version 2 codex launches the Codex CLI; builtin uses the Rust agent with a model API
agent.model Runner/provider default Optional model ID; omitted for Codex to use its CLI default
agent.allow_paid false Explicit account-usage opt-in; required for Codex, OpenAI and Anthropic
agent.timeout_seconds 1200 Agent wall-clock limit, from 1 through 3600 seconds
agent.max_requests 16 Builtin inference budget, from 1 through 16, including compaction; does not limit Codex turns
agent.codex.binary codex Worker-owned executable on PATH or an absolute path
agent.codex.sandbox Native: workspace-write; v2 Compose: danger-full-access read-only, workspace-write, or danger-full-access with isolation supplied by the worker
agent.codex.network_access true in version 2 Allow outbound access for workspace-write tools; container isolation uses the Docker network policy

init writes version 2. If omitted there, agent.runner is Codex, validation is a generic whitespace check, and editable paths include common source/test extensions. Account use still requires agent.allow_paid: true. Configure the project's actual checks before unattended work. Version 1, including files with no version field, retains its builtin runner, Rust validation and restricted Codex tool networking defaults. Explicit settings always take precedence. For version 2, MAINTENANCE_CODEX_SANDBOX_DEFAULT can supply the sandbox default; Compose sets it to danger-full-access and supplies container isolation. An explicit YAML sandbox or a restricted network_access: false request takes precedence over that default. See Docker boundaries.

Codex CLI

Install Codex on the worker, or enable the workflow's install_codex input. The Docker image includes the native CLI by default. Authenticate with the worker's Codex login or CODEX_API_KEY; OPENAI_API_KEY is accepted as a fallback key for this runner. CODEX_HOME can select a worker-owned authentication home. Other model keys and GitHub tokens are not forwarded to the Codex process.

The adapter uses non-interactive execution, a JSON output schema, an execution deadline and the selected sandbox. User config is ignored for this invocation; authentication is still available. Shell commands launched by Codex exclude the API key environment variables. The agent's changed files still pass the same patch guard and independent project checks before publishing. Official Codex automation documentation describes CLI authentication, sandboxes and structured output.

Model providers

agent:
  runner: builtin
  provider: groq
  max_requests: 12
agent.provider Bundled default model Key Paid opt-in
groq openai/gpt-oss-120b GROQ_API_KEY No
google gemini-3.8-flash GEMINI_API_KEY No
openai or oai gpt-5.4 OPENAI_API_KEY Yes
anthropic claude-sonnet-4-6 ANTHROPIC_API_KEY Yes

These defaults come from the bundled provider profiles. Groq also accepts qwen/qwen3.8-27b; Google also accepts gemini-3.6-flash and gemini-3.5-flash-lite. OpenAI and Anthropic accept model IDs available to your account. The adapters use native HTTP APIs from Rust.

MAINTENANCE_API_KEY overrides the selected provider key. SDK_MAINTENANCE_API_KEY remains a legacy alias, after the new override and before the provider key. These overrides apply to the builtin runner. There is no provider/key rotation or paid fallback. Actual charges and quotas depend on the account, including billed Groq/Google accounts.

Optional environment overrides are MAINTENANCE_RUNNER, MAINTENANCE_PROVIDER, MAINTENANCE_MODEL and MAINTENANCE_ALLOW_PAID (true/false). Changing a runner or provider clears its previous model selection unless a model override is given. The Codex runner uses its own authentication; provider selection is for builtin.

Task and reference sources

Field Default Meaning
version 2 in new files; absent means legacy 1 Configuration format
name Repository maintenance Short display name
instructions Focused maintenance task Task text, at most 16,000 characters
instructions_file Unset Repository-relative file appended to the task
sources [] Optional HTTPS docs/changelogs fetched before inference
official_hosts Hosts inferred from sources Allowed reference and evidence hosts

Repository-only tasks need no external URL. With configured sources, every URL must use an allowed host and a changed result must cite reference evidence. Without sources, a result can cite no URL. Source text, docs and PR feedback are untrusted evidence; the trusted task/config defines the job. URLs cannot contain credentials. Add official hosts when documentation redirects to another domain.

Checks for any language

validation:
  profile: custom
  setup:
    - name: dependencies
      command: [npm, ci]
      timeout_seconds: 600
  checks:
    - name: tests
      command: [npm, test]
      working_directory: .
      timeout_seconds: 300
    - name: lint
      command: [npm, run, lint]

custom requires at least one check. Names are unique simple identifiers; commands are argument arrays, executed directly without an implicit shell. working_directory defaults to . and must stay inside the repository without symlink traversal. A command's timeout defaults to 300 seconds and can be from 1 through 1800. Each setup/check list has at most 20 entries.

Setup runs before inference and again in the fresh validation checkout. Checks run independently before publication; the builtin agent can also call them by name during repair. The model cannot invent a new command for the builtin check tool. Child commands receive a restricted environment without model/GitHub keys, and CI=true. If a shell is needed, the operator must explicitly configure a command such as [sh, -c, 'your command'].

Install the project runtimes on every worker or select an appropriate Docker base image. Native setup can depend on tools such as npm, Python or Go without depending on Cargo.

Run repo-maintainer validate --repo /path/to/project to execute setup and checks directly, without inference. It prints passing check names; it does not create a publication receipt. In a pipeline, validate --source FRESH_SOURCE --output ARTIFACTS validates an applied proposal and writes that receipt.

Rust checks

validation.profile: rust retains Cargo dependency setup, formatting, workspace tests/doctests, Clippy, rustdoc, the minimum Rust version, optional packaging and audit. Additional configured checks run afterwards. Its settings remain:

rust:
  msrv: 1.88.0
  crates: [my-library]
  package_check: scripts/verify-packages

crates defaults to [] and permits scoped builtin-agent checks. package_check defaults to empty; when supplied it is a repository-relative executable with its own interpreter or compiled binary. The workflow installs Rust and cargo-audit for this profile. Custom profiles do not install or invoke Cargo for the target.

Editable paths

editable:
  root_files: [README.md, CHANGELOG.md]
  source_dirs: [src, tests, docs]
  markdown_dirs: [docs]
  extensions: [.ts, .tsx, .js, .py, .go, .rs, .md, .json]

Root files are exact names. Source directories allow the selected extensions recursively; Markdown directories allow immediate .md children. Version 2 defaults cover src/, tests/ and crates/ with common language extensions; version 1 keeps the original Rust-oriented defaults. Allow manifests/lockfiles only when the task should change them. Hidden paths, traversal, symlinks and executable files cannot enter a proposal. Patches stay within 25 regular files and 500 KB.

Publishing and scheduling

Field Default Meaning
branch_prefix dylan/repo-maintenance- Run-specific branch prefix, ending in -
issue_title Repository maintenance needs help Deduplicated blocker issue title
commit_title fix: maintain repository Commit and PR title
ci_workflow ci.yml Target workflow dispatched for the maintenance branch

A scheduler belongs in your workflow/job system, not inside this task file. Use distinct config paths, branch prefixes and issue titles for independent recurring jobs in the same repository. The workflow's concurrency group includes config_path. Its owner input selects the issue/PR assignee, and runner_labels chooses your self-hosted infrastructure or GitHub-hosted workers. The target CI workflow must support workflow_dispatch.