Back to zerosuite
zerosuite

L'orchestrateur ne code pas : treize sessions en une journée, un navigateur qui vérifie, et savoir quand s'arrêter

Une journée, une plateforme client privée, treize sessions Claude headless enchaînées par un orchestrateur qui n'écrit jamais de code. Vérifier dans le navigateur du CEO, grouper les correctifs sans lâcher la gate, et écrire quand fermer une session.

Juste Thales Gnimavo & Claude | September 30, 2026 19 min zerosuite
EN/ FR/ ES
caspclaude-codeclaude-opus-5.5multi-sessionheadlesschainsubagentsbrowser-automationclaude-in-chromeverificationlegacy-migrationdesign-systemledgertesting-strategycontext-managementsession-lifecycle

Par Thales (CEO, ZeroSuite) et Claude Opus 5.5 — instance Claude Code

Ce billet parle d'une façon de travailler, pas d'un produit. Le produit est une plateforme client privée, et elle le reste : nous ne la nommerons pas, ne la montrerons pas et ne dirons pas ce qu'elle vend. Ce que nous pouvons décrire, c'est sa forme, parce que c'est sa forme qui a rendu la journée intéressante :

  • Elle fait circuler de l'argent réel. Chaque solde repose sur un grand livre en partie double,
  • et une erreur atteint un client.
  • Elle remplace un back-office utilisé depuis quinze ans. Le propriétaire connaît chaque
  • libellé de menu par cœur et s'attend à les retrouver.
  • Chaque push sur main déploie en production. Il n'y a aucune CI derrière, seulement un script
  • de gate local.
  • Le propriétaire valide le travail dans un navigateur. Il ne lit pas les diffs.

Entre le soir du 29 septembre et le soir du 30 septembre 2026, une session Claude Code a fait tourner treize autres sessions Claude Code, l'une après l'autre, sur cette plateforme. La session qui les pilotait n'a pas écrit une ligne de code produit. Voici comment cela fonctionne, ce qui a mal tourné, et les trois règles que nous avons écrites en fin de journée.


Partie 1 — Une phase, un processus neuf

La file de travail vit dans le dépôt, sous forme de prompts CASP : un fichier Markdown par phase, avec status: queued, un pointeur next_after, une liste MUST et une liste DO NOT. casp/state.json indique quel prompt vient ensuite.

La session à laquelle vous parlez est l'orchestrateur. Pour chaque phase, il fait cinq choses :

  1. Il vérifie la file : le prompt suivant existe, il est queued, et son next_after pointe
  2. vers quelque chose qui a été livré.
  3. Il arbitre la forme, solo ou en parallèle, et écrit la décision dans casp/state.json avant le
  4. lancement. Toutes les phases de la journée sont sorties en solo, pour une raison mesurable : la
  5. gate utilise des ports fixes, une base de test partagée et un seul répertoire de build. Deux
  6. rédacteurs en parallèle ne produiraient pas un conflit git. Ils produiraient des tests rouges
  7. que quelqu'un imputerait au mauvais diff.
  8. Il lance un enfant : claude -p "/next …" dans un script démarré avec nohup, sortie vers
  9. un fichier de log.
  10. Il le surveille : un moniteur en arrière-plan émet une ligne par nouveau commit, une ligne
  11. quand l'enfant se termine, et une ligne STALLED si aucun fichier du dépôt n'a changé depuis
  12. vingt minutes.
  13. Il vérifie lui-même la clôture : rien de non poussé, un arbre propre, casp check qui sort
  14. à 0, l'identifiant de session qui a avancé, le log présent, et un script qui lit quel commit la
  15. production sert réellement.

L'enfant démarre avec le dépôt pour seul bagage. C'est tout l'intérêt : le contexte ne s'accumule jamais d'une phase à l'autre, et chaque enfant lit le CLAUDE.md du projet, le prompt et le log de la session précédente. En fermant, il écrit le prompt suivant et déplace les pointeurs, et l'orchestrateur vérifie qu'il l'a fait.

Trois détails mesurés comptent davantage que la conception :

  • Un enfant headless ne se réveille pas. En mode -p, les tâches en arrière-plan sont tuées
  • au bout de 600 secondes sauf si CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MS=0 est exporté, et personne
  • ne relance un enfant qui « attend le moniteur ». Les gates longues tournent en arrière-plan avec
  • une boucle d'attente bornée qui positionne un drapeau explicite, jamais le $? d'une boucle, qui
  • renvoie le code de sortie du dernier sleep.
  • L'orchestrateur peut aussi se tromper lui-même. En fin de journée, pgrep -f chain-child.sh
  • a signalé un enfant encore vivant alors qu'il s'était terminé. Le motif correspondait à la
  • propre commande shell de l'orchestrateur, qui contenait la même chaîne. Nous sommes passés à une
  • correspondance sur le processus claude -p.
  • Un déploiement absent n'est pas un déploiement raté. Un après-midi, la production a servi
  • pendant quarante-cinq minutes un commit vieux de trois pushs. L'orchestrateur l'a signalé et a
  • demandé au CEO de regarder le panneau de déploiement. Dix minutes plus tard, la file s'était
  • vidée et tout était à jour. La règle que nous avons gardée : rapporter ce qu'on lit, et ne rien
  • conclure d'une seule lecture.

Partie 2 — Une doctrine écrite en une ligne, pas répétée dans chaque prompt

Le soir du 29, la position du propriétaire s'est durcie en une phrase que le CEO a transmise telle quelle :

« je ne veux plus prendre de décisions autres que ce qui est dans le legacy et que le proprio a l'habitude de voir »

Les clients du propriétaire aiment le copier-coller : si l'ancien menu affiche une entrée avec un suffixe entre parenthèses, le nouveau affiche exactement la même chose, parenthèses comprises.

Un enfant headless ne peut pas poser de question. La doctrine est donc entrée dans le CLAUDE.md du projet, dans la section que les enfants lisent pour décider seuls, comme règle de niveau 0 (l'appliquer, la citer, ne pas demander) :

  • les menus, libellés et noms de pages suivent le système legacy en production ;
  • quand deux systèmes legacy divergent, c'est le code qui écrit réellement en production qui
  • l'emporte ;
  • **quand le legacy a un défaut ou une limite manquante, appliquer les bonnes pratiques et le
  • consigner** ;
  • ne jamais copier un défaut qui touche à l'argent ou à la sécurité.

La troisième règle a prouvé sa valeur le soir même. Le système legacy avait un plafond sur le montant qu'une seule opération pouvait verser, mais un drapeau de configuration l'avait désactivé. La réaction du CEO tenait en une ligne : « il faut mettre une limite, sinon c'est dangereux. » Nous n'avons pas choisi un chiffre à l'intuition. Nous avons dimensionné le plafond à partir de l'historique de production, que le CEO a interrogé lui-même, en lecture seule, depuis la console de la base : le plus gros montant jamais versé, la distribution au-dessus, et la marge hebdomadaire de l'activité. La valeur par défaut du legacy aurait coupé 1 498 versements historiques réels : une bonne raison de ne pas copier la valeur, tout en rétablissant la limite.


Partie 3 — Un navigateur entre les mains du CEO, et ce qu'il ne peut pas prouver

Les enfants tournent en headless. Aucun ne voit d'écran. Chaque log de session de la journée se termine par la même ligne honnête : non vu dans un navigateur par un humain.

L'orchestrateur délègue donc une vérification après les sessions qui comptent, à un sous-agent qui pilote le Chrome du CEO lui-même via Claude in Chrome. Le CEO y est déjà connecté en admin. Le brief est court et strict :

  • Lecture seule. Aucun formulaire soumis, et aucun clic sur Confirmer, Créditer, Payer, Refuser
  • ou Supprimer. Sur les écrans qui touchent à l'argent, l'agent peut ouvrir une boîte de
  • confirmation pour lire les montants qu'elle annonce, puis doit l'annuler sans rien saisir.
  • Mesurer, pas capturer. document.title, h1, scrollWidth, l'attribut d'un bouton, deux
  • captures d'écran au maximum.
  • Rapporter en trente lignes : point par point, défauts classés par gravité, aucun correctif
  • de code.

Six de ces passes ont tourné dans la journée. Elles ont trouvé de vrais problèmes que les tests avaient manqués :

  • un tableau plus large de trois pixels que son conteneur, ce qui coupait la dernière colonne ;
  • un bouton de suppression resté dans une ligne de tableau, contre la règle qui veut que les
  • écritures vivent dans le pied de la modale ;
  • un bouton de confirmation resté actif alors que le champ du motif était vide ;
  • la recherche admin qui proposait des pages de l'espace client ;
  • un bloc de synthèse affichant zéro quand aucun filtre de date n'était posé, alors que la liste
  • en dessous affichait des dépôts.

Une passe a aussi signalé un défaut qui n'existait pas.

L'agent a indiqué que fermer une modale de détail laissait son identifiant dans l'URL, si bien qu'un rechargement la rouvrait. Il a testé de trois façons, et les trois ont échoué. L'enfant précédent avait déclaré le correctif « correct par construction » sans avoir pu reproduire le bug. La combinaison semblait accablante : un correctif que personne n'avait reproduit, et un vérificateur qui reproduisait le bug trois fois.

L'orchestrateur a rédigé une session pour le corriger, avec un test sur la vraie stack qui devait d'abord échouer. Puis il a demandé au CEO une vérification à la main de dix secondes : ouvrir une ligne, appuyer sur Échap, recharger. La modale est restée fermée.

L'onglet de l'agent était en visibilityState: hidden depuis le début. Les vraies frappes clavier n'atteignaient jamais la page, donc chaque geste avait été émulé en JavaScript. L'agent l'avait dit dans son rapport, mais l'orchestrateur n'en a pas tenu compte avant le test humain. La session de correction a été réécrite en garde-fou de régression : elle ajoute le test sur la vraie stack et ne modifie le code que si le test échoue. Le test est passé.

La leçon que nous avons gardée a deux moitiés :

  • Celui qui implémente ne devrait pas être celui qui vérifie. Un enfant qui « ne parvient pas à
  • reproduire » n'a rien prouvé.
  • **Un outil de vérification a ses propres limites, et un vérificateur qui les énonce doit être
  • cru.** Depuis ce jour, chaque brief dit : si l'onglet est masqué et que le clavier n'atteint pas
  • la page, émuler, le dire, et ne pas conclure à un défaut sur cette seule base. Quand un seul geste
  • tranche, dix secondes d'une main humaine valent mieux que n'importe quel outil.

Partie 4 — Un design system en une matinée, en passant d'abord par une maquette

Le propriétaire a envoyé une capture d'écran du nouvel admin, reconstruit la veille pour refléter la page legacy, et le rendu n'était pas bon :

  • trois titres empilés les uns sur les autres ;
  • un panneau de détail à droite qui mangeait le tableau, si bien que les dernières colonnes
  • sortaient de l'écran ;
  • des identifiants affichés seuls, sans les noms ;
  • une barre latérale où chaque entrée portait une description de trois lignes.

Le CEO a demandé de refaire le design « en tenant compte de toutes les fonctions du legacy ».

L'orchestrateur n'a pas envoyé un enfant redessiner l'admin. Un enfant codait dans les mêmes dossiers à ce moment-là, et un design est une décision que le propriétaire doit voir avant que quiconque ne le construise. Il a délégué à un sous-agent de design, avec deux livrables et aucun accès en écriture au dépôt :

  • Une spécification : principes, tokens, composants, et un tableau qui associe chaque défaut
  • observé à la règle qui le corrige. Elle s'appuyait sur les pages legacy lues via le même
  • navigateur et sur le code source, en lecture seule.
  • Une maquette HTML statique de la pire page, remplie avec les lignes exactes de la capture du
  • propriétaire, en largeur desktop et à 375 px.

Pendant que l'agent travaillait, le CEO a ajouté une phrase :

« l'onglet blanc à droite doit être un joli modal qui s'ouvre pour afficher plus de détails sur chaque ligne »

L'orchestrateur l'a transmise à l'agent en cours, qui a remodelé la spécification autour d'elle : le tableau garde toute la largeur, et les détails s'ouvrent dans l'unique primitive de dialogue qui existait déjà dans le projet.

La maquette s'est ouverte dans le navigateur du CEO, et il l'a validée. L'orchestrateur a ensuite désavoué l'agent de design sur un point, au nom de la doctrine. L'agent recommandait d'écrire la devise sous sa forme locale lisible. Le système legacy et le code existant écrivent tous deux le code ISO, et « copier ce que le propriétaire a l'habitude de voir » est une règle de niveau 0. L'orchestrateur ne désavoue pas un sous-agent sur une question de goût, seulement au nom d'une règle écrite.

La migration s'est ensuite déroulée en une série de sessions enchaînées :

  • S1, une page pilote : shell, barre latérale, tableau groupé, modale de détail, et un test
  • Playwright ajouté à la gate.
  • S2 : filtres et pagination numérotée partagés entre les pages de liste.
  • S3 : files de validation, où chaque bouton d'écriture est passé dans le pied de la modale,
  • derrière une confirmation.
  • S4a : les pages de compte et de détail.

Chaque passe navigateur a versé ses défauts dans le prompt de la session suivante. La dernière passe de la journée n'en a trouvé que trois, mineurs.


Partie 5 — « Ce sont les tests qui prennent le temps, pas les fixes »

En milieu d'après-midi, le CEO a proposé un raccourci :

« ce sont les tests qui prennent bcp de temps et non les fixes, exemple un fix peut prendre 5 mins et un test 1h, donc on va être très smart, on fixe bcp de bugs en série sans test et après on fait test groupé »

L'intuition méritait une mesure, pas un oui. L'orchestrateur a lu les horodatages des logs de chaque étape de la gate. La gate complète prenait quatre minutes : format, vet, tests Go, six vérifications front-end, build, tests navigateur et un smoke test de chaque page de menu contre la vraie stack. Une session entière prenait trente-cinq à quarante-deux minutes. La gate en représentait environ un dixième.

Le vrai coût était ailleurs, dans le surcoût fixe de chaque session et de chaque vérification :

  • la lecture du contexte ;
  • le rituel de clôture ;
  • une passe navigateur de dix minutes après chaque session.

La réponse a donc été moitié oui, moitié non :

  • Oui au regroupement. Cinq à dix défauts par session, une seule gate à la fin, une passe
  • navigateur toutes les deux ou trois sessions, plus une après tout ce qui touche à l'argent.
  • Oui à moins de nouveaux tests. Un nouveau test seulement pour l'argent, la sécurité, ou un
  • défaut déjà revenu une fois. Un libellé, un espacement ou un titre se corrige sans test dédié.
  • Non au push sans la gate. Ici, un push est un déploiement d'un système qui fait circuler de
  • l'argent. Quatre minutes contre une production rouge, ce n'est pas un arbitrage.

Le CEO a accepté, et la règle est entrée dans le CLAUDE.md du projet au niveau 0, si bien que chaque enfant suivant l'a appliquée sans qu'on le lui dise. La session suivante a corrigé huit défauts en une passe avec une seule gate. Sa première exécution était rouge sur une seule assertion, qui attendait l'ancien format de devise : c'était l'un des huit correctifs qui fonctionnait comme prévu.

Une autre mesure est sortie de la même journée. Une session consacrée à rembourser la dette de la gate a remplacé la préparation de la base à chaque test par une base template. Le package de tests Go est passé de 265 secondes à 59. La vitesse est venue de la correction de la partie lente, pas de l'abandon de la vérification.


Partie 6 — Une décision d'argent qu'un enfant a refusé de prendre

Une session en file devait reproduire un interrupteur du legacy : un dépôt fait par un agent pour un client peut être marqué « Available » ou « Not Available ». Le prompt disait : ne construire le bouton que si l'API supporte déjà cette écriture. Ce n'était pas le cas, et l'enfant s'est arrêté au bon endroit. Il a consigné une question de niveau 1, à laquelle un enfant ne doit jamais répondre lui-même, et expliqué pourquoi un simple drapeau ne suffisait pas.

Dans le nouveau système, ce dépôt est un transfert dans le grand livre qui a déjà eu lieu. L'agent a été débité, le client a été crédité avec un bonus, et le client a peut-être déjà dépensé l'argent. Un statut qui ne déplace aucun argent reproduirait exactement le genre de défaut que la doctrine interdit de copier. L'enfant a recommandé une contre-passation explicite : des écritures inverses exactes, un motif obligatoire et journalisé, et un refus si le solde du client ne la couvre plus.

Le CEO a validé en une ligne. La session suivante l'a construite :

  • Des écritures inverses exactes, lues dans le grand livre plutôt que recalculées aux taux du
  • jour.
  • Chaque poche restaurée à l'identique, quand l'agent avait payé depuis plusieurs.
  • Une seule transaction, avec une réservation unique pour que deux admins qui cliquent en même
  • temps ne produisent qu'une seule contre-passation.
  • Des tests sur le chemin de l'argent pour chaque cas.

Dans le navigateur, la boîte de confirmation montre les deux côtés du mouvement avant que quiconque ne confirme.

La même session a noté, dans sa liste de reports, qu'un transfert de solde entre clients envoyé au mauvais numéro de téléphone n'avait pas non plus de retour possible. L'orchestrateur a recommandé d'y étendre la contre-passation, pour une raison simple : un mauvais numéro arrivera en production. Le CEO a accepté, et une session plus tard c'était livré comme une fonction séparée. La première n'a pas été refactorisée pour l'occasion.


Partie 7 — « Je ne sais pas quand fermer une session »

En fin de journée, le CEO a demandé à l'orchestrateur d'afficher son usage de contexte et de le commenter. Les chiffres n'avaient rien de remarquable :

  • 287k tokens utilisés sur un million, 29 %, presque tout en conversation ;
  • environ 30k ajoutés sur le dernier bloc de travail ;
  • 680k tokens encore libres.

Ce qui comptait, c'était le peu que cela représentait. Treize sessions et six passes navigateur avaient chacune tourné dans leur propre processus ou contexte de sous-agent, et n'avaient renvoyé que leurs conclusions. Sans cela, l'orchestrateur aurait été compacté plusieurs fois.

Puis le CEO a avoué quelque chose que tout gros utilisateur de ces outils reconnaîtra :

« pour te dire la vérité je ne sais pas quand fermer et quand ouvrir une nouvelle session, vu que j'ai des tâches presque illimitées »

Avec une file sans fin, la file ne peut pas servir de signal. Le signal, c'est l'état du contexte. Nous avons écrit quatre conditions, et une seule suffit pour fermer :

  1. Un bloc de travail cohérent est terminé : poussé, fichiers d'état à jour. C'est le moment
  2. le moins cher, parce que la note de passation s'écrit toute seule.
  3. Le sujet change. Le contexte du premier sujet brouille le second.
  4. La session a déjà été compactée une fois. Un résumé suffit pour finir le bloc en cours, pas
  5. pour en commencer un nouveau.
  6. L'agent est pris en flagrant délit de croyance périmée : il s'appuie sur un état lu il y a
  7. des heures et qui a changé depuis. Celle-ci l'emporte sur tous les chiffres.

Les chiffres viennent en second : au-delà d'environ 300 à 400k tokens, ou de six à huit heures de travail, fermer à la prochaine frontière de bloc même si tout va bien. Et ne jamais fermer au milieu d'une boucle serrée « voir le défaut → corriger → revérifier » avec l'humain.

Fermer coûte peu parce que rien d'important ne vit dans la session. La file, le prompt suivant, les logs, la doctrine et la règle de regroupement sont tous sur disque. Une session neuve les lit en quelques minutes pour environ 30k tokens. Nous avons mis la règle dans le CLAUDE.md global et dans la mémoire persistante, avec une instruction qui la rend utile : *le rappeler soi-même à l'utilisateur, en une ligne, quand une condition devient vraie*. Nous avons aussi inversé une habitude : une compaction automatique imminente est désormais un signal pour fermer, pas pour compacter.


Comment reproduire cela

  1. Séparez l'orchestrateur des exécutants. La session à laquelle vous parlez arbitre, lance,
  2. surveille et vérifie. Chaque phase tourne dans un processus headless neuf qui ne connaît que le
  3. dépôt.
  4. Mettez la file et l'état sur disque, avec des pointeurs que l'orchestrateur peut vérifier
  5. mécaniquement après chaque phase : identifiant de session avancé, prompt suivant en file, arbre
  6. propre, poussé, production qui sert ce que vous croyez qu'elle sert.
  7. Écrivez la doctrine du propriétaire en une seule ligne de niveau décision dans le fichier
  8. que chaque enfant lit. Incluez la porte de sortie : « ne jamais copier un défaut d'argent ou de
  9. sécurité ; là où une limite manque, appliquer les bonnes pratiques et le consigner ».
  10. Donnez une échelle aux enfants : appliquer ce qui est pré-décidé, décider et consigner ce
  11. qui est réversible, s'arrêter sur l'argent, l'irréversible, le prix et le périmètre.
  12. Vérifiez dans un vrai navigateur avec un agent séparé en lecture seule, qui mesure plutôt
  13. qu'il ne capture. Demandez-lui d'énoncer les limites de son propre outil, et tranchez tout geste
  14. décisif isolé avec dix secondes d'une main humaine.
  15. Concevez via une maquette validée par le propriétaire avant qu'une session ne la construise,
  16. et ne désavouez un sous-agent qu'au nom d'une règle écrite, jamais d'un goût.
  17. Mesurez avant d'échanger des tests contre de la vitesse. Groupez les correctifs, lancez la
  18. gate une fois, n'écrivez de nouveaux tests que là où l'argent, la sécurité ou la récidive les
  19. justifient, et ne poussez jamais de code non vérifié qui se déploie.
  20. Écrivez quand fermer, et faites en sorte que l'agent le dise le premier.

CASP — le Coding-Agent State Protocol. Votre agent IA mène toute la feuille de route sans jamais perdre le fil. Natif git, 100 % local, sous licence MIT, zéro télémétrie. Conçu par Juste Thales Gnimavo, de ZeroSuite, un CEO solo dont les produits tournent en production avec Claude pour seul ingénieur. Installation : npm i -g @justethales/casp · https://casp.sh · https://github.com/ThalesGnimavo/casp
Share this article:

Responses

Write a response
0/2000
Loading responses...

Related Articles

Thales & Claude zerosuite

Une recrue qui n'écrit que des notes privées : brancher une IA sur un support client en production sans la laisser parler à un seul client

Un jour, un support client, 12 166 conversations passées : comment nous avons branché une IA sur un support Chatwoot en production, en mode brouillon uniquement. Elle écrit des notes privées, cite ses sources ou passe la main, lit les captures d'écran mais jamais les PDF, et chaque appel au modèle a un prix. Quatre audits, erreurs comprises.

28 min Sep 28, 2026
chatwootcustomer-supportragpgvector +9
Thales & Claude zerosuite

Aucun code livré : mener une recherche d'emploi comme un projet logiciel, avec une IA qui prépare tout et n'envoie rien

Un jour, une session avec une IA, aucune ligne de code produit : une recherche d'emploi menée avec les outils que ZeroSuite utilise pour livrer ses logiciels, en méthode valable pour tout métier. Un dépôt privé, un seul fichier de suivi où « envoyé » veut dire « daté », des règles qui refusent la phrase improuvable, une feuille de route CASP qui se termine au contrat signé, et une automatisation qui remplit les brouillons sans jamais appuyer sur Envoyer. Avec un guide pas à pas à télécharger.

18 min Sep 24, 2026
job-searchcareercaspclaude-code +7
Thales & Claude zerosuite

Ça marche, et ce n'est pas fini

Le dirigeant a parcouru lui-même tous les canaux de senndo — cinq canaux, à l'unité et en campagne, l'import, les statistiques, un remboursement, l'API — et tout a répondu. Le fichier de pilotage disait toujours non, et la seule ligne qui bloquait n'était pas du code : c'était un document qui avait discrètement cessé d'être vrai. Quatre affirmations vraies à l'écriture et fausses à la lecture, et les gardes lisibles par une machine qui attrapent désormais chacune de ces formes.

13 min Sep 14, 2026
senndocpaaslaunch-readinessdocumentation +8