pace.config.yaml
pace.config.yaml lives at pace/pace.config.yaml and is read by every agent before each run. All fields in this document are required unless marked optional.
Top-level fields
| Field | Type | Description |
|---|---|---|
framework_version | string | PACE framework version. Currently "1.0". |
product
product: name: "Acme API" description: > A one-paragraph description. github_org: "acme-corp"| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Short product name. Injected into every agent system prompt. |
description | string | Yes | One paragraph describing the product, its users, and the problem it solves. |
github_org | string | Yes* | GitHub organisation name. Used for constructing PR/issue URLs. *Not used when platform.ci is not github. |
sprint
sprint: duration_days: 30| Field | Type | Required | Description |
|---|---|---|---|
duration_days | integer | Yes | Total days in the sprint. Running --day N where N > duration_days raises an error. |
source
source: dirs: - name: "api" path: "src/" language: "Python" description: "FastAPI application" docs_dir: nullsource.dirs
A list of source directory entries. FORGE is restricted to reading and writing files only inside these directories.
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Short label used in agent prompts. |
path | string | Yes | Path relative to the repository root. Must end with /. |
language | string | Yes | Primary programming language in this directory. |
description | string | Yes | One-line description injected into FORGE’s system prompt. |
source.docs_dir
| Field | Type | Required | Description |
|---|---|---|---|
docs_dir | string | null | No | Path to an external documentation directory. SCRIBE reads from and writes to this location. Can be absolute or relative to the repo root’s parent directory. Default: null. |
tech
tech: primary_language: "Python 3.12" secondary_language: null ci_system: "GitHub Actions" test_command: "pytest -v --tb=short" build_command: null| Field | Type | Required | Description |
|---|---|---|---|
primary_language | string | Yes | Primary language FORGE writes. Injected into agent prompts. |
secondary_language | string | null | No | Optional secondary language (e.g. "Go 1.22" for a CLI binary). Default: null. |
ci_system | string | Yes | CI/CD system name. Injected into CONDUIT’s prompt. |
test_command | string | Yes | Command GATE runs from the repo root to execute the test suite. Must exit 0 on success. |
build_command | string | null | No | Optional command run before tests (e.g. "go build ./..."). Default: null. |
platform
platform: ci: github tracker: github # optional — defaults to ci valueplatform.ci controls where pull/merge requests and CI polling happen. platform.tracker controls where issues (escalations, advisories) are opened. Both accept the same adapter names and default to the same value when tracker is omitted.
| Field | Type | Required | Description |
|---|---|---|---|
ci | string | Yes | CI/CD adapter. Controls PR creation and CI pipeline polling. See table below. |
tracker | string | No | Issue tracker adapter. Controls escalation issue creation. Defaults to ci. |
Adapter values
| Value | PR/MR | Issues | CI polling | Job summary |
|---|---|---|---|---|
github | GitHub PR | GitHub Issue | GitHub Actions via API | $GITHUB_STEP_SUMMARY |
gitlab | GitLab MR | GitLab Issue | GitLab Pipelines API | $CI_JOB_SUMMARY or file |
bitbucket | Bitbucket PR | Bitbucket Issue | Bitbucket Pipelines API | pace-summary.md |
jenkins | Local file | Local file | Jenkins REST API | jenkins-summary.md |
jira | n/a | Jira Bug/Task | Not supported (no_runs) | pace-summary.md |
local | Local file | Local file | Returns no_runs | pace-summary.md |
Example — CI on GitHub, issues in Jira:
platform: ci: github tracker: jiraSee Switch Platform and Connect PACE to Jira for credential setup per platform.
advisory
advisory: push_to_issues: falseControls how non-blocking advisory findings from SENTINEL and CONDUIT are surfaced.
| Field | Type | Required | Description |
|---|---|---|---|
push_to_issues | boolean | No | Open an issue per backlisted advisory batch. Default: false. |
Advisory findings always accumulate in .pace/advisory_backlog.yaml regardless of this setting. The push_to_issues flag controls whether they are also mirrored to an external issue tracker.
See Push Advisory Findings to Issue Trackers for details.
llm
llm: provider: anthropic model: claude-sonnet-4-6 analysis_model: claude-haiku-4-5-20251001 base_url: null| Field | Type | Required | Description |
|---|---|---|---|
provider | string | Yes | LLM adapter to use. One of: anthropic, litellm. Default: anthropic. |
model | string | Yes | Model identifier. For litellm, include the provider prefix (e.g. openai/gpt-4o). Used by FORGE and SCRIBE. |
analysis_model | string | null | No | Model for PRIME, GATE, SENTINEL, CONDUIT. Defaults to model if not set. Use a cheaper model (e.g. claude-haiku-4-5-20251001) to reduce cost without sacrificing quality on analytical tasks. |
base_url | string | null | No | Optional API endpoint override. Required for self-hosted Ollama. Default: null. |
Model examples
| Provider | Model string | Notes |
|---|---|---|
anthropic | claude-sonnet-4-6 | Recommended default |
anthropic | claude-opus-4-6 | Best capability |
anthropic | claude-haiku-4-5-20251001 | Fastest / cheapest |
litellm | openai/gpt-4o | OpenAI |
litellm | gemini/gemini-2.0-flash | |
litellm | bedrock/anthropic.claude-sonnet-4-6 | AWS Bedrock |
litellm | azure/gpt-4o | Azure OpenAI |
litellm | groq/llama-3.1-70b-versatile | Groq |
litellm | mistral/mistral-large-latest | Mistral |
litellm | ollama/llama3.1 | Local Ollama |
See Switch LLM Provider for provider credential setup.
reporter
reporter: timezone: "UTC"Controls output formatting for PROGRESS.md and GitHub Actions job summaries.
| Field | Type | Required | Description |
|---|---|---|---|
timezone | string | No | IANA timezone for timestamps. Default: UTC. |
cost_control
cost_control: max_story_ac: 5 max_story_cost_usd: 1.50
forge: tdd_enforcement: true coverage_rule: true max_iterations: 35Controls proactive story scoping. When a story exceeds either threshold, PRIME is automatically re-invoked to split it: today’s story carries the highest-value criteria (up to max_story_ac), and the remainder is written to .pace/day-N/deferred_scope.yaml for the next day’s PRIME to pick up automatically.
| Field | Type | Required | Description |
|---|---|---|---|
max_story_ac | integer | No | Trigger PRIME refinement if AC count exceeds this. 0 to disable. Default: 5. |
max_story_cost_usd | float | No | Trigger PRIME refinement if SCOPE predicts FORGE cost exceeds this (USD). 0 to disable. Default: 0 (disabled). |
Up to 2 refinement rounds are attempted. If refinement fails, FORGE runs on the original story as a fallback.
See Proactive Story Scoping for details and threshold tuning guidance.
forge
forge: tdd_enforcement: true coverage_rule: true max_iterations: 35Controls how the FORGE agent runs each story. All fields are optional — defaults match the previous hardcoded behaviour.
tdd_enforcement boolean · default true
Mandatory 4-phase TDD (RED → GREEN → REFACTOR → COMMIT). The confirm_red_phase tool is a hard gate — FORGE cannot call complete_handoff without first running the suite and proving at least one new test fails. Set false for stories with nothing to test (docs, infra, migrations).
coverage_rule boolean · default true
Inject the COVERAGE RULE into FORGE’s system prompt. Every production file FORGE creates or modifies must have corresponding tests; existing test counts must not decrease. Only effective when tdd_enforcement is true.
max_iterations integer · default 35
Safety limit on the agentic tool-use loop. If FORGE does not call complete_handoff within this many LLM calls the run raises an error and the pipeline fails. See Tuning max_iterations.
compression_model string | null · default null
Model used for Haiku context compression (Stage 2). After the first confirmed RED-phase test failure, FORGE compresses its message history into a structured YAML summary using this model. Defaults to llm.analysis_model when not set; compression is skipped if neither is configured. Recommended: claude-haiku-4-5-20251001. Cost: ~$0.005 per compression call.
file_hints_enabled boolean · default true
When true, a lightweight pre-pass over engineering.md identifies likely-relevant files and injects them as a ## File Hints section in FORGE’s initial message (Stage 3). Skipped automatically when engineering.md is absent or not tracked in context.manifest.yaml. Set false to disable globally.
file_hints_confidence_threshold float · default 0.7
Minimum confidence score (0.0–1.0) for a file hint to be included. Hints below this threshold are excluded from the ## File Hints section. Lower the value to surface more candidates; raise it to show only high-confidence hints. Only effective when file_hints_enabled: true.
fork_enabled boolean · default false
Opt-in forked subcontext (Stage 4, Phase A). When true, the commit_plan tool is added to FORGE’s tool list. Calling commit_plan triggers _fork_context(), which constructs a compact implementation-phase context from the compressed exploration summary and committed plan. Enable after validating on several stories with Stages 1–3. See FORGE Context Efficiency for Phase B/C roadmap.
releases
releases: - name: "v1.0" label: "GA" - name: "v2.0" label: "Next" default: trueOptional list of named releases. When defined, the release field in plan.yaml must match one of these names. Useful for multi-release or branching workflows.
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Release identifier. Must match release in plan.yaml. |
label | string | No | Human-readable label shown in PROGRESS.md. |
default | boolean | No | If true, used when release is omitted from plan.yaml. |
cron
cron: pace_pipeline: "0 6 * * 1-5" planner_pipeline: "0 5 * * 1" update_check: "0 4 * * *" timezone: "UTC"Configures scheduled execution. All fields are optional.
| Field | Type | Required | Description |
|---|---|---|---|
pace_pipeline | string | No | Cron expression for the daily pipeline run. Default: not scheduled (manual trigger). |
planner_pipeline | string | No | Cron expression for the PLANNER (Day 0) run. Typically weekly on sprint start. |
update_check | string | No | Cron expression for the auto-update check. Default: "0 4 * * *" (daily at 04:00). |
timezone | string | No | IANA timezone for cron expressions. Default: "UTC". |
See Schedule PACE with Cron for examples.
updates
updates: channel: stable auto_apply: false notify_only: trueControls PACE’s auto-update behaviour. PACE checks GitHub Releases for newer versions.
| Field | Type | Required | Description |
|---|---|---|---|
channel | string | No | Release channel: stable or beta. Default: stable. |
auto_apply | boolean | No | If true, apply updates automatically when no local customisations are detected. Default: false. |
notify_only | boolean | No | If true, log available updates but take no action. Overrides auto_apply. Default: true. |
See Auto-Update for details on the update check and customisation detection.
notifications
notifications: slack: webhook_url: "${SLACK_WEBHOOK_URL}" channel: "#pace-alerts" teams: webhook_url: "${TEAMS_WEBHOOK_URL}" email: smtp_host: "smtp.example.com" smtp_port: 587 username: "${SMTP_USER}" password: "${SMTP_PASS}" from: "pace@example.com" to: - "team@example.com"Configures notification channels for PACE events. All fields are optional.
notifications.slack
| Field | Type | Required | Description |
|---|---|---|---|
webhook_url | string | Yes | Slack incoming webhook URL (supports env var interpolation). |
channel | string | No | Override the channel set in the webhook. Default: webhook default. |
notifications.teams
| Field | Type | Required | Description |
|---|---|---|---|
webhook_url | string | Yes | Microsoft Teams incoming webhook URL. |
notifications.email
| Field | Type | Required | Description |
|---|---|---|---|
smtp_host | string | Yes | SMTP server hostname. |
smtp_port | integer | No | SMTP port. Default: 587. |
username | string | No | SMTP auth username. Supports env var interpolation. |
password | string | No | SMTP auth password. Supports env var interpolation. |
from | string | Yes | Sender address. |
to | list[string] | Yes | List of recipient addresses. |
See Notifications and Alerts for setup instructions.
alerts
alerts: - event: hold_opened channels: [slack, email] - event: story_shipped channels: [slack] - event: cost_exceeded threshold_usd: 2.00 channels: [slack] - event: pipeline_lock_timeout channels: [slack] - event: update_available channels: [slack]Maps pipeline events to notification channels. Each entry is an alert rule.
| Field | Type | Required | Description |
|---|---|---|---|
event | string | Yes | Event name. See table below. |
channels | list[string] | Yes | List of channel names: slack, teams, email. Must be configured in notifications. |
threshold_usd | float | No | For cost_exceeded only: notify when story cost exceeds this amount (USD). |
threshold_sec | integer | No | For pipeline_lock_timeout only: notify when lock wait exceeds this many seconds. |
Event types
| Event | Fires when |
|---|---|
hold_opened | GATE, SENTINEL, or CONDUIT issues a HOLD |
story_shipped | All agents issue SHIP and the day advances |
cost_exceeded | FORGE story cost exceeds threshold_usd |
pipeline_lock_timeout | A concurrent pipeline run cannot acquire the lock within threshold_sec |
update_available | A newer PACE version is found on the configured release channel |
See Notifications and Alerts for alert configuration examples.
plugins
plugins: dirs: - "plugins/" webhook_port: 9876Configures the PACE plugin system for extending pipeline behaviour.
| Field | Type | Required | Description |
|---|---|---|---|
dirs | list[string] | No | Additional directories to scan for plugin entry points. Default: ["plugins/"]. |
webhook_port | integer | No | Port for the inbound webhook server. Plugins implementing WebhookInBase listen here. Default: 9876. |
Plugins are Python packages discovered via pace.hooks, pace.webhook_in, pace.webhook_out, pace.llm_providers, pace.platforms, or pace.reporters entry points.
See Plugins for the plugin development guide.
training
training: enabled: false export_dir: ".pace/training" format: sft min_reward: 0.6Controls training data collection and export for fine-tuning LLMs on your PACE runs.
| Field | Type | Required | Description |
|---|---|---|---|
enabled | boolean | No | Enable training data collection. Default: false. |
export_dir | string | No | Directory where exported JSONL files are written. Default: ".pace/training". |
format | string | No | Export format: sft (supervised fine-tuning messages) or reward (prompt + completion + score). Default: sft. |
min_reward | float | No | Minimum reward score (0.0–1.0) to include a story trace in the export. Default: 0.6. |
See Training Data Export for the reward scoring formula and export workflow.
Full annotated example
framework_version: "1.0"
product: name: "Acme API" description: > Acme API is a REST backend for the Acme e-commerce platform. It serves mobile and web clients and handles orders, inventory, and payments for small business owners. github_org: "acme-corp"
sprint: duration_days: 30
source: dirs: - name: "api" path: "src/" language: "Python" description: "FastAPI application, domain models, and business logic" - name: "cli" path: "cli/" language: "Go" description: "Operator CLI for database migrations and admin tasks" docs_dir: "../acme-docs/api"
tech: primary_language: "Python 3.12" secondary_language: "Go 1.22" ci_system: "GitHub Actions" test_command: "pytest -v --tb=short" build_command: "go build ./cli/..."
platform: ci: github tracker: github
llm: provider: anthropic model: claude-sonnet-4-6 analysis_model: claude-haiku-4-5-20251001 base_url: null
cost_control: max_story_ac: 5 max_story_cost_usd: 1.50
notifications: slack: webhook_url: "${SLACK_WEBHOOK_URL}" channel: "#pace-alerts"
alerts: - event: hold_opened channels: [slack] - event: story_shipped channels: [slack]