Marketplace perso. Un plugin : flow — le cycle spec → design → implémentation → vérification → livraison, disponible dans tous les projets.
Le principe : ce qui rend un logiciel robuste, ce ne sont pas des avis d'experts, ce sont des portes — des étapes qu'on ne franchit pas tant que quelque chose de mesurable est rouge. /flow:verify est cette porte, et elle a le droit de dire non.
claude plugin marketplace add pymenvert/pym-workflow
claude plugin install flow@pym --scope user--scope user = disponible dans tous les projets.
Quand le dépôt est privé, git doit savoir s'identifier sur la machine :
- Windows — le gestionnaire d'identifiants installé par GitHub Desktop suffit. Rien à configurer.
- Ubuntu — GitHub Desktop n'existe pas pour Linux. Installer
gh(sudo apt install gh), puis lancergh auth loginetgh auth setup-git. Git réutilisera ces identifiants pour les dépôts privés, sans autre réglage.
La version de gh livrée par Ubuntu suffit. Vérifié le 4 septembre 2026 sur la tour : paquet noble/universe, gh 2.45.0, et les cinq appels que le plugin utilisait alors fonctionnent — repo view, api, pr list, pr create, run list. Trois autres sont venus depuis — pr checks, repo create, auth refresh — et restent à constater sur la tour. Depuis la version 0.12.0, plus aucune commande n'emploie de capacité apparue dans une version récente ; c'est l'objet de docs/decisions/0002-visibilite-par-api-et-porte-du-plugin.md.
| Commande | Rôle | Ce qu'elle empêche |
|---|---|---|
/flow:init-project |
Détecte la stack, écrit le profil projet, la fiche produit et la liste à faire avec toi, pose tests et CI | Un projet sans filet automatique |
/flow:spec <idée> |
Lit la fiche produit, place l'idée dans la liste à faire ; critères d'acceptation testables, hors-périmètre, cas limites | Construire la mauvaise chose |
/flow:design <spec> |
Architecture, attaquée par l'agent architect, tracée en ADR |
Le code qui devient intouchable |
/flow:new-feature <desc> |
Branche, plan court, petits lots, tests d'abord sur le critique | Le grand diff illisible |
/flow:verify |
La porte : les contrôles automatiques, puis les relecteurs que la tâche appelle — de un à cinq. Verdict PASSE ou BLOQUÉ | Livrer du cassé |
/flow:ship |
Commit atomique, push, PR, surveillance de la CI | Le « je corrigerai après » |
Les étapes intermédiaires savent s'effacer : sur une faute de frappe — mais pas sur un libellé qu'on lit à l'écran, qui est un texte exact d'une référence d'écrans —, /flow:spec va directement à /flow:new-feature — ou te le dit, en pas à pas — plutôt que de produire de la paperasse.
La règle de base : les commandes marquent des moments, elles ne remplacent pas la conversation. Entre deux commandes, on parle normalement — c'est même là que se prennent les décisions.
| # | Tu tapes | Ce qui se passe | Tes fichiers | Il s'arrête ? |
|---|---|---|---|---|
| 1 | /flow:spec <ton idée> |
Il lit ton code et ta fiche produit, pose trois questions maximum, place l'idée dans la liste à faire, écrit un document dans docs/specs/ |
1 fichier créé, 1 ligne ajoutée | seulement s'il a une question pour toi, ou si l'idée contredit un « ne doit jamais arriver » de la fiche |
| 2 | il enchaîne /flow:design |
Il propose une architecture et la fait attaquer par l'agent architect ; si la tâche change ce que tu vois, il dessine les écrans et les fait attaquer aussi. Puis il écrit la décision dans docs/decisions/ |
1 à 3 fichiers créés | seulement si un choix te revient — il te le pose alors dans une forme fixe, recommandation d'abord |
| 3 | il enchaîne /flow:new-feature |
Il crée la branche tout seul, explore le code, annonce un plan court, implémente par petits lots | il écrit ton code | seulement si le code contredit le cadrage |
| 4 | il enchaîne /flow:verify |
Les contrôles automatiques, les budgets de performance s'il y en a, puis les relecteurs que la tâche appelle : code-reviewer toujours, les quatre autres selon ce qui a changé. Corrige les bloquants. Rend PASSE ou BLOQUÉ, puis un compte-rendu pour toi |
il peut corriger | sur BLOQUÉ |
| 5 | il enchaîne /flow:ship |
Retire l'item livré de la liste à faire, enregistre, envoie, ouvre la pull request avec le compte-rendu, surveille la CI, te donne le lien | il enregistre | non |
| 6 | sur GitHub | Tu fusionnes, tu supprimes la branche, tu récupères la fusion sur ta machine | — | c'est toi qui fusionnes |
Entre deux étapes, un point de passage de trois lignes — fait, décidé ou constaté, commence — pour relire un fil de deux heures en trente secondes.
En rythme enchaîné — le défaut —, une commande ne s'arrête que pour l'une de ces quatre raisons, et elle la nomme :
- une réponse qui n'appartient qu'à toi : le besoin, la priorité, l'apparence, « est-ce fini ? » ;
- de l'argent ou un engagement : un service payant, un abonnement, un compte à ouvrir ;
- un acte irréversible ou public : la fusion sur la branche par défaut, l'étiquette de version, la mise en ligne, la visibilité, une suppression ;
- une porte rouge qu'elle ne sait pas rendre verte sans changer le besoin.
Chaque arrêt commence par « J'attends ta réponse. » et tu réponds dans la discussion, en français. Tu ne relances pas une commande. Un mot de toi dans le fil — « attends », « pas à pas » — l'emporte sur le profil pour la tâche en cours.
En pas à pas (ligne rythme du profil projet), les trois arrêts d'avant sont de retour : après les questions de /flow:spec, après la proposition de /flow:design, après le plan de /flow:new-feature — et c'est toi qui tapes la commande suivante. Un projet qu'on découvre peut le mériter ; un projet qu'on connaît ne le mérite plus. Le raisonnement est dans docs/decisions/0004-rythme-enchaine-et-quatre-raisons.md.
/flow:verify est la seule commande chère du cycle : elle lance toute la suite de tests et jusqu'à cinq relecteurs automatiques. Plusieurs minutes. En rythme enchaîné, elle tourne sans te demander : c'est le prix de ne pas attendre, et « attends » la retient. À la version, /flow:release lance le bilan de santé avec ses relecteurs : la version est chère, et c'est voulu.
Tout le reste répond en quelques secondes. /flow:guide est gratuit — il ne lance ni test ni agent — et c'est le bon réflexe quand on ne sait pas où on en est.
Le cycle complet sert aux tâches qui comptent. Pour le reste :
- Une faute de frappe, un libellé → directement
/flow:new-feature./flow:specy va lui-même plutôt que de produire de la paperasse. - Un défaut dont la définition de « terminé » est évidente →
/flow:new-featuresuffit. Une spec ne sert qu'à écrire ce qu'on ne sait pas encore. - Rien ne touche à la structure → saute
/flow:design. Il sert aux décisions qu'on regrette, pas aux modifications qu'on oublie. - « Ça plante quand… », un comportement qui a cessé →
/flow:new-featureen mode incident : il écrit la panne au journal, reproduit d'abord par un test qui échoue, corrige, garde le test, puis note la cause et la leçon.
En revanche, /flow:verify et /flow:ship ne se sautent jamais : ce sont eux qui empêchent de livrer du cassé.
Rien de ton travail ne vit dans la conversation. Le code est sur ton disque, la branche et la pull request sont sur GitHub. Ouvrir une conversation neuve ne perd que le fil de la discussion — jamais le travail. Il suffit de redire le contexte en trois lignes, ou de lancer /flow:guide, qui le reconstitue tout seul.
Quatre commandes ne servent pas à une tâche mais à une version, ou à la machine :
| Commande | Rôle | Quand |
|---|---|---|
/flow:audit |
Le bilan de santé de tout le programme : ce qui se répète au journal, la dérive lente, les dépendances en retard, ce que l'app dit d'elle-même qui est devenu faux | À chaque version, lancé par /flow:release |
/flow:mutation |
Casse le code exprès et exige que la suite tombe. La seule commande qui met en doute les tests plutôt que le code | Après une grosse vague de tests |
/flow:release |
CI verte exigée, bilan de santé, numéro annoncé, section du CHANGELOG.md écrite pour qui installe, ligne au journal, numéros cohérents, puis l'étiquette de version qui publie. Deux arrêts : une fonctionnalité visible annoncée au changelog et absente du manuel — seulement si le projet a un manuel —, puis l'étiquette elle-même |
Au moment de livrer une version |
/flow:visibilite |
Ouvre un dépôt privé le temps d'une campagne de CI coûteuse, puis le referme et le vérifie | Rare — et jamais sans lire ce qu'elle expose |
/flow:visibilite mérite un avertissement : rendre un dépôt public expose tout son historique, pas seulement son état actuel, et repasser en privé n'annule ni un clone, ni un fork, ni une mise en cache. La commande fouille l'historique à la recherche de secrets avant d'ouvrir, et refuse de considérer le travail fini tant qu'elle n'a pas vérifié la fermeture.
/flow:mutation mérite un mot : toutes les autres commandes font confiance à la suite de tests. Une suite verte n'est pourtant pas une preuve, c'est une affirmation. Casser le code délibérément est le seul moyen de la vérifier — et sur un projet où cette épreuve a été passée, elle a révélé que la suite était aveugle à quatre cassages réels. Comme la commande modifie du code source, git sert de filet : dossier propre exigé au départ, restauration par git checkout, et preuve par git status à l'arrivée.
Fusionner une pull request ne publie rien. Dans ce type de projet, c'est le tag vX.Y.Z qui déclenche la publication — et le workflow qui publie ne rejoue généralement pas les tests. Le tag est donc le point de non-retour : /flow:release existe pour que rien ne le franchisse sans avoir été vérifié.
Le cycle ne sert à rien si on ne sait pas où on en est. Quatre mécanismes s'en occupent, et aucun ne coûte cher :
Chaque commande — ou chaque chaîne de commandes — finit par trois lignes — Où on en est, Ensuite, Si tu hésites. Sauf /flow:guide, qui est le recours et ne peut pas se citer lui-même. Une seule action proposée, jamais deux options, jamais de « si » à arbitrer soi-même. Et si la commande s'est arrêtée en route, elle le dit là plutôt que d'annoncer un travail qui n'a pas eu lieu.
/flow:guide fait le point quand on est perdu ou qu'on reprend un projet trois semaines plus tard. Il lit l'état du dépôt en un seul appel groupé et nomme la seule commande à lancer. Il lui est interdit de lancer un test, un agent, un lint ou un build — c'est la commande gratuite du lot. Là où git ne permet pas de trancher, il pose une question au lieu de deviner : deviner enverrait relancer la porte, qui est la commande chère. Au repos, il propose le premier item de « Maintenant » de la liste à faire — jamais « ton idée » quand la liste en a une — et il ne propose plus de concevoir un cadrage qui a déjà sa décision : les deux se lisent dans son appel groupé, pas dans un appel de plus, et le banc du plugin les éprouve.
Une livraison qui attend se dit toujours. Les demandes de fusion ouvertes sont lues dans le même appel groupé, jamais derrière une condition : jusqu'à la 0.21.4 cette lecture ne se faisait que si le dossier était propre, et un seul fichier posé par un autre outil suffisait à cacher une livraison qui attendait depuis la veille.
/flow:guide <mot> explique un mot en trois lignes et un exemple tiré de ton projet — « ça veut dire quoi ? », le même recours que « je fais quoi ? ». Chaque mot de sa liste y a le sens précis que flow lui donne ; les autres s'expliquent en termes généraux.
Le bloc « Boussole », écrit par /flow:init-project dans le CLAUDE.md du projet, capte les questions posées en français — « et maintenant ? », « je fais quoi ? », « c'est fini ? » — et y répond comme /flow:guide. C'est le mécanisme le plus utile des quatre, parce que c'est ainsi qu'on demande son chemin en vrai : pas en tapant le nom d'une septième commande.
Deux règles complètent l'ensemble : chaque arrêt commence par « J'attends ta réponse », et tout passage long et muet — agents, tests, surveillance de la CI — est annoncé avec sa durée. Un silence long ressemble à un plantage, et le réflexe est alors de taper une autre commande.
La porte relit ce que la tâche avait promis. Depuis la 0.21.4, /flow:verify retrouve le cadrage — par le nom de la branche, sinon par la ligne Spec : de la décision — et donne à chaque critère d'acceptation son état : tenu, non tenu, non vérifiable, ou sans objet quand il ne concerne pas cette branche. Un critère non tenu est un refus. Sans ça, ce qui entrait par /flow:spec n'était plus jamais comparé à ce qu'il promettait.
Et le nom de la branche de référence se cherche. Il était écrit en dur à six endroits : sur un dépôt qui l'appelle autrement — trunk, develop, ou simplement master, que git init fabrique encore —, git rendait une erreur et rien du tout, et la porte en déduisait « rien à vérifier » sur du vrai travail. Depuis la 0.21.7, la recherche est écrite une seule fois, sous forme exécutable, dans /flow:guide ; les autres commandes y renvoient. Et quand aucun candidat ne répond, le plugin dit qu'il ne sait pas et lance ses vérifications quand même — une sortie vide n'est jamais un zéro.
docs/journal.md, dans chaque projet : une ligne par événement, ajoutée par les commandes, jamais réécrite — une panne corrigée ajoute une ligne pour le même objet, elle n'en modifie pas. Quatre types — porte (checks, bloquants réels par relecteur, non vérifié, durée, jetons, et la mesure de performance quand le profil a un budget), livraison (branche, ce que ça change), incident (quoi, cause, leçon), version (numéro, bilan). Tu n'as rien à taper : /flow:verify, /flow:ship, /flow:new-feature et /flow:release l'écrivent. /flow:audit le lit et en tire deux chiffres, par une seule commande : le rendement de chaque relecteur, et les incidents par version — le seul chiffre qui dit si la porte protège. Un relecteur à zéro sur dix portes devient rare ; on ne le supprime pas. Ces chiffres sont déclarés par la porte elle-même : ils mesurent son accord avec ses relecteurs, pas la vérité (docs/decisions/0005-le-journal-et-le-bilan-de-sante.md). Le registre docs/reste-a-faire.md ne garde plus que ce qui est ouvert.
/flow:init-project écrit dans le CLAUDE.md du projet un bloc que toutes les autres commandes lisent :
## Profil projet
- type : cli | desktop | web | service | script
- stack : <langage + framework>
- format / lint / typecheck / test / build / run : <commandes réelles>
- rythme : enchaîné | pas à pas
- cibles / temps réel / matériel / performance / journaux : <ce que le projet livre, et à qui — voir ci-dessous>
- critique : <modules à couvrir en priorité>L'adaptation est donc écrite une fois, pas redevinée à chaque session. C'est ce bloc qui dit à /flow:verify quoi lancer, et à ux-reviewer s'il doit juger un --help, une fenêtre ou une page web.
Règle d'or : chaque commande du profil doit avoir été exécutée avec succès au moment où elle y est inscrite. Une commande écrite au jugé rendrait la porte mensongère. rythme est la seule ligne sans vérité extérieure : rien ne la lance, elle se lit — et absente, c'est enchaîné.
Cinq clés disent ce que le projet livre, et à qui. Chacune entre avec un lecteur et une façon de se vérifier — une ligne que rien ne lit ni ne vérifie n'entre pas, c'est la règle de docs/decisions/0002-visibilite-par-api-et-porte-du-plugin.md :
| Clé | Ce qu'elle dit | Qui la lit | Comment elle se vérifie |
|---|---|---|---|
cibles |
les systèmes et versions minimales visés | ux-reviewer, qui dit sur quel système la première exécution se juge ; /flow:release au lot 7 |
à la construction — d'ici là, déclarée |
temps réel |
le protocole ou l'appareil qui impose une cadence — Art-Net, sACN, MIDI, LiDAR | /flow:spec, qui ajoute alors une section « Conditions réelles et performance » |
à l'endurance, lot 8 |
matériel |
les appareils externes, chacun avec ou sans simulateur | /flow:spec, qui écrit « sans simulateur » comme un manque dans cette section |
à l'endurance, lot 8 |
performance |
des budgets, chacun un chiffre et sa commande de mesure | /flow:verify, à chaque porte — dépassé, c'est rouge ; /flow:spec |
mesurée, et la mesure va au journal (perf :) |
journaux |
où le logiciel écrit ses journaux sur disque, ou « aucun » | /flow:verify, à chaque porte, comme un item du socle |
bloquante si rien, dans le projet, ne dit à l'utilisateur où les trouver |
Trois autres attendent le lot qui les lira : distribution (lot 7), déploiement et sauvegardes (lot 9) — et ces deux-là ne seront jamais lancées pour être vérifiées, mettre en ligne est un acte public. Une ligne absente vaut « aucun » : rien à migrer. Le raisonnement est dans docs/decisions/0006-le-profil-etendu-la-fiche-produit-et-la-liste-a-faire.md.
La liste de ce qu'un projet doit avoir selon son type, pour ne jamais la rediscuter. Elle vit dans le plugin, trois grilles de type et une surcouche, et trois commandes la lisent : /flow:init-project en fait un bilan, /flow:verify juge l'item que la tâche touche, /flow:release liste ce qui manque encore avant de publier.
plugins/flow/socles/commun.md— ce que tout projet doit, quel que soit son type ; il porte aussi les verdicts et la forme d'un item.plugins/flow/socles/ligne-de-commande.md— pour les typesclietscript, une seule grille pour les deux : ton plan n'en fait qu'un titre, et deux fichiers auraient divergé.plugins/flow/socles/desktop.md— pour le typedesktop.plugins/flow/socles/temps-reel.md— s'ajoute quand la lignetemps réelou la lignematérieldit autre chose que « non » ou « aucun ».
Les grilles web et serveur ne sont pas encore écrites : un projet de ces types reçoit la grille commune, et la commande te le dit plutôt que de se taire.
Quatre verdicts, pas trois : présent · manquant, qui devient une puce de la liste à faire · non vérifié, quand il faudrait lancer le logiciel pour savoir · sans objet, parce que …, quand l'item n'a pas de sens ici. Le quatrième évite qu'un projet en markdown rende six lignes rouges qui ne deviendront jamais des tâches.
Chaque item dit ce qu'il est, ce qu'on risque sans lui, ce qu'il coûte à poser, et comment on le constate — un item sans façon de le constater n'entre pas dans une grille. Si le dossier du plugin est introuvable, les commandes disent laquelle des deux pannes s'est produite et continuent sans grille : jamais un bilan vide présenté comme « rien ne manque ». Le raisonnement est dans docs/decisions/0009-le-socle-par-type-de-projet.md.
Un logiciel sans manuel n'est pas fini, il est seulement compilé. /flow:init-project propose un manuel — docs/manuel.md, dont le nom, les cinq titres et la règle sont écrits une seule fois, en tête de la grille commune du socle —, à cinq titres fixes — installation · première exécution · cinq minutes pour découvrir · ce que le logiciel sait faire · dépannage —, seulement si quelqu'un d'autre que toi installe le logiciel : c'est la ligne cibles du profil qui le dit. Si tu es le seul, il te l'écrit et ne propose rien — le README tient ce rôle, et deux documents pour le même lecteur divergent toujours sans que personne les compare. Ce dépôt-ci est dans ce cas.
À la version, /flow:release compare la section du changelog au manuel : une fonctionnalité visible annoncée et absente du manuel arrête la publication — raison 1. Il te propose la ligne rédigée, tu tranches le ton : c'est la voix de ton produit vers ceux qui l'installent, elle n'appartient qu'à toi. Le manuel entre dans l'enregistrement de version — le commit, la sauvegarde datée du travail — avec les numéros, le changelog et la ligne de journal, pour que trois phrases oubliées ne coûtent pas un cycle complet un soir de veille de spectacle. Pas de manuel, pas de changelog, ou une version qui ne corrige que l'intérieur : c'est dit en une ligne et ça continue.
ux-reviewer gagne la même préoccupation côté écran : quand le projet a un manuel, il vérifie que l'aide intégrée — aide en ligne de commande, « À propos », aide d'un site — dit la même chose, dans les deux sens. Le bilan de santé ne la refait pas : sa question 3 la lui délègue.
L'accueil pose aussi la vérification des licences des dépendances, si le projet en a : elle dit si l'une d'elles interdit ce que tu veux faire de ton logiciel, et c'est le genre de chose qu'on découvre trop tard. Sans dépendance, « sans objet » — un automate qui n'a jamais rien à dire finit par être ignoré quand il parle.
Depuis la 0.21.0, /flow:audit rend ses indicateurs deux fois : ceux d'aujourd'hui, puis les mêmes tels qu'ils étaient à la version précédente. La différence est ce qui compte — un instantané cache une dérive lente. Le calcul lui-même n'a pas changé d'un octet : il tourne une seconde fois sur le journal arrêté à la dernière ligne version. Une seule version au journal, ou aucune : « première mesure, pas de tendance », jamais une flèche inventée. S'y ajoute la fraîcheur du manuel — touché depuis la version précédente, oui ou non. Le raisonnement est dans docs/decisions/0010-le-redacteur-et-l-entretien.md.
Deux fichiers courts, écrits avec toi par /flow:init-project — ce sont les deux seuls arrêts de plus qu'il fait, parce que le besoin et la priorité n'appartiennent qu'à toi :
docs/produit.md, la fiche produit — vingt à trente lignes : pour qui, dans quelle situation, mieux que quoi, ce qui ne doit jamais arriver, plateformes, contraintes./flow:spec,/flow:design,ux-revieweret le bilan de santé la lisent avant tout ; une idée qui contredit un « ne doit jamais arriver » arrête/flow:spec, et c'est toi qui tranches — l'idée, ou la fiche.docs/a-faire.md, la liste à faire — trois paliers, « Maintenant », « Ensuite », « Un jour », une ligne par item avec son pourquoi./flow:guide, au repos, en propose le premier item ;/flow:specy place chaque idée qu'il cadre, avec le chemin de son cadrage ;/flow:shipretire ce qu'il livre ; le bilan de santé dit si la liste décrit encore le produit. Le registredocs/reste-a-faire.mdgarde son rôle : ce qui est cassé, pas ce qui est à construire.
Sur un projet déjà équipé, /flow:init-project va droit à ce qui manque — la fiche, la liste, les cinq clés, le bilan de socle, les automates de sécurité — sans refaire ses dix étapes.
| Agent | Son objet | Quand |
|---|---|---|
architect |
Le dépôt entier : point de rupture, couplage, dérive | /flow:design, puis dès qu'un fichier grossit |
code-reviewer |
Ce que ce lot introduit : correction, textes, conventions | Toujours |
test-engineer |
Ce qui n'est pas couvert, et la tenue en conditions réelles | Dès que de la logique change |
ux-reviewer |
Ce que l'utilisateur voit : la référence d'écrans avant le code, puis l'interface rendue | À la conception dès qu'une tâche change ce qu'on voit ; à la porte si l'interface ou ce qui construit l'exécutable a changé ; au bilan de santé, sur l'interface complète |
securite |
Ce qu'un attaquant peut faire faire au logiciel : menaces, secrets, injections, failles connues, posture | À la conception d'une tâche exposée, à la porte quand la surface a changé, au bilan de santé |
Ils se partagent le travail par objet, pas par vocabulaire. Deux agents peuvent regarder la duplication sans faire doublon : code-reviewer celle que ce lot ajoute, architect celle du dépôt. Chacun porte un bloc « Ce que tu ne fais pas » qui nomme le propriétaire des sujets voisins, et deux contrôles du vérificateur les tiennent : l'un exige que ce bloc existe, l'autre refuse qu'un sujet réservé soit repris ailleurs sans citer son propriétaire dans la même phrase. C'est une vérification de forme, pas de sens : elle attrape le doublon qui revient par distraction, pas celui qu'on écrirait exprès. C'est l'objet de docs/decisions/0003-un-proprietaire-par-preoccupation.md.
Chaque rapport s'ouvre par trois lignes pour toi, sans terme non traduit — ce que l'agent a regardé, ce que ça change pour ton logiciel, ce qu'il recommande —, avant ses constats écrits pour le studio, avec fichiers et lignes. /flow:verify recopie ces lignes dans son compte-rendu.
Dès qu'une tâche change ce que tu vois, /flow:design écrit une référence d'écrans — un fichier texte dans docs/ecrans/, nommé comme le cadrage, à cinq titres toujours les mêmes : les écrans (zones, éléments, textes exacts), le parcours (d'où on vient, où on va, combien de gestes), les trois états de chaque écran (vide, en cours, en erreur), le clavier, et pour un outil de régie : sombre, gros, lisible à deux mètres, un geste pour tout couper. Un titre vide est un manque visible, et c'est ce qui permet de l'attaquer.
ux-reviewer l'attaque alors avant que rien soit codé : ce qui manquera, ce qui confondra, ce qui ne se lira pas à taille réelle, ce qui exclut quelqu'un. Puis la conception te montre les écrans dans la forme « Décision » et s'arrête — l'apparence n'appartient qu'à toi : tu tranches le goût, le studio a tranché la cohérence. Seulement la première fois que cet écran apparaît ; une retouche d'un écran déjà tranché se verra à la porte.
À la porte, le même agent juge le rendu contre cette référence : « l'état vide prévu au point 3 n'existe pas » vaut cent fois « il manque un état vide ». Ce qui n'y était pas prévu est une amélioration — sauf les trois états et le clavier, qui restent bloquants même absents de la référence : une référence incomplète est un défaut de la référence, jamais une permission.
Une charte visuelle par projet, écrite une fois dans docs/charte-visuelle.md — une échelle d'espacements, trois tailles de texte, des couleurs dont le contraste est mesuré, l'apparence des états d'un bouton. La cohérence fait « pro » avant tout le reste, et c'est le studio qui la tient ; le goût t'appartient, la charte t'est proposée, pas imposée. C'est l'objet de docs/decisions/0008-les-ecrans-dessines-avant-le-code.md.
Chacun a l'ordre explicite de ne rien dire quand il ne trouve rien. Un rapport vide est un résultat — sauf pour ux-reviewer en contexte B et securite, les deux dont un rapport court peut vouloir dire « je n'ai pas pu regarder » — devant une référence d'écrans, il n'y a rien à lancer, et ce n'est pas un « pas pu ». Ils doivent alors le dire en toutes lettres, et /flow:verify le porte dans sa section « non vérifié » plutôt que de le prendre pour un feu vert. Pour securite, un outil qui manque n'est pas « je n'ai pas pu regarder » : il a regardé avec sa grille, et il dit quelle mesure lui a manqué.
Deux choses que personne ne regardait, et que la version 0.14.0 a rattachées à leur propriétaire naturel : la tenue en conditions réelles (l'appareil qui disparaît en cours de route, la reprise sans redémarrage, l'arrêt d'urgence) va à test-engineer · la première exécution sur une machine nue et ce que l'opérateur voit quand ça casse en direct vont à ux-reviewer. Sans agent supplémentaire.
Le cinquième agent, securite, est le seul qui pense comme un attaquant quand les quatre autres pensent comme une panne — c'est ce qui justifie un agent de plus, montré et non affirmé dans docs/decisions/0007-un-cinquieme-relecteur-la-securite.md. La sécurité intervient à quatre moments, lui à trois :
| Moment | Ce qui se passe | Coût |
|---|---|---|
| Conception | /flow:design le convoque quand la tâche est exposée — un site, un serveur, un outil qui écoute le réseau — ; il écrit le modèle de menace en quinze lignes, section « Menaces » de la décision |
un appel d'agent, sur les tâches exposées seulement |
| Chaque envoi | .github/workflows/securite.yml, posé par /flow:init-project : gitleaks, épinglé, fouille tout l'historique que GitHub connaît — branches et étiquettes comprises — et rend rouge tant qu'un secret y reste, avec un témoin qu'il doit voir à chaque passage ; les failles connues des dépendances avec l'outil de la pile ; le robot de mise à jour ; et ce que GitHub offre gratuitement quand le dépôt est public, mesuré plutôt que supposé |
des minutes de machine, zéro jeton |
| Porte | /flow:verify lance /security-review, la revue livrée avec Claude Code, puis convoque securite avec son rapport quand la surface a changé — au sens de sa liste, la seule —, et toujours pour le web et les serveurs ; code-reviewer lui tend la main pour ce qu'il voit dans le diff |
un agent, quand la surface a changé |
| Version | /flow:audit le convoque pour la posture : failles connues, dernier résultat de l'automate, ce qui est exposé, ce qui a changé |
via le bilan de santé |
Ce que ça ne promet pas : un test d'intrusion humain. Pour une application qui manipule de l'argent ou des données sensibles, un studio le commande à un tiers ; le plugin te le dira, il ne le remplacera pas. Et un secret déjà parti dans un commit se traite dans l'ordre — révoquer, remplacer, puis seulement nettoyer — et se note au journal.
Ce plugin n'installe aucun hook. Le formatage se fait au passage de la porte : /flow:verify lance la commande format déclarée dans le bloc « Profil projet » du projet, et le résultat apparaît dans son tableau de vérification.
La commande format du profil est celle qui vérifie (prettier --check), jamais celle qui écrit. C'est ce qui permet à /flow:verify de démarrer ses checks sans rien te demander : un check ne modifie rien. Si elle est rouge, la porte lance alors la variante qui écrit — mais en tant que correction, annoncée comme telle, et soumise à la règle « jamais directement sur la branche par défaut ».
Un hook de formatage a existé jusqu'à la 0.10.1. Il a été retiré pour deux raisons : aucun projet n'avait adopté de formateur, donc il n'avait jamais rien produit — et il était la seule pièce du plugin qui ne fonctionnait pas sous Linux. Le raisonnement complet, avec les quatre impasses d'implémentation qu'il aura coûtées, est dans docs/decisions/0001-hook-de-formatage-portable.md.
Pour formater un projet : pose-lui un .prettierrc (ou l'équivalent de sa stack) et déclare la commande format dans son Profil projet. /flow:verify s'en chargera, sur toutes tes machines. Le style d'un projet appartient au projet — c'est aussi pour ça qu'il n'a rien à faire dans un plugin installé pour tous.
Nouveau projet : /flow:init-project une fois.
Puis, par tâche : /flow:spec → /flow:design → /flow:new-feature → /flow:verify → /flow:ship.
Entre deux tâches sans rapport : /clear.
Ce que ce cycle ne promet pas : « zéro bug ». Ça n'existe pas. Ce qu'il change, c'est quand les bugs apparaissent — attrapés par une machine en trente secondes plutôt que par toi trois semaines plus tard.
Un plugin qui prêche « une porte qui a le droit de dire non » et n'en a aucune sur lui-même finit par dériver — il est passé de 3 à 11 commandes en huit jours, et tous les défauts trouvés à la main jusqu'ici étaient détectables mécaniquement.
sh scripts/verifier-le-plugin.shQuelques secondes, aucun réseau sauf pour comparer la version. Ce qu'il contrôle : le bloc de fin partagé, présent et identique dans les dix commandes qui le portent · chaque commande citée par le README et par la description de la marketplace, et réciproquement · le frontmatter de chaque commande (sans lui, elle disparaît de l'autocomplétion) · chaque agent avec ses outils déclarés, sans Edit ni Write, et tous ceux que /flow:verify convoque bien présents · les deux manifestes valides, cohérents, et pointant vers un plugin qui existe · la version bumpée — jamais égale, jamais en recul · les chemins du dépôt cités par le README · aucun appel gh dépendant d'une version · aucun reste PowerShell · les scripts forcés en LF, sans quoi Windows refuse de les lancer · une préoccupation chez un seul propriétaire, et chaque agent qui dit ce qu'il ne fait pas · chaque agent dont la ligne « name: » correspond à son nom de fichier, sans quoi personne ne répondrait à sa convocation · les grilles du socle que le plugin désigne, présentes et non vides, chacune de leurs lignes gardant son « comment on le constate », et les trois commandes qui les lisent qui ne cessent pas de le faire · aucun $ suivi d'un chiffre dans une commande — Claude Code le remplacerait par un mot de l'argument, et le calcul se tairait.
Il ne dit jamais « vert » d'un contrôle qu'il n'a pas pu lancer : ceux-là ressortent IGNORÉ, comptés à part. Et il les lance tous avant de conclure, plutôt que de s'arrêter au premier rouge — découvrir un seul défaut par exécution est le meilleur moyen de faire abandonner à la troisième.
sh scripts/eprouver-le-verificateur.shUne porte verte n'est pas une preuve, c'est une affirmation. Ce banc casse le dépôt exprès — un défaut à la fois, chacun dans une copie jetable — et exige que le bon contrôle tombe à chaque fois. Il pose aussi la réciproque, sans laquelle un contrôle qui rougirait sur tout passerait chaque cas avec les félicitations : un changement légitime doit laisser la porte verte.
Il éprouve aussi les deux calculs que des commandes embarquent — celui de /flow:audit sur un journal connu, ceux de /flow:guide sur une liste à faire et des cadrages connus — parce que ce sont les seules lignes de logique du plugin qui tournent chez toi. C'est /flow:mutation appliqué d'avance, et il a déjà servi deux fois. Écrit avant les corrections qu'il justifiait, six de ses cas passaient alors au vert. Puis ses propres relecteurs y ont trouvé qu'une variable non initialisée le faisait répondre « attrapé » à tout : ses vingt-quatre cas ne prouvaient rien. Il refuse désormais de compter un cas qui n'a pas tourné, distingue un contrôle IGNORÉ d'un trou, vérifie que la mutation a bien changé quelque chose, et lit le code de sortie de la porte autant que son texte.
Les deux scripts forment ensemble la commande test du Profil projet — donc ce que lance /flow:verify — et exactement ce que rejoue .github/workflows/ci.yml à chaque poussée. Deux définitions du mot « vert » finissent toujours par diverger. À côté, .github/workflows/securite.yml est l'automate des secrets du dépôt lui-même — le plugin applique ce qu'il pose ailleurs, sauf le robot de mise à jour : chacune de ses propositions serait rouge au contrôle 6, faute de montée de version.
Le plugin a un cap écrit : docs/plan-studio.md. Son tableau d'avancement, en tête, dit l'état de chaque lot — à faire, livré, constaté — ; sa section 13 liste les choix qui reviennent à l'auteur. Ce qui vient ensuite n'a qu'un endroit, docs/a-faire.md, la liste à faire de ce dépôt, comme pour n'importe quel projet. La règle qui va avec : aucun lot sur ce dépôt sans un item de ce plan ou une app réelle qui le justifie. Le lot 1 — le rythme enchaîné et la pédagogie — est dans la 0.15.0, le lot 2 — le journal, le mode incident, le bilan de santé — dans la 0.16.1, le lot 3 — le profil étendu, la fiche produit, la liste à faire — dans la 0.17.1 (la 0.17.0 n'a pas été étiquetée), le lot 4 — l'expert sécurité et ses automates — dans la 0.18.1, le lot 5 — les écrans dessinés avant le code — dans la 0.19.1, le lot 6 — le socle par type de projet — et le lot 10 — le rédacteur et l'entretien — dans l'étiquette qui suit ; aucun des sept n'est « constaté » tant qu'une tâche réelle n'a pas traversé la chaîne sur une app.
Quatre étapes, dans cet ordre. Les deux premières sont contre-intuitives et sautent silencieusement si on les oublie.
- Modifier le repo, puis bumper
versiondansplugins/flow/.claude-plugin/plugin.json. Ce champ épingle le plugin : tant qu'il ne change pas, aucune mise à jour n'est proposée, même si le dépôt distant a changé. Sans bump, tout le reste est sans effet. - Commit et push.
/plugin marketplace update pym, puis/plugin update flow@pym. (L'auto-update en arrière-plan peut échouer sur un dépôt privé en HTTPS ; la mise à jour manuelle utilise tes identifiants et fonctionne toujours.)- Ouvrir une NOUVELLE conversation. Les plugins sont lus au démarrage d'une conversation, une fois pour toutes. Une discussion déjà ouverte gardera pour toujours la liste de commandes qu'elle avait à sa naissance — redémarrer l'application n'y change rien, elle reste accrochée à sa session d'origine.
Pour vérifier qu'une mise à jour a bien pris, taper /flow: dans une conversation neuve : les onze commandes doivent apparaître dans l'autocomplétion.
~/.claude/settings.json — bloquer les fichiers sensibles partout :
{
"permissions": {
"deny": [
"Read(**/.env)",
"Read(**/.env.*)",
"Edit(**/.env)",
"Edit(**/.env.*)"
]
}
}Trois précisions qui comptent :
- Écrire
Read(./.env)serait une erreur : la forme./est ancrée au dossier courant et ne bloquerait niconfig/.envnipackages/api/.env. La forme**/.envsuit la syntaxe gitignore et couvre toutes les profondeurs. - Une règle
denysurReadbloque aussiEditetWritesur le même chemin. Les règlesEditrestent utiles : elles couvrentNotebookEdit, queReadne couvre pas. - Ces règles s'appliquent aux outils fichiers de Claude et aux commandes Bash reconnues (
cat,head,sed…). Elles ne bloquent pas un script Python ou Node qui ouvrirait le fichier lui-même.
~/.claude/CLAUDE.md — règles universelles :
## Git
- Jamais de travail direct sur main : une branche dédiée par tâche.
- Commits atomiques et descriptifs.
- Jamais de secrets, .env ou tokens dans le code, les commits ou les prompts.
## Méthode
- Comprendre l'existant avant de modifier ; plan court avant toute grosse modification.
- Lancer format / lint / typecheck / tests avant de livrer.
- Préférer la solution la plus simple qui respecte l'architecture.Par repo : entire enable --agent claude-code. Les sessions (prompts, transcripts, appels d'outils) sont stockées dans une branche cachée et poussées avec le repo → à réserver aux repos privés.