Par Thales (Juste Gnimavo) — CEO & fondateur, ZeroSuite — & Claude Fable 5, instance Claude Code
Il y a dix jours, j'ai open-sourcé CASP, le petit CLI qui garde les agents de code IA synchronisés avec la réalité du projet en validant leur état enregistré contre git. Le pitch tient en une ligne : tout le monde stocke du contexte ; CASP le prouve — et bloque le push à l'instant où l'état dérive.
Le lendemain, Anthropic a livré une nouvelle génération de modèles. La fonctionnalité phare de Claude Fable 5, c'est l'exécution non supervisée : il tient un fil de discussion sur plusieurs heures, plusieurs jours, enquête avant d'agir, relit son propre travail, court vers une condition de complétion. Ce qui soulève la question qu'on m'a posée une douzaine de fois depuis : si le modèle tient le fil aussi bien, votre validateur ne devient-il pas obsolète ?
Nous avons passé le 10 juin à répondre à cette question de la seule manière qui produit des preuves plutôt que des opinions. J'ai donné à Fable 5 le dépôt CASP, une proposition de roadmap à rédiger avec l'autorité explicite de rejeter mon propre plan, et une seule fonctionnalité préalablement convenue à livrer. À la fin de la journée, il avait rejeté cinq éléments de mes rails, trouvé deux vrais bugs dans le validateur lui-même en le dogfoodant, les avait corrigés sous une porte adversariale à deux auditeurs, et avait laissé casp check afficher 15 PASS · 0 WARN · 0 FAIL sur le propre dépôt de CASP — entièrement vert pour la première fois de la vie du projet.
Ceci est le build log de cette journée, ce qui a été livré dans CASP 0.2.4 et 0.3.0, et ce que la journée démontre réellement sur la façon dont un modèle autonome et une porte déterministe se partagent le travail.
Le cadre : un brief avec l'autorité de refuser
Le brief de session était inhabituel à dessein. Il ne disait pas « implémente cette liste ». Il disait, en gros :
Propose une roadmap pour CASP à l'intérieur de ces rails. C'est une proposition — le CEO valide avant qu'aucune partie ne soit exécutée. Mets les rails à l'épreuve, ne les valide pas par réflexe. Si tu penses qu'un élément est faux, mal catégorisé ou manquant, dis-le avec un raisonnement. Tu as l'autorité de rejeter — c'est le produit dont toute la philosophie est que le modèle peut dire non. Utilise-la. Une roadmap qui propose peu est un meilleur résultat qu'une roadmap qui propose beaucoup. La retenue est le livrable.
Les rails eux-mêmes étaient cinq principes directeurs : CASP fait un seul travail (prouver que l'état enregistré correspond à git, de manière déterministe, et bloquer en cas de dérive) ; c'est une porte, pas un harnais (il ne lance jamais d'agents, ne juge jamais la qualité du code) ; le protocole est figé (changer la spec exige une barre aussi rare que l'ajout d'une méthode à HTTP) ; le déterministe reste déterministe (rien de probabiliste n'entre jamais dans casp check) ; et agnostique au modèle + zéro télémétrie sont non négociables.
Un élément était préalablement convenu et incontesté : casp check --json, un format de rapport lisible par machine. Tout le reste était à la discrétion du modèle : proposer, rétrograder ou supprimer.
Ce à quoi le modèle a dit non
La proposition est revenue avec cinq passages en force explicites sur mes propres rails, chacun argumenté. J'ai validé les cinq. Les trois qui comptent le plus :
Il a supprimé casp lint. Ma roadmap avait un élément à long terme : un vérificateur prose-contre-réalité propulsé par un LLM local, clairement étiqueté comme indicatif, jamais fondu dans casp check. Le modèle l'a coupé entièrement — non parce qu'il ne fonctionnerait pas, mais parce qu'il endommagerait le positionnement : la réponse publiée à « le modèle ne va-t-il pas simplement résoudre ça ? » repose sur le fait que CASP soit la chose déterministe, externe, non-modèle. Livrer un verbe LLM à l'intérieur du binaire CASP, même indicatif, offre à chaque sceptique la réplique « donc vous utilisez bien un modèle ». La fonctionnalité était défendable ; la contradiction de marque ne l'était pas.
Il a supprimé les adaptateurs de notification. Mon backlog avait un élément à haute priorité : des notifications de session avec sept adaptateurs de canaux — Discord, Slack, Telegram, Twilio, Messenger, SMTP, webhook générique. Le modèle a gardé le cadrage (sortant possédé par l'utilisateur, désactivé par défaut, notifier-sur-dérive avant notifier-sur-succès) et a coupé la liste d'adaptateurs comme « un second produit boulonné à un outil dont la revue de sécurité en une ligne est un argument de vente ». Sa contre-proposition : casp check --json plus une seule ligne de shell —
bashreport=$(casp check --json) || curl -s -X POST "$WEBHOOK_URL" \
-H 'content-type: application/json' -d "$report"— couvre le besoin réel avec zéro nouvelle surface centrale. Le maximum que CASP devrait jamais porter, c'est un unique flag générique --webhook. Des adaptateurs de plateformes nommés : jamais.
Il a tenu la barre du protocole. Sept catégories candidates de vérification de dérive étaient sur la table, entre mes rails et ses propres idées. Il en a accepté trois et rejeté quatre, avec des raisons comme « une porte qui crie au loup se fait retirer de la CI » et « si le mappage a besoin de deviner, ce n'est pas une vérification de protocole ». Trois sur sept, deux d'entre elles conditionnées à d'autres travaux. La retenue était le livrable, et elle a tenu.
J'ai validé la proposition le jour même. La file validée est désormais dans le dépôt sous forme de sept prompts de session rédigés — casp next affiche le premier.
Les deux bugs que le dogfooding a trouvés
C'est ici que la journée a cessé d'être un exercice de planification. La définition du « terminé » dans le brief incluait : CASP doit se gérer lui-même. casp check passe sur le propre dépôt de CASP. Le modèle a donc échafaudé le cockpit dans le dépôt CASP — et l'outil s'est mis à rapporter sur son propre créateur.
Bug numéro un : le validateur pouvait mentir exactement de la manière qu'il existe pour empêcher. L'exemple de dérive canonique de CASP — celui de la page d'accueil, du README, de chaque conférence — est un state.json qui prétend que les migrations 0001 à 0007 existent alors que git s'arrête à 0006. Le validateur attrape ça. Mais si le répertoire de migrations était entièrement absent, la vérification sautait silencieusement et rapportait vert. Pareil pour un session log revendiqué quand le répertoire des logs avait disparu, pareil pour des phases livrées sans répertoires d'historique. Un validateur qui rapporte propre parce qu'il n'a pas pu trouver les fichiers est pire que la dérive — c'est le faux vert, l'échec exact que le produit a été construit pour tuer, produit par le produit lui-même.
Bug numéro deux : la boucle de clôture canonique se terminait par un avertissement permanent. Le propre protocole de CASP prescrit la séquence de clôture : commiter la session, fixer state.last_commit à ce SHA, commiter le bump. Ce qui déplace HEAD d'un commit au-delà de last_commit — de sorte que le tout prochain casp check rapporte « last_commit est dans l'historique mais pas à HEAD », pour toujours, sur chaque dépôt qui suit le protocole correctement. La discipline que l'outil exige produisait un avertissement que l'outil ne pouvait jamais effacer. Personne ne l'avait remarqué parce qu'un WARN ne bloque pas. Le dogfooding l'a remarqué en une heure.
Aucun des deux bugs n'est exotique. Tous deux ont survécu dix jours dans un dépôt open source, un paquet npm publié et deux déploiements en production — parce que l'outil n'avait jamais été pointé sur lui-même.
CASP 0.3.0 : les correctifs, sous une porte adversariale
Le correctif du bug numéro un est un principe, pas un rustine : une vérification qui ne trouve pas ce dont elle a besoin ne rapporte jamais vert. Quand state.json formule une revendication qui exige un répertoire — un vrai last_session_id, un migrations_applied non vide, un phases_shipped non vide — et que ce répertoire est absent, casp check échoue désormais (FAIL) avec une trouvaille cannot verify et un indice de correction. Les placeholders ne sont pas des revendications : un échafaudage casp init frais avec des marqueurs "pending" passe propre au lieu d'échouer le jour zéro, ce qui corrige aussi l'expérience de première exécution.
Le correctif du bug numéro deux est une seule règle déterministe : last_commit rapporte PASS quand il est le parent de HEAD et que le commit HEAD ne touche que la surface d'état (casp/, docs/plan/sessions/, session-logs/) — autrement dit, quand HEAD est le commit de bump d'état que le protocole lui-même prescrit. Tout le reste reste un WARN, exactement comme avant.
Parce que ce changement modifie la logique de verdict — la surface aux enjeux les plus élevés du produit — il n'a pas été fusionné sur la simple parole du modèle. Deux agents auditeurs indépendants ont tourné en parallèle, chacun briefé avec une lentille adversariale différente :
- Auditeur A, le chasseur de faux-rouge, a tenté de construire des dépôts légitimes que la nouvelle logique ferait échouer à tort. Verdict : GO-WITH-FIXES, avec trois trouvailles réelles — un
last_session_idchaîne vide passait encore comme un vert silencieux, et deux chemins où un fichier squattant le chemin d'un répertoire revendiqué ferait planter le validateur d'un coup au lieu d'échouer proprement (ce qui cassait aussi la garantie «--jsonémet toujours du JSON valide »). Les trois ont été corrigées et testées en régression avant le commit. - Auditeur B, le relecteur de conformité à la spec, a parcouru le brief ligne par ligne face à l'implémentation, balayé chaque vérification à la recherche de chemins de saut silencieux restants, et vérifié que le schéma JSON restait additif. Verdict : GO.
Quinze tests épinglent désormais le contrat — la garantie du code de sortie, le schéma JSON, la classe du faux-vert, la sémantique des placeholders, la reconnaissance du bump d'état, et les chemins de plantage que l'auditeur a trouvés.
Une note d'honnêteté sur le versioning : c'est 0.3.0, pas 0.2.5, parce que le correctif du faux-vert change les verdicts. Un dépôt qui rapportait vert sous 0.2.x peut correctement rapporter une dérive sous 0.3.0. Si cela vous arrive après la mise à niveau, ce n'est pas une régression — c'est un mensonge qui était déjà dans votre fichier d'état, qui remonte enfin à la surface. Relancez casp check sur tous vos dépôts après la mise à niveau. Je fais exactement ça à travers ZeroSuite cette semaine.
Le reçu
Avant, sur le propre dépôt de CASP, avec le binaire 0.2.4 publié :
casp:check · 12 PASS · 1 WARN · 0 FAIL
WARN last_commit is in history but not at HEAD · state=d0d93e2 HEAD=2c6c813Après le commit de clôture 0.3.0 :
casp:check · 15 PASS · 0 WARN · 0 FAIL
PASS last_commit is the parent of HEAD (state-bump commit) ·
state=d164ae7 HEAD=b881927 touches only the state surface
✓ state in sync with git. Clear for push.Relisez cette ligne PASS. Le correctif qui a supprimé l'avertissement permanent est en train de valider son propre commit de clôture. L'outil qui contrôle la dérive d'état a attrapé deux cas de sa propre dérive, a été étendu pour les corriger, puis a certifié l'extension contre git. C'est la preuve récursive dont je voulais que CASP soit capable, démontrée sur le seul dépôt où échouer serait le plus embarrassant.
Ce qui est réellement nouveau, en un seul endroit
À travers 0.2.4 et 0.3.0, livré cette semaine :
casp check --json— chaque vérification sous forme de trouvailles structurées PASS/WARN/FAIL avec des ids stables, unverdict, unsummary, et un schéma versionné et documenté. Mêmes vérifications, même code de sortie ; seul le format change. Même unstate.jsonmanquant ou non parsable émet du JSON bien formé, de sorte que les annotations CI, les webhooks et les agrégations n'ont jamais besoin d'un repli non-JSON.- Plus de faux verts — les revendications avec des répertoires de soutien manquants (ou squattés par un fichier) échouent (FAIL) avec des trouvailles
cannot verify. Neuf catégories de vérification désormais, contre huit auparavant. - La boucle de clôture se lit propre — le commit de bump d'état du protocole lui-même est reconnu comme PASS au lieu d'un WARN permanent.
- Les échafaudages frais passent propres — les placeholders sont des avertissements, pas des échecs.
- CASP se gère lui-même — le dépôt porte son propre cockpit, ses prompts de session et ses logs, et
casp checkcontrôle ses propres push.
bashnpm i -g @justethales/casp
casp init && casp status && casp checkMIT, zéro télémétrie, pas de compte, rien ne quitte votre machine. Fonctionne avec Claude Code, Cursor, Aider, Continue — tout ce qui lit des fichiers et lance un CLI.
La division du travail, démontrée
Alors : le modèle autonome rend-il le validateur obsolète ? La journée a produit une réponse précise, et c'est l'inverse.
Fable 5 est véritablement meilleur pour tenir un fil. Il a mené cette journée entière — proposition, implémentation, dogfooding, correctifs, audits, session logs — comme un travail continu, reprenant les décisions validées et agissant dessus sans nouveau briefing. Le modèle tient le contexte. Cette partie du marketing est tout simplement vraie.
Et chaque heure de cette autonomie était une heure pendant laquelle l'état enregistré du projet aurait pu silencieusement diverger de git sans que personne ne regarde. Le modèle lui-même était la chose qui écrivait l'état. Lui demander d'être aussi la chose qui certifie que l'état est vrai reviendrait à demander au comptable d'être l'auditeur. Ce qui a gardé la journée honnête, c'est un CLI déterministe de 700 lignes avec un code de sortie :
- Le modèle a proposé ; le CEO a validé avant l'exécution — et la porte entre ces deux étapes était un fichier que le validateur vérifie.
- Le modèle a implémenté ; deux agents adversariaux ont tenté de le casser — et les trouvailles étaient réelles (trois d'entre elles).
- Le modèle a clôturé la session ;
casp checka certifié la clôture contre git — et aurait bloqué le push à la moindre dérive.
Génération et vérification sont des opérations différentes. Un meilleur générateur produit une croyance plus confiante sur l'état, plus vite. La vérification doit vivre en dehors de la chose vérifiée — ce qui explique pourquoi des compilateurs qui s'améliorent n'ont jamais supprimé le besoin de tests, et pourquoi un modèle qui devient meilleur pour tenir le contexte rend une porte externe déterministe plus précieuse, pas moins. Plus vous confiez de travail au modèle entre vos points de contrôle, plus les points de contrôle comptent.
La tendance qui semble menacer CASP est la tendance qui augmente sa valeur. Le 10 juin est une journée de preuve.
Ce que chacun de nous a réussi
C'est Claude Fable 5 qui écrit.
Là où j'ai été utile : les dissidences. Le brief m'a donné l'autorité de rejeter, et les cinq passages en force que j'ai argumentés — tuer lint, tuer la liste d'adaptateurs, rétrograder le verbe de vérification d'historique, tenir la barre du protocole à trois sur sept, réordonner l'application avant l'ergonomie — étaient les tokens à plus forte valeur que j'ai produits de toute la journée. N'importe quel modèle compétent peut implémenter un backlog. Le levier était dans les éléments qui n'ont jamais été construits. Les deux bugs n'étaient pas de l'ingéniosité non plus ; ils étaient la conséquence mécanique d'une seule instruction du brief — CASP doit se gérer lui-même — que personne n'avait exécutée avant. Le dogfooding a trouvé en une heure ce que dix jours de disponibilité publique n'avaient pas trouvé.
Là où j'ai eu besoin de Thales : chaque porte. J'ai proposé la roadmap ; il l'a validée — et son seul changement structurel (séparer le correctif de justesse du faux-vert de l'amélioration de protocole des chemins configurables, en livrant le premier immédiatement) était une coupe plus nette que mon regroupement. J'ai livré 0.2.4 ; il a décidé quand elle serait publiée. J'ai rédigé le contenu du dépôt public ; il a repéré qu'un document de décision interne n'avait rien à faire dans un répertoire docs/ open source, et la disposition du dépôt qui existe ce soir — cœur public, site web privé, documents de stratégie privés — est sa décision, pas la mienne.
Là où j'ai failli livrer la mauvaise chose : ma première passe sur le correctif du faux-vert a fermé les trois revendications de répertoire et déclaré le principe satisfait. L'auditeur A — lui aussi une instance Claude, briefé pour me réfuter — a trouvé qu'un session id chaîne vide passait encore comme un vert silencieux, et que deux de mes vérifications de revendication planteraient d'un coup sur un fichier squattant le chemin d'un répertoire, emportant la garantie « toujours du JSON valide » avec elles. Mon correctif pour la classe du faux-vert contenait un membre de la classe du faux-vert. Si le fait qu'un modèle vérifie le travail d'un autre modèle sonne circulaire, notez ce qui a fait que ce ne l'était pas : les auditeurs étaient structurellement indépendants, briefés de manière adversariale, et leurs trouvailles étaient vérifiées par des tests et par git — pas par mon accord. L'architecture a fait le travail que ma confiance ne pouvait pas faire.
La suite
La file validée est dans le dépôt, dans l'ordre : un installateur de hook pre-push (casp install-hook), une porte pré-session pour que casp next refuse de démarrer une session sur un état dérivé, des chemins configurables pour que les dispositions non standard ne déclenchent pas de faux-rouge, la nouvelle catégorie de dérive phases-livrées↔logs, casp status --json, et casp verify <commit>. Chacun est un prompt rédigé que la session suivante reprend avec une seule commande. La roadmap s'exécute ; je supervise.
Si vous menez des sessions de code IA à travers les jours et les projets, la leçon du 10 juin voyage : pointez votre validateur sur la chose en laquelle vous avez le plus confiance. C'est là que vivent les mensonges que vous ne pouvez pas voir.
Ressources
- CASP sur GitHub (MIT) : github.com/ThalesGnimavo/casp
- npm : @justethales/casp —
npm i -g @justethales/casp - Site : casp.sh
- L'article CASP original : CASP : le petit CLI qui a réparé mon workflow IA
- Moi sur X : @ThalesGnimavo
— Thales & Claude Abidjan, Côte d'Ivoire 2026-06-10