Skip to content

Configuration Reference (.github/agents.yml) ​

EPURE centralizes all orchestration, LLM routing, polyglot verification, web exploration, and non-weakenable security invariants in a single versioned declarative file: .github/agents.yml.


Complete Canonical Flat Schema (serializeAgentsConfigYaml / parseAgentsYaml) ​

Below is the canonical flat .github/agents.yml file generated by setup-repo (src/bootstrap/setup-repo.ts) with all supported keys and their defaults (Q78, Q91–Q96, ADR-0028–ADR-0033):

yaml
# EPURE Consumer Repository Configuration (.github/agents.yml)
# Generated by setup-repo — security boundaries are enforced by shared workflows (ADR-0010, ADR-0023).
harness: pi
models:
  planning: anthropic/claude-sonnet-4-20250514
  implementation: anthropic/claude-sonnet-4-20250514
  review: openai/gpt-4.1
providers:
  azure-prod:
    provider: azure
    api_key: os.environ/AZURE_OPENAI_API_KEY
    base_url: os.environ/AZURE_OPENAI_ENDPOINT
    api_version: 2024-10-21
  foundry-deepseek:
    provider: azure_ai
    api_key: os.environ/AZURE_AI_API_KEY
    base_url: https://my-foundry.services.ai.azure.com
merge_policy: strict
task_auto_merge_enabled: true
max_code_fix_attempts: 3
max_epic_phases: 2
max_transient_api_retries: 4
transient_retry_backoff_seconds: [5, 15, 45, 120]
llm_request_timeout_seconds: 900
job_timeout_minutes: 60
review_timeout_minutes: 30
max_concurrent_tasks_per_feature: 3
trace_retention_days: 30
preview_retention_days: 14
github_pages_previews: false
reviewers_dir: .agents/reviewers
llm_environment: epure-agent
verification:
  wait_for_external_ci: true
  external_ci_timeout_minutes: 15
  grace_window_seconds: 45
  targets:
    - name: root
      working_directory: .
      kind: node
      path_patterns: ["**"]
      install_command: "npm ci --ignore-scripts"
      typecheck_command: "npm run typecheck"
      lint_command: "npm run lint"
      test_command: "npm test"
      build_command: "npm run build"
web_tools:
  enabled: true
  phases: ["plan", "spec", "implementation"]
  max_requests_per_turn: 4
  max_requests_per_run: 12
  max_bytes_per_response: 16384
  max_fetch_bytes: 16384
  timeout_ms: 10000
security_invariants:
  require_write_permission: true
  sandbox_isolation: true
  allow_agent_release: false
  auto_merge_dev: false
  auto_merge_main: false

Configurable & LLM-Agnostic GitHub Environment (<llm-env>) ​

In .github/workflows/epure-issue-command.yml, the orchestrate-command job runs inside a dedicated GitHub Environment (environment: <llm-env>) only after the secretless authorize-command job verifies effective write or admin permission:

  • Free & Provider-Agnostic Naming: The <llm-env> environment name defaults to epure-agent (llm_environment in .github/agents.yml) and is completely configurable via setup-repo --llm-env <env-name> and setup-github-apps-wizard.sh --llm-env <env-name> (use the same value for both). It is agnostic of the underlying LLM provider (other examples: llm, openai, anthropic, or gemini) and must only contain [A-Za-z0-9._-].
  • Zizmor-Compliant Secret Isolation: EPURE_AGENT_APP_ID, EPURE_AGENT_APP_PRIVATE_KEY, and LLM_API_KEY (or custom provider secret referenced via os.environ/VAR_NAME) are scoped strictly to --env <llm-env>, while EPURE_RELEASE_APP_ID and EPURE_RELEASE_APP_PRIVATE_KEY are scoped to the human-approved --env release environment. Public pull request workflows and authorize-command never have access to any secret.

Section-by-Section Reference ​

Root Execution, Retry & Governance Keys ​

KeyTypeDefaultDescription
harness"pi" | "codex""pi"Agent execution adapter harness used for sandboxed runs.
merge_policy"strict" | "relaxed""strict"Stale-base policy for task/* -> feature/* integration (strict requires up-to-date base; relaxed allows clean 3-way merge when approved diff is unchanged).
task_auto_merge_enabledbooleanfalse (true when CI & branch protections exist)Enables autonomous squash-merge of validated task/* -> feature/* PRs; forced to false (AUTO_MERGE_DISABLED_MISSING_PROTECTIONS) if required CI or branch protections are missing.
max_code_fix_attemptsinteger3Maximum number of automated remediation rounds (Stage 1 sandbox, external CI, or multi-agent review) per ticket before escalating to needs-human (Q78).
max_epic_phasesinteger (1..3)2Maximum number of epic execution phases when runEpicConvergenceAudit detects unwired entrypoints ([Phase 2 - Ticket N], ADR-0032).
max_transient_api_retriesinteger4Per-HTTP-request retry ceiling for transient LLM errors (5xx, 408, network timeout). HTTP 429 rate limits honor Retry-After (up to 10 waits) without consuming this quota.
transient_retry_backoff_seconds[int, int, int, int][5, 15, 45, 120]Exponential backoff schedule in seconds between transient HTTP retries.
llm_request_timeout_secondsinteger900Unitary HTTP request timeout in seconds (15 minutes) for each LLM API call.
job_timeout_minutesinteger60Wall-clock timeout in minutes for orchestrate-command in .github/workflows/epure-issue-command.yml (Q78).
review_timeout_minutesinteger30Timeout in minutes for multi-agent PR review jobs (with up to max_parallel_reviewers = 4 specialist/transverse reviewers selected per PR diff alongside spec-parity-reviewer).
max_concurrent_tasks_per_featureinteger3Maximum number of unblocked task/* tickets executed concurrently per feature/* branch.
trace_retention_daysinteger30Retention period in days for minimized audit trajectories (iFixAi).
preview_retention_daysinteger14Number of days before hosted /prototype previews are automatically purged (Q71).
github_pages_previewsbooleanfalseOpt-in flag (legacy alias enable_pages_preview: false) to publish static /prototype previews to an isolated GitHub Pages origin; requires github_pages_human_consent: true and preview_separate_origin: true (Q70, Q73).
reviewers_dirstring (relative path)".agents/reviewers"Reviewer roster directory where setup-repo writes and the orchestrator reads reviewer prompt files <name>.md (always from the trusted dev branch, falling back to EPURE's embedded templates). Configurable via setup-repo --reviewers-dir <path> (for example .cursor/agents for a team that wants Cursor to load the reviewers as subagents). Absolute paths, paths with . or .. segments, and paths under src/ are rejected fail-closed with SECURITY_INVARIANT_VIOLATION.
llm_environmentstring ([A-Za-z0-9._-])"epure-agent"GitHub Environment name used by the orchestrate-command job of the generated .github/workflows/epure-issue-command.yml (environment: <llm-env>). Configurable via setup-repo --llm-env <name>; must match the environment created by setup-github-apps-wizard.sh --llm-env <name>.

models & providers (Multi-Provider Routing — ADR-0029) ​

EPURE includes a zero-dependency multi-provider LLMClient supporting Google Gemini (google/ or gemini/), OpenAI (openai/), Azure OpenAI (azure/), Azure AI Foundry (azure_ai/), and Anthropic (anthropic/).

models.planning, models.implementation, and models.review are required: EPURE has no fallback model, consistent with ADR-0012's no-automatic-fallback principle. A non-empty model input on the orchestrate-issue action overrides all three phases; otherwise each phase uses its models.<phase> value verbatim. When a command that calls an LLM finds a key missing, it suspends with a needs-human escalation (model_config_missing) naming the key to set, before any LLM call; commands that make no LLM call (status, cancel, replies outside grilling/spec, continue with nothing waiting) are unaffected. EPURE reads .github/agents.yml from dev (from main only when dev has no such file); a file that fails to parse is never ignored or replaced by the main copy: commands that call an LLM escalate to needs-human with the parser message (Invalid .github/agents.yml on 'dev': ...).

KeyTypeDefaultDescription
models.planningstring(Required; setup-repo writes "anthropic/claude-sonnet-4-20250514")Model used for /epure plan Grill interviews, /epure to-spec / /epure to-tickets, and plan-to-feature ADR reconciliation (<provider>/<model> or bare model). Override with setup-repo --planning-model (or --model for all phases).
models.implementationstring(Required; setup-repo writes "anthropic/claude-sonnet-4-20250514")Model used for incremental workspace tool loops (write_repo_file, patch_repo_file), 3-way conflict resolution, /epure sync ADR reconciliation, and Stage 1/2/3 auto-remediation. Override with setup-repo --implementation-model (or --model).
models.reviewstring(Required; setup-repo writes "openai/gpt-4.1")Model used for the multi-agent PR review roster, runGoldfishSpecAudit, runEpicConvergenceAudit, user-advocate, and squash commit synthesis (requested at temperature 0.0; no temperature is sent to Claude Opus 4.7+ / Claude 5.x+). Override with setup-repo --review-model (or --model).
providers.<alias>.provider"google" | "openai" | "azure" | "azure_ai" | "anthropic"(Optional)Underlying protocol family for a custom provider alias referenced in models.* (<alias>/<model>).
providers.<alias>.api_keystringos.environ/<VAR>Secret-free environment variable reference (os.environ/VAR_NAME) resolved at runtime from process.env. Never commit literal API keys in .github/agents.yml.
providers.<alias>.base_urlstringProvider defaultCustom base URL or os.environ/VAR_NAME.
providers.<alias>.api_versionstring"2024-10-21"Azure OpenAI deployment API version (?api-version=...).
providers.<alias>.default_headersRecord<string, string>{}Optional custom HTTP headers attached to every request for this provider alias.
providers.<alias>.effort"low" | "medium" | "high" | "xhigh" | "max"(Optional, model default)Anthropic only: sent as output_config.effort on every request for every model routed through this alias (e.g. effort: high for anthropic/claude-haiku-5-5). Omitted when unset. Any other value makes .github/agents.yml invalid: commands that call an LLM escalate to needs-human with the parse error. temperature is automatically omitted for Claude Opus 4.7+ and Claude 5.x+ models, which reject sampling parameters.

An Anthropic response with stop_reason: refusal raises an LLMError with reasonCode: "REFUSAL". It is not retried: the orchestrator suspends with a needs-human escalation (llm_refusal) without consuming the ticket's max_code_fix_attempts budget.

verification & verification.targets (Polyglot Stage 1 & Stage 2 CI — ADR-0028, ADR-0030) ​

Always loaded at runtime from the trusted dev branch so an untrusted task/* branch can never weaken its own test commands:

KeyTypeDefaultDescription
verification.wait_for_external_cibooleantrueEnables Stage 2 external CI waiting (waiting_ticket_ci / waiting_feature_ci) on task/* and feature/* PRs.
verification.external_ci_timeout_minutesinteger15Maximum external CI wait ceiling in minutes before timeout classification.
verification.grace_window_secondsinteger45Grace window in seconds after PR push to allow GitHub Actions check runs to register before evaluating completion.
verification.deferred_external_workflowsstring[][]Optional workflow names deferred from per-ticket task/* blocking and enforced only on feature/* -> dev.
verification.targetsVerificationTargetSpec[]Auto-discovered by setup-repoPer-subproject Stage 1 verification targets (name, working_directory, kind: node | python | rust | go | make | custom, path_patterns, install_command, codegen_command, typecheck_command, lint_command, test_command, build_command) executed inside the 2-phase Ubuntu 26.04 kernel sandbox (landrun + bubblewrap).

web_tools (Confined Public Web Exploration — ADR-0031) ​

KeyTypeDefaultDescription
web_tools.enabledbooleantrueEnables zero-API-key read-only public Web exploration tools (web_search, web_fetch) constrained to https:// port 443 with strict Anti-SSRF filtering and <untrusted_web_content> wrapping.
web_tools.phasesstring[]["plan", "spec", "implementation"]Lifecycle phases allowed to invoke web_search and web_fetch (excluded from review by default).
web_tools.max_requests_per_turninteger4Maximum Web tool requests permitted within a single LLM turn.
web_tools.max_requests_per_runinteger12Maximum Web tool requests permitted across an entire orchestrator run.
web_tools.max_bytes_per_responseinteger16384Maximum UTF-8 byte budget returned per tool response.
web_tools.max_fetch_bytesinteger16384Maximum UTF-8 byte budget returned per web_fetch call after HTML stripping.
web_tools.timeout_msinteger10000Per-request HTTP timeout in milliseconds for Web exploration calls.

security_invariants & Sensitive Paths ​

Any attempt in .github/agents.yml to weaken security_invariants (require_write_permission: false, sandbox_isolation: false, allow_agent_release: true, auto_merge_dev: true, auto_merge_main: true) is rejected fail-closed with SECURITY_INVARIANT_VIOLATION. Furthermore, any modification to .github/workflows/**, .github/agents.yml, the reviewer roster directory (the configured reviewers_dir/** and the default .agents/reviewers/**), or CODEOWNERS on a task/* branch triggers a Sensitive Path Escalation (needs-human) unless a maintainer explicitly adds the approved-sensitive-change label (Q81, Q93).


Supply-Chain & Renovate Security Policy (renovate.json & .github/zizmor.yml) ​

Every EPURE repository ships a hardened renovate.json and .github/zizmor.yml generated by /setup-repo (Q46–Q48):

  • Quarantine Cooldown (No Day-1 Merges): Enforces minimumReleaseAge: "3 days" globally ("7 days" for minor updates and GitHub Actions/Docker images, "14 days" for major npm updates) coupled with internalChecksFilter: "strict" and prCreation: "not-pending" so newly published or compromised packages are quarantined before any PR is opened.
  • Maximum Safe Automation: Groups minor, patch, pin, and digest updates into single weekly PRs (npm-minor-and-patch, github-actions, docker), pins exact versions (rangeStrategy: "pin", helpers:pinGitHubActionDigests, docker:pinDigests), runs monthly lockFileMaintenance, and automatically rebases behind dev (rebaseWhen: "behind-base-branch").
  • Post-Install Script Isolation: Injects npmrc: "ignore-scripts=true" during Renovate lockfile resolution to prevent untrusted lifecycle scripts from executing.
  • No Unreviewed Auto-Merge into dev: automerge: false and platformAutomerge: false are strictly enforced; Renovate PRs target dev, run the full CI + multi-agent review pipeline, and optionally trigger the assisted auto_migrate agent if a breaking change is detected on a verified Renovate App PR.

Released under the Apache-2.0 License.