Compétence Graph
Exécute un graphe d'orchestration déterministe à partir d'un descripteur JSON déclaratif.
Le moteur consomme les contrats sealed-descriptor et pure-scheduler dans
src/graph/* et s'exécute via un processus OS indépendant (omc graph run),
ce qui permet une reprise après crash réelle (tuer en milieu d'exécution, relancer, reprendre depuis le journal).
Utilisation
/oh-my-claudecode:graph <descriptor.json>
/oh-my-claudecode:graph "build puis test puis demande-moi avant déploiement" (rédiger d'abord le descripteur)
La surface d'exécution est toujours la sous-commande CLI :
omc graph run <descriptor.json> [--runs-root <répertoire>]
Exécutez-la via l'outil Bash pour les graphes non interactifs. Les lignes de progression s'affichent sous la forme
[run], [node], [ok], [fail], [join], [done].
Quand l'utiliser
- Pipelines multi-étapes reproductibles avec dépendances explicites (DAG)
- Travail devant survivre à une interruption : tuer/redémarrer reprend depuis le journal
- Exécutions auditable : journal OCC + instantanés de projection sous
.omc/graph-runs/<run_id>/
À NE PAS utiliser : travail exploratoire ponctuel (utiliser la conversation ou /team) ; tout ce qui nécessite une re-planification adaptative en cours d'exécution (les graphes sont déterministes).
Flux de travail
-
Descripteur donné -> passer à l'étape 3.
-
Pipeline décrit -> rédiger le descripteur JSON (schéma ci-dessous), l'écrire à côté du projet (suggérer
.omc/graphs/<nom>.json) et le montrer à l'utilisateur avant d'exécuter.run_iddoit être unique par pipeline logique ; relancer avec le mêmerun_idREPREND, ne redémarre pas. -
Nœuds d'approbation : si le descripteur contient un nœud
"kind": "human-approval", ne PAS l'exécuter via l'outil Bash (stdin n'est pas interactif ; EOF échoue en fermé vers refusé). Demander à l'utilisateur d'exécuter en mode interactif :! omc graph run <fichier>Le préfixe
!exécute dans cette session avec stdin en direct, donc oui/non fonctionne. -
Exécuter et relayer la progression. Codes de sortie (normatifs) : 0 succès | 1 échec terminal | 19 un autre rédacteur possède cette exécution (occupé) 20 journal corrompu/falsifié (échec fermé) | 21 dérive du descripteur lors de la reprise | 70 crash du moteur (erreur non mappée)
-
Reprendre : relancer la même commande après un crash rejoue les transitions validées et continue. Les nœuds terminés ne sont jamais réexécutés.
Schéma du descripteur (minimal)
{
"descriptor_version": 1,
"run_id": "id-pipeline-unique",
"revision_id": "rev-1",
"goal": "une ligne",
"nodes": [
{ "id": "n1", "kind": "command", "title": "...", "timeout_ms": 60000,
"max_attempts": 2, "effect_policy": { "policy": "side_effect_free" },
"command": "npm test" },
{ "id": "a1", "kind": "agent", "title": "...", "timeout_ms": 300000,
"max_attempts": 1, "effect_policy": { "policy": "side_effect_free" },
"instructions": "..." },
{ "id": "gate", "kind": "human-approval", "title": "...",
"prompt": "Continuer ?" }
],
"edges": [ { "id": "e1", "kind": "fixed", "from": "n1", "to": "a1" } ],
"entry_node_ids": ["n1"],
"concurrency_limit": 2,
"terminal_verification_node_id": "a1"
}
Types d'arêtes : fixed | conditional | paires fan_out/join | back_edge (nouvelles tentatives bornées via max_traversals). Voir src/graph/schema.ts pour le schéma Zod faisant autorité — et lisez la section Limite de capacité ci-dessus pour ce que les exécuteurs intégrés exécutent réellement aujourd'hui.
Limite de capacité et sémantique (à lire avant de rédiger)
- Support des arêtes : les exécuteurs intégrés commande/agent couvrent les arêtes
fixedet les pairesfan_out/join. Les routesconditionaletback_edgesont entièrement supportées par le moteur et les contrats du planificateur mais nécessitent un NodeExecutor personnalisé qui émetroutesur ses résultats — les exécuteurs intégrés ne produisent jamais de routes, donc les graphes qui en dépendent échouent rapidement avecroute_requiredplutôt que de deviner. - La garantie de reprise après crash est au moins une fois pour les nœuds de commande : un crash
entre un effet de bord externe et son ajout au journal réexécute ce nœud
lors de la reprise. Pour les commandes
idempotent, la clé résolue est disponible pour la commande sousGRAPH_IDEMPOTENCY_KEYavant son démarrage et est également enregistrée pour la déduplication aval. Les exécuteurs intégrés rejettentreconcile; la réconciliation nécessite un exécuteur personnalisé avec une autorité de réconciliation externe réelle. L'exactitude une fois pour les effets de bord externes est hors scope pour la v1. - Périmètre de confiance de la commande : les nœuds de commande sont des lignes shell arbitraires avec
l'autorité du processus dans le répertoire de travail courant. N'exécutez que des descripteurs
que vous avez écrits ou auxquels vous faites confiance. Les commandes enfants reçoivent un environnement
listé autorisé (PATH, HOME/USERPROFILE, TEMP/TMP, locale/fuseau horaire, identité USER,
GRAPH_*, et la clé d'idempotence facultative), pas tous les secrets de l'hôte. Les commandes ne sont pas isolées dans un bac à sable fichiers/processus. - Périmètre d'autorité de l'agent : les nœuds agents intégrés sont explicitement en lecture seule.
Ils s'exécutent dans le répertoire de travail courant sans répertoires supplémentaires,
uniquement
Read,Glob,Grep,permissionMode: dontAsk, persistance de session désactivée, et une liste autorisée d'environnement spécifique au fournisseur. Les délais d'attente des agents abandonnent et interrompent la requête SDK. Utilisez un exécuteur personnalisé pour tout agent nécessitant des mutations ou des effets externes. Traitez.omc/graph-runs/<run_id>/descriptor.jsoncomme un contenu exécutable.