Architecture du système
Le framework APEX v2 repose sur un modèle à 4 niveaux qui sépare clairement les responsabilités : quand exécuter, qui exécute (avec quelle identité et quelles connaissances), et quoi faire.
Vue d'ensemble
Step (QUAND) — phases séquentielles du pipeline
└─ Agent (QUI + COMMENT) — identité, contraintes, model, tools
└─ Profile (SAIT QUOI) — conventions, patterns, toolchain
└─ Prompt (FAIT QUOI) — tâche spécifique + artifactsChaque niveau a une responsabilité unique et peut être réutilisé indépendamment des autres. Un même agent executor peut être instancié avec des profiles différents (Rust, Vue, Python).
Principe de conception
La séparation en niveaux évite le problème classique des prompts monolithiques qui mélangent identité, connaissances techniques et tâche concrète. Chaque niveau est composable et remplaçable.
Step — Phase du pipeline
Rôle : définir QUAND quelque chose se passe dans le pipeline.
Un step est un fichier dans skills/{skill}/steps/, nommé step-{NN}-{name}.md (numéro à deux chiffres avec zéro de padding). Chaque step correspond à une phase séquentielle nommée. Les steps se succèdent dans l'ordre et peuvent être conditionnels (ex. : step-05-examine.md n'est activé qu'avec le flag -x, step-07-tests.md qu'avec le flag -t).
Chaque fichier step contient des sections XML qui définissent son comportement :
| Section | Rôle |
|---|---|
<objective> | Ce que ce step accomplit globalement |
<delegation> | Agent à invoquer, tier, mode, exception |
<process> | Étapes détaillées d'exécution |
<rules> | Contraintes à respecter pendant ce step |
<output_template> | Format attendu du fichier produit |
<save> | Nom du fichier à écrire (artifact de sortie) |
<next> | Step suivant à enchaîner |
Granularité recommandée
Un step = une phase cohérente du travail. La frontière naturelle est le changement de mode de travail : analyse, implémentation, review sont trois modes distincts.
Agent — Identité et mécanisme d'exécution
Rôle : définir QUI exécute le travail et COMMENT.
Un agent combine l'identité (rôle, contraintes, style) et le mécanisme d'exécution (modèle, outils). Les agents sont définis dans framework/agents/{name}.md et contiennent :
- Identité : qui est cet agent, comment il pense, quel est son objectif
- Contraintes : ce qu'il ne fait pas (ex. : l'architecte ne touche pas au code)
- Menu d'actions : codes courts pour invoquer des actions spécifiques
- Agent_Prompt : instructions d'exécution détaillées (responsabilités, format de sortie)
- Modèle : tier (
haiku,sonnet,opus) ou ID concret configuré dansframework/models.md
Un même agent est réutilisable dans des contextes différents. L'agent executor est identique que le travail porte sur du Rust backend ou du Vue frontend — c'est le profile qui change ce qu'il sait, pas qui il est.
Les agents sont instanciés à l'intérieur des steps via un bloc <delegation>.
Exemple : agent executor
# Executor
Tu es un développeur senior qui implémente du code de production.
Tu privilégies la lisibilité, la maintenabilité et la correction.
Tu ne modifies pas l'architecture — tu l'implémentes.
## Contraintes
- Pas de refactoring non demandé
- Pas de changement d'architecture
- Commit atomiques et cohérentsIsolation
Chaque agent travaille dans son propre contexte. Les artifacts (fichiers produits) constituent le seul canal de communication entre agents.
Délégation obligatoire
Rôle : garantir que chaque step non-trivial est exécuté par l'agent spécialisé prévu.
Tout step qui a un agent dédié s'ouvre sur un bloc <delegation>. Ce bloc force la délégation et prévient toute rationalisation inline.
<delegation>
agent: architect
tier: opus
mode: mandatory
exception: economy mode (`-e`) → work inline, no subagents
STOP — You MUST delegate this step to the agent above using the Agent tool.
DO NOT use Edit, Write, or other file-modification tools directly.
DO NOT rationalize skipping delegation ("it's simpler", "it's faster", "just a few edits").
The ONLY exception is economy mode (`-e`). If `-e` is not active, delegation is not optional.
Resolve the model from the "Models" section in 00-context.md (loaded from models.md at init).
Dispatch:
Claude Code: Agent(subagent_type="oh-my-claudecode:architect", model="{resolved-model}", prompt="...")
Other runtimes: delegate to the architect agent with the resolved model using the runtime's native dispatch.
</delegation>Règles clés :
mode: mandatory— la délégation n'est jamais optionnelle- Exception unique : le flag
-e(economy mode) autorise le travail inline sans sous-agents - Les instructions anti-rationalisation empêchent l'IA de décider de court-circuiter
- Le modèle est résolu depuis
00-context.md, écrit parstep-00après lecture demodels.md
Correspondance agent/step dans Kensho :
| Step | Agent | Tier |
|---|---|---|
| 01-analyze | architect | opus |
| 01b-spec | analyst | opus |
| 02-plan | architect | opus |
| 03-execute | executor | sonnet |
| 05-examine | code-reviewer | opus |
| 07-tests | test-engineer | sonnet |
Les steps 00, 04, 06, 08, 09 s'exécutent dans le contexte principal sans délégation.
Anti-pattern à éviter
Ne jamais ignorer un bloc <delegation> sous prétexte que la tâche "semble simple" ou "serait plus rapide en direct". La délégation obligatoire existe précisément pour les cas où l'IA serait tentée de rationaliser le raccourci.
Profile — Connaissance technique
Rôle : définir ce que l'agent SAIT sur la stack technique.
Les profiles sont définis dans framework/profiles/{name}.md. Un profile injecte dans l'agent les conventions, patterns et spécificités de la toolchain concernée.
Un profile ne change pas QUI est l'agent — il change QUOI il connaît.
Les agents supportent les multi-profiles : un agent peut recevoir plusieurs profiles simultanément.
Exemple : profile rust
# Rust Profile
## Conventions
- Nommage snake_case pour fonctions et variables
- Types explicites dans les signatures publiques
- Gestion d'erreur via `Result<T, E>`, pas de `unwrap()` en production
- Modules organisés par domaine fonctionnel
## Patterns
- Builder pattern pour les structs complexes
- Newtype pattern pour la type safety
- `thiserror` pour les erreurs custom, `anyhow` pour le propagation
## Toolchain
- `cargo fmt` avant chaque commit
- `cargo clippy -- -D warnings` en CI
- Tests unitaires dans le même fichier avec `#[cfg(test)]`Multi-profiles
profile: [rust, tauri]Les profiles sont concaténés dans l'ordre. En cas de conflit, le dernier profile l'emporte.
Prompt — Tâche spécifique
Rôle : définir ce que l'agent FAIT concrètement.
Le prompt est transmis à l'agent lors de sa délégation (champ prompt de l'appel Agent()). Il spécifie :
- La tâche précise à accomplir
- Les artifacts en entrée (fichiers à lire)
- Les artifacts à produire en sortie
Le prompt est le niveau le plus spécifique — il change à chaque step et chaque agent. Les autres niveaux (agent, profile) sont réutilisables.
Comment ça s'assemble
Quand un step délègue à un agent, le contexte final est construit en concaténant les niveaux dans l'ordre :
[Agent: framework/agents/executor.md] ← QUI tu es + contraintes
[Profile: framework/profiles/rust.md] ← SAIT : conventions Rust
[Artifacts: spec.md, plan.md, tasks.md] ← CONTEXTE partagé
[Prompt: "Implémente les tâches backend..."] ← FAIT : la tâche concrèteL'ordre est fixe et intentionnel : l'identité et les contraintes de l'agent sont établies en premier, avant d'injecter les connaissances techniques et le contexte de travail.
Priorité en cas de conflit
Si le profile contredit l'agent sur un point, le profile l'emporte pour les conventions techniques. Si le prompt contredit l'agent sur les contraintes (ex. : "refactorise tout"), l'agent l'emporte.
Orchestration multi-agents
L'architecture prévoit la capacité de dispatcher plusieurs agents simultanément depuis un même step :
- parallel : les agents s'exécutent en simultané (ex. : backend-dev + frontend-dev)
- sequential : les agents s'exécutent l'un après l'autre (ex. : analyse → plan)
Dans l'implémentation actuelle, chaque step délègue à un seul agent via son bloc <delegation>. Le dispatch parallèle est une capacité architecturale disponible pour des pipelines avancés.
Exemple de step d'exécution avec bloc de délégation réel :
<delegation>
agent: executor
tier: sonnet
mode: mandatory
exception: economy mode (`-e`) → work inline, no subagents
STOP — You MUST delegate this step to the agent above using the Agent tool.
DO NOT use Edit, Write, or other file-modification tools directly.
DO NOT rationalize skipping delegation ("it's simpler", "it's faster", "just a few edits").
The ONLY exception is economy mode (`-e`). If `-e` is not active, delegation is not optional.
Resolve the model from the "Models" section in 00-context.md (loaded from models.md at init).
Dispatch:
Claude Code: Agent(subagent_type="oh-my-claudecode:executor", model="{resolved-model}", prompt="...")
Other runtimes: delegate to the executor agent with the resolved model using the runtime's native dispatch.
</delegation>Les artifacts produits par un agent (fichiers écrits) constituent le seul canal de communication avec le step suivant.
Boucle de feedback
Kensho implémente une boucle de feedback entre les steps 05 et 06 :
step-05-examine(conditionnel, flag-x) délègue àcode-reviewer(opus) qui produit un rapport de findings- Si des findings sont détectés,
step-06-resolveprend le relai dans le contexte principal et applique les corrections step-04-validatepeut être ré-exécuté après résolution pour confirmer que le build et les tests passent toujours
Le fichier de findings produit par step-05 est l'artifact d'entrée de step-06. La transition est conditionnelle : step-06 n'est pertinent que si step-05 a signalé des findings.
Conditions de déclenchement
Step-06 résout les findings issus de step-05. En l'absence de findings, on passe directement à step-07 (si -t est actif) ou à step-09.
Pipeline Kensho (vue simplifiée)
00-init
└─ Initialise le contexte, lit les flags, charge models.md et profiles
01-analyze
└─ Delegation: architect (opus) → exploration lecture seule du codebase
01b-spec [gate obligatoire, même en -a]
└─ Delegation: analyst (opus) → spec formelle avec requirements SHALL
02-plan
└─ Delegation: architect (opus) → plan fichier par fichier
03-execute
└─ Delegation: executor (sonnet) → implémentation todo-driven
04-validate
└─ Vérification build + tests + spec (contexte principal)
05-examine [flag -x requis]
└─ Delegation: code-reviewer (opus) → review adversariale
06-resolve [si findings au step 05]
└─ Corrections (contexte principal)
07-tests [flag -t requis]
└─ Delegation: test-engineer (sonnet) → création de tests
08-run-tests [flag -t requis]
└─ Exécution des tests en boucle (contexte principal)
09-finish
└─ Commit conventionnel + résumé (contexte principal)Tableau récapitulatif
| Niveau | Fichier | Rôle | Exemple |
|---|---|---|---|
| Step | skills/kensho/steps/step-03-execute.md | QUAND — phase séquentielle du pipeline | 03-execute, 05-examine |
| Agent | framework/agents/executor.md | QUI + COMMENT — identité, contraintes, model, tools | executor, code-reviewer, analyst |
| Profile | framework/profiles/rust.md | SAIT QUOI — conventions, toolchain | rust, vue-typescript, tauri |
| Prompt | (transmis lors de la délégation) | FAIT QUOI — tâche + artifacts | "Implémente les tâches backend..." |
Réutilisabilité
Les agents et profiles sont les niveaux les plus réutilisables. Un profile rust est partagé entre tous les agents qui travaillent sur du code Rust, qu'ils soient executors, reviewers ou analyzers.
