Leçon 07 · Mémoire

L'état sur disque, survivant à la compression

« Un état qui survit à la compression — parce qu'il est en dehors de la conversation. »

⏱ ~10 min · 📝 3 widgets interactifs · 🧑‍💻 Basé sur shareAI-lab · s07_task_system.py

Quelle différence entre TodoWrite et Task ?

Le TodoManager de s03 permet aussi de lister des tâches — mais il les stocke en mémoire. Quand auto_compact de s06 se déclenche et remplace messages[] par un résumé, l'état du TodoManager disparaît avec lui (il est in-memory).

Le Task de s07 fonctionne différemment : chaque tâche est un fichier .tasks/task_42.json. Peu importe si le contexte est compressé, si le processus redémarre ou si l'agent est remplacé — tant que le fichier est sur disque, la tâche existe.

# .tasks/task_12.json
{
  "id": 12,
  "subject": "Refactor auth middleware",
  "description": "Extract JWT logic to shared module",
  "status": "pending",
  "blockedBy": [8, 11],   # #8 et #11 doivent être terminés d'abord
  "owner": ""
}
Règle de choix : pour une liste temporaire (oubliée après la session), utilisez todo ; pour des tâches persistantes (multi-session, avec dépendances), utilisez task.

blockedBy · le comportement du graphe de dépendances

blockedBy est une liste d'IDs de tâches — toutes doivent être completed avant que la tâche courante soit « exécutable ».

s07 intègre un détail élégant : quand une tâche est terminée, elle se retire automatiquement de la liste blockedBy de toutes les autres tâches.

def _clear_dependency(self, completed_id: int):
    # Scan every task, remove completed_id from their blockedBy
    for f in self.dir.glob("task_*.json"):
        task = json.loads(f.read_text())
        if completed_id in task.get("blockedBy", []):
            task["blockedBy"].remove(completed_id)
            self._save(task)

L'agent n'a pas besoin de maintenir une table séparée des « tâches débloquées ». Il lui suffit de parcourir .tasks/ et de trouver les tâches avec status=="pending" and not blockedBy — ce sont celles qu'il peut exécuter maintenant.

Interaction avec le graphe de dépendances

Le widget ci-dessous vous présente un graphe de 5 tâches. Cliquez sur « complete » pour observer la mise à jour automatique de blockedBy et identifier quelles tâches deviennent exécutables (surlignées en vert).

Les tâches survivent-elles à la compression ?

s06 nous a montré qu'auto_compact remplace messages[] par un seul résumé. Mais les tâches ne sont pas affectées, car elles sont sur disque. Test : créez 5 tâches, compressez la conversation, puis demandez à l'agent de rescanner .tasks/ — il reprend là où il s'était arrêté.

Interactif

Widget 1 · Dependency Graph · cliquez sur complete pour voir les dépendances se mettre à jour

Topologie de 5 tâches. Cliquez sur Start ou Complete pour modifier le statut d'une tâche et observer comment blockedBy évolue ainsi que la liste des tâches « prêtes à démarrer ».

Liste de tâches (répertoire .tasks/)
Tâches exécutables (status=pending, blockedBy=[])
Graphe de dépendances
Interactif

Widget 2 · Compression Survival · les tâches survivent à auto_compact

Créez 3 tâches, déclenchez auto_compact (messages vidé), puis rescannez — les tâches sont toujours là.

Répertoire .tasks/
messages[]
Interactif

Widget 3 · Dependency Chain · quelles tâches sont exécutables maintenant ?

5 tâches avec des dépendances. En fonction de l'état décrit, répondez quelles tâches peuvent être démarrées (plusieurs réponses possibles).

Correct : 0 / 4