Colony Configuration Reference
Colony Configuration Reference
Section titled “Colony Configuration Reference”This document is the Colony configuration reference. It covers global infrastructure sections, agent configuration, and the config resolution chain. For multi-repo and multi-tenant configuration (Colony Cloud), see the Multi-Repo (Colony Cloud) section at the bottom.
Which tier do I need?
Section titled “Which tier do I need?”| Scenario | Read | Skip |
|---|---|---|
| First-time single repo | Tier 1 + 2 | Tier 3 |
| Production single repo | Tier 1 + 2 + relevant Tier 3 sections | Multi-tenant |
| Multi-repo / Colony Cloud | All tiers | — |
Config File Format
Section titled “Config File Format”Colony uses YAML configuration files. The config is loaded from the first location found in this order:
- Path passed via the
--configCLI flag ./colony.config.yaml(current working directory)~/.colony/config.yaml(user home directory)
If no config file is found, Colony uses built-in defaults where available.
Config Schema & Editor Integration
Section titled “Config Schema & Editor Integration”Colony ships a machine-readable JSON Schema for colony.config.yaml at schema/colony.config.schema.json in the repository root. The schema uses the Draft 2020-12 dialect and is identified by:
$id: https://runcolony.com/schema/colony.config.schema.jsonThe $id URL is the schema’s canonical version identifier — there is no separate version field. When Colony releases a new schema version, the $id changes.
Note: The schema is generated with
additionalProperties: trueat the root level, which means unknown top-level keys are not flagged as errors. This keeps the schema forward-compatible with config files written against older Colony versions. Typos in key names will not produce schema validation errors — usecolony check --stage configfor semantic validation.
Editor autocomplete and inline validation
Section titled “Editor autocomplete and inline validation”Most YAML editors (VS Code with the YAML extension, JetBrains IDEs, Neovim with yaml-language-server) honour the yaml-language-server modeline. The canonical header uses the hosted schema URL and works from any config file location (~/.colony/config.yaml, a target repo, or anywhere else):
# yaml-language-server: $schema=https://runcolony.com/schema/colony.config.schema.json
github: owner: your-org repo: your-repo # ...This header is already included as the first line of colony.config.example.yaml and in configs generated by colony init --generate, so if you started from either of those you do not need to add it manually.
In-repo alternative: if your config is committed alongside the Colony repository’s schema/ directory, you can use a relative path instead:
# yaml-language-server: $schema=./schema/colony.config.schema.jsonThis relative form will not resolve for configs at ~/.colony/config.yaml or in a separate target repository — use the URL form for those.
Config validation
Section titled “Config validation”Use colony check --stage config to run semantic validation on your config file. This performs the same checks that Colony runs at startup — credential resolution, required-field presence, and value-range enforcement — and reports actionable errors with field paths.
Required fields vs. Colony-defaulted fields
Section titled “Required fields vs. Colony-defaulted fields”The schema marks some fields as required that Colony’s runtime fills in automatically from built-in defaults when the parent block is omitted entirely. The schema reflects what is structurally required if you provide the parent block, not what you must write in every config file.
Worked example: claude.scaling.*.developer_max_turns
In ClaudeScalingEntry, developer_max_turns is the only required field — model, effort, planning_max_turns, no_progress_window, and backstop_max_turns are all optional:
# OK — claude.scaling is omitted entirely; Colony substitutes DEFAULT_SCALING for all three tiers# (no claude.scaling block needed)
# OK — partial entry; only developer_max_turns is required per tierclaude: scaling: small: developer_max_turns: 100 medium: developer_max_turns: 200 large: developer_max_turns: 300However, ClaudeScalingConfig itself requires all three tier keys (small, medium, large) once you provide the claude.scaling block at all. Providing only small is a schema error:
# ERROR — claude.scaling is present but missing medium and largeclaude: scaling: small: developer_max_turns: 100 # medium and large are required once claude.scaling is setThe general rule: omit a block entirely to get Colony’s defaults for the whole block; provide it to take full ownership of that block’s required fields. See ClaudeScalingEntry for the full field table and built-in defaults per tier.
Regenerating the schema (contributors)
Section titled “Regenerating the schema (contributors)”After changing config types in packages/core/src/config-types.ts, regenerate the schema artifact by running:
npm run generate:schemaThis invokes scripts/generate-schema.mjs and overwrites schema/colony.config.schema.json. Commit the updated schema alongside the type change so the artifact stays in sync with the types.
Environment Variable Resolution
Section titled “Environment Variable Resolution”Call resolveConfig() before any GitHub operations. This function validates the config and resolves credentials from environment variables — reading GITHUB_TOKEN (or the value of token_env) into github.token, reading GitHub App private keys from disk, and resolving per-repo secrets.
Never use the raw parsed config object directly for GitHub operations; always go through resolveConfig().
Tier 1: Essential Configuration
Section titled “Tier 1: Essential Configuration”Fields you must set to get Colony running on a single repository. Copy the snippet below, fill in the placeholders, then move to Tier 2 to tune cost and model settings.
Minimum Viable Config
Section titled “Minimum Viable Config”github: owner: your-org # GitHub org or user that owns the repo repo: your-repo # repository name token_env: GITHUB_TOKEN # default; set GITHUB_TOKEN in your environment
workspace: repo_dir: /path/to/your/repo # absolute path to your local git clone
review: checks: test: npm test # CHANGE to your actual test command lint: npm run lint # CHANGE to your actual lint commandEnvironment Variables
Section titled “Environment Variables”| Variable | Required | Description |
|---|---|---|
GITHUB_TOKEN | required | Personal Access Token. See required scopes. Used by Colony to create branches, open PRs, and post comments |
ANTHROPIC_API_KEY | required | Anthropic API key for Claude Code invocations by worker agents |
DATABASE_URL | required | Postgres connection string (e.g. postgresql://user:pass@localhost:5432/colony) |
github (essential fields)
Section titled “github (essential fields)”Authentication and identity settings for the target repository.
| Field | Type | Default | Description |
|---|---|---|---|
owner | string | required | GitHub organization or user that owns the target repository |
repo | string | required | Target repository name |
token_env | string | 'GITHUB_TOKEN' | Name of the environment variable containing the Personal Access Token used for GitHub API calls |
For GitHub App auth, bot identity, and ops identity settings, see the full github reference in Tier 3.
workspace (essential fields)
Section titled “workspace (essential fields)”| Field | Type | Default | Description |
|---|---|---|---|
repo_dir | string | '.' | Path to the local git clone of the target repository. Colony creates worktrees under this directory. Not required for Docker Compose deployments — workers clone the repo automatically inside their container |
For all workspace settings (base directory, setup command, branch, cleanup, etc.), see the full workspace reference in Tier 3.
review.checks (required — do not leave empty)
Section titled “review.checks (required — do not leave empty)”Warning: Leaving
review.checksempty means Colony uses LLM judgement alone — no build, test, or lint validation. The LLM reviewer may approve PRs that break your build or fail your test suite. Always configure at least one check.
| Field | Type | Default | Description |
|---|---|---|---|
checks | Record<string, string> | {} | Named shell commands to run as deterministic review checks (e.g. test: 'npm test', lint: 'npm run lint'). Keys are check names; values are shell commands |
Example:
review: checks: test: npm test lint: npm run lint build: npm run buildFor all review settings (CI gating, auto-merge, LLM review rounds, etc.), see the full review reference in Tier 3.
Tier 2: Recommended Configuration
Section titled “Tier 2: Recommended Configuration”Settings most users want to tune after their first issue. The essentials already got Colony running — these fields control cost, quality, and workflow preferences.
logging
Section titled “logging”Controls log output from all Colony processes.
| Field | Type | Default | Description |
|---|---|---|---|
level | string | 'info' | Pino log level. Valid values: 'trace', 'debug', 'info', 'warn', 'error', 'fatal' |
format | 'json' | 'pretty' | 'pretty' | Log output format. Use 'json' in production/containerized deployments for structured log ingestion; use 'pretty' for local development |
max_daily_usd
Section titled “max_daily_usd”A top-level scalar field that caps aggregate spend across all issues and repos for the current UTC day.
| Field | Type | Default | Description |
|---|---|---|---|
max_daily_usd | number | null | 50 | Maximum USD to spend in a single UTC day across all repos. When the ceiling is hit, Colony logs a warning and skips repo polling for the rest of the day — issues already running are not interrupted, but no new work is started. Resets at midnight UTC. Set to null or remove the field to disable the ceiling entirely. |
Example — raise the ceiling to $200:
max_daily_usd: 200Example — disable the ceiling:
max_daily_usd: nullNote:
max_daily_usdis a top-level field, not nested underclaude:oragents:. When the ceiling is hit you will see a log line likeGlobal daily cost ceiling exceeded — skipping repo until next UTC day. Issues will remain in whatever state they are in and resume processing automatically once daily spend resets at midnight UTC — no label changes or manual intervention are required.
Cost Controls (claude.max_cost_per_issue)
Section titled “Cost Controls (claude.max_cost_per_issue)”| Field | Type | Default | Description |
|---|---|---|---|
max_cost_per_issue | number | — | USD cost cap per issue. When the accumulated cost for an issue reaches this limit, the Claude invocation is aborted, the issue is moved to colony:blocked, and Colony posts a comment with the cost breakdown. To unblock: raise this value in config, then comment /colony:retry on the GitHub issue to re-trigger processing. Omit for no limit. |
Example:
claude: max_cost_per_issue: 10For all claude settings (timeout, model overrides, Foundry, scaling), see the full claude reference in Tier 3.
Model Selection (claude.models)
Section titled “Model Selection (claude.models)”Override which Claude model each agent uses. The defaults balance capability against cost; use this section to tune the trade-off.
| Field | Type | Default | Description |
|---|---|---|---|
developer | string | 'claude-opus-4-8' | Model used for the developer agent |
reviewer | string | 'claude-opus-4-8' | Model used for the reviewer agent |
analyzer | string | 'claude-sonnet-4-6' | Model used for the analyzer agent |
planner | string | 'claude-opus-4-8' | Model used for the planner agent |
merger | string | 'claude-sonnet-4-6' | Model used for the merger agent |
Model Cost Guidance
Section titled “Model Cost Guidance”Colony agents make different demands on the model. The table below shows approximate pricing and recommended use cases to help you balance cost against quality.
| Model | Approx. pricing (input / output per M tokens) | Recommended use |
|---|---|---|
claude-opus-4-8 | ~$5 / $25 (placeholder — official rate TBD) | Developer, Reviewer, and Planner — lowest fake-validation rate of any Opus generation. Reference default for developer, reviewer, and planner. |
claude-opus-4-7 | ~$5 / $25 | Alternate Opus generation — same pricing as 4-8 and 4-6; useful for users already running 4-7 in existing workflows. |
claude-opus-4-6 | ~$5 / $25 | Previous generation Opus — still capable for complex tasks, but 4-8 reduces test-gaming behavior significantly. |
claude-sonnet-4-6 | ~$3 / $15 | Analyzer and Merger — good balance of speed and quality for code triage and merge orchestration. Reference default for analyzer and merger. Also preferred over Opus-medium for small dev tasks (better cost-for-quality). |
claude-haiku-4-5-20251001 | ~$1 / $5 | Analyzer on cost-constrained setups — fastest and cheapest; suitable when issues are well-scoped and analysis depth is less critical. |
Pricing figures are approximate and may change. Use hedged budget estimates when planning spend.
Why Opus 4-8 for Reviewer and Developer?
Section titled “Why Opus 4-8 for Reviewer and Developer?”Opus 4-8 makes significantly fewer fake validations than earlier generations. Older Opus versions would sometimes tweak acceptance criteria or game tests so that everything appeared green while still shipping bugs. This failure mode is particularly costly in two roles:
- Reviewer: rubber-stamping spec gaps, approving PRs that satisfy the letter of the criteria but miss the intent
- Developer: writing code that games the test rather than satisfying the spec
Opus 4-8 reduces this behaviour, making it the right choice for correctness-critical roles even though it is slower at high thinking effort (high/max).
Effort-mode economics
Section titled “Effort-mode economics”Colony uses thinking effort hints (effort field in claude.scaling) to control how deeply the model reasons per turn. The cost-quality tradeoffs:
max(extended thinking): worth it only for multi-file / cross-cutting work. ~4x token spend; negligible quality gain on single-file tasks. Default forlargecomplexity developer tasks.high: the right default for non-trivial work. Used bymediumdev tasks and by the reviewer and planner.medium: suboptimal — if you want balance plus cheap tokens, use Sonnet onhighinstead of Opus onmedium.low: very fast but poor at non-trivial tasks. Only suitable for mechanical renames or tiny edits.
Override any agent’s model via claude.models.<agent>:
claude: models: developer: claude-opus-4-8 # highest capability, lowest fake-validation rate reviewer: claude-opus-4-8 # read-only loop; slowness tolerable; 4-8 matters here analyzer: claude-sonnet-4-6 # high volume; sonnet-high is the sweet spot planner: claude-opus-4-8 # lowest volume, highest blast radius merger: claude-sonnet-4-6 # conflict resolution is bounded; sonnet sufficientNote: The annotated example config (
colony.config.example.yaml) sets all agents toclaude-sonnet-4-6as a cost-conscious starting point for evaluation, and also ships with aclaude.scalingblock that pins all three complexity tiers (small/medium/large) to Sonnet. This makes the example internally consistent: it will not trigger thecolony checkmodel-scaling-conflict warning, and all developer spend stays at Sonnet rates regardless of issue complexity. To re-enable auto-escalation to Opus 4.8 for medium and large issues, delete theclaude.scalingblock. This differs from the reference defaults above (Opus 4-8 fordeveloper,reviewer, andplanner) — adjust those once you are comfortable with Colony’s output.Note on
opusplanalias: Theopusplanalias in pricing configuration is frozen atclaude-opus-4-6for backward compatibility with existing user configs. Users who want the new default should useclaude-opus-4-8explicitly.
For all claude settings, see the full claude reference in Tier 3.
Cost model selection {#cost-model-selection}
Section titled “Cost model selection {#cost-model-selection}”Four overlapping knobs control what model is used and how much you spend. This section explains how they interact so you can predict spend before you hit a ceiling.
Developer model precedence
Section titled “Developer model precedence”The developer agent picks its model per-issue based on the issue’s assessed complexity:
| Complexity | Effective model |
|---|---|
| small | claude.scaling.small.model → fallback: claude.models.developer |
| medium | claude.scaling.medium.model → fallback: claude.models.developer |
| large | claude.scaling.large.model → fallback: claude.models.developer |
claude.scaling[complexity].model always wins over claude.models.developer for the developer agent. The claude.models.developer value is only used when the matching scaling entry has no model field.
All other agents (analyzer, reviewer, merger, planner) read directly from claude.models.<agent> — they are not affected by claude.scaling.
Built-in scaling defaults (used when claude.scaling is not set):
| Tier | Model | Max turns |
|---|---|---|
| small | claude-sonnet-4-6 | 80 |
| medium | claude-opus-4-8 | 150 |
| large | claude-opus-4-8 | 250 |
Common gotcha: If you set claude.models.developer: claude-sonnet-4-6 to cap developer spend, medium and large issues will still use claude-opus-4-8 via the built-in scaling defaults. To force all tiers to Sonnet, you must also set claude.scaling.medium.model and claude.scaling.large.model. The shipped colony.config.example.yaml already implements this pattern — if you copied from that file, no additional changes are needed:
claude: models: developer: claude-sonnet-4-6 # only affects tiers without a scaling.model override scaling: small: developer_max_turns: 80 model: claude-sonnet-4-6 medium: developer_max_turns: 150 model: claude-sonnet-4-6 # explicit — otherwise DEFAULT_SCALING.medium.model wins large: developer_max_turns: 250 model: claude-sonnet-4-6 # explicit — otherwise DEFAULT_SCALING.large.model winsRun colony check to detect this conflict — it emits a warning when claude.models.developer is set to a model that differs from the effective scaling models for any tier. Run colony estimate to see which model each complexity tier actually uses in the cost projection.
Cost ceilings
Section titled “Cost ceilings”| Field | Scope | What happens when hit |
|---|---|---|
claude.max_cost_per_issue | Per-issue | Claude invocation is aborted; issue moves to colony:blocked; comment posted with cost breakdown. Resume with /colony:retry after raising the limit. |
max_daily_usd | Global/daily | No new work is started for the rest of the UTC day. Issues already running are not interrupted. Resets at midnight UTC automatically — no manual action needed. |
The two ceilings are independent and additive. An issue can be blocked by max_cost_per_issue while the daily ceiling has not yet been reached, or vice versa.
Intake Mode (agents.sprint_master.intake_mode)
Section titled “Intake Mode (agents.sprint_master.intake_mode)”Controls whether the sprint master picks up all new issues or only those tagged with colony:enqueue.
| Field | Type | Default | Description |
|---|---|---|---|
intake_mode | 'all' | 'tagged' | 'tagged' | Whether to pick up all new issues or only colony-tagged ones |
Example:
agents: sprint_master: intake_mode: all # pick up every new issue automaticallyFor all sprint master settings, see the full agents.sprint_master reference in Tier 3.
Default Branch (workspace.branch)
Section titled “Default Branch (workspace.branch)”Override when your repository’s default branch is not main.
| Field | Type | Default | Description |
|---|---|---|---|
branch | string | 'main' | Default branch name for the repository. Override when the repo’s default branch is not main (e.g. 'master', 'develop') |
Example:
workspace: branch: masterFor all workspace settings, see the full workspace reference in Tier 3.
Auto-Merge (review.auto_merge_on_approval)
Section titled “Auto-Merge (review.auto_merge_on_approval)”| Field | Type | Default | Description |
|---|---|---|---|
auto_merge_on_approval | boolean | false | Automatically merge the PR after the reviewer approves it |
Example:
review: auto_merge_on_approval: trueFor all review settings, see the full review reference in Tier 3.
Monitor Dashboard (agents.monitor.enabled)
Section titled “Monitor Dashboard (agents.monitor.enabled)”The monitor agent is disabled by default. Enable it to access the pipeline dashboard and alerting.
| Field | Type | Default | Description |
|---|---|---|---|
enabled | boolean | false | Enable the monitor agent. Exposes a dashboard and Prometheus metrics endpoint |
Example:
agents: monitor: enabled: trueFor all monitor settings (alerting, self-healing, cost thresholds, etc.), see the full agents.monitor reference in Tier 3.
Attribution (EU AI Act transparency)
Section titled “Attribution (EU AI Act transparency)”Colony appends a short disclosure footer to every agent-authored GitHub artifact — issue comments, PR descriptions, review bodies, and created issue bodies. This satisfies the EU AI Act Article 50(1) obligation, which requires AI systems that interact directly with natural persons to disclose that interaction. The deadline is 2 August 2026 and was not deferred by the May 2026 Digital Omnibus agreement.
attribution: enabled: true # default true text: 'Orchestrated by [Colony](https://runcolony.com) — autonomous software development pipeline.'| Field | Type | Default | Description |
|---|---|---|---|
enabled | boolean | true | When false, no disclosure footer is appended. Disabling this weakens the operator’s own Article 50(1) compliance posture — only disable after legal review. |
text | string | See above | The disclosure text appended after a horizontal rule (---). Self-hosted operators may substitute their own deployment name. |
The footer format is always:
---<text>Tier 3: Advanced & Multi-Repo Configuration
Section titled “Tier 3: Advanced & Multi-Repo Configuration”Complete reference for all configuration fields. New users can skip this section until they encounter a scenario that requires it.
github
Section titled “github”Authentication and identity settings for the target repository.
| Field | Type | Default | Description |
|---|---|---|---|
owner | string | required | GitHub organization or user that owns the target repository |
repo | string | required | Target repository name |
token_env | string | 'GITHUB_TOKEN' | Name of the environment variable containing the Personal Access Token used for GitHub API calls |
app | GitHubAppConfig | — | GitHub App credentials for the coder identity (Analyzer, Developer). Use instead of token_env for App-based auth |
ops_app | GitHubAppConfig | — | Separate GitHub App credentials for the ops identity (Sprint Master, Reviewer, Merger). Allows two distinct bot identities |
ops_token_env | string | — | Name of the environment variable containing the PAT for the ops identity. Alternative to ops_app |
bot_username | string | — | Display name shown for bot-authored comments and labels |
GitHubAppConfig
Section titled “GitHubAppConfig”Used by github.app and github.ops_app.
| Field | Type | Default | Description |
|---|---|---|---|
app_id | number | required | GitHub App ID (found in the App settings page) |
private_key_path | string | required | Path to the .pem private key file for this App |
installation_id | number | required | Installation ID for this App on the target organization or repo |
labels
Section titled “labels”Controls the prefix used for all pipeline state labels created by Colony on GitHub issues.
| Field | Type | Default | Description |
|---|---|---|---|
prefix | string | 'colony' | Prefix for pipeline state labels (e.g. colony:analyzing, colony:in-development). Change this if you need to run multiple Colony instances against the same repo with distinct label namespaces |
workspace
Section titled “workspace”Controls how Colony creates and manages git worktrees for each issue.
| Field | Type | Default | Description |
|---|---|---|---|
repo_dir | string | '.' | Path to the local git clone of the target repository. Colony creates worktrees under this directory. Not required for Docker Compose deployments — workers clone the repo automatically inside their container |
base_dir | string | '~/.colony/workspaces/{owner}/{repo}' | Base directory for worktrees. Supports {owner} and {repo} template tokens which are substituted at runtime |
cleanup_after_merge | boolean | true | Remove the worktree after a PR is merged. Set to false to retain worktrees for post-merge inspection |
setup_command | string | — | Command to run after creating a worktree, instead of the default npm install. Use for non-TypeScript repos (e.g. 'bundle install' for Ruby/Rails) |
setup_timeout | number | 300 | Seconds to allow the setup command to run before timing out |
prebuild_command | string | — | Command to run after setup_command to pre-build workspace packages (e.g. 'npm run build'). Use for monorepos with internal packages that must be built before tests can run |
prune_blocked_after_days | number | 7 | Days before worktrees for blocked issues are automatically pruned |
review_workspace_base | string | — | Container-local path for ephemeral reviewer worktrees. Required when the reviewer runs in an isolated container with a different filesystem layout |
skip_pre_push_hook | boolean | — | When true, passes --no-verify to git push. Colony runs its own validation steps, so this is safe in containerized deployments where the local pre-push hook is not meaningful |
branch | string | 'main' | Default branch name for the repository. Override when the repo’s default branch is not main (e.g. 'master', 'develop') |
database
Section titled “database”Connection settings for the Postgres database used by the pipeline store. This section is optional for configuration — if omitted, Colony reads DATABASE_URL from the environment using built-in defaults. However, a Postgres connection is always required at runtime — colony check will always validate database connectivity regardless of whether this section is present.
| Field | Type | Default | Description |
|---|---|---|---|
url_env | string | 'DATABASE_URL' | Name of the environment variable containing the Postgres connection string |
max_connections | number | 10 | Maximum number of connections in the pg connection pool. Increase for high-throughput deployments with many concurrent workers |
idle_timeout | number | 10000 | idleTimeoutMillis for the pg connection pool (milliseconds). Lower this for connection-constrained environments |
ssl | boolean | false | Enable SSL for Postgres connections. Required for most cloud-hosted Postgres instances (e.g. RDS, Cloud SQL) |
Database migrations: Colony runs Postgres migrations automatically at agent startup — both the sprint-master and worker call
PipelineStore.initialize()which applies all pending migrations before the agent begins processing. No manual migration step is needed. If startup fails with a migration error, verifyDATABASE_URLconnectivity and that the Postgres user hasCREATE TABLEprivileges.
event_log
Section titled “event_log”Controls the local event log written by Colony agents. This section is optional.
| Field | Type | Default | Description |
|---|---|---|---|
enabled | boolean | — | Enable or disable event logging |
dir | string | '~/.colony/events' | Directory where event log files are written |
retention_days | number | 30 | Number of days to retain event log files before pruning |
webhook
Section titled “webhook”Configures the webhook receiver that listens for incoming GitHub webhook events. This section is optional — omit it if you are not running the webhook receiver.
| Field | Type | Default | Description |
|---|---|---|---|
enabled | boolean | required | Enable the webhook receiver |
port | number (1–65535) | required | Port for the webhook receiver HTTP server to listen on |
secret_env | string | — | Name of the environment variable containing the HMAC secret used to verify webhook payloads from GitHub |
claude
Section titled “claude”Controls Claude CLI invocation behaviour and model selection for all agents.
| Field | Type | Default | Description |
|---|---|---|---|
timeout | number | 1800 | Overall Claude CLI invocation timeout in seconds |
max_retries | number | 1 | Number of times to retry a failed Claude invocation |
inactivity_timeout | number | 300 | Seconds without stdout/stderr output before the process is killed with SIGKILL |
max_cost_per_issue | number | — | USD cost cap per issue. When the accumulated cost for an issue reaches this limit, the Claude invocation is aborted, the issue is moved to colony:blocked, and Colony posts a comment with the cost breakdown. To unblock: raise this value in config, then comment /colony:retry on the GitHub issue to re-trigger processing. Omit for no limit. |
binary_path | string | 'claude' | Path to the Claude CLI binary. Override when the binary is not on PATH or you need a specific version |
provider | 'anthropic' | 'foundry' | 'anthropic' | API provider for Claude Code CLI. Use 'foundry' to route through Azure Foundry |
foundry | ClaudeFoundryConfig | — | Azure Foundry configuration. Only used when provider: 'foundry' |
models | ClaudeModelsConfig | — | Per-agent model overrides |
scaling | ClaudeScalingConfig | — | Per-complexity turn limits and model overrides. When omitted, built-in defaults are used (see below) |
ClaudeFoundryConfig
Section titled “ClaudeFoundryConfig”Used by claude.foundry. Only applies when claude.provider is 'foundry'.
| Field | Type | Default | Description |
|---|---|---|---|
resource | string | — | Azure resource name. URL constructed as https://{resource}.services.ai.azure.com/anthropic. Mutually exclusive with base_url |
base_url | string | — | Full Foundry base URL. Mutually exclusive with resource |
api_key_env | string | 'ANTHROPIC_FOUNDRY_API_KEY' | Environment variable holding the Foundry API key |
pin_models.opus | string | — | Pin the Opus deployment name (sets ANTHROPIC_DEFAULT_OPUS_MODEL) |
pin_models.sonnet | string | — | Pin the Sonnet deployment name (sets ANTHROPIC_DEFAULT_SONNET_MODEL) |
pin_models.haiku | string | — | Pin the Haiku deployment name (sets ANTHROPIC_DEFAULT_HAIKU_MODEL) |
Example:
claude: provider: foundry foundry: resource: my-azure-resource api_key_env: ANTHROPIC_FOUNDRY_API_KEY pin_models: opus: claude-opus-4-6 sonnet: claude-sonnet-4-6 haiku: claude-haiku-4-5Authentication: set ANTHROPIC_FOUNDRY_API_KEY in your environment, or omit it to use Azure Entra ID (DefaultAzureCredential chain). See the Claude Code Foundry docs for details.
ClaudeModelsConfig
Section titled “ClaudeModelsConfig”Used by claude.models.
| Field | Type | Default | Description |
|---|---|---|---|
developer | string | 'claude-opus-4-8' | Model used for the developer agent |
reviewer | string | 'claude-opus-4-8' | Model used for the reviewer agent |
analyzer | string | 'claude-sonnet-4-6' | Model used for the analyzer agent |
planner | string | 'claude-opus-4-8' | Model used for the planner agent |
merger | string | 'claude-sonnet-4-6' | Model used for the merger agent |
Model Cost Guidance
Section titled “Model Cost Guidance”Colony agents make different demands on the model. The table below shows approximate pricing and recommended use cases to help you balance cost against quality.
| Model | Approx. pricing (input / output per M tokens) | Recommended use |
|---|---|---|
claude-opus-4-8 | ~$5 / $25 (placeholder — official rate TBD) | Developer, Reviewer, and Planner — lowest fake-validation rate of any Opus generation. Reference default for developer, reviewer, and planner. |
claude-opus-4-7 | ~$5 / $25 | Alternate Opus generation — same pricing as 4-8 and 4-6; useful for users already running 4-7 in existing workflows. |
claude-opus-4-6 | ~$5 / $25 | Previous generation Opus — still capable for complex tasks, but 4-8 reduces test-gaming behavior significantly. |
claude-sonnet-4-6 | ~$3 / $15 | Analyzer and Merger — good balance of speed and quality for code triage and merge orchestration. Reference default for analyzer and merger. Also preferred over Opus-medium for small dev tasks (better cost-for-quality). |
claude-haiku-4-5-20251001 | ~$1 / $5 | Analyzer on cost-constrained setups — fastest and cheapest; suitable when issues are well-scoped and analysis depth is less critical. |
Pricing figures are approximate and may change. Use hedged budget estimates when planning spend.
Override any agent’s model via claude.models.<agent>:
claude: models: developer: claude-opus-4-8 # highest capability, lowest fake-validation rate reviewer: claude-opus-4-8 # read-only loop; slowness tolerable; 4-8 matters here analyzer: claude-sonnet-4-6 # high volume; sonnet-high is the sweet spot planner: claude-opus-4-8 # lowest volume, highest blast radius merger: claude-sonnet-4-6 # conflict resolution is bounded; sonnet sufficientNote: The annotated example config (
colony.config.example.yaml) sets all agents toclaude-sonnet-4-6as a cost-conscious starting point for evaluation. This differs from the reference defaults above (Opus 4-8 fordeveloper,reviewer, andplanner). If you start from the example config, you will get cheaper but potentially less capable behaviour for complex issues — adjustdeveloper,reviewer, andplannerto Opus 4-8 once you are comfortable with Colony’s output.Note on
opusplanalias: Theopusplanalias is frozen atclaude-opus-4-6for backward compatibility. Users who want the new default should useclaude-opus-4-8explicitly.
ClaudeScalingConfig
Section titled “ClaudeScalingConfig”Used by claude.scaling. The config is a map with keys small, medium, and large (matching issue complexity levels). Each entry is a ClaudeScalingEntry.
Example:
claude: scaling: small: developer_max_turns: 80 medium: developer_max_turns: 150 large: developer_max_turns: 250 no_progress_window: 75ClaudeScalingEntry
Section titled “ClaudeScalingEntry”| Field | Type | Default (built-in) | Description |
|---|---|---|---|
developer_max_turns | number | 80 / 150 / 250 (small / medium / large) | Maximum Claude turns for a developer invocation at this complexity |
model | string | claude-sonnet-4-6 (small) / claude-opus-4-8 (medium/large) | Override the model for this complexity level, taking precedence over claude.models.developer |
effort | 'low' | 'medium' | 'high' | 'max' | high (small/medium) / max (large) | Effort level hint passed to the Claude CLI for this complexity. Use max only for large/multi-file work; see effort-mode economics above |
planning_max_turns | number | 500 | Maximum turns for planning sub-tasks at this complexity |
no_progress_window | number | — (75 for large only) | Number of turns without measurable progress before aborting |
backstop_max_turns | number | 500 | Hard turn ceiling regardless of other limits |
Built-in default scaling (used when claude.scaling is not set):
| Tier | model | effort | developer_max_turns | Rationale |
|---|---|---|---|---|
| small | claude-sonnet-4-6 | high | 80 | Sonnet-high beats Opus-medium on cost-for-quality for 1–3 file mechanical work |
| medium | claude-opus-4-8 | high | 150 | Opus-high for 3–7 file work; max not justified at this scope |
| large | claude-opus-4-8 | max | 250 | The one tier where extended thinking’s 4x cost pays back on multi-file refactors |
Tuning for first use: The defaults work well for evaluation. If you find issues timing out or review checks failing on slow test suites, these are the first fields to adjust:
Field Default Recommended starting point claude.timeout1800Increase to 3600for large repos with long build timesreview.timeout_per_check120Raise to 300for slow test suitesagents.sprint_master.poll_interval3030is sufficient for evaluation; lower only if you need sub-30s latency and have webhooks configured
review
Section titled “review”Controls PR review behaviour: deterministic check commands, LLM review rounds, CI gating, and merge policy.
| Field | Type | Default | Description |
|---|---|---|---|
checks | Record<string, string> | {} | Named shell commands to run as deterministic review checks (e.g. test: 'npm test', lint: 'npm run lint'). Keys are check names; values are shell commands |
timeout_per_check | number | 120 | Seconds allowed for each check command before it is killed |
max_review_cycles | number | — | Maximum number of LLM review rounds before giving up. Unlimited if unset |
max_reimplement_cycles | number | — | Maximum number of times the developer re-implements after a review rejection. Unlimited if unset |
max_diff_lines | number | 3000 | Truncate the PR diff at this many lines when sending it to the LLM reviewer |
rebase_before_check | boolean | true | Rebase the PR branch onto the base branch before running check commands |
auto_merge_on_approval | boolean | false | Automatically merge the PR after the reviewer approves it |
require_ci_pass | boolean | true | Wait for all required CI checks to pass before merging |
ci_check_timeout | number | 300 | Seconds to wait for CI checks to complete before timing out |
ci_required_checks | string[] | [] | Names of specific CI checks that must pass. When empty, all checks must pass |
format_command | string | — | Formatting command to run before review checks (e.g. 'npm run format:fix'). Optional |
empty_verdict_auto_approve | boolean | true | Auto-approve when the LLM returns an empty or unparseable verdict and all deterministic checks passed |
external_prs | ExternalPrReviewConfig | mode: off | External PR review settings — controls whether Colony reviews human-authored PRs. See ExternalPrReviewConfig below |
ExternalPrReviewConfig
Section titled “ExternalPrReviewConfig”Used by review.external_prs. Controls how Colony handles PRs that are not part of its own pipeline (i.e., PRs not on colony/issue-N branches). The feature is disabled by default (mode: off). See External PR Review for a usage guide covering all three modes.
| Field | Type | Default | Description |
|---|---|---|---|
mode | 'off' | 'on_request' | 'on_ready' | 'auto' | 'off' | When to review external PRs. off — disabled. on_request — only when a human comments /colony:review on the PR. on_ready — automatically when a PR is opened or transitions from draft to ready. auto — same triggers as on_ready, with the auto_approve flag available |
author_filter | string[] | ['*'] | Allowlist of GitHub usernames to review. ['*'] means any author. Set to a specific list to limit reviews to those users |
label_filter | string[] | [] | Require all listed labels to be present on the PR before reviewing. Empty list means no label requirement. Multiple labels use AND semantics — all must be present |
exclude_bots | boolean | true | Skip PRs authored by bot accounts (GitHub user type 'Bot') |
exclude_drafts | boolean | true | Skip draft PRs |
auto_approve | boolean | false | Recorded as task metadata and validated — Colony logs a startup warning if this is set to true without mode: auto. Note: Colony posts a formal GitHub Approve review event whenever the LLM verdict is APPROVE, regardless of this flag. Reserved for future use |
Example:
review: external_prs: mode: on_request # safest starting modeagents
Section titled “agents”Configures the Colony agent processes. Each agent type extends a common set of fields. Agents run as standalone processes (singletons) or as part of the per-repo worker pool.
Common AgentConfig Fields
Section titled “Common AgentConfig Fields”All agent types share these base fields:
| Field | Type | Default | Description |
|---|---|---|---|
enabled | boolean | true | Whether the agent runs |
poll_interval | number | 30 | Seconds between poll cycles (minimum 5) |
health_port | number | (per agent) | HTTP health check port |
effort | 'low' | 'medium' | 'high' | 'max' | — | Claude effort level for this agent |
agents.sprint_master
Section titled “agents.sprint_master”Issue intake and pipeline monitoring. Enqueues tasks to the Postgres work queue when issues transition states.
| Field | Type | Default | Description |
|---|---|---|---|
| Common fields | health_port: 9100 | See Common AgentConfig Fields | |
intake_mode | 'all' | 'tagged' | 'tagged' | Whether to pick up all new issues or only colony-tagged ones |
heartbeat_timeout_minutes | number | 5 | Minutes before reclaiming stale tasks from workers that stopped heartbeating |
sweep_cooldown_minutes | number | 10 | Minutes to suppress re-enqueueing a sweep task after completion (0 to disable) |
label_sync_limit | number | 25 | Max issues to reconcile labels for per poll cycle |
projection_drain_limit | number | 50 | Max queued VCS write projections to drain per poll cycle |
agents.analyzer
Section titled “agents.analyzer”Issue analysis and triage. Uses bare AgentConfig with no additional fields.
| Field | Type | Default | Description |
|---|---|---|---|
| Common fields | health_port: 9101 | See Common AgentConfig Fields |
agents.reviewer
Section titled “agents.reviewer”PR review: deterministic checks plus LLM review. Uses bare AgentConfig with no additional fields.
| Field | Type | Default | Description |
|---|---|---|---|
| Common fields | health_port: 9103 | See Common AgentConfig Fields |
agents.developer
Section titled “agents.developer”Issue implementation via Claude Code.
| Field | Type | Default | Description |
|---|---|---|---|
| Common fields | health_port: 9102 | See Common AgentConfig Fields | |
repo_context | RepoContextConfig | — | Controls repository context injection into prompts |
pr_overlap_threshold | number (0–1) | — | Fraction of plan files overlapping with open PRs to trigger block |
max_tooling_retries | number | 2 | Poll-level retries for transient push failures |
forbidden_paths | string[] | — | Glob patterns the agent may not read or write. See Protected Paths. |
read_only_paths | string[] | — | Glob patterns the agent may read but not write. See Protected Paths. |
RepoContextConfig
Section titled “RepoContextConfig”Used by agents.developer.repo_context.
| Field | Type | Default | Description |
|---|---|---|---|
enabled | boolean | — | Enable repository context injection |
max_tokens | number | — | Maximum tokens for the context payload |
tree_depth | number | — | Depth of the directory tree to include |
agents.planner
Section titled “agents.planner”Epic decomposition — breaks large issues into sub-tasks.
| Field | Type | Default | Description |
|---|---|---|---|
| Common fields | health_port: 9105 | See Common AgentConfig Fields | |
max_turns | number | 200 | Max Claude turns for planning |
model | string | — | Override model for planner |
agents.merger
Section titled “agents.merger”Merge orchestration — handles PR merging and conflict resolution.
| Field | Type | Default | Description |
|---|---|---|---|
| Common fields | health_port: 9104 | See Common AgentConfig Fields | |
conflict_resolution | ConflictResolutionConfig | — | Automated merge conflict resolution settings |
ConflictResolutionConfig
Section titled “ConflictResolutionConfig”Used by agents.merger.conflict_resolution.
| Field | Type | Default | Description |
|---|---|---|---|
enabled | boolean | — | Enable automated conflict resolution |
max_conflict_files | number | — | Maximum number of conflicting files to attempt resolution on |
max_conflict_regions | number | — | Maximum number of conflict regions to attempt resolution on |
timeout | number | — | Timeout in seconds for conflict resolution |
model | string | — | Override model for conflict resolution |
auto_merge_high_confidence_resolutions | boolean | — | Automatically merge when conflict resolution has high confidence |
agents.monitor
Section titled “agents.monitor”Pipeline observability, self-healing, and Prometheus metrics. Disabled by default.
| Field | Type | Default | Description |
|---|---|---|---|
| Common fields | enabled: false, health_port: 9106 | See Common AgentConfig Fields | |
agent_down_timeout | number | 120 | Seconds before alerting that an agent is down |
pipeline_stall_timeout_minutes | number | 60 | Minutes before alerting a pipeline stall |
error_rate_threshold | number (0–1) | 0.5 | Alert if error rate exceeds this fraction |
error_rate_window | number | 30 | Minutes, rolling window for error rate calculation |
cost_alert_threshold | CostAlertThreshold | — | Cost alerting thresholds |
alert_cooldown | number | 30 | Minutes, deduplication window for alerts |
alert_channels | MonitoringAlertChannel[] | [] | Alert delivery channels |
metrics_refresh_minutes | number | 10 | How often to refresh pipeline metrics |
sweep_cooldown_minutes | number | 10 | Minutes to suppress re-enqueueing a sweep task after completion (0 to disable) |
agent_health_host | string | 'localhost' | Host for polling agent health endpoints |
auth | MonitorAuth | — | Basic auth for the monitor HTTP API |
self_healing | SelfHealingConfig | (see below) | Self-healing automation settings |
regression_guard | RegressionGuardConfig | (see below) | Pipeline health regression guard settings |
CostAlertThreshold
Section titled “CostAlertThreshold”Used by agents.monitor.cost_alert_threshold.
| Field | Type | Default | Description |
|---|---|---|---|
daily_usd | number | — | Alert when daily cost exceeds this USD amount |
monthly_usd | number | — | Alert when monthly cost exceeds this USD amount |
MonitorAuth
Section titled “MonitorAuth”Used by agents.monitor.auth.
| Field | Type | Default | Description |
|---|---|---|---|
username | string | required | Username for basic auth |
password_env | string | required | Name of the environment variable containing the password |
MonitoringAlertChannel
Section titled “MonitoringAlertChannel”Used by agents.monitor.alert_channels.
| Field | Type | Default | Description |
|---|---|---|---|
type | 'github_issue' | 'webhook' | 'slack' | 'pagerduty' | required | Alert channel type |
url | string | — | Endpoint URL for webhook/slack/pagerduty |
url_env | string | — | Name of the environment variable containing the endpoint URL |
routing_key | string | — | PagerDuty integration routing key (literal value, not an env var name) |
Example: Alerting Configuration
Section titled “Example: Alerting Configuration”agents: monitor: alert_cooldown: 30 cost_alert_threshold: daily_usd: 50 monthly_usd: 500 alert_channels: - type: slack url_env: COLONY_SLACK_WEBHOOK_URL - type: pagerduty routing_key: YOUR_PAGERDUTY_ROUTING_KEY - type: webhook url_env: COLONY_ALERT_WEBHOOK_URL - type: github_issueslack— Posts Block Kit messages to a Slack incoming webhook. Seturl_envto the name of the environment variable containing the webhook URL.pagerduty— Sends Events API v2 triggers. Setrouting_keyto the PagerDuty integration routing key (literal value, not an env var).webhook— POSTs a JSON payload to any HTTP endpoint. Seturl_envto the name of the environment variable containing the URL.github_issue— Creates a GitHub issue labeledcolony:alertin the first configured repo. No additional fields required.
The alert_cooldown (minutes) controls deduplication — each unique alert ID is only dispatched once per window. The cost_alert_threshold fires a warning when aggregate daily or monthly spend exceeds the configured USD amounts.
SelfHealingConfig
Section titled “SelfHealingConfig”Used by agents.monitor.self_healing.
| Field | Type | Default | Description |
|---|---|---|---|
auto_relabel_orphans | boolean | false | Deprecated. Parsed for backward compatibility but has no effect; orphan recovery runs automatically via reclaimStaleTasks and the monitor task-enqueue sweep. |
worktree_cleanup_interval_hours | number | 6 | Hours between worktree cleanup sweeps |
auto_unblock_transient | boolean | false | Automatically unblock issues that were blocked by transient failures |
max_auto_unblocks_per_issue | number | — | Maximum automatic unblocks per issue before requiring manual intervention |
auto_restart | boolean | false | Enable automatic agent restart on failure |
restart_strategy | 'pid' | 'systemd' | 'pm2' | 'pid' | Process restart mechanism |
restart_cooldown | number | 300 | Seconds between restart attempts |
max_restart_attempts | number | 3 | Maximum restart attempts before giving up |
restart_dry_run | boolean | false | Log restart actions without executing them |
work_task_retention_days | number | 31 | Days to retain completed work tasks before pruning (≈4× more rows than the previous 7-day default; negligible at current Colony scale) |
RegressionGuardConfig
Section titled “RegressionGuardConfig”Used by agents.monitor.regression_guard. Controls the pipeline-health regression guard that detects KPI degradation over rolling windows.
| Field | Type | Default | Description |
|---|---|---|---|
enabled | boolean | false | Enable the regression guard |
current_window_hours | number | 24 | Hours in the recent (current) measurement window |
baseline_window_days | number | 7 | Days in the baseline measurement window |
relative_threshold | number (0–1) | 0.25 | Fractional degradation that counts as a regression |
min_samples | number | 20 | Minimum sample floor — regressions are not reported below this count |
kpis | Record<RegressionKpi, boolean> | {} | Per-KPI enable flags; omitted keys are disabled |
KPI regression directions — a regression is flagged when the metric moves in the bad direction beyond relative_threshold:
| KPI | Regresses on |
|---|---|
block_rate | rise |
failure_blocked_rate | rise |
review_pass_rate | fall |
mean_cost_per_issue | rise |
mean_turns_per_issue | rise |
reimplement_loop_rate | rise |
dead_letter_rate | rise |
The REGRESSION_DIRECTION const exported from @colony/core encodes this mapping as a runtime value — downstream compute code should import it rather than re-deriving the direction.
This block is hot-reloadable via POST /api/config/reload. A partial reload merges only the specified keys and preserves all unspecified fields (including nested kpis entries).
Example
Section titled “Example”agents: monitor: regression_guard: enabled: true current_window_hours: 24 baseline_window_days: 7 relative_threshold: 0.25 min_samples: 20 kpis: block_rate: true review_pass_rate: true mean_cost_per_issue: trueagents.workers
Section titled “agents.workers”Per-repo worker pool configuration. Workers claim tasks from the Postgres work_tasks queue and dispatch to executor libraries. This section is optional — omit it when using standalone agent processes.
| Field | Type | Default | Description |
|---|---|---|---|
| Common fields | — | Inherits enabled, poll_interval, health_port from Common AgentConfig Fields; defaults depend on deployment configuration | |
heartbeat_interval | number | — | Seconds between task heartbeats. Workers send heartbeats to the Postgres queue to signal liveness — if a worker stops heartbeating for longer than sprint_master.heartbeat_timeout_minutes, the task is reclaimed |
max_task_retries | number | 3 | Max failures for a repo+issue+taskType combination within 60 minutes before dropping re-enqueue |
Resolution Chain
Section titled “Resolution Chain”Note: The resolution chain applies to multi-repo deployments using
repos[]. For single-repo setups (the default), all settings are configured at the top level — no per-repo overrides are needed. See Multi-Repo (Colony Cloud) for details.
When a field can be set both globally and per-repo, Colony resolves the value using this fallback chain:
repoConfig.<field> ?? config.<field> ?? defaultThe per-repo value takes precedence when set; it falls back to the global value, then to the built-in default. The following helper functions in packages/core/src/config.ts implement this pattern for specific fields:
resolveIntakeMode(repoConfig, config)— resolvesintake_moderesolveAutoMerge(repoConfig, config)— resolves auto-merge behaviorresolveSelfImprovement(repoConfig, config)— resolvesself_improvementsettingsresolveDependabotConfig(repoConfig)— resolvesdependabotsettings
self_improvement
Section titled “self_improvement”Controls Colony’s self-improvement feature, which allows Colony to file issues against itself.
| Field | Type | Default | Description |
|---|---|---|---|
enabled | boolean | false | Enable the self-improvement feature |
label | string | 'colony:self-improvement' | GitHub label used to tag self-improvement issues |
cooldown_minutes | number (≥1) | 30 | Minimum minutes between self-improvement issue filings |
tracks | SelfImprovementTrack[] | — | Per-track configuration for self-improvement. See deprecated fields |
calibration
Section titled “calibration”Controls the complexity calibration feature used to tune issue complexity estimates.
| Field | Type | Default | Description |
|---|---|---|---|
lookback_days | number | 7 | Number of days of historical issues to consider when calibrating complexity estimates |
Credential File Convention
Section titled “Credential File Convention”Colony workers support an optional operator-mounted credential file at /colony/keys/credentials.yaml. When present, the container entrypoint runs scripts/render-credentials.sh before starting any agent process. The rendered config files authenticate package manager clients against private feeds (Azure DevOps Artifacts npm registries and NuGet feeds).
The /colony/keys volume already exists in the default container setup (it also holds the GitHub App private key).
Schema
Section titled “Schema”schema: 1credentials: azure_devops: pat: <personal-access-token> # required; Azure DevOps PAT with Packaging read scope organization: <org-name> # informational; not used by the renderer feeds: - url: https://<org>.pkgs.visualstudio.com/_packaging/<feed-name>/npm/registry/ kind: npm scope: '@my-scope' # optional; derived from feed name if omitted - url: https://<org>.pkgs.visualstudio.com/_packaging/<feed-name>/nuget/v3/index.json kind: nuget| Field | Type | Required | Description |
|---|---|---|---|
schema | number | required | Schema version. Must be 1. Any other value causes entrypoint to exit non-zero |
credentials.azure_devops.pat | string | required | Azure DevOps Personal Access Token. Missing or null value causes entrypoint to exit non-zero |
credentials.azure_devops.organization | string | — | Azure DevOps organization name. Informational only; not used by the renderer |
credentials.azure_devops.feeds | array | — | List of feed entries. Empty array or missing section is not an error — entrypoint exits 0 silently |
feeds[].kind | 'npm' | 'nuget' | required | Package manager for this feed |
feeds[].url | string | required | Full registry/feed URL |
feeds[].scope | string | — | npm scope to bind (e.g. "@acme"). For kind: npm only. Derived from the feed name in the URL if omitted |
Example
Section titled “Example”schema: 1credentials: azure_devops: pat: ghp_xxxxxxxxxxxxxxxxxxxx organization: myorg feeds: - url: https://myorg.pkgs.visualstudio.com/_packaging/my-npm-feed/npm/registry/ kind: npm scope: '@myorg' - url: https://myorg.pkgs.visualstudio.com/_packaging/my-nuget-feed/nuget/v3/index.json kind: nugetWhat gets rendered
Section titled “What gets rendered”| Kind | Output file | Format |
|---|---|---|
npm | ~/.npmrc | scope→registry mapping + base64-encoded _authToken |
nuget | ~/.config/NuGet/NuGet.Config | XML <packageSources> + <packageSourceCredentials> |
All rendered files are written with mode 0600.
Reserved kinds (not yet implemented)
Section titled “Reserved kinds (not yet implemented)”The following kind values are reserved for future use and are not processed in v1:
github— reserved; the existingscripts/git-credential-colony.mjshelper handles GitHub auth and is not superseded by this conventionpypi— future:~/.config/pip/pip.confmaven— future:~/.m2/settings.xml
Behavior
Section titled “Behavior”- Missing file — If
/colony/keys/credentials.yamldoes not exist,render-credentials.shexits 0 silently. No warning is logged, and all agents start normally. - Schema mismatch — If
schemais not1, the entrypoint exits non-zero with a message naming the offending file. No agent process starts. Fix the YAML and restart the worker. - Missing PAT — If
credentials.azure_devops.patis absent or null, the entrypoint exits non-zero with a clear error. Fix and restart. - Empty feeds — Zero feed entries is not an error; entrypoint exits 0.
- Credential values — The renderer never logs token values. Log output only reports the count of entries written (e.g.,
render-credentials: wrote 2 npm credential entries to ~/.npmrc).
Rotating credentials
Section titled “Rotating credentials”Edit /colony/keys/credentials.yaml on the host and restart the worker container. The entrypoint re-renders all credential files from scratch on each start — stale entries from a previous run are replaced.
Security
Section titled “Security”Credentials are never baked into image layers. The /colony/keys directory is operator-mounted at container run time. Rendered config files (~/.npmrc, ~/.config/NuGet/NuGet.Config) are written inside the running container’s filesystem with mode 0600 and do not persist across restarts.
Enterprise Networks
Section titled “Enterprise Networks”On networks that perform TLS interception (corporate proxies, Zscaler, Palo Alto, and similar), every outbound HTTPS connection is re-signed by an internal CA that the system trust store does not recognize. Without trust propagation, every npm install, dotnet restore, az login, and curl call fails at the TLS handshake — before authentication is even attempted.
Root CA mount
Section titled “Root CA mount”Mount your PEM-format root CA certificate(s) under /colony/keys/ca-certs/:
services: worker: volumes: - /path/to/ca-certs/:/colony/keys/ca-certs/:roOr mount individual files:
volumes: - ./corp-root-ca.crt:/colony/keys/ca-certs/corp-root-ca.crt:roAny *.crt file in that directory is treated as a PEM-encoded root CA. The directory is operator-managed and never baked into image layers.
Trust propagation
Section titled “Trust propagation”The entrypoint runs scripts/install-trusted-cas.sh before any other initialization. It propagates trust to:
| Runtime / tool | Mechanism |
|---|---|
curl, wget, apt, Azure CLI | System trust store via update-ca-certificates |
dotnet restore, dotnet tool install | System trust store (honored automatically) |
Node.js, npm, npx, bun | NODE_EXTRA_CA_CERTS env var pointing at a combined CA bundle |
Format requirement
Section titled “Format requirement”Certificates must be PEM-encoded with a .crt extension. If your CA certificate is in DER or PFX format, convert it before mounting:
# DER → PEMopenssl x509 -inform DER -in corp-ca.der -out corp-ca.crt
# PFX → PEM (extract CA cert only)openssl pkcs12 -in corp-ca.pfx -nokeys -out corp-ca.crtBehavior
Section titled “Behavior”- Empty or absent directory — exits 0 silently; trust stores are unchanged; behavior is identical to a standard deployment.
- Malformed cert — entrypoint exits non-zero with a message naming the offending file. No agent process starts. Fix the certificate and restart.
- Multiple certs — all
.crtfiles in the directory are installed. - Cert rotation — replace files on the host and restart the worker. Trust stores are rebuilt from scratch on each start.
- Cert contents — never logged. Log output only reports the count of certificates installed (e.g.,
install-trusted-cas: installed 1 CA certificate(s)).
executors (ExecutorsConfig)
Section titled “executors (ExecutorsConfig)”Executor-specific settings that belong to the execution logic of each agent type (distinct from agent process infrastructure such as poll_interval and health_port).
If executors is not set, values are auto-populated from the corresponding agents.* fields for backward compatibility via populateExecutorsFromAgents() in config.ts.
Workflow YAML and task inputs: Executors can receive typed inputs forwarded from a preceding stage via the
outputsblock in.colony/workflow.yaml— this is separate fromcolony.config.yaml. For theoutputsblock syntax, per-task-type input schemas, and merge semantics, see the Executor Contract Reference.
executors.analyzer
Section titled “executors.analyzer”| Field | Type | Default | Description |
|---|---|---|---|
effort | 'low' | 'medium' | 'high' | — | Claude effort level for the analyzer. Maps to claude --effort |
executors.developer
Section titled “executors.developer”| Field | Type | Default | Description |
|---|---|---|---|
repo_context | RepoContextConfig | — | Controls how the developer builds repository context for Claude Code |
pr_overlap_threshold | number | — | Number of overlapping files with another open PR before blocking development |
max_tooling_retries | number | — | Maximum retries for transient tooling errors during development |
effort | 'low' | 'medium' | 'high' | — | Claude effort level for the developer |
forbidden_paths | string[] | — | Glob patterns the agent may not read or write. See Protected Paths. |
read_only_paths | string[] | — | Glob patterns the agent may read but not write. See Protected Paths. |
self_validation_max_cycles | number (1–10) | 3 | Maximum self-validation repair cycles before escalating to human review. |
ci_repair_max_cycles | number (1–10) | 2 | Maximum CI repair cycles before escalating to human review. |
Protected Paths
Section titled “Protected Paths”forbidden_paths and read_only_paths let operators restrict which files the developer agent may access or modify. The enforcement happens at the tool call level — the agent receives a hard error rather than a prompt-level suggestion.
forbidden_paths — the agent cannot read or write these paths. Use for secrets, credentials, and other files the agent should never see (e.g. .env*, secrets/**).
read_only_paths — the agent can read these paths for context but cannot edit them. Use for IaC definitions, generated migration files, and CI workflows (e.g. infrastructure/**, .github/workflows/**, **/Migrations/**).
Example:
developer: forbidden_paths: - 'secrets/**' - '.env*' read_only_paths: - 'infrastructure/**' - '**/*.bicep' - '**/*.bicepparam' - '.github/workflows/**' - '**/Migrations/**'Paths are repo-relative and use minimatch glob syntax with { dot: true } (so .env* matches .env). Empty or unset lists mean no enforcement — behavior is identical to deployments without these keys.
Cascade: values set under agents.developer are cascaded into executors.developer by resolveConfig(). At runtime, executors.developer is the authoritative source.
Hook glob engine limitation: the PreToolUse hook script that enforces the lists at tool-call time uses a custom glob-to-regex engine that does not support brace expansion ({a,b}). Use separate list entries instead — e.g. '**/*.bicep' and '**/*.bicepparam' rather than '**/*.{bicep,bicepparam}'. The reviewer diff check uses minimatch directly and does support brace expansion.
Bash detection limitation: the hook pattern-matches common shell write idioms (>, >>, tee, sed -i, cp, mv, cat <<HEREDOC >) and read idioms (cat, less, head, tail, grep, source), but is best-effort. It misses variable expansion ($DEST), subshell paths ($(get_path)/file), and quoted paths with spaces. The reviewer diff check (which scans the actual PR diff) is the reliable safety net.
executors.reviewer
Section titled “executors.reviewer”| Field | Type | Default | Description |
|---|---|---|---|
effort | 'low' | 'medium' | 'high' | — | Claude effort level for the reviewer |
executors.planner
Section titled “executors.planner”| Field | Type | Default | Description |
|---|---|---|---|
max_turns | number | — | Maximum number of turns for the planner’s Claude session |
effort | 'low' | 'medium' | 'high' | — | Claude effort level for the planner |
model | string | — | Override the Claude model used by the planner |
executors.merger
Section titled “executors.merger”| Field | Type | Default | Description |
|---|---|---|---|
conflict_resolution | ConflictResolutionConfig | — | LLM-assisted conflict resolution settings. See the agents.merger section for field details |
Multi-Repo (Colony Cloud)
Section titled “Multi-Repo (Colony Cloud)”Colony Cloud supports managing multiple repositories from a single Colony instance using repos[] or tenants[] configuration. For single-repo deployments (the default open-source path), these sections are not needed — the flat github + workspace top-level config is all you need.
repos[] (RepoConfig)
Section titled “repos[] (RepoConfig)”Multi-repo deployments list each repository under repos. Each entry configures authentication, workspace, and pipeline behavior for one repository. Config cannot have both top-level repos and tenants.
| Field | Type | Default | Description |
|---|---|---|---|
owner | string | required | GitHub organization or user that owns the repository |
repo | string | required | Repository name |
token_env | string | — | Name of the environment variable containing the PAT for this repo. Either token_env or app is required |
app | GitHubAppConfig | — | Per-repo GitHub App credentials for the coder identity. Either app or token_env is required |
ops_app | GitHubAppConfig | — | Per-repo GitHub App credentials for the ops identity |
ops_token_env | string | — | Name of the environment variable containing the PAT for the ops identity. Alternative to ops_app |
bot_username | string | — | Display name shown for bot-authored comments and labels for this repo |
workspace | RepoWorkspaceConfig | required | Per-repo workspace settings. Overrides the global workspace section |
review | RepoReviewConfig | — | Per-repo review overrides. Only the fields in the explicit pick list can be overridden |
self_improvement | SelfImprovementConfig | — | Per-repo override for self-improvement settings |
pattern_memory | PatternMemoryConfig | — | Per-repo pattern memory settings. See fields below |
sla | SlaConfig | — | Per-repo SLA thresholds. See fields below |
intake_mode | 'all' | 'tagged' | — | Overrides the global agents.sprint_master.intake_mode for this repo. When set, only this repo’s intake behavior changes |
workers | WorkerPoolConfig | — | Per-repo worker pool settings. See fields below |
dependabot | DependabotConfig | — | Per-repo Dependabot integration settings. See fields below |
pattern_memory
Section titled “pattern_memory”| Field | Type | Default | Description |
|---|---|---|---|
enabled | boolean | required | Enable pattern memory for this repo |
max_results | number (≥1) | required | Maximum number of pattern results to include in prompts |
lookback_days | number (≥1) | required | Number of days of history to search for patterns |
| Field | Type | Default | Description |
|---|---|---|---|
warn_after_minutes | Record<string, number> | — | Map of pipeline state name (e.g. 'in-development') to the number of minutes before a warning is emitted. Only states that need a threshold need to be listed |
workers
Section titled “workers”| Field | Type | Default | Description |
|---|---|---|---|
pool_size | number (integer ≥1) | — | Number of worker processes to run for this repo |
memory | string | — | Container memory limit for worker processes (e.g. '4g', '6G') |
health_port_start | number | — | Starting port for sequential health check endpoint allocation. Port ranges must not overlap across repos |
dependabot
Section titled “dependabot”| Field | Type | Default | Description |
|---|---|---|---|
auto_review | boolean | — | Automatically trigger a review cycle for Dependabot PRs |
auto_merge_patch | boolean | false | Auto-merge patch updates after deterministic checks pass |
auto_merge_minor | boolean | false | Require LLM review for minor updates before merging |
auto_migrate_breaking | boolean | false | Automatically create migration issues for breaking major updates (opt-in) |
bot_usernames | string[] | ['dependabot[bot]'] | GitHub usernames to treat as Dependabot for triggering this integration |
Per-Repo Workspace Overrides (RepoWorkspaceConfig)
Section titled “Per-Repo Workspace Overrides (RepoWorkspaceConfig)”Each entry in repos[] requires a workspace block. Fields here override the corresponding global workspace values for that repo using the fallback chain repoConfig.workspace.<field> ?? config.workspace.<field> ?? default.
| Field | Type | Default | Scope | Description |
|---|---|---|---|---|
repo_dir | string | required | overrides global | Path to the local git clone for this repo |
base_dir | string | required | overrides global | Base directory for this repo’s worktrees. Supports {owner} and {repo} template tokens |
setup_command | string | — | overrides global | Command to run after creating a worktree (e.g. 'bundle install'). Overrides the global workspace.setup_command |
setup_timeout | number | 300 | overrides global | Seconds to allow the setup command to run. Overrides the global workspace.setup_timeout |
prebuild_command | string | — | overrides global | Command to run after setup_command to pre-build workspace packages. Overrides the global workspace.prebuild_command |
review_workspace_base | string | — | overrides global | Container-local path for ephemeral reviewer worktrees |
skip_pre_push_hook | boolean | — | overrides global | Pass --no-verify to git push for this repo |
branch | string | 'main' | overrides global | Default branch name for this repo |
secret_env_vars | string[] | — | per-repo only | Names of environment variables to resolve and inject into worker processes for this repo |
timeouts | TimeoutsConfig | — | per-repo only | Fine-grained clone and tooling timeouts. See fields below |
timeouts (TimeoutsConfig)
Section titled “timeouts (TimeoutsConfig)”| Field | Type | Default | Description |
|---|---|---|---|
clone | number | 600 (recommended) | Seconds before git clone is timed out |
mise_install | number | 600 | Seconds before mise install is timed out |
mise_reshim | number | 30 | Seconds before mise reshim is timed out |
submodule_init | number | 120 | Seconds before git submodule update --init is timed out |
Per-Repo Review Overrides (RepoReviewConfig)
Section titled “Per-Repo Review Overrides (RepoReviewConfig)”The review block inside a repos[] entry accepts an explicit subset of the global ReviewConfig fields. Only fields in the following pick list can be overridden per-repo:
| Field | Type | Description |
|---|---|---|
checks | Record<string, string> | Override the review check commands for this repo |
timeout_per_check | number | Seconds to allow each check to run |
rebase_before_check | boolean | Rebase the PR branch onto the base branch before running checks |
require_ci_pass | boolean | Require all CI checks to pass before merging |
ci_check_timeout | number | Seconds to wait for CI checks to complete |
ci_required_checks | string[] | Names of CI checks that must pass |
format_command | string | Command to auto-format code before review |
auto_merge_on_approval | boolean | Auto-merge the PR when the reviewer approves |
external_prs | ExternalPrReviewConfig | External PR review settings (mode, filters, auto_approve). Per-repo value overrides the corresponding global review.external_prs fields (field-by-field fallback — unset fields inherit from global) |
The following ReviewConfig fields are global-only and cannot be overridden per-repo: max_review_cycles, max_reimplement_cycles, max_diff_lines, empty_verdict_auto_approve.
Note: New fields added to
ReviewConfigare not automatically per-repo-overridable. The pick list inRepoReviewConfigmust be updated explicitly to expose them.
tenants[] (TenantConfig)
Section titled “tenants[] (TenantConfig)”Multi-tenant deployments group repositories by tenant under tenants. Each tenant has its own GitHub App credentials and optional cost budget. Config cannot have both top-level tenants and repos.
| Field | Type | Default | Description |
|---|---|---|---|
id | string | required | Unique identifier for this tenant |
name | string | — | Human-readable tenant name |
app | GitHubAppConfig | — | Tenant-level GitHub App credentials for the coder identity |
ops_app | GitHubAppConfig | — | Tenant-level GitHub App credentials for the ops identity |
anthropic_api_key_env | string | — | Name of the environment variable containing the Anthropic API key for this tenant. Overrides the global ANTHROPIC_API_KEY |
cost_budget | object | — | Cost budget settings for this tenant. See fields below |
defaults | object | — | Default settings cascaded to repos in this tenant that do not override them. Currently supports timeouts (TimeoutsConfig) |
repos | RepoConfig[] | required | List of repositories belonging to this tenant |
cost_budget
Section titled “cost_budget”| Field | Type | Default | Description |
|---|---|---|---|
monthly_usd | number | — | Monthly spending cap in USD for this tenant |
Per-agent-type keys alongside repos[].workers
Section titled “Per-agent-type keys alongside repos[].workers”When repos[].workers (the worker pool model) is configured, setting per-agent-type keys under agents (developer, analyzer, reviewer, merger, planner) for executor-specific settings is deprecated. Use the executors section instead.
# Before (deprecated — when repos[].workers is set)agents: developer: effort: high
# Afterexecutors: developer: effort: highDeprecated Configuration
Section titled “Deprecated Configuration”The following fields are still accepted by the config loader but will be removed in a future release. Migrate away from them as soon as possible.
llm.* (LlmConfig)
Section titled “llm.* (LlmConfig)”Fields: llm.analyzer_max_turns, llm.reviewer_max_turns, llm.developer_max_turns
Migration: Use claude.scaling (ClaudeScalingConfig) instead. Per-agent max_turns are now configured via claude.scaling entries keyed by complexity (small, medium, large).
# Before (deprecated)llm: developer_max_turns: 150
# Afterclaude: scaling: medium: developer_max_turns: 150monitoring.* (legacy top-level key)
Section titled “monitoring.* (legacy top-level key)”Migration: Move all fields under agents.monitor. The loader still accepts monitoring: as a top-level key and merges it into agents.monitor for backward compatibility (see config.ts:179–194), but this bridge will be removed in a future release.
# Before (deprecated)monitoring: enabled: true port: 9100
# Afteragents: monitor: enabled: true port: 9100self_improvement.tracks (SelfImprovementTrack[])
Section titled “self_improvement.tracks (SelfImprovementTrack[])”Migration: Manage tracks via the dashboard UI or the monitor REST API (POST /api/si/tracks). YAML track definitions in the config file are ignored as of the deprecation warning emitted at config load time (see config.ts:249–257) and will be fully removed in a future release.