---
name: forge-execute
description: "Exécution par waves parallèles : dispatch tâches aux teammates frais, commits atomiques"
allowed-tools:
  - Read
  - Write
  - Edit
  - Glob
  - Grep
  - Bash
---

## Contexte dynamique (injecté automatiquement)

**Config projet :**
!`cat .planning/config.json 2>/dev/null || echo "config.json non trouvé"`

**Waves :**
!`node .claude/bin/dagsmith-tools.js wave-group --plan .planning/PLAN.md 2>/dev/null || echo "wave-group non disponible"`

**Critical flows :**
!`node -e "const p='.forge/project-profile.json';const fs=require('fs');if(fs.existsSync(p)){const d=JSON.parse(fs.readFileSync(p,'utf-8'));console.log(JSON.stringify(d.critical_flows||[],null,2))}else{console.log('project-profile.json non trouvé')}" 2>/dev/null || echo "extraction impossible"`

**Error patterns :**
!`cat .planning/error-patterns.md 2>/dev/null || echo "Aucun error-pattern"`

**Allowed files :**
!`cat .planning/allowed-files.json 2>/dev/null || echo "allowed-files.json non trouvé"`

---

# forge-execute — Moteur d'exécution par waves

Tu es le moteur d'exécution. Tu prends le plan d'une phase et tu le déroules
wave par wave, en déléguant chaque tâche à un teammate frais.
Tu ne codes JAMAIS toi-même — tu orchestres les teammates.

---

## Entrée

`$ARGUMENTS` = N° de phase (obligatoire).

Si `$ARGUMENTS` est vide ou absent :
> "Usage : `/forge-execute N` où N est le numéro de phase à exécuter.
> Consulte `.planning/ROADMAP.md` pour voir les phases disponibles."

---

## Étape 1 — Lecture du contexte

Lire ces fichiers pour préparer l'exécution :

1. `.planning/PLAN.md` — tâches de la phase N avec waves et dépendances
2. `.planning/phases/{N}-CONTEXT.md` — décisions prises lors du discuss
3. `.planning/config.json` — configuration (model_profile, branching, post_task_verify)
4. `.planning/allowed-files.json` — scope de fichiers autorisés par tâche

Vérifier `post_task_verify` dans config.json (défaut: `true`) :
- Si `true` : chaque tâche sera vérifiée par un agent `verifier` après le teammate
- Si `false` : pas de vérification automatique (comportement pré-D62)

Si le CONTEXT.md ou le PLAN.md n'existent pas, signaler :
> "Impossible d'exécuter la phase {N} : le contexte ou le plan n'existent pas.
> Lance `/forge-discuss {N}` puis `/forge-planner {N}` d'abord."

Vérifier que les tâches de la phase N ont le statut `[ ]` (non exécutées).
Si toutes les tâches sont déjà `[x]` :
> "Phase {N} déjà exécutée. Lance `/forge-verify {N}` pour la vérifier."

---

## Étape 2 — Calcul des waves

Lancer la commande :

```bash
node .claude/bin/dagsmith-tools.js wave-group --plan .planning/PLAN.md
```

Filtrer la sortie pour ne garder que les waves de la phase N.
Chaque wave contient une liste de tâches indépendantes entre elles.

---

## Étape 3 — Exécution wave par wave (mode séquentiel)

> **Condition** : cette étape s'applique SI `agent_teams: false` dans
> `.planning/config.json` (défaut). Sinon, voir étape 3-AT ci-dessous.

Pour chaque wave (W1, W2, ..., Wn) **séquentiellement** :

### 3.1 — Dispatch des tâches

Pour chaque tâche de la wave, lire le fichier `.planning/tasks/task-{id}.xml`
et préparer le **brief teammate**.

#### Brief teammate — Contrainte de taille (~2K tokens max)

Le teammate est un subagent frais (`context: fork` — D03). Son contexte
de départ = zéro. Le brief est sa **seule** source d'information.

**Budget** : viser ~2 000 tokens maximum par brief. Au-delà, le teammate
perd en focus et le ratio signal/bruit se dégrade (benchmark Superpowers).

**Ce que le brief CONTIENT** (et rien d'autre) :

```
## Tâche {id} — {nom}

### Feature
{feature-ref}

### Fichiers autorisés
{liste des fichiers depuis <files>}

### Instructions
{contenu de <action>}

### Critères d'acceptation
{contenu de <acceptance>}

### Vérification
{contenu de <verify>}

### Conventions
Charger le skill `project-conventions` pour les conventions du projet.

### Contexte critique (si pertinent)
{section ajoutée uniquement si au moins un élément est pertinent — voir ci-dessous}
```

#### Construction du contexte critique

Cette section est ajoutée au brief UNIQUEMENT si au moins un élément est pertinent
pour la tâche. Ne pas l'ajouter si aucun élément ne s'applique.

**Quand l'ajouter** : si la tâche implique des webhooks, des API externes,
des opérations financières, de la concurrence, des données personnelles,
ou si un pattern d'erreur connu match la stack de la tâche.

**Comment la construire** (l'orchestrateur lit ces sources) :
1. Lire `.forge/project-profile.json` → `critical_flows`
   - Si un critical_flow implique la même feature que la tâche, inclure
     ses invariants dans le brief
2. Lire `.planning/error-patterns.md` (si existant)
   - Si un pattern concerne la même stack ou le même type d'opération
     que la tâche, inclure le titre + la solution
3. Déduire la concurrence :
   - Si la feature implique webhook/API/async → ajouter :
     "⚠ Cette feature est appelée de manière concurrente (webhook/API).
      Les opérations de write doivent être atomiques (transaction)."

**Format** (max ~200 tokens — le brief total doit rester sous ~2.2K) :

```text
### Contexte critique
- **Invariants** : {1-2 invariants du critical_flow pertinent}
- **Concurrence** : {oui/non + source}
- **Erreurs connues** : {titre du pattern + solution courte, ou "aucune"}
```

Si aucun élément n'est pertinent, **ne pas inclure cette section** dans le brief.

La suite du brief après le contexte critique (si présent) :

```
### Commit
À la fin, commiter avec le message :
feat(T-{id}): {nom de la tâche}
```

**Ce que le brief NE CONTIENT PAS** :

- Le plan complet (PLAN.md) — le teammate n'a pas besoin de connaître les
  autres tâches ni les waves
- L'historique du projet ou des sessions précédentes
- Le contenu de STATE.md ou config.json
- Le Blueprint entier — seule la feature-ref suffit, sauf pour le contexte
  critique (invariants extraits du profil, pas du BLUEPRINT directement)
- Les décisions architecturales (DECISIONS.md) — les conventions du skill
  `project-conventions` couvrent ce dont le teammate a besoin

**Si le brief dépasse ~2K tokens**, c'est un signal que la tâche est trop
grosse. Envisager de la découper dans le plan plutôt que de gonfler le brief.

### 3.2 — Lancement et vérification

Les tâches d'une même wave sont théoriquement parallèles (indépendantes).
En mode séquentiel, les lancer une par une via subagents.

Pour chaque tâche de la wave :

1. Lancer le teammate avec le brief préparé
2. Attendre la fin de l'exécution
3. **Vérification post-task (D62)** — si `post_task_verify: true` dans config.json :

   Spawner un agent `verifier` avec ce brief (~500 tokens) :

   ```
   ## Vérification T-{id} — {nom}

   ### Critères d'acceptation
   {contenu de <acceptance> depuis la tâche}

   ### Commande de vérification
   {contenu de <verify>}

   ### Fichiers autorisés
   {liste des fichiers depuis <files>}

   ### Dernier commit attendu
   feat(T-{id}): {nom de la tâche}
   ```

   Traiter le verdict du verifier :

   - **PASS** → marquer la tâche `[x]` (succès)
   - **WARN** → marquer `[x]` mais logger l'avertissement dans le résumé d'exécution
   - **FAIL** → marquer `[!]` (échec) avec la raison du verifier

4. Si le verifier timeout (>2 min) ou crashe :
   - Logger un warning "Verifier timeout/crash for T-{id}"
   - **Fallback** : vérifier uniquement que le commit existe et que `<verify>` passe
   - Si le fallback passe → marquer `[x]`
   - Si le fallback échoue → marquer `[!]`

5. Si `post_task_verify: false` : comportement pré-D62 (vérifier commit + `<verify>` uniquement)

### 3.3 — Gestion des erreurs

Si un teammate échoue sur une tâche :
- **Ne PAS arrêter** l'exécution des autres tâches de la wave
- Logger l'erreur dans le résumé d'exécution
- Marquer la tâche comme `[!]` (échec) dans PLAN.md
- Continuer avec les tâches restantes de la wave

Si une tâche échoue et que des tâches des waves suivantes en dépendent :
- Marquer les tâches dépendantes comme `[-]` (skipped)
- Logger la raison du skip

### 3.4 — Mise à jour STATE.md (après chaque wave)

Après que toutes les tâches d'une wave sont terminées (succès ou échec) :

```bash
node .claude/bin/dagsmith-tools.js state-update --key "Progression" --value "Phase {N}, Wave {W} terminée — {X}/{Y} tâches réussies"
```

Mettre aussi à jour le statut des tâches dans PLAN.md :
- `[x]` pour les tâches réussies
- `[!]` pour les tâches en échec
- `[-]` pour les tâches skippées

### 3.5 — Log pipeline

Logger chaque événement significatif pour la traçabilité :
- Début/fin de wave
- Début/fin de chaque tâche (avec durée si disponible)
- Erreurs rencontrées

---

## Étape 3-AT — Exécution avec Agent Teams (mode parallèle)

> **Condition** : cette étape remplace l'étape 3 standard SI ET SEULEMENT SI
> `agent_teams: true` dans `.planning/config.json`.
> Si `agent_teams: false` ou absent, utiliser l'étape 3 standard ci-dessus.

Le mode Agent Teams utilise le vrai parallélisme de Claude Code : chaque
tâche d'un batch s'exécute dans sa propre session, en même temps.

### 3-AT.1 — Batching des waves

Lire `max_teammates` depuis config.json (défaut: 4).

Si une wave contient plus de `max_teammates` tâches, la spliter en batches :

- Chaque batch contient au plus `max_teammates` tâches
- L'ordre au sein d'une wave n'a pas d'importance (tâches indépendantes)
- Les batches d'une même wave s'exécutent séquentiellement entre eux

Exemple : Wave 1 avec 6 tâches, max_teammates=4 :
- Batch 1 : tâches A, B, C, D (parallèles)
- Batch 2 : tâches E, F (parallèles)

### 3-AT.2 — Exécution d'un batch

Pour chaque batch :

1. **Créer la team** :
   - Nom : `{{PROJECT_NAME}}-P{N}-W{W}-B{B}`
   - Description : "Phase {N}, Wave {W}, Batch {B} — {X} tâches"

2. **Spawner les teammates** :
   Pour chaque tâche du batch :
   - Préparer le brief identique au mode séquentiel (étape 3.1)
   - Le brief reste le même : tâche, fichiers autorisés, instructions,
     critères, vérification, conventions, commit. ~2K tokens max (R6.7).
   - Spawner le teammate avec le brief comme message initial
   - Le teammate hérite automatiquement : CLAUDE.md, hooks, MCP, skills

3. **Attendre la complétion** :
   - Surveiller les statuts des tâches dans la shared task list
   - Timeout : si aucune activité d'un teammate pendant 10 minutes, émettre
     un warning et considérer la tâche en échec
   - Un teammate qui termine → marquer `[x]` dans PLAN.md

4. **Cleanup** :
   - Quand toutes les tâches du batch sont terminées ou en échec
   - Nettoyer la team (TeamCleanup)

4bis. **Vérification post-batch (D62)** — si `post_task_verify: true` :

   Après que toutes les tâches du batch sont terminées, pour chaque tâche
   marquée comme réussie, spawner un verifier (séquentiellement, pas en parallèle,
   pour limiter la consommation de tokens).

   Si le verifier marque FAIL, changer le statut de la tâche de `[x]` à `[!]`.
   Si le verifier marque WARN, conserver `[x]` et logger l'avertissement.

5. **Évaluation** :
   - Si toutes les tâches du batch réussies → passer au batch/wave suivant
   - Si au moins une tâche en échec → **STOP** (D39)

### 3-AT.3 — Gestion d'erreur (D39) — STOP sur échec

Si un teammate échoue (tâche `[!]`) :

1. Attendre que les autres teammates du batch terminent
   (ne pas les interrompre — ils travaillent sur des fichiers différents)
2. Cleanup la team
3. Marquer les tâches dépendantes des waves suivantes comme `[-]` (skip)
4. Mettre à jour STATE.md
5. Écrire SUMMARY.md (étape 4) avec le détail de l'échec
6. Recommander :

> "Phase {N} arrêtée — T-{id} a échoué en mode Agent Teams.
> Consulte `.planning/phases/{N}-SUMMARY.md` pour les détails.
>
> Options :
> - Corriger le problème et relancer `/forge-execute {N}`
>   (les tâches `[x]` seront skippées)
> - Passer en mode séquentiel : `agent_teams: false` dans config.json
>   puis relancer `/forge-execute {N}`"

**Pas de retry automatique.** L'utilisateur décide.

### 3-AT.4 — Mise à jour STATE.md

Après chaque batch (pas après chaque tâche) :

```bash
node .claude/bin/dagsmith-tools.js state-update --key "Progression" --value "Phase {N}, Wave {W}, Batch {B} — {X}/{Y} tâches réussies (Agent Teams)"
```

### 3-AT.5 — Vérification anti-collision

Avant de spawner les teammates d'un batch, vérifier que les fichiers
autorisés (allowed-files.json) des tâches du batch sont **disjoints** :

- Extraire les fichiers de chaque tâche
- Si intersection non vide → **ne pas utiliser Agent Teams pour ce batch**,
  fallback vers exécution séquentielle pour ce batch uniquement
- Logger un warning : "Tâches T-{x} et T-{y} partagent des fichiers,
  exécution séquentielle pour ce batch"

C'est un garde-fou contre les merge conflicts. Le wave-group devrait
garantir des fichiers disjoints, mais cette vérification est le filet.

---

## Étape 4 — SUMMARY.md

À la fin de toutes les waves de la phase, écrire `.planning/phases/{N}-SUMMARY.md` :

```markdown
# Exécution Phase {N} — {Titre du milestone}

> Généré par forge-execute

## Waves exécutées

| Wave | Tâches | Statut | Résultat |
|------|--------|--------|----------|
| W1 | {id1}, {id2} | terminée | {X}/{Y} OK |
| W2 | {id3} | terminée | {X}/{Y} OK |

## Commits produits

- `{hash}` — T-{id}: {description}
- `{hash}` — T-{id}: {description}

## Tâches en échec (si applicable)

| Tâche | Erreur | Impact |
|-------|--------|--------|
| {id} | {description erreur} | {tâches skippées} |

## Statistiques

- Tâches totales : {N}
- Réussies : {N}
- Échouées : {N}
- Skippées : {N}

## Vérification post-task (D62)

| Tâche | Verdict | Détail |
|-------|---------|--------|
| T-{id} | ✅ PASS | — |
| T-{id} | ⚠️ WARN | {observation} |
| T-{id} | ❌ FAIL | {raison} |

Mode : {post_task_verify: true/false}

## Prochaine étape

Lance `/forge-verify {N}` pour valider la phase.
```

---

## Étape 5 — Recommandation

**Si toutes les tâches ont réussi :**
> "Phase {N} exécutée avec succès — {X} tâches, {Y} commits.
> Lance `/forge-verify {N}` pour valider."

**Si certaines tâches ont échoué :**
> "Phase {N} exécutée avec {M} échec(s) sur {X} tâches.
> Consulte `.planning/phases/{N}-SUMMARY.md` pour les détails.
> Corrige les problèmes puis relance `/forge-execute {N}` (les tâches réussies seront skippées)."

---

## Règles absolues

- **Ne JAMAIS coder** — toute implémentation est déléguée aux teammates
- **Ne JAMAIS modifier** les fichiers de planification sauf PLAN.md (statuts) et STATE.md
- **Teammates frais** — chaque teammate démarre sans contexte accumulé (D03)
- **Brief minimal (~2K tokens)** — ne donner au teammate que ce dont il a besoin (tâche + fichiers + conventions). Si le brief dépasse ~2K tokens, découper la tâche.
- **Scope enforcement** — chaque teammate ne touche que ses fichiers autorisés (hook enforce-files)
- **Commits atomiques** — un commit par tâche, format `feat(T-{id}): {description}`
- **Échec isolé** — un teammate qui échoue ne bloque pas les autres tâches de la wave
- **Mise à jour STATE.md** — après chaque wave, pas après chaque tâche (limiter les I/O)
- **Idempotence** — les tâches déjà `[x]` sont skippées lors d'une ré-exécution
- **Agent Teams opt-in** — ne JAMAIS utiliser Agent Teams si `agent_teams: false` dans config.json
- **Batching** — ne jamais spawner plus de `max_teammates` agents simultanément
- **Anti-collision** — vérifier les fichiers disjoints avant chaque batch Agent Teams
- **Stop on failure** — en mode Agent Teams, un échec arrête l'exécution (D39)
