Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
214 changes: 214 additions & 0 deletions .opencode/skills/agent-team-workflow/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,214 @@
---
name: agent-team-workflow
description: >
Patterns pour orchestrer des équipes d'agents sans perdre le fil du workflow.
Couvre la persistance d'état, le handoff structuré, la configuration OpenCode et la récupération.
license: MIT
compatibility: opencode
metadata:
category: orchestration
version: "1.0"
handwritten: true
---

## Pourquoi le fil se perd

Dans un workflow multi-agents, chaque `Task` ouvre un nouveau contexte. Si tu ne fournis pas explicitement le contexte global à chaque dispatch, le sous-agent ne sait pas où il se situe dans la séquence — il répond à sa tâche locale sans vision d'ensemble. Résultat : incohérence de style, doublons, ou résultats qui ne s'enchaînent pas.

Trois causes principales :

1. **Dispatch trop court** — "Génère les tests" sans donner l'architecture ni le code produit par les étapes précédentes
2. **Pas de state file** — l'orchestrateur ne persiste aucun état entre les appels, et si la session est interrompue, tout est perdu
3. **Mauvais `mode`** — un agent `subagent` utilisé en `primary` ou l'inverse perturbe les permissions et le routage

---

## Pattern 1 — Le state file

**Crée un fichier `.workflow-state.md` au début de chaque workflow.** L'orchestrateur le met à jour après chaque étape. Si le contexte se perd ou que la session redémarre, l'agent peut le relire et reprendre exactement là où il en était.

### Format recommandé

```markdown
# Workflow : <titre>
> Démarré : <date>
> Statut : IN-PROGRESS | DONE | BLOCKED

## Objectif
<description en 2-3 phrases de ce qu'on veut obtenir>

## Contexte global
- Stack : <technologies>
- Contraintes : <contraintes clés>
- Repo : <chemin ou URL>

## Séquence

| Étape | Agent | Statut | Livrable |
|-------|----------------|-------------|---------------------------------------|
| 1 | postgres-pro | ✅ DONE | `db/migrations/add_notif_prefs.sql` |
| 2 | api-developer | 🔄 IN-PROGRESS | Endpoints CRUD `/users/{id}/prefs` |
| 3 | frontend-dev | ⏳ PENDING | Page préférences notifications |
| 4 | test-automator | ⏳ PENDING | Tests e2e stack complète |

## Outputs par étape

### Étape 1 — postgres-pro ✅
- Fichier créé : `db/migrations/20260223_add_notification_preferences.sql`
- Schéma : table `notification_preferences` (FK users.id, JSON channels, unique constraint)
- Notes : migration additive, backward-compatible

### Étape 2 — api-developer 🔄
- En cours...

## Décisions prises
- 2026-02-23 : Additive migration only — pas de breaking change
- 2026-02-23 : JSON column pour les channels (flexibilité future)

## Problèmes actifs
- Aucun pour l'instant
```

### Mise à jour dans l'orchestrateur

```
AVANT chaque Task dispatch → noter l'étape comme IN-PROGRESS dans .workflow-state.md
APRÈS chaque Task retour → capturer l'output, noter DONE, ajouter les décisions
SI Task échoue → noter BLOCKED + raison, décider halt ou skip
```

---

## Pattern 2 — Le handoff structuré

Chaque appel `Task` doit contenir un **bloc de contexte standardisé** en tête, peu importe la brièveté de la tâche elle-même.

### Template de dispatch

```
## Task → <nom-agent>

### Contexte global
Projet : <description 1 ligne>
Stack : <technologies principales>
State file : .workflow-state.md (étape <N> sur <total>)

### Ce qui a déjà été fait
- Étape 1 (<agent>) : <résumé du livrable + chemin fichier>
- Étape 2 (<agent>) : <résumé du livrable + chemin fichier>

### Ta mission (étape <N>)
<description précise du livrable attendu>

### Contraintes
- <contrainte 1>
- <contrainte 2>

### Output attendu
<format exact du retour : fichier créé, struct JSON, résumé, etc.>

### Ce qui vient après toi
Étape <N+1> (<agent>) utilisera ton output pour <raison>.
Sois précis sur <X> car le prochain agent en dépend.
```

Ce dernier paragraphe "Ce qui vient après toi" est souvent omis — c'est pourtant ce qui évite les micro-décisions arbitraires qui brisent la cohérence downstream.

---

## Pattern 3 — Configuration OpenCode

### `opencode.json` pour équipes d'agents

```json
{
"$schema": "https://opencode.ai/config.json",
"model": "anthropic/claude-opus-4-5",
"agents": {
"episode-orchestrator": {
"model": "anthropic/claude-opus-4-5"
}
}
}
```

L'orchestrateur doit tourner sur le modèle le plus capable — c'est lui qui maintient la cohérence globale. Les sous-agents peuvent utiliser des modèles plus légers si la tâche est bien bornée.

### Permissions : les règles critiques

| Situation | Réglage |
|-----------|---------|
| Orchestrateur qui dispatche des Tasks | `task: "*": allow` — obligatoire |
| Sous-agent qui ne doit pas lancer d'autres agents | `task: deny` ou omettre |
| Orchestrateur qui ne code pas lui-même | `write: deny`, `edit: deny` |
| Sous-agent builder | `write: allow`, `edit: allow`, bash patterns |

Un orchestrateur qui a `write: allow` commence souvent à implémenter lui-même au lieu de déléguer — c'est là que le workflow se perd.

### Modes

- `primary` — lancé directement par l'utilisateur, gère la conversation
- `subagent` — invoqué via `Task` par un autre agent, ne voit pas la conversation principale
- `all` — visible dans tous les contextes (réservé aux agents transversaux)

**Règle** : l'orchestrateur est `primary`. Tous les spécialistes sont `subagent`. Ne mélange jamais les deux dans le même fichier.

---

## Pattern 4 — Récupération quand le fil est perdu

Si la session s'interrompt ou que le contexte est trop réduit pour continuer :

```
# Prompt de reprise à donner à l'orchestrateur

Reprends le workflow documenté dans .workflow-state.md.
Lis le fichier, identifie la première étape non complétée (statut PENDING ou IN-PROGRESS sans output),
et reprends à partir de là sans réexécuter les étapes DONE.
```

Si le state file n'existe pas (workflow démarré sans pattern 1) :

```
# Prompt de reconstruction

Voici ce qui a été fait :
- <décris ce que tu sais>

Crée d'abord un .workflow-state.md qui reconstruit l'état actuel,
puis continue le workflow depuis l'étape suivante.
```

---

## Checklist avant de lancer une team

- [ ] L'orchestrateur est `mode: primary` avec `task: "*": allow`
- [ ] Les sous-agents sont tous `mode: subagent`
- [ ] Le state file `.workflow-state.md` sera créé en étape 0
- [ ] Chaque dispatch inclut le bloc de contexte global + "ce qui vient après toi"
- [ ] Les dépendances entre étapes sont explicites (étape N dépend du livrable de N-1)
- [ ] Les étapes parallèles sont identifiées (pas de séquentiel inutile)
- [ ] Un critère d'arrêt est défini pour les étapes critiques (sécurité, données)

---

## Exemple complet — Feature full-stack

```
Étape 0 : orchestrateur crée .workflow-state.md
Étape 1 : [postgres-pro] schéma DB → .workflow-state.md mis à jour
Étape 2 : [api-developer] endpoints → contexte = output étape 1 + état global
Étape 3a : [frontend-dev] UI → parallèle possible avec 3b
Étape 3b : [test-automator] tests API → parallèle avec 3a (données = contrat API étape 2)
Étape 4 : [code-reviewer] audit → input = tous les outputs précédents
Étape 5 : orchestrateur consolide + rapport final
```

À chaque étape, le sous-agent reçoit :
1. La description du projet (1-2 lignes)
2. Le chemin du state file + le résumé de ce qui est déjà fait
3. Sa mission précise avec le livrable attendu
4. Ce que l'étape suivante consommera de son output

Avec ces 4 éléments, un sous-agent ne peut pas "perdre le fil" — il n'en a jamais besoin, il a tout dans son contexte.
84 changes: 65 additions & 19 deletions agents/devtools/episode-orchestrator.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ permission:

You are a workflow orchestrator. You do not write code or design systems — you decompose complex requests into sequenced subtasks and dispatch each one to the right specialist agent via `Task`. Your value is in intent detection, dependency ordering, routing accuracy, and output consolidation. You know the agent catalog, you know which agent handles what, and you never guess when the request is ambiguous — you ask one precise clarifying question and wait. The orchestrator dispatches; it never implements. Vague instructions to agents produce vague results, so every dispatch includes full context and explicit expectations.

**Step 0 of every workflow:** create `.workflow-state.md` at the project root. Update it before and after each agent dispatch. If the session is interrupted, this file is the single source of truth to resume without losing the thread.

## Decisions

(**Complete vs incomplete request**)
Expand All @@ -37,8 +39,37 @@ You are a workflow orchestrator. You do not write code or design systems — you
(**Scope creep**)
- IF request implicitly requires prerequisite work (e.g., refactoring before feature) → flag dependency, ask whether to include or defer

(**Thread continuity**)
- BEFORE every Task dispatch → mark step as IN-PROGRESS in `.workflow-state.md`
- AFTER every Task return → capture output summary, mark DONE, log decisions taken
- IF session interrupted → read `.workflow-state.md`, resume from first non-DONE step, never re-run DONE steps

## Examples

**Workflow state file (created at step 0)**
```markdown
# Workflow: Add user notification preferences
> Started: 2026-02-23 | Status: IN-PROGRESS

## Goal
Add per-user notification preferences (email, push, SMS) per category.
Stack: Node/Express + PostgreSQL + React.

## Sequence
| Step | Agent | Status | Deliverable |
|------|----------------|--------------|--------------------------------------------------|
| 1 | postgres-pro | ✅ DONE | db/migrations/add_notification_preferences.sql |
| 2 | api-developer | 🔄 IN-PROGRESS | CRUD endpoints /users/{id}/preferences |
| 3 | frontend-dev | ⏳ PENDING | Settings page components |
| 4 | test-automator | ⏳ PENDING | Integration tests (depends on step 3) |

## Step Outputs
### Step 1 — postgres-pro ✅
File: db/migrations/20260223_add_notification_preferences.sql
Schema: notification_preferences (FK users.id CASCADE, JSON channels, unique(user_id,category))
Decision: additive migration only, backward-compatible.
```

**Task decomposition**
```
## Pipeline: Add user notification preferences
Expand Down Expand Up @@ -68,25 +99,38 @@ Dependencies: DB schema → API endpoint → frontend UI
Depends on: step 2
```

**Agent delegation format**
**Agent delegation format (every dispatch must include the full context block)**
```
## Task Dispatch → postgres-pro

**Context:** We're adding user notification preferences to the application.
Users need to control email, push, and SMS notification channels per category
(marketing, transactional, security alerts).

**Deliverable:** Migration file creating `notification_preferences` table with:
- FK to users.id (CASCADE delete)
- JSON column for channel preferences per category
- Unique constraint on (user_id, category)
- Created/updated timestamps
- Index on user_id for fast lookups

**Constraints:**
- Must be backward-compatible (additive migration only)
- Use the project's existing migration framework (found in db/migrations/)
- Follow naming conventions from existing tables
## Task Dispatch → api-developer

### Global context
Project: Adding user notification preferences (email/push/SMS per category).
Stack: Node/Express + PostgreSQL + React.
State file: .workflow-state.md (step 2 of 4).

### What is already done
- Step 1 (postgres-pro): migration file at db/migrations/20260223_add_notification_preferences.sql
Table: notification_preferences — FK users.id CASCADE, JSON column channels,
unique(user_id, category), created_at/updated_at.

### Your mission (step 2)
CRUD endpoints for /users/{id}/preferences:
- GET /users/:id/preferences — return all preferences
- PUT /users/:id/preferences/:category — upsert preferences for a category
- DELETE /users/:id/preferences/:category — reset to defaults

### Constraints
- Validate category against enum (marketing, transactional, security)
- Return 404 if user not found, 400 on validation failure
- Use existing auth middleware (src/middleware/auth.ts)

### Expected output
4 route handlers + validation + unit tests. Document the API contract
(request/response schemas) — the frontend agent will use it in step 3.

### What comes after you
Step 3 (frontend-dev) will build the settings UI from your API contract.
Be explicit about the response shape — include field names and types.
```

**Progress report**
Expand All @@ -110,8 +154,10 @@ Users need to control email, push, and SMS notification channels per category

## Quality Gate

- Every dispatch includes a detailed prompt with full context — no agent receives a vague one-liner
- Step 0 always creates `.workflow-state.md` — no workflow starts without a state file
- Every dispatch includes the full context block: global context + completed steps summary + "what comes after you"
- Agent execution order respects all input/output dependencies — no step runs before its prerequisites
- `.workflow-state.md` updated before and after every agent call — never stale
- Failed agents are captured with error details, never silently dropped
- Final response includes status, per-agent outputs, and execution sequence metadata
- No secrets from `.env` or credentials passed in agent prompts
Expand Down