Skip to main content
Le rejeu re-dérive une exécution terminée. L’exécution durable reprend une exécution interrompue : processus tué, machine redémarrée, déploiement en plein run.

Démarrer et reprendre

La même commande démarre et reprend. C’est le journal du répertoire qui dit si l’exécution est neuve, interrompue ou terminée.
Après un crash, relancez la même ligne :
--durable et --record s’excluent : un journal durable s’exporte.

Le protocole d’une action

À la reprise, le programme est ré-exécuté depuis le tick 0 et chaque franchissement de frontière est servi par le journal : aucun effet, aucun appel au modèle, aucune question. Un point de contrôle qui ne correspond pas à l’état re-dérivé arrête tout. Au-delà du journal, l’exécution continue en direct.

Une action restée sans résultat

Si le processus meurt entre l’intention et le résultat, l’effet a peut-être eu lieu. La reprise tranche :
1

Outil idempotent : relancé avec la même clé

L’outil est déclaré idempotent=True : l’hôte promet que son service ignore une seconde requête portant la même clé. L’action s’exécute exactement une fois.
2

Réconciliateur : on demande au monde

Un réconciliateur dit si l’action a eu lieu. Si oui, son résultat est journalisé. S’il rend NOT_EXECUTED, l’action est exécutée.
3

Sinon : indéterminée

L’action n’est pas relancée (au plus une fois). Le runtime ne présume aucun EFFECT, marque les SIDE_EFFECT déclarés comme sales, et pose tools.<outil>.in_doubt = true.

Côté hôte

payments.py
Un réconciliateur qui ne sait pas doit lever, pas rendre NOT_EXECUTED : ce serait transformer « peut-être » en « relancer ». Et idempotent=True est une promesse de l’hôte que le runtime ne peut pas vérifier.

Côté programme

Une action indéterminée est un fait, et la politique le lit :
tools.<outil>.in_doubt vaut false au démarrage : la garde n’est pas indéterminée sur une exécution neuve.

Garanties

Refus de reprise

La chaîne du journal est un SHA-256 sans clé. Elle détecte la corruption et la réécriture naïve, pas un faussaire qui peut écrire le répertoire et recalculer toute la chaîne.

API Python

Stockages : FileStore (fichier + fsync), SQLiteStore(path, run_id), MemoryStore(). Une société s’exécute sous un seul journal.

Noyau et permis

D’où viennent l’identifiant d’action et la clé d’idempotence.

Banc comparatif

Crash après un virement : AGENT-L, LangGraph, PydanticAI, CrewAI.