Référence de Configuration (.github/agents.yml)
EPURE centralise l'ensemble des paramètres d'orchestration, du routage LLM, de la vérification polyglotte, de l'exploration Web et des invariants de sécurité non abaissables dans un unique fichier déclaratif versionné à la racine du dépôt : .github/agents.yml.
Schéma Canonique Plat Complet (serializeAgentsConfigYaml / parseAgentsYaml)
Voici le fichier .github/agents.yml canonique plat généré par setup-repo (src/bootstrap/setup-repo.ts) avec toutes les clés prises en charge et leurs valeurs par défaut (Q78, Q91–Q96, ADR-0028–ADR-0033) :
# 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: falseEnvironnement GitHub d'Agent Configurable et Agnostique du LLM (<llm-env>)
Dans .github/workflows/epure-issue-command.yml, le job orchestrate-command s'exécute au sein d'un environnement GitHub dédié (environment: <llm-env>) uniquement après que le job sans secret authorize-command a validé la permission effective write ou admin :
- Nommage libre et agnostique du fournisseur : le nom de l'environnement
<llm-env>vautepure-agentpar défaut (llm_environmentdans.github/agents.yml) et est entièrement configurable viasetup-repo --llm-env <nom-env>etsetup-github-apps-wizard.sh --llm-env <nom-env>(utilisez la même valeur pour les deux). Il est agnostique du fournisseur LLM utilisé (autres exemples :llm,openai,anthropicougemini) et ne doit contenir que des caractères[A-Za-z0-9._-]. - Cloisonnement des secrets conforme Zizmor :
EPURE_AGENT_APP_ID,EPURE_AGENT_APP_PRIVATE_KEYetLLM_API_KEY(ou la variable fournisseur référencée paros.environ/VAR_NAME) sont attachés exclusivement à--env <llm-env>, tandis queEPURE_RELEASE_APP_IDetEPURE_RELEASE_APP_PRIVATE_KEYsont attachés à l'environnement--env releaseavec approbation humaine obligatoire. Les workflows publics de Pull Request etauthorize-commandn'ont accès à aucun secret.
Détail des Sections
Clés Racines d'Exécution, de Reprise & de Gouvernance
| Clé | Type | Défaut | Description |
|---|---|---|---|
harness | "pi" | "codex" | "pi" | Adaptateur de moteur d'agent utilisé pour les exécutions en sandbox. |
merge_policy | "strict" | "relaxed" | "strict" | Politique de base obsolète pour l'intégration task/* -> feature/* (strict exige une base à jour ; relaxed tolère une fusion 3-way propre si le diff approuvé est inchangé). |
task_auto_merge_enabled | boolean | false (true si CI & protections actives) | Active le squash-merge autonome des PRs task/* -> feature/* validées ; forcé à false (AUTO_MERGE_DISABLED_MISSING_PROTECTIONS) si la CI requise ou les protections de branches sont absentes. |
max_code_fix_attempts | integer | 3 | Nombre maximal de tours de correction automatique (Sandbox Stage 1, CI externe ou revue multi-agents) par ticket avant escalade needs-human (Q78). |
max_epic_phases | integer (1..3) | 2 | Nombre maximal de phases d'exécution de la fonctionnalité lorsque runEpicConvergenceAudit détecte des points d'entrée non câblés ([Phase 2 - Ticket N], ADR-0032). |
max_transient_api_retries | integer | 4 | Plafond de reprises par requête HTTP unitaire en cas d'erreur transitoire (5xx, 408, timeout réseau). Les limitations de débit HTTP 429 attendent Retry-After (jusqu'à 10 attentes) sans consommer ce quota. |
transient_retry_backoff_seconds | [int, int, int, int] | [5, 15, 45, 120] | Paliers de backoff exponentiel en secondes entre deux reprises HTTP transitoires. |
llm_request_timeout_seconds | integer | 900 | Délai d'expiration HTTP unitaire en secondes (15 minutes) pour chaque appel au fournisseur LLM. |
job_timeout_minutes | integer | 60 | Délai d'expiration global en minutes du job orchestrate-command dans .github/workflows/epure-issue-command.yml (Q78). |
review_timeout_minutes | integer | 30 | Délai d'expiration en minutes des jobs de revue multi-agents (avec un plafond max_parallel_reviewers = 4 reviewers spécialisés/transverses sélectionnés par diff en plus de spec-parity-reviewer). |
max_concurrent_tasks_per_feature | integer | 3 | Nombre maximal de tickets task/* débloqués exécutables en parallèle pour une même branche feature/*. |
trace_retention_days | integer | 30 | Durée de conservation en jours des trajectoires d'audit minimisées (iFixAi). |
preview_retention_days | integer | 14 | Durée de conservation en jours avant purge automatique des previews /prototype hébergées (Q71). |
github_pages_previews | boolean | false | Option sur consentement (alias historique enable_pages_preview: false) pour publier des previews statiques /prototype sur une origine GitHub Pages isolée ; exige github_pages_human_consent: true et preview_separate_origin: true (Q70, Q73). |
reviewers_dir | string (chemin relatif) | ".agents/reviewers" | Répertoire du roster de reviewers dans lequel setup-repo écrit et l'orchestrateur lit les prompts <nom>.md (toujours depuis la branche de confiance dev, avec repli sur les templates embarqués d'EPURE). Configurable via setup-repo --reviewers-dir <chemin> (par exemple .cursor/agents pour une équipe souhaitant que Cursor charge les reviewers comme sous-agents). Les chemins absolus, les chemins comportant un segment . ou .. et les chemins sous src/ sont rejetés en mode fail-closed avec SECURITY_INVARIANT_VIOLATION. |
llm_environment | string ([A-Za-z0-9._-]) | "epure-agent" | Nom de l'environnement GitHub utilisé par le job orchestrate-command du workflow généré .github/workflows/epure-issue-command.yml (environment: <llm-env>). Configurable via setup-repo --llm-env <nom> ; doit correspondre à l'environnement créé par setup-github-apps-wizard.sh --llm-env <nom>. |
models & providers (Routage Multi-Fournisseurs — ADR-0029)
EPURE intègre un client LLMClient multi-fournisseurs sans dépendance externe compatible avec Google Gemini (google/ ou gemini/), OpenAI (openai/), Azure OpenAI (azure/), Azure AI Foundry (azure_ai/) et Anthropic (anthropic/).
models.planning, models.implementation et models.review sont obligatoires : EPURE n'a aucun modèle de repli, conformément au principe d'absence de bascule automatique de l'ADR-0012. Une entrée model non vide de l'action orchestrate-issue surcharge les trois phases ; sinon chaque phase utilise telle quelle sa valeur models.<phase>. Lorsqu'une commande appelant un LLM constate une clé manquante, elle est suspendue avec une escalade needs-human (model_config_missing) nommant la clé à renseigner, avant tout appel LLM ; les commandes sans appel LLM (status, cancel, réponses hors grilling/spec, continue sans attente en cours) ne sont pas affectées. EPURE lit .github/agents.yml sur dev (sur main uniquement si dev ne contient pas ce fichier) ; un fichier impossible à analyser n'est jamais ignoré ni remplacé par la copie de main : les commandes appelant un LLM sont escaladées en needs-human avec le message de l'analyseur (Invalid .github/agents.yml on 'dev': ...).
| Clé | Type | Défaut | Description |
|---|---|---|---|
models.planning | string | (Obligatoire ; setup-repo écrit "anthropic/claude-sonnet-4-20250514") | Modèle utilisé pour l'entretien /epure plan, /epure to-spec / /epure to-tickets et la réconciliation des ADRs lors de l'intégration plan -> feature (<fournisseur>/<modèle> ou nom court). Surchargeable via setup-repo --planning-model (ou --model pour toutes les phases). |
models.implementation | string | (Obligatoire ; setup-repo écrit "anthropic/claude-sonnet-4-20250514") | Modèle utilisé pour la boucle d'outils incrémentaux (write_repo_file, patch_repo_file), la résolution de conflits 3-way, la réconciliation des ADRs lors de /epure sync et les boucles d'auto-remédiation Stage 1/2/3. Surchargeable via setup-repo --implementation-model (ou --model). |
models.review | string | (Obligatoire ; setup-repo écrit "openai/gpt-4.1") | Modèle utilisé pour le roster de revue multi-agents, runGoldfishSpecAudit, runEpicConvergenceAudit, user-advocate et la synthèse du message de squash (demandée à température 0.0 ; aucune température n'est transmise à Claude Opus 4.7+ / Claude 5.x+). Surchargeable via setup-repo --review-model (ou --model). |
providers.<alias>.provider | "google" | "openai" | "azure" | "azure_ai" | "anthropic" | (Optionnel) | Famille de protocole associée à un alias personnalisé référencé dans models.* (<alias>/<modèle>). |
providers.<alias>.api_key | string | os.environ/<VAR> | Référence de variable d'environnement (os.environ/VAR_NAME) résolue à l'exécution depuis process.env. Ne commitez jamais de clé API en clair dans .github/agents.yml. |
providers.<alias>.base_url | string | Défaut du fournisseur | URL de base personnalisée ou os.environ/VAR_NAME. |
providers.<alias>.api_version | string | "2024-10-21" | Version d'API du déploiement Azure OpenAI (?api-version=...). |
providers.<alias>.default_headers | Record<string, string> | {} | En-têtes HTTP additionnels transmis à chaque requête vers cet alias. |
providers.<alias>.effort | "low" | "medium" | "high" | "xhigh" | "max" | (Optionnel, défaut du modèle) | Anthropic uniquement : transmis comme output_config.effort à chaque requête de tout modèle routé via cet alias (ex. effort: high pour anthropic/claude-haiku-5-5). Omis si non défini. Toute autre valeur rend .github/agents.yml invalide : les commandes appelant un LLM sont escaladées en needs-human avec l'erreur d'analyse. temperature est automatiquement omis pour les modèles Claude Opus 4.7+ et Claude 5.x+, qui rejettent les paramètres d'échantillonnage. |
Une réponse Anthropic avec stop_reason: refusal lève une LLMError de reasonCode: "REFUSAL". Elle n'est pas relancée : l'orchestrateur est suspendu avec une escalade needs-human (llm_refusal) sans consommer le quota max_code_fix_attempts du ticket.
verification & verification.targets (Vérification Polyglotte Stage 1 & CI Stage 2 — ADR-0028, ADR-0030)
Toujours chargé à l'exécution depuis la branche de confiance dev afin qu'une branche task/* ne puisse jamais affaiblir ses propres commandes de test :
| Clé | Type | Défaut | Description |
|---|---|---|---|
verification.wait_for_external_ci | boolean | true | Active l'attente événementielle de la CI externe Stage 2 (waiting_ticket_ci / waiting_feature_ci) sur les PRs task/* et feature/*. |
verification.external_ci_timeout_minutes | integer | 15 | Délai maximal d'attente de la CI externe en minutes. |
verification.grace_window_seconds | integer | 45 | Fenêtre d'amorçage en secondes après un push PR permettant aux workflows GitHub Actions de s'enregistrer avant d'évaluer leur complétude. |
verification.deferred_external_workflows | string[] | [] | Workflows externes lourds optionnels différés des sous-tickets task/* et requis uniquement sur la PR finale feature/* -> dev. |
verification.targets | VerificationTargetSpec[] | Découvert automatiquement par setup-repo | Cibles de vérification Stage 1 par sous-projet (name, working_directory, kind: node | python | rust | go | make | custom, path_patterns, install_command, codegen_command, typecheck_command, lint_command, test_command, build_command) exécutées dans la sandbox noyau Ubuntu 26.04 en 2 phases (landrun + bubblewrap). |
web_tools (Exploration Web Publique Confinée — ADR-0031)
| Clé | Type | Défaut | Description |
|---|---|---|---|
web_tools.enabled | boolean | true | Active les outils d'exploration Web publics sans clé API (web_search, web_fetch) restreints à https:// sur le port 443 avec filtrage anti-SSRF strict et balisage <untrusted_web_content>. |
web_tools.phases | string[] | ["plan", "spec", "implementation"] | Phases autorisées à invoquer web_search et web_fetch (exclu de review par défaut). |
web_tools.max_requests_per_turn | integer | 4 | Nombre maximal d'appels Web autorisés au cours d'un même tour LLM. |
web_tools.max_requests_per_run | integer | 12 | Nombre maximal d'appels Web autorisés sur l'ensemble d'un run d'orchestration. |
web_tools.max_bytes_per_response | integer | 16384 | Volume maximal en octets UTF-8 retourné par réponse d'outil. |
web_tools.max_fetch_bytes | integer | 16384 | Volume maximal en octets UTF-8 retourné par appel web_fetch après nettoyage HTML. |
web_tools.timeout_ms | integer | 10000 | Délai d'expiration HTTP en millisecondes par requête d'exploration Web. |
security_invariants & Chemins Sensibles
Toute tentative dans .github/agents.yml d'abaisser security_invariants (require_write_permission: false, sandbox_isolation: false, allow_agent_release: true, auto_merge_dev: true, auto_merge_main: true) est rejetée en mode fail-closed avec l'erreur SECURITY_INVARIANT_VIOLATION. De plus, toute modification de .github/workflows/**, .github/agents.yml, du répertoire du roster de reviewers (le reviewers_dir/** configuré ainsi que .agents/reviewers/** par défaut) ou CODEOWNERS sur une branche task/* déclenche une Escalade sur Chemin Sensible (needs-human) tant qu'un mainteneur n'a pas explicitement accordé le label approved-sensitive-change (Q81, Q93).
Politique Supply-Chain & Sécurité Renovate (renovate.json & .github/zizmor.yml)
Chaque dépôt EPURE embarque un fichier renovate.json et .github/zizmor.yml durcis générés par /setup-repo (Q46–Q48) :
- Quarantaine Anti-Jour-1 (
minimumReleaseAge) : Applique un délai minimal de3 dayspar défaut (7 dayspour les mises à jour mineures et les GitHub Actions / images Docker,14 dayspour les mises à jour majeures npm) associé àinternalChecksFilter: "strict"etprCreation: "not-pending". Aucune version fraîchement publiée ou compromise le jour 1 ne déclenche de PR avant la fin de la quarantaine. - Automatisation Maximale maîtrisée : Regroupe les mises à jour
minor,patch,pinetdigestdans des PRs hebdomadaires consolidées (npm-minor-and-patch,github-actions,docker), épingle toutes les versions (rangeStrategy: "pin",helpers:pinGitHubActionDigests,docker:pinDigests), assure la maintenance mensuelle du lockfile (lockFileMaintenance) et rebase automatiquement surdev(rebaseWhen: "behind-base-branch"). - Isolation des Scripts Post-Install : Force
npmrc: "ignore-scripts=true"lors de la résolution Renovate afin d'empêcher l'exécution de scripts post-install arbitraires. - Aucun Auto-Merge Aveugle vers
dev:automerge: falseetplatformAutomerge: falsesont verrouillés ; toutes les PRs Renovate ciblentdev, passent par la CI et le panel de review multi-agents, et peuvent déclencher l'agent de migration assistée (auto_migrate) uniquement si la provenance cryptographique de la GitHub App Renovate est vérifiée.

