# Maedow Flow Un workflow de développement pour construire des applications solides avec des agents IA. Site : https://maedow-flow.vercel.app Ce fichier rassemble le corpus entier. Il est dérivé du dépôt à chaque publication, jamais recopié à la main : il ne peut pas se périmer sans que le corpus se périme aussi. ======================================================================== # Manifeste ======================================================================== Un workflow de développement pour construire des applications solides avec des agents IA, du premier prompt jusqu'à la production. Web, mobile ou desktop. ## Le problème Un agent IA écrit du code plus vite que n'importe qui. Livré à lui-même, il invente les décisions qu'on ne lui a pas données, élargit le périmètre au passage, déclare fini ce qu'il n'a pas vérifié, et oublie d'une session à l'autre ce qui avait été tranché. Le résultat tient en démonstration et casse en production. Maedow Flow ne rend pas l'agent plus intelligent. Il fixe l'ordre des choses : ce qui se décide avant de coder, ce qui se prouve avant de fusionner, et ce qui ne se fait jamais. ## Six principes 1. **Décider avant de construire.** Un choix coûteux à défaire (schéma de données, authentification, paiement, fournisseur, structure du code) s'écrit avant la première ligne. Le reste se décide en construisant. 2. **Une chose à la fois.** Un lot livre une capacité, et une seule. L'application grandit par tranches vérifiées, jamais d'un bloc. 3. **Prouver, pas affirmer.** « Les tests passent » ne veut pas dire « ça marche ». Fini veut dire constaté sur l'application qui tourne. 4. **Ce qui doit arriver est une machine.** Une règle sans exception devient un hook, une permission ou un contrôle de CI. Une consigne écrite n'est qu'un rappel, et un agent peut l'oublier. 5. **La complexité se mérite.** Pas de cache, de file d'attente ou de microservice sans le goulot mesuré qui les réclame. Pas de skill ni de sous-agent de projet avant que le projet en ait eu besoin. 6. **La mémoire est écrite.** Ce qu'il faut savoir d'une session à l'autre vit dans le dépôt (`AGENTS.md`, le scope, les specs), jamais dans la seule conversation. ## Les rôles | Rôle | Titulaire | Responsabilité | | :--- | :--- | :--- | | Product owner | l'humain | Décide du produit, valide le scope et les specs, fusionne les pull requests. | | Lead tech | l'agent en posture de cadrage (`/scope`, `/architect`, `/check review`) | Découpe, décide, relit. N'écrit pas le code applicatif. | | Dev | l'agent en posture de construction (`/develop`, `/test`, `/debug`) | Exécute ce qui a été décidé, et rien d'autre. | Les deux postures peuvent être tenues par la même session. Ce qui compte, c'est de savoir laquelle on occupe. Un désaccord de fond entre le cadrage et la construction remonte à l'humain, les deux positions résumées : personne ne tranche à sa place. ## Ce que Maedow Flow réunit | Brique | Ce qu'elle apporte | Où la lire | | :--- | :--- | :--- | | Le cycle | Les phases, les portes à franchir et le palier d'exigence de chaque feature | [Cycle](https://maedow-flow.vercel.app/docs/cycle) | | Les règles | Dix-sept règles codées `MF-001` à `MF-017`, chacune avec ce qui la fait respecter | [Règles](https://maedow-flow.vercel.app/docs/regles) | | Le moteur | Les skills `/scope`, `/architect`, `/develop`, `/check`, `/test`, `/debug`, `/sync`, `/audit`, `/document` | [Claude Code](https://maedow-flow.vercel.app/docs/claude-code) | | Le kit | `AGENTS.md`, garde-fous Claude Code, hooks git, CI GitHub, installés par `/flow` | [Démarrer](https://maedow-flow.vercel.app/docs/demarrer) | | Les profils | Les stacks par défaut pour le web, le mobile et le desktop | [Plateformes](https://maedow-flow.vercel.app/docs/plateformes) | | Les socles | La sécurité minimale, et ce qu'il faut pour ne pas tomber sous la charge | [Sécurité](https://maedow-flow.vercel.app/docs/securite), [Tenir la charge](https://maedow-flow.vercel.app/docs/echelle) | | Les prompts | Les formulations éprouvées pour chaque moment du cycle | [Prompts](https://maedow-flow.vercel.app/docs/prompts) | L'architecture du code relève d'un standard séparé, [Maedow Arch](https://maedow-arch-docs.vercel.app/llms.txt), pour les projets TypeScript. Maedow Flow dit comment on travaille ; Maedow Arch dit comment le code est rangé. ## Ce que Maedow Flow n'est pas - **Un générateur d'application.** Il ne choisit pas la stack à ta place. Il fournit des défauts éprouvés que `/architect` discute projet par projet. - **Un remplaçant des skills.** Les skills de [JavaScript-Mastery-Pro/skills](https://github.com/JavaScript-Mastery-Pro/skills) sont le moteur. Maedow Flow les ordonne, et comble ce qu'ils ne couvrent pas : les règles non négociables, les garde-fous mécaniques, les défauts de plateforme. - **Un texte figé.** Une règle qui résiste à la réalité se corrige, et la correction prend une ligne au `CHANGELOG.md` qui dit pourquoi. ## Par où continuer Une IA qui découvre ce workflow lit, dans l'ordre : [Démarrer](https://maedow-flow.vercel.app/docs/demarrer), [Cycle](https://maedow-flow.vercel.app/docs/cycle), [Règles](https://maedow-flow.vercel.app/docs/regles). Le reste se consulte au moment où il sert. ======================================================================== # Démarrer ======================================================================== Trois situations : préparer une machine (une fois), lancer un projet neuf, ou faire entrer un projet existant dans le workflow. ## Préparer la machine, une seule fois | Quoi | Commande | Pourquoi | | :--- | :--- | :--- | | Claude Code | voir la documentation officielle | l'agent principal | | Les skills moteur | `npx skills add JavaScript-Mastery-Pro/skills` | `/scope`, `/architect`, `/develop`, `/check`, `/test`, `/debug`, `/sync`, `/audit`, `/document` | | Le plugin Maedow Flow | `/plugin marketplace add maedow-arch/maedow-flow#main` puis `/plugin install maedow-flow@maedow-flow` | le skill `/flow` et le kit de templates | | Context7, recommandé | `claude mcp add --transport http context7 https://mcp.context7.com/mcp` | la documentation à jour des bibliothèques sans quitter la session ; la documentation officielle fait aussi l'affaire ([MF-013](https://maedow-flow.vercel.app/docs/regles#mf-013--la-documentation-se-consulte-elle-ne-se-suppose-pas)) | | GitHub CLI | `gh auth login` | dépôts, pull requests, protections de branche | | Tes règles personnelles | copier `global/CLAUDE.md` du dépôt vers `~/.claude/CLAUDE.md` | elles s'appliquent alors à toutes tes sessions, dans tous tes projets | Le `#main` de la commande du plugin compte : sans lui, l'installation suit la branche par défaut du dépôt, `develop`, qui porte l'intégration en cours et non la version publiée. Aucun autre serveur MCP n'est à installer d'avance : chacun se branche quand un projet s'en sert, selon sa stack (voir [Claude Code](https://maedow-flow.vercel.app/docs/claude-code#mcp)). ## Le prompt d'amorçage À coller en premier message dans un dossier vide, ou dans un projet existant : ```text Ce projet suit Maedow Flow. Avant toute action, lis le corpus en texte brut : curl -fsSL https://maedow-flow.vercel.app/llms-full.txt Applique ensuite la procédure de la page Démarrer qui correspond à ce dossier (nouveau projet ou projet existant). N'écris aucun code applicatif tant que je n'ai pas validé le scope et la stack. L'idée : ``` **Pourquoi `curl` et pas un outil de lecture web.** Les outils qui « lisent » une page la font souvent résumer par un petit modèle avant de la rendre. Un résumé perd précisément ce qui compte ici : le texte exact des règles. `curl` rend le texte intégral. ## Nouveau projet L'ordre compte. Les initialiseurs de projet (`create-next-app`, `create-expo-app`, `create-tauri-app`) refusent souvent un dossier qui contient déjà des fichiers : le kit s'installe donc **après** l'échafaudage, et seul `docs/` existe avant lui. 1. **Cadrer.** `/scope ` écrit `docs/scope/scope.md` : les features, leur ordre, et le palier d'exigence par défaut (voir [Cycle](https://maedow-flow.vercel.app/docs/cycle#les-paliers)). Tu valides. 2. **Choisir la stack.** `/architect` en mode architecture, en partant du profil de [Plateformes](https://maedow-flow.vercel.app/docs/plateformes). Il écrit `docs/specs/0001-.md`. Tu valides : la stack est ensuite une décision, pas une suggestion. 3. **Échafauder.** `/develop` sur la tâche d'échafaudage lance l'initialiseur officiel de la stack décidée. Pour un projet web TypeScript, `npx create-maedow-arch-app ` produit directement un projet conforme à Maedow Arch. 4. **Installer le kit.** `/flow installer` pose `AGENTS.md`, `CLAUDE.md`, `.claude/`, `.githooks/`, `.github/` et le script `verify`. Il n'écrase jamais un fichier existant. 5. **Compléter le contexte.** `/audit` remplit `## Stack`, `## Commands` et `## Rules` d'`AGENTS.md`. À sa question sur git, réponds `integration: on`. 6. **Brancher GitHub.** Voir [Le dépôt distant](#le-dépôt-distant) ci-dessous. 7. **Brancher le déploiement.** Web : projet Vercel lié au dépôt, un aperçu par pull request, la production depuis `main`. Mobile : EAS. Desktop : releases GitHub signées. Détails dans [Plateformes](https://maedow-flow.vercel.app/docs/plateformes). 8. **Entrer dans la boucle.** `/scope` sans argument désigne la première feature à construire, et le [cycle](https://maedow-flow.vercel.app/docs/cycle#phase-2--construire) prend le relais. La porte de sortie de cette phase : `verify` passe en local **et** en CI sur le projet encore vide. Une CI qui n'a jamais tourné au vert sur un projet vide ne dira rien d'utile sur un projet plein. ## Projet existant 1. **Mesurer l'écart.** `/flow controler` liste ce qui manque par rapport au kit, sans rien modifier. 2. **Ouvrir une branche.** `git switch -c chore/maedow-flow`. L'adoption est un lot comme un autre ([MF-003](https://maedow-flow.vercel.app/docs/regles#mf-003--jamais-sur-main-ni-sur-develop)). 3. **Installer ce qui manque.** `/flow installer` ajoute les fichiers absents et laisse les autres en place, en disant lesquels il a laissés. 4. **Documenter l'existant.** `/audit` lit tout le code et écrit ou complète `AGENTS.md`, racine et zones. 5. **Enrôler l'existant.** `/scope` inscrit les features déjà là (`existing`) ou à moitié faites (`in-progress`), puis propose la suite. 6. **Chiffrer la dette d'architecture** (projets TypeScript) : `npx maedow-arch check`. Ne rien corriger dans ce lot : l'audit sert à décider, pas à réparer en série. 7. **Ouvrir la pull request** vers `develop`. Si `develop` n'existe pas encore, crée-la depuis `main` (voir ci-dessous). ## Le dépôt distant Le flux est le même partout : ```text / ──PR──▶ develop ──PR──▶ main ``` `develop` est la branche par défaut et reçoit les lots. `main` porte ce qui est en production et ne reçoit que `develop`. Mise en place, depuis le projet échafaudé : ```bash gh repo create --private --source . --remote origin git push -u origin main # naissance du dépôt : le commit de l'initialiseur, rien d'autre git push -u origin main:develop # develop naît de main gh repo edit --default-branch develop ``` Le hook `pre-push` du kit autorise la **création** de `main` et de `develop` sur le distant, et refuse ensuite toute mise à jour directe. La naissance d'un dépôt n'est pas du travail sur `main` ; tout ce qui suit l'est. Ensuite, la protection côté serveur, qui tient même pour un poste mal configuré : ```bash /flow proteger ``` Le skill applique un ruleset GitHub sur `main` et `develop` : pas de suppression, pas de réécriture, pull request obligatoire, CI verte obligatoire, **et aucun contournement autorisé**, y compris pour toi. Un garde-fou que son propriétaire peut contourner n'en est pas un. Sur un dépôt privé d'un compte gratuit, GitHub refuse les rulesets (erreur 403) : les hooks locaux et la CI tiennent alors la règle seuls, et il faut le savoir. ## Avec une autre IA que Claude Code Tout ce qui précède reste valable. Seuls les raccourcis changent. - **Le corpus** : `https://maedow-flow.vercel.app/llms-full.txt`, ou page par page depuis l'index `https://maedow-flow.vercel.app/llms.txt`. - **Les skills moteur** sont des Agent Skills : `npx skills add JavaScript-Mastery-Pro/skills` les installe aussi pour Cursor, Codex et les autres clients compatibles. - **Le kit, sans le plugin** : le script d'installation se télécharge et va chercher les templates sur le site. ```bash curl -fsSL https://maedow-flow.vercel.app/flow.mjs -o flow.mjs node flow.mjs installer --profil web # ou mobile, desktop node flow.mjs controler rm flow.mjs ``` - **Les garde-fous propres à Claude Code** (`.claude/settings.json` et son hook) n'ont pas d'effet ailleurs. Les hooks git et la CI, eux, s'appliquent à tous les outils et à tous les humains : c'est pour cela que les règles critiques y sont doublées. ======================================================================== # Cycle ======================================================================== Cinq phases. Les deux premières se jouent une fois, la troisième se répète pour chaque feature, les deux dernières rythment la vie en production. Chaque phase se termine par une **porte** : une condition vérifiable, sans laquelle on ne passe pas à la suite. ```text 0 Cadrer ──▶ 1 Fonder ──▶ 2 Construire ──▶ 3 Livrer ──▶ 4 Exploiter ▲ │ ▲ │ │ └────────┘ │ │ feature suivante │ └──────────────────── nouvelle tranche ◀──────────────────┘ ``` ## Les paliers Toutes les features ne méritent pas le même effort. Le palier se fixe une fois pour le projet (par `/scope`), et se relève feature par feature quand l'enjeu l'exige : une maquette de démonstration n'a pas les exigences d'un paiement. | Palier | Pour quoi | Ce qui suit `/develop` | Ce qui marque la feature `done` | | :--- | :--- | :--- | :--- | | `Prototype` | explorer une idée, jeter si besoin | rien de plus que l'auto-contrôle de `/develop` | `/develop` | | `Alpha` | premiers utilisateurs de confiance | `/check verify` | `/check verify` | | `Beta` | vrais utilisateurs, vraies données | `/check verify`, `/test` | `/test` | | `GA` | production, argent, données sensibles | `/check verify`, `/test`, `/check review`, `/document` | `/test`, revue sans constat critique ouvert | Trois relèvements ne se discutent pas : **l'authentification, le paiement et toute écriture de données personnelles** sont au moins en `Beta`, quel que soit le palier du projet. Les règles de sécurité et de git ([MF-003](https://maedow-flow.vercel.app/docs/regles#mf-003--jamais-sur-main-ni-sur-develop) à [MF-009](https://maedow-flow.vercel.app/docs/regles#mf-009--les-migrations-sont-versionnées-et-immuables)) s'appliquent à tous les paliers, `Prototype` compris. Un prototype qui fuit un secret a fui un secret. ## Phase 0 · Cadrer **Entrée** : une idée. **Sortie** : `docs/scope/scope.md`. `/scope ` pose les questions que seul l'humain peut trancher (pour qui, quel problème, ce qui prouve le succès), découpe en features grossières, les ordonne, et recommande le palier par défaut. Il ne choisit aucun outil : ce n'est pas son travail. **Porte** : tu as relu le scope, et chaque feature tient en une phrase d'intention et une ligne « Fini quand ». On revient ici à chaque nouvelle tranche du produit : `/scope` sans argument fait le point (ce qui est livré, ce qui a dérivé, ce qui vient ensuite). ## Phase 1 · Fonder **Entrée** : le scope validé. **Sortie** : un projet vide qui passe `verify`, en local et en CI. 1. `/architect` en mode architecture : la stack, depuis le profil de [Plateformes](https://maedow-flow.vercel.app/docs/plateformes). 2. `/develop` sur l'échafaudage : l'initialiseur officiel, les dépendances de base seulement. 3. `/flow installer` : le kit. 4. `/audit` : le contexte durable dans `AGENTS.md`. 5. Dépôt distant, protections, déploiement des aperçus (voir [Démarrer](https://maedow-flow.vercel.app/docs/demarrer#le-dépôt-distant)). **Porte** : `verify` vert en local, CI verte sur la première pull request, un aperçu déployé. ## Phase 2 · Construire La boucle, une feature à la fois. Chaque étape a sa commande, et sa porte. | # | Étape | Commande | Porte | | :--- | :--- | :--- | :--- | | 1 | Choisir | `/scope` | La feature est la prochaine du scope, ou tu as dit pourquoi pas. | | 2 | Décider | `/architect `, en mode Plan pour tout ce qui est structurel | Si la feature porte « needs a decision », une spec validée existe. Sinon, on passe. | | 3 | Construire | `/develop ` | Le code existe sur une branche dédiée, le typage passe. | | 4 | Prouver | `/check verify ` | Chaque critère d'acceptation constaté sur l'application qui tourne. | | 5 | Tester | `/test ` | Les tests couvrent ce qui casserait un utilisateur, y compris les refus d'accès. | | 6 | Relire | `/check review` | Aucun constat critique ouvert. Les constats sont reproduits avant d'être corrigés. | | 7 | Proposer | `verify`, puis `/document pr` | Pull request vers `develop`, décrite depuis le vrai diff. | | 8 | Fusionner | toi, sur GitHub | CI verte. | | 9 | Consigner | `/sync` | `AGENTS.md`, scope et statut des specs à jour. | Les étapes 4 à 6 suivent le palier de la feature (tableau ci-dessus). L'étape 7 et les suivantes ne se sautent jamais. **Si une étape échoue** : `/debug` pour un comportement faux, retour à `/architect` si l'échec révèle une mauvaise décision plutôt qu'une erreur de code. Corriger le code d'une mauvaise décision, c'est payer deux fois. **Si une idée surgit en cours de route** : elle ne rejoint pas le lot. `/scope ` l'inscrit pour plus tard ([MF-002](https://maedow-flow.vercel.app/docs/regles#mf-002--un-lot-une-intention)). ## Phase 3 · Livrer **Entrée** : `develop` contient une tranche utile. **Sortie** : cette tranche en production. 1. Revue d'ensemble de l'application, sur contexte neuf (prompt dans [Prompts](https://maedow-flow.vercel.app/docs/prompts#revue-densemble)). 2. `/security-review` sur tout ce qui part en production, et la liste de [Sécurité](https://maedow-flow.vercel.app/docs/securite). 3. Parcours complets vérifiés sur l'aperçu de `develop` : le parcours client et le parcours d'administration, y compris ce qu'un utilisateur ordinaire ne doit **pas** pouvoir faire. 4. En option, une passe CodeRabbit : ses constats sont triés (confirmé, à vérifier, faux positif) avant toute correction. 5. `/document release-note`, puis pull request `develop` vers `main`, que tu fusionnes. Le tag de version suit la fusion. **Porte** : parcours critiques constatés, aucun constat critique ouvert, migrations de base de données appliquées et réversibles ou documentées comme irréversibles. ## Phase 4 · Exploiter - **Observer dès le premier jour.** Erreurs, journaux et analytique sont en place avant la première mise en production, pas après le premier incident. - **Incident** : `/debug` sur une branche `fix/`, pull request, puis `/document postmortem`. Le postmortem dit ce qui a manqué au workflow, et le workflow se corrige. - **Montée en charge** : on mesure, puis on consulte [Tenir la charge](https://maedow-flow.vercel.app/docs/echelle). Jamais l'inverse. - **Dépendances** : Dependabot ouvre les pull requests, la CI les juge, tu fusionnes chaque semaine. ## Les outils arrivent quand le projet les réclame Un projet neuf n'a besoin que des skills moteur. Les autres outils de Claude Code entrent quand une situation réelle les appelle : | Signal | Outil | | :--- | :--- | | Tu répètes la même consigne pour la troisième fois | un skill de projet (`.claude/skills//SKILL.md`) | | Plusieurs enquêtes indépendantes avant une décision | des sous-agents en parallèle | | Deux lots doivent avancer en même temps | des worktrees (`claude -w `) | | Un changement mécanique touche tout le dépôt | `/batch` | | Tu recopies régulièrement des données d'un service | un serveur MCP | Le détail de chacun est dans [Claude Code](https://maedow-flow.vercel.app/docs/claude-code). ======================================================================== # Règles ======================================================================== Dix-sept règles, chacune avec un code stable. Une revue, un commit ou un message d'erreur cite le code (`MF-007`), jamais le titre : un titre se réécrit, un code ne bouge pas. Chaque règle dit ce qui la fait respecter, et la distinction compte : - **machine** : un hook, une permission ou la CI refuse la violation. Elle ne dépend de la mémoire de personne. - **skill** : un skill du moteur s'arrête ou la constate au bon moment. - **revue** : seule une relecture la tient. C'est la catégorie la plus fragile, et elle est dite comme telle. | Code | Règle | Tenue par | | :--- | :--- | :--- | | MF-001 | Décider avant de construire | skill, revue | | MF-002 | Un lot, une intention | revue | | MF-003 | Jamais sur main ni sur develop | machine | | MF-004 | Fusion sur CI verte uniquement | machine | | MF-005 | Une commande `verify` par projet | machine | | MF-006 | Les secrets restent hors de portée | machine | | MF-007 | Ce qui entre est `unknown` | revue | | MF-008 | L'autorisation se vérifie côté serveur | revue, tests | | MF-009 | Les migrations sont versionnées et immuables | revue | | MF-010 | Fini veut dire prouvé | skill | | MF-011 | Un regard neuf avant de fusionner | skill | | MF-012 | Un bug se reproduit avant de se corriger | skill | | MF-013 | La documentation se consulte, elle ne se suppose pas | revue | | MF-014 | Pas de brique sans goulot mesuré | revue | | MF-015 | Le contexte durable vit dans `AGENTS.md` | skill | | MF-016 | L'irréversible se confirme | machine | | MF-017 | Écrire juste | machine, revue | ## MF-001 · Décider avant de construire **Règle.** Un choix coûteux à défaire est décidé par écrit avant l'implémentation : schéma de données, authentification, paiement, choix d'un fournisseur, structure du code, tout ce qui touche plusieurs systèmes. La décision prend la forme d'une spec `/architect` (`docs/specs/`) ou d'un plan approuvé en mode Plan. **Pourquoi.** Un agent à qui manque une décision l'invente, silencieusement, au milieu du code. Relire un plan de trente lignes coûte moins cher que défaire un diff de deux mille. **Tenue par.** `/develop` s'arrête quand une décision structurante n'a pas de spec, et renvoie vers `/architect`. La revue vérifie qu'aucune décision n'a été prise en douce. **Exception.** Construire sur une hypothèse est permis si l'humain le choisit : `/develop` l'enregistre comme spec `Assumed`, qui reste signalée tant que `/architect` ne l'a pas ratifiée. Une dette de décision visible vaut mieux qu'une décision cachée. ## MF-002 · Un lot, une intention **Règle.** Un lot livre une seule capacité, décrite par ses critères d'acceptation. Ce qui est utile mais hors du lot se propose (`/scope `) et ne se code pas. **Pourquoi.** Un lot qui fait trois choses se relit mal, se teste mal et se défait mal. C'est aussi la pente naturelle d'un agent : « tant que j'y suis ». **Tenue par.** La revue, et `/check review` qui signale les changements sans lien avec la feature. ## MF-003 · Jamais sur main ni sur develop **Règle.** Tout travail part d'une branche dédiée (`feat/`, `fix/`, `chore/`, `refactor/`, `docs/`, `test/`) et rejoint `develop` par pull request. `main` ne reçoit que `develop`, par pull request. Aucun commit ni push direct sur l'une ou l'autre, pas même un commit vide « pour vérifier ». **Pourquoi.** `develop` est l'intégration, `main` la production. Un raccourci sur l'une ou l'autre fait entrer du code qu'aucune CI n'a jugé et qu'aucun humain n'a relu. **Tenue par.** Trois couches, parce qu'aucune ne suffit seule : - le hook Claude Code `.claude/hooks/garde.mjs` refuse le commit sur ces branches et le push vers elles ; - le hook git `.githooks/pre-push` refuse la mise à jour directe de `main` et `develop`, pour tous les outils et tous les humains ; - le workflow CI `garde-flux.yml` refuse une pull request vers `main` qui ne vient pas de `develop`. Côté serveur, un ruleset GitHub sans contournement (`/flow proteger`) quand le plan GitHub le permet. **Exception.** La création initiale de `main` et `develop` sur le dépôt distant (voir [Démarrer](https://maedow-flow.vercel.app/docs/demarrer#le-dépôt-distant)). ## MF-004 · Fusion sur CI verte uniquement **Règle.** Lint, typage, tests, build et scan de secrets passent en CI avant toute fusion. Une CI rouge ne se contourne pas, elle se répare. **Pourquoi.** « Ça marche sur ma machine » n'est pas un état du projet. La CI est le seul juge qui voit le même code pour tout le monde. **Tenue par.** `.github/workflows/ci.yml`, et le ruleset qui exige le statut `verify`. ## MF-005 · Une commande `verify` par projet **Règle.** Le projet expose une commande unique, `verify`, qui enchaîne les contrôles disponibles (lint, typage, tests, build). L'agent la lance avant chaque pull request, et `AGENTS.md` la nomme. **Pourquoi.** Une liste de cinq commandes à retenir finit toujours amputée d'une. Une seule commande se lance, ou ne se lance pas, et ça se voit. **Tenue par.** `/flow installer` crée le script, `/flow controler` signale son absence, la CI exécute les mêmes contrôles. ## MF-006 · Les secrets restent hors de portée **Règle.** L'agent ne lit ni n'écrit les fichiers d'environnement réels (`.env`, `.env.local`, `.env.*.local`, `.env.production`). Seul `.env.example`, sans valeur, est versionné. Le code lit `process.env` sans jamais afficher une valeur. Une variable préfixée pour le client (`NEXT_PUBLIC_`, `EXPO_PUBLIC_`, `VITE_`) est publique : elle ne porte jamais de secret. **Pourquoi.** Un secret lu par l'agent finit dans une transcription, un journal ou un commit. Un secret poussé sur un distant est compromis, même sur un dépôt privé, même retiré au commit suivant. **Tenue par.** Les règles `deny` de `.claude/settings.json`, le `.gitignore`, et le scan de secrets de la CI. **Si ça arrive.** Révoquer et régénérer le secret d'abord, nettoyer l'historique ensuite. Dans cet ordre. ## MF-007 · Ce qui entre est `unknown` **Règle.** Toute donnée venue de l'extérieur du serveur (formulaire, paramètre d'URL, corps de requête, réponse d'API tierce, webhook, fichier téléversé, stockage local du client) est `unknown` jusqu'à sa validation par un schéma, côté serveur, à la frontière. Un prix, un rôle, un statut de paiement ou un identifiant de propriétaire ne sont **jamais** crus sur parole : le serveur les relit depuis sa propre source. **Pourquoi.** C'est la faute que les agents commettent par défaut : faire confiance au client parce que le client, c'est le code qu'ils viennent d'écrire. **Tenue par.** La revue, `/check review` et `/security-review`. Pour le web TypeScript, Maedow Arch interdit en plus `any` et la double assertion (MA-005, MA-006). ## MF-008 · L'autorisation se vérifie côté serveur **Règle.** Chaque route, action serveur et requête protégée vérifie l'identité **et** le droit, à chaque accès. Masquer un bouton ou un lien n'est pas une protection. Avec une base exposée au client (Supabase), la sécurité au niveau des lignes (RLS) est activée sur chaque table, et ses règles sont testées. **Pourquoi.** L'interface n'est qu'un client parmi d'autres. N'importe qui peut appeler l'API sans elle. **Tenue par.** La revue, et des tests obligatoires pour trois cas : non authentifié, authentifié sans le droit, authentifié avec le droit. ## MF-009 · Les migrations sont versionnées et immuables **Règle.** Tout changement de schéma passe par une migration versionnée dans le dépôt. Une migration appliquée ne se modifie jamais : on en écrit une nouvelle. Un changement de schéma se prépare en mode Plan (MF-001), et une migration destructive (suppression de colonne ou de table) se fait en deux temps : d'abord le code cesse de s'en servir, ensuite la donnée disparaît. **Pourquoi.** Une migration modifiée après coup diverge entre les environnements, et la divergence ne se voit qu'en production. **Tenue par.** La revue. ## MF-010 · Fini veut dire prouvé **Règle.** Une feature est finie quand chacun de ses critères d'acceptation a été constaté sur l'application qui tourne. Ce qui n'a pas pu être vérifié est écrit comme tel, jamais passé sous silence. **Pourquoi.** Des tests verts prouvent que le code fait ce que les tests demandent. Ils ne prouvent pas que la page s'affiche, que le bouton est branché, ni que la feature correspond à ce qui avait été décidé. **Tenue par.** `/check verify`, à partir du palier `Alpha`. ## MF-011 · Un regard neuf avant de fusionner **Règle.** Aux paliers `Beta` et `GA`, le code est relu avant la pull request par un contexte qui ne l'a pas écrit : un autre modèle, ou un sous-agent sans l'historique de la session. Chaque constat est reproduit avant d'être corrigé, et seuls les problèmes confirmés se corrigent. **Pourquoi.** Un modèle qui relit son propre travail partage ses angles morts. Et un relecteur, humain ou non, produit aussi des faux positifs : corriger sans reproduire, c'est parfois casser ce qui marchait. **Tenue par.** `/check review`, qui écrit ses constats dans `docs/reviews/`. ## MF-012 · Un bug se reproduit avant de se corriger **Règle.** Une correction commence par une reproduction déterministe et se termine par un test de régression qui échouait avant et passe après. La correction est minimale : pas de refonte ni de nouveauté glissée avec elle. **Pourquoi.** Une correction qu'on ne sait pas expliquer est un bug qu'on n'a pas encore trouvé. **Tenue par.** `/debug`, puis `/test`. ## MF-013 · La documentation se consulte, elle ne se suppose pas **Règle.** Avant d'utiliser l'API d'une bibliothèque, d'un framework ou d'un service, l'agent en consulte la documentation actuelle (Context7, ou la documentation officielle), et installe les versions courantes plutôt que celles de sa mémoire. **Pourquoi.** La connaissance d'un modèle a une date. Les bibliothèques, non : une API renommée ou dépréciée produit un code qui compile parfois, et qui échoue en silence. **Tenue par.** La revue. C'est une règle de discipline, et elle est fragile. ## MF-014 · Pas de brique sans goulot mesuré **Règle.** Cache, file d'attente, réplique de lecture, microservice, sharding ou tout autre élément d'infrastructure n'entrent dans le projet qu'avec la mesure qui les justifie, citée dans la spec. Un seul serveur et une seule base suffisent à des milliers d'utilisateurs. **Pourquoi.** Chaque brique ajoute de la complexité, de la maintenance et des données potentiellement périmées. L'ajouter avant le besoin, c'est payer le coût sans le bénéfice. **Tenue par.** La revue. L'ordre des étapes et leurs signaux sont dans [Tenir la charge](https://maedow-flow.vercel.app/docs/echelle). ## MF-015 · Le contexte durable vit dans `AGENTS.md` **Règle.** `AGENTS.md` porte ce qu'un agent doit savoir à chaque session et ne peut pas déduire du code : stack décidée, commandes, conventions, pièges. Il reste court. `CLAUDE.md` n'est qu'un pointeur vers lui. Les généralités (« écris du code propre ») n'y entrent pas. Il est mis à jour après chaque lot. **Pourquoi.** Tous les outils lisent `AGENTS.md`. Un contexte trop long dilue l'attention de l'agent ; un contexte périmé l'induit en erreur, ce qui est pire que pas de contexte. **Tenue par.** `/audit` le crée, `/sync` le maintient après chaque lot. ## MF-016 · L'irréversible se confirme **Règle.** Une opération qu'on ne peut pas défaire demande une confirmation humaine au moment où elle s'exécute : suppression récursive, `git reset --hard`, `git push --force-with-lease`, `DROP` ou `TRUNCATE`, suppression d'une branche distante. Deux opérations sont refusées sans appel : `git push --force` et tout contournement des hooks (`--no-verify`). **Pourquoi.** Une confirmation coûte trois secondes. Une perte de données, une réécriture d'historique partagé ou un garde-fou désactivé coûtent des heures, parfois tout. **Tenue par.** Le hook `.claude/hooks/garde.mjs`, qui répond « demander » ou « refuser » avant l'exécution. ## MF-017 · Écrire juste **Règle.** Français correct partout où un humain lira : interface, documentation, commentaires, commits, pull requests. Pas de tiret cadratin pour accoler une incise ou une explication (`texte — suite`) : on construit la phrase avec deux-points, virgule, parenthèses, ou deux phrases. Un message de commit est une phrase au présent qui dit ce qui est désormais vrai (« Le panier refuse une quantité supérieure au stock »), sans trailer d'attribution (`Co-Authored-By`) ni mention d'outil. **Pourquoi.** L'historique et la documentation sont lus plus souvent qu'ils ne sont écrits. Et l'historique d'un dépôt est signé par son auteur, pas par ses outils. **Tenue par.** Le hook `.githooks/commit-msg` refuse le trailer d'attribution, la mention d'outil et le tiret cadratin dans les messages de commit. Ailleurs, la revue. Cette règle prime sur le format de commit que proposent les skills installés. ======================================================================== # Claude Code ======================================================================== Claude Code n'est pas une collection de commandes à mémoriser, c'est un jeu de contrôles. La seule question utile : quel problème est-ce que je cherche à résoudre ? ## Où vit chaque consigne | Ce que tu veux | Où ça vit | | :--- | :--- | | Que l'agent le sache toujours | `AGENTS.md` (et `CLAUDE.md` qui pointe vers lui) | | Une façon répétée de travailler | un skill | | Que ça arrive à coup sûr | un hook | | Que ça n'arrive jamais | une permission `deny`, ou un hook qui refuse | | Une demande ponctuelle | le prompt | | Un système extérieur (GitHub, base, suivi d'erreurs) | un serveur MCP | | Une enquête qui ne doit pas encombrer la session | un sous-agent | | Deux chantiers en parallèle sans se marcher dessus | un worktree | Mettre une règle au mauvais endroit est l'erreur la plus fréquente : une interdiction écrite dans `AGENTS.md` sera oubliée un jour, la même en `deny` ne le sera jamais ([MF-015](https://maedow-flow.vercel.app/docs/regles#mf-015--le-contexte-durable-vit-dans-agentsmd), principe 4 du [manifeste](https://maedow-flow.vercel.app/docs)). ## Le moteur : les skills Installés depuis [JavaScript-Mastery-Pro/skills](https://github.com/JavaScript-Mastery-Pro/skills), plus `/flow` fourni par Maedow Flow. | Skill | Ce qu'il fait | Ce qu'il écrit | Moment du [cycle](https://maedow-flow.vercel.app/docs/cycle) | | :--- | :--- | :--- | :--- | | `/scope` | quoi construire, dans quel ordre, à quel palier | `docs/scope/` | phase 0, puis après chaque lot | | `/architect` | les décisions structurantes, options pesées | `docs/specs/` | phase 1, étape 2 de la boucle | | `/develop` | construit depuis la spec et `AGENTS.md` | le code | étape 3 | | `/check verify` | fait tourner l'application et constate | rien | étape 4 | | `/test` | les tests des fichiers modifiés | `*.test.*` | étape 5 | | `/check review` | relecture par un autre modèle | `docs/reviews/` | étape 6 | | `/document` | description de PR, changelog, notes de version, postmortem | selon le type | étape 7, phases 3 et 4 | | `/sync` | remet le contexte à jour après un lot | `AGENTS.md`, scope | étape 9 | | `/audit` | écrit le contexte initial d'un projet | `AGENTS.md` | phase 1, projet existant | | `/debug` | trouve la cause racine, corrige au minimum | la correction | quand ça casse | | `/flow` | installe, contrôle et protège le kit Maedow Flow | les fichiers du kit | phase 1, contrôles | **Trois frottements connus**, et ce qui l'emporte : - `/develop` propose des messages de commit en anglais au format Conventional Commits, avec un trailer `Co-Authored-By`. [MF-017](https://maedow-flow.vercel.app/docs/regles#mf-017--écrire-juste) l'emporte : phrase française au présent, aucun trailer. Le hook `commit-msg` refuse le trailer si la consigne est oubliée. - `/develop` crée ses branches depuis la branche courante. Pars toujours de `develop` à jour. - Les skills lisent des titres de section précis dans `AGENTS.md` (`## Stack`, `## Build approach`, `## Commands`, `## Git`, `## Context files`). Ces titres restent en anglais dans le template, exprès : les traduire casserait la lecture. ## `AGENTS.md` Ce qui y entre : la stack décidée, les commandes, les conventions qui ne se lisent pas dans le code, les pièges, les règles du produit qui ne se négocient pas. Ce qui n'y entre pas : ce que l'agent découvre en lisant le dépôt, les généralités, l'historique des décisions (il est dans `docs/specs/`). `/audit` l'écrit, `/sync` le tient à jour. Après un plan approuvé qui fixe une convention durable : « Mets à jour `AGENTS.md` avec les conventions du plan approuvé. Reste court. N'ajoute rien que le code dise déjà. » Un `AGENTS.md` imbriqué (`src/payments/AGENTS.md`) se justifie pour une zone qui a ses propres conventions ou ses pièges, jamais par dossier. ## Permissions Le kit pose `.claude/settings.json` : - **allow** : lecture git (`status`, `diff`, `log`, `branch`), `add`, `commit`, `switch`, et les scripts du projet (`verify`, `lint`, `typecheck`, `test`, `build`, `dev`). - **ask** : `git push`, `gh pr create`, `gh pr merge`, l'installation de dépendances. - **deny** : lecture et écriture des fichiers d'environnement réels ([MF-006](https://maedow-flow.vercel.app/docs/regles#mf-006--les-secrets-restent-hors-de-portée)). `Shift+Tab` fait tourner les modes. Mode Plan pour tout ce qui est structurel ; « accepter les modifications » pendant `/develop`, puisque la branche et les hooks bornent les dégâts ; mode manuel quand on touche à quelque chose de sensible. ## Hooks Le kit en installe un, `.claude/hooks/garde.mjs`, qui s'exécute avant chaque commande shell de l'agent : | Commande | Décision | Règle | | :--- | :--- | :--- | | `git commit` sur `main` ou `develop` | refus | MF-003 | | `git push` vers `main` ou `develop` | refus | MF-003 | | `git push --force` | refus | MF-016 | | `--no-verify`, `core.hooksPath` modifié | refus | MF-016 | | `git push --force-with-lease`, `git reset --hard`, `git clean -f` | demande | MF-016 | | `rm -rf`, `Remove-Item -Recurse` | demande | MF-016 | | `DROP`, `TRUNCATE`, suppression de branche distante | demande | MF-016 | Un formatage automatique après chaque modification est un bon ajout par projet, à condition de ne formater **que** le fichier modifié : formater tout le dépôt à chaque édition noie le diff et ralentit tout. ## Mode Plan À utiliser pour : schéma de données et migrations, authentification, paiement, permissions, refonte large, code inconnu, tout ce qui touche plusieurs systèmes. À éviter pour : changer un texte, renommer une variable, corriger une marge. Un plan se conteste avant de s'approuver. Trois questions suffisent souvent : « Qu'est-ce qui casse dans le code existant si on fait ça ? », « Quelle est la version la plus simple qui tient les critères ? », « Pourquoi cette brique, et quelle mesure la justifie ? ». Un plan trop ambitieux se ramène au besoin : voir [Prompts](https://maedow-flow.vercel.app/docs/prompts#simplifier-un-plan-trop-ambitieux). ## Modèle et effort Deux réglages indépendants : `/model` choisit le cerveau, `/effort` dit combien il réfléchit. | Travail | Modèle | Effort | | :--- | :--- | :--- | | Renommer, formater, CRUD de routine, tests simples | rapide | bas | | Construire une feature décidée | fort | moyen | | Architecture, schéma, sécurité, revue approfondie | le plus fort | haut | | Bug de concurrence, bug intermittent, fuite de données | le plus fort | maximal | ## Contexte | Situation | Geste | | :--- | :--- | | Sujet sans rapport avec le précédent | `/clear` | | Même sujet, conversation trop longue | `/compact garde les décisions de schéma et les problèmes ouverts` | | L'agent oublie, se répète, cite des décisions périmées | `/context` pour voir ce qui occupe l'attention | | Essayer une autre voie sans perdre celle-ci | `/branch ` | | L'agent est parti dans la mauvaise direction | `Esc Esc`, ou `/rewind` | | Une question à côté, sans polluer la session | `/btw ` | | Reprendre le travail de la veille | `claude -c`, ou `/resume` | Entre deux features : `/sync`, puis `/clear`. La mémoire est dans le dépôt ([principe 6](https://maedow-flow.vercel.app/docs#six-principes)), la conversation peut repartir de zéro. ## Sous-agents Un sous-agent, c'est un contexte séparé, une tâche ciblée, et un résultat rendu à la session principale. Trois usages rentables : 1. **Enquêtes parallèles** avant une décision : un sous-agent par question indépendante (le modèle de données, le parcours existant, la couverture de tests), chacun rendant comportement actuel, fichiers concernés, risques et recommandation. 2. **Relecture fraîche** d'une feature finie ([MF-011](https://maedow-flow.vercel.app/docs/regles#mf-011--un-regard-neuf-avant-de-fusionner)). 3. **Vérification d'un constat** : un relecteur peut se tromper. Un sous-agent neuf reproduit le problème avant que quiconque le corrige. Les formulations sont dans [Prompts](https://maedow-flow.vercel.app/docs/prompts). ## Worktrees, `/batch` et arrière-plan - `claude -w ` ouvre une session dans un worktree isolé : deux lots avancent sans éditer les mêmes fichiers. - `/batch ` découpe un changement mécanique et divisible (migrer des tests, remplacer une API dépréciée partout) en unités confiées à des agents en worktree, chacune avec sa pull request. Pas pour une feature dont les décisions sont liées, comme un tunnel de paiement. - `/bg ` détache la session pour qu'elle continue sans le terminal ; `claude agents` montre toutes les sessions en cours. ## Skills de projet Le signal : la troisième fois que tu tapes la même suite de consignes. Le skill vit dans `.claude/skills//SKILL.md`, versionné avec le projet. ```markdown --- description: Construit ou modifie une page client en réutilisant le design system, les composants existants et les conventions responsives du projet. À utiliser pour toute page ou section visible par les clients. --- Construis : $ARGUMENTS 1. Inspecte la page actuelle et les composants voisins. 2. Cherche un composant réutilisable avant d'en créer un. 3. Suis les jetons de typographie, d'espacement et de couleur. 4. Garde le changement centré sur la demande. 5. Lance l'application et vérifie le rendu, bureau et mobile. 6. Lance `verify`. Résume ce qui a changé. ``` La `description` est ce qui décide quand l'agent déclenche le skill : elle dit **quoi** et **quand**, concrètement. Un skill s'emploie là où ses consignes s'appliquent, et pas ailleurs : un skill d'interface client n'a rien à faire sur un écran d'administration. ## MCP Aucun serveur MCP n'est imposé. La liste dépend de la stack que `/architect` a décidée pour le projet, pas de ce workflow. Un serveur se branche quand le projet s'en sert, et le signal est simple : tu te surprends à recopier régulièrement des informations d'un service dans la conversation. | Besoin | Exemples, selon la stack du projet | | :--- | :--- | | La documentation à jour des bibliothèques ([MF-013](https://maedow-flow.vercel.app/docs/regles#mf-013--la-documentation-se-consulte-elle-ne-se-suppose-pas)) | Context7, ou la documentation officielle consultée directement | | Le dépôt, les pull requests, les revues | le serveur de ton hébergeur de code (GitHub, GitLab…) | | La base de données | celui de ta base ou de ton BaaS (Supabase, Neon…) | | Les déploiements et leurs journaux | celui de ton hébergeur (Vercel, Netlify…) | | Les erreurs et l'analytique | celui de ton outil d'observabilité (PostHog, Sentry…) | | Les maquettes | celui de ton outil de design (Figma…) | | Les builds mobiles | celui de ta chaîne mobile (Expo…) | Un serveur branché élargit ce que l'agent peut faire. N'en branche pas un « au cas où », et donne-lui les droits les plus étroits qui suffisent au besoin. ## Au quotidien `/diff` avant d'accepter, `/review` et `/security-review` avant de fusionner, `@chemin/fichier` pour désigner exactement ce qui compte, `!commande` pour lancer une commande toi-même dans la conversation, `/doctor` quand Claude Code lui-même se comporte mal. ======================================================================== # Plateformes ======================================================================== Trois profils, chacun avec une stack par défaut. Un défaut n'est pas une obligation : c'est le point de départ que `/architect` discute, et qu'il ne remplace qu'avec une raison écrite dans la spec. Sans défaut, chaque projet rouvre les mêmes débats ; avec un défaut imposé, on force une stack là où elle ne convient pas. Chaque profil dit aussi **son degré de preuve**. Un défaut éprouvé en production n'a pas le même poids qu'un défaut recommandé mais jamais livré. | Profil | Degré de preuve | | :--- | :--- | | Web | éprouvé sur plusieurs projets en production | | Mobile | recommandé, à éprouver sur un premier projet | | Desktop | recommandé, à éprouver sur un premier projet | Dans tous les cas, les versions installées sont les versions courantes, vérifiées au moment de l'échafaudage ([MF-013](https://maedow-flow.vercel.app/docs/regles#mf-013--la-documentation-se-consulte-elle-ne-se-suppose-pas)). Ce document ne fige aucun numéro de version, parce qu'un numéro écrit ici serait périmé avant d'être lu. ## Web | Couche | Défaut | Quand s'en écarter | | :--- | :--- | :--- | | Framework | Next.js (App Router), TypeScript strict | Vite et React pour une application sans SEO ni rendu serveur | | Architecture | [Maedow Arch](https://maedow-arch-docs.vercel.app/llms.txt), mode Light puis Full quand le domaine prend du poids | jamais pour un projet TypeScript | | Style | Tailwind CSS, primitives dans `components/ui/` | un design system existant imposé | | Données et authentification | Supabase (Postgres, Auth, Storage, RLS) | Postgres et Drizzle quand le backend nous appartient, ou qu'un modèle d'accès complexe se tient mal en RLS | | Validation | Zod aux frontières ([MF-007](https://maedow-flow.vercel.app/docs/regles#mf-007--ce-qui-entre-est-unknown)) | aucune raison courante | | Tests | Vitest, Playwright avec axe pour les parcours et l'accessibilité | aucune raison courante | | Hébergement | Vercel : un aperçu par pull request, la production depuis `main` | contrainte de souveraineté, de coût ou de réseau | **Services, installés au moment où une feature en a besoin, pas avant** : Resend (e-mails), PostHog (analytique, erreurs, flags), Upstash (limitation de débit, cache), Inngest (tâches de fond), Stripe (paiement). **Ce qui revient souvent** : - `TypeScript strict` veut dire `strict`, `noUncheckedIndexedAccess` et `exactOptionalPropertyTypes`, dès le premier jour. Les activer plus tard coûte des centaines d'erreurs d'un coup. - En serverless, la connexion à Postgres passe par l'URL du pooler dès le premier jour ([Tenir la charge](https://maedow-flow.vercel.app/docs/echelle)). - Un projet Vercel neuf protège ses déploiements derrière une connexion Vercel. Un agent qui vérifie un aperçu (`/check verify`, `curl`) reçoit alors une page de connexion, pas l'application. Site public : désactiver la protection. Application privée : utiliser le secret de contournement pour l'automatisation, rangé avec les autres secrets (MF-006). - Lier le projet Vercel **sans** déploiement initial : le premier déploiement d'un projet neuf part en production, même depuis une branche de feature. - Un module qui manipule un secret porte `import "server-only"` (MA-008) : l'importer côté client casse le build au lieu de fuiter. - La qualité d'interface a ses propres skills (`impeccable`, `better-interface`) : ils s'invoquent pendant `/develop` sur le volet interface, pas à la place de lui. ## Mobile | Couche | Défaut | Quand s'en écarter | | :--- | :--- | :--- | | Framework | Expo (React Native), Expo Router, TypeScript strict | besoin natif lourd que les modules Expo ne couvrent pas | | Architecture | Maedow Arch : `core/` en TypeScript pur, partageable avec un projet web | jamais | | Données et authentification | le même backend que le web (Supabase par défaut) | aucune raison courante | | Tests | Jest avec `jest-expo` et React Native Testing Library ; Maestro pour les parcours | aucune raison courante | | Build et distribution | EAS Build, EAS Submit, EAS Update pour les correctifs JavaScript | aucune raison courante | **Ce qui revient souvent** : - **Tout ce qui est embarqué dans l'application est public.** Une clé dans le bundle est une clé publiée ([MF-006](https://maedow-flow.vercel.app/docs/regles#mf-006--les-secrets-restent-hors-de-portée)). Les appels qui exigent un secret passent par le serveur. - Une mise à jour à distance (EAS Update) ne change que le JavaScript. Tout changement natif (module, permission, configuration) exige un nouveau build et une nouvelle soumission : la `runtimeVersion` doit suivre, sinon l'application reçoit un code qu'elle ne sait pas exécuter. - La validation des stores prend des jours. Une date de sortie se planifie avec cette marge. - Permissions système, liens profonds et notifications se testent sur un appareil réel avant `GA`. ## Desktop | Couche | Défaut | Quand s'en écarter | | :--- | :--- | :--- | | Framework | Tauri 2 : interface Vite, React et TypeScript, cœur Rust réduit au nécessaire | Electron quand le produit dépend de l'écosystème Node côté système ou de modules natifs Node | | Architecture | Maedow Arch côté interface, commandes Rust fines côté système | aucune raison courante | | Sécurité | capacités Tauri déclarées au plus juste : chaque fenêtre n'accède qu'à ce qu'elle utilise | aucune raison | | Mises à jour | le plugin updater de Tauri, mises à jour signées | aucune raison | | Tests | Vitest pour l'interface ; WebDriver (`tauri-driver`) pour les parcours, sur Windows et Linux | aucune raison courante | | Build | GitHub Actions avec `tauri-action`, une cible par système | aucune raison courante | **Ce qui revient souvent** : - **La signature de code est un poste de coût et de délai** : certificat pour Windows, compte développeur et notarisation pour macOS. Sans elle, le système avertit l'utilisateur à l'installation. À prévoir dès le scope, pas la veille de la sortie. - Avec Electron : `contextIsolation` activé, `nodeIntegration` désactivé, un script de préchargement minimal qui n'expose que des fonctions précises. Jamais le module `fs` entier. - L'interface d'une application desktop reste du web : les règles [MF-007](https://maedow-flow.vercel.app/docs/regles#mf-007--ce-qui-entre-est-unknown) et [MF-008](https://maedow-flow.vercel.app/docs/regles#mf-008--lautorisation-se-vérifie-côté-serveur) valent entre l'interface et le cœur système, qui joue le rôle du serveur. ## Ce qui ne change pas d'un profil à l'autre Le cycle, les règles, le flux git, la commande `verify`, la CI, le kit. Un projet mobile et un projet web se conduisent exactement de la même façon ; seuls l'échafaudage, les tests de parcours et la distribution diffèrent. ======================================================================== # Sécurité ======================================================================== Le socle minimal, par domaine. Il ne remplace pas une revue de sécurité : il liste ce qu'un agent oublie par défaut, et que `/security-review` doit trouver fait avant chaque livraison. Chaque ligne est vérifiable. Une case qu'on ne sait pas vérifier se coche « non vérifié », jamais « fait ». ## Secrets ([MF-006](https://maedow-flow.vercel.app/docs/regles#mf-006--les-secrets-restent-hors-de-portée)) - [ ] Seul `.env.example` est versionné, sans aucune valeur réelle. - [ ] Aucun secret dans une variable publique (`NEXT_PUBLIC_`, `EXPO_PUBLIC_`, `VITE_`), ni dans un bundle mobile ou desktop. - [ ] Les modules qui manipulent un secret sont marqués `server-only`. - [ ] Le scan de secrets tourne en CI sur chaque pull request. - [ ] Les clés de service (clé `service_role` de Supabase, clé secrète Stripe) ne quittent jamais le serveur. ## Entrées ([MF-007](https://maedow-flow.vercel.app/docs/regles#mf-007--ce-qui-entre-est-unknown)) - [ ] Chaque route, action serveur et webhook valide son entrée par un schéma avant tout usage. - [ ] Aucune requête SQL construite par concaténation. - [ ] Les fichiers téléversés sont contrôlés côté serveur : type réel, taille, nom réécrit. - [ ] Le contenu fourni par un utilisateur est échappé à l'affichage ; aucun HTML brut injecté sans assainissement. ## Authentification - [ ] Un fournisseur éprouvé (Supabase Auth, Better Auth), jamais un système fait maison. - [ ] Cookies de session `HttpOnly`, `Secure`, `SameSite`. - [ ] Les messages d'erreur de connexion ne disent pas si le compte existe. - [ ] La réinitialisation de mot de passe expire et ne sert qu'une fois. ## Autorisation ([MF-008](https://maedow-flow.vercel.app/docs/regles#mf-008--lautorisation-se-vérifie-côté-serveur)) - [ ] Chaque accès protégé vérifie l'identité et le droit, côté serveur. - [ ] Chaque ressource vérifie son propriétaire (`commande.clientId === session.userId`), pas seulement la connexion. - [ ] RLS activée sur toutes les tables exposées, règles testées pour un utilisateur sans droit. - [ ] Les routes d'administration refusent un utilisateur ordinaire, vérifié par un test. ## Paiement - [ ] Prix et totaux calculés côté serveur depuis la base ; jamais reçus du client. - [ ] Le stock est revalidé au moment de payer. - [ ] Une commande n'est payée que sur un webhook dont la signature a été vérifiée. Arriver sur la page de succès ne prouve rien. - [ ] Le webhook est idempotent : l'identifiant d'événement est enregistré, un second envoi ne produit aucun effet. - [ ] Les cas d'échec et d'abandon laissent la commande dans un état cohérent. ## Abus - [ ] Limitation de débit sur la connexion, l'inscription, les formulaires publics et tout appel coûteux (IA, envoi d'e-mails, génération de documents). - [ ] Un plafond de dépense sur chaque service facturé à l'usage. - [ ] Si le produit utilise un modèle d'IA : le contenu des utilisateurs est traité comme une donnée, jamais comme une instruction ; les outils accessibles au modèle sont limités au nécessaire. La limitation de débit protège aussi la disponibilité. Le reste de ce qui empêche l'application de tomber sous un afflux de requêtes est dans [Tenir la charge](https://maedow-flow.vercel.app/docs/echelle#dès-le-premier-jour). ## En-têtes et navigateur (web) - [ ] `Content-Security-Policy`, `Strict-Transport-Security`, `X-Content-Type-Options: nosniff`, `frame-ancestors` ou `X-Frame-Options`. - [ ] Les requêtes qui modifient un état sont protégées contre la falsification de requête (CSRF) : vérification d'origine ou jeton. - [ ] CORS restreint aux origines connues. ## Données personnelles - [ ] On ne collecte que ce qui sert. - [ ] Aucune donnée personnelle ni aucun jeton dans les journaux. - [ ] Un utilisateur peut supprimer son compte et ses données. ## Dépendances - [ ] Le fichier de verrouillage est versionné. - [ ] Dependabot ouvre les mises à jour ; la CI les juge. - [ ] `npm audit` (ou l'équivalent) ne remonte aucune vulnérabilité haute ou critique sans décision écrite. ## Les outils | Outil | Quand | | :--- | :--- | | `/security-review` | avant chaque pull request `develop` vers `main` | | `/check review` | à chaque feature `Beta` ou `GA` | | Scan de secrets en CI | chaque pull request | | Avis de sécurité Supabase (`get_advisors`) | après chaque migration | | CodeRabbit | en option avant une livraison ; constats triés avant correction | ======================================================================== # Tenir la charge ======================================================================== Ce qu'il faut faire côté serveur pour que l'application ne tombe pas quand les requêtes affluent. La page distingue deux choses qu'on confond souvent : - **les précautions du premier jour**, qui ne coûtent presque rien et valent pour tout projet, avant même le premier utilisateur ; - **les étapes de montée en charge**, qui ajoutent chacune une brique d'infrastructure, et qu'on ne franchit que lorsque la mesure l'exige ([MF-014](https://maedow-flow.vercel.app/docs/regles#mf-014--pas-de-brique-sans-goulot-mesuré)) : chaque brique a un coût en complexité, en maintenance et en risque de données périmées. Source des étapes : la feuille de route de la vidéo [*How Senior Engineers Actually Think About System Design & Architecture*](https://www.youtube.com/watch?v=EaXHfuHRWwg) (JavaScript Mastery). La vidéo range les étapes par thème (serveurs, base de données, cache, asynchrone, données). Cette page les range **par coût** : on commence par ce qui ne coûte presque rien (un index), et l'on garde pour plus tard ce qui coûte une machine et une refonte (un second serveur, un partitionnement). ## Dès le premier jour Ces précautions ne sont pas des briques d'infrastructure. Elles ne coûtent presque rien, et ce sont elles qui évitent la panne le jour où le trafic arrive : MF-014 ne les concerne pas. | Précaution | Ce qu'elle évite | | :--- | :--- | | Toute liste est paginée, toute requête est bornée (`LIMIT`) | une page qui marche avec 100 lignes et écroule la base à 100 000 | | Chaque appel sortant (API tierce, IA, e-mail) a un délai d'expiration | un service tiers lent qui immobilise tous les serveurs pendant qu'ils attendent sa réponse | | Limitation de débit sur la connexion, les formulaires publics et les appels coûteux | un robot, ou un seul client mal écrit, qui monopolise les ressources de tous ([Sécurité](https://maedow-flow.vercel.app/docs/securite#abus)) | | Ce qui ne dépend pas de l'utilisateur part en cache HTTP (en-têtes `Cache-Control`, pages statiques) | une foule qui atteint le serveur alors que le CDN pouvait lui répondre | | La base se joint par un pool de connexions (en serverless, l'URL du pooler) | l'épuisement des connexions au premier pic, voir l'étape 2 plus bas | | L'application est sans état | une refonte le jour où il faut un second serveur, voir [Serverless ou serveurs à soi](#serverless-ou-serveurs-à-soi) | | La panne d'un service tiers dégrade une section, pas la page entière | une page blanche causée par un encart secondaire | | Un plafond de dépense sur chaque service facturé à l'usage | un pic de trafic transformé en pic de facture | ## Avant un pic annoncé Un lancement, une campagne, un passage dans les médias : une charge qui arrive d'un coup se prépare. 1. **Tester la charge sur un aperçu, jamais sur la production.** Un outil comme k6, sur les trois ou quatre parcours critiques, à deux ou trois fois le trafic attendu. Relever le p95, le taux d'erreurs et les connexions à la base. 2. **Vérifier les limites des abonnements** : concurrence des fonctions chez l'hébergeur, connexions maximales de la base, quotas des API tierces (e-mail, IA, paiement). La première limite atteinte est souvent un quota, pas un serveur. 3. **Préparer la défense** : le pare-feu applicatif de l'hébergeur et ses règles de limitation de débit. Sur Vercel, le mode de défi contre les attaques s'active en un geste si des robots affluent. 4. **Savoir reculer** : le retour arrière d'un déploiement en un clic, et un interrupteur (feature flag) pour couper une fonctionnalité coûteuse sans redéployer. ## Ce qu'on mesure avant de décider - Le temps de réponse au 95e centile (p95) des routes principales, pas la moyenne. - Le taux d'erreurs. - Les requêtes les plus lentes de la base, et leur plan d'exécution. - Le nombre de connexions ouvertes vers la base. - L'utilisation du processeur et de la mémoire de la base. Sans ces chiffres, aucune des étapes suivantes n'a de justification. Les outils de l'hébergeur (Vercel, Supabase) et PostHog les fournissent sans rien installer de plus. ## Les étapes de montée en charge, dans l'ordre | # | Étape | Le signal qui la déclenche | Ce qu'elle coûte | | :--- | :--- | :--- | :--- | | 0 | Un serveur (ou des fonctions serverless) et une base | le point de départ | rien : suffit pour des milliers d'utilisateurs | | 1 | Index | une requête fréquente lit toute la table (le plan d'exécution le montre) | un peu d'espace, des écritures légèrement plus lentes | | 2 | Pool de connexions (PgBouncer, Supavisor) | erreurs « too many connections », ou une connexion ouverte par invocation serverless | quasi nul ; **en serverless, dès le premier jour** | | 3 | Cache (Redis, Upstash, cache HTTP ou CDN) | le même calcul coûteux se répète (un nombre d'abonnés recalculé à chaque affichage), les lectures dominent largement les écritures | l'invalidation, et le risque de servir une donnée périmée | | 4 | Files d'attente et workers (Inngest, QStash) | une tâche de plus de quelques secondes bloque une requête : e-mails, rapports, appels d'IA | idempotence, reprises, suivi des échecs | | 5 | Répliques de lecture | la base primaire sature en lecture malgré index et cache | le décalage de réplication : une donnée écrite peut ne pas être encore lisible | | 6 | Répartition de charge (Nginx) et serveurs sans état | un seul serveur ne suffit plus | les sessions et tout état local déménagent dans un stockage partagé (Redis) ; déjà acquis en serverless | | 7 | Partitionnement des données (sharding) | les données ne tiennent plus sur une seule machine | très élevé : clé de partition à choisir une fois pour toutes (`user_id`), requêtes transverses, migrations, rééquilibrage. Dernier recours | ## Serverless ou serveurs à soi Le point de départ change ce qui est déjà fait pour toi. | Étape | En serverless (Vercel, Supabase) | Sur tes propres serveurs (VPS, machine dédiée) | | :--- | :--- | :--- | | 2 · Pool de connexions | à brancher dès le premier jour : l'URL du pooler, jamais la connexion directe | PgBouncer devant Postgres quand les connexions saturent | | 3 · Cache | Upstash, ou le cache de données et le CDN de l'hébergeur | Redis sur la machine, puis sur une machine à part | | 4 · Files d'attente | Inngest ou QStash, rien à héberger | un worker à part (BullMQ sur Redis, par exemple), supervisé comme un service | | 5 · Répliques | proposées par l'hébergeur de la base | réplication Postgres à configurer et à surveiller | | 6 · Répartition de charge | déjà faite : chaque requête peut atterrir sur une instance différente | Nginx (ou l'équilibreur du fournisseur) devant plusieurs instances identiques | Deux conséquences valent dès le premier jour, même avec un seul serveur : - **Écrire l'application sans état.** Pas de session en mémoire, pas de fichier téléversé sur le disque local, pas de tâche planifiée qui suppose une instance unique. Une application sans état passe à l'étape 6 en ajoutant une machine ; une application avec état y passe par une refonte. - **Sur tes propres serveurs, la production est aussi de l'exploitation** : HTTPS et son renouvellement, sauvegardes de la base testées par une vraie restauration, supervision et alertes, mises à jour de sécurité du système. Ces tâches arrivent avant la première mise en production, pas avec la croissance ; en serverless, l'hébergeur les porte. ## Trois erreurs classiques - **Le cache avant l'index.** Un cache masque une requête lente au lieu de la réparer, et ajoute l'invalidation par-dessus. - **Les microservices pour « préparer la croissance ».** Ils multiplient les déploiements, les pannes partielles et les appels réseau, pour un problème qu'on n'a pas encore. - **Mesurer la moyenne.** Une moyenne de 100 ms peut cacher un utilisateur sur vingt qui attend trois secondes. Le p95 le montre. ## Dans le cycle Une étape de montée en charge est une feature comme une autre : elle entre dans le scope, elle a sa spec `/architect` qui cite la mesure, et elle suit la boucle. La mesure qui l'a justifiée devient son critère d'acceptation (« le p95 de la liste des commandes passe sous 300 ms »). ======================================================================== # Prompts ======================================================================== Les formulations qui ont fait leurs preuves, rangées par moment du [cycle](https://maedow-flow.vercel.app/docs/cycle). Elles ont trois points communs : elles disent ce qui est hors périmètre, elles demandent une preuve, et elles séparent le moment de trouver du moment de corriger. Les skills du moteur portent déjà l'essentiel de ces consignes. Ces prompts servent quand on travaille sans skill, quand un skill ne couvre pas le cas, ou pour recadrer une session qui dérive. ## Explorer un projet ```text Explore ce projet et explique l'architecture actuelle, les technologies, les dossiers importants et la façon dont les pièces principales se connectent. Ne modifie rien. ``` ## Nettoyer AGENTS.md ```text Relis AGENTS.md en le confrontant au projet réel. Garde uniquement ce qu'un agent doit vraiment retenir d'une session à l'autre. Retire ce qui se lit directement dans le dépôt. N'ajoute aucune consigne générique du type « écris du code propre ». ``` ## Poser un design system depuis une référence ```text Étudie comme source visuelle pour ce projet. Analyse la typographie, les espacements, la mise en page, la navigation, les boutons, les bordures, les couleurs et le comportement responsive, sans copier ses textes, ses images ni sa marque. Puis implémente ces principes dans le projet : jetons de typographie, de couleur et d'espacement, conteneurs, boutons, liens, et primitives responsives, dans les fichiers de style appropriés. Explique brièvement les règles retenues et les fichiers modifiés. ``` Le point important : l'agent doit **implémenter** le design system, pas décrire la référence. ## Planifier une décision structurante En mode Plan (`/plan`), ou via `/architect` : ```text Inspecte le projet et planifie . Pour cette première version, on a seulement besoin de : . Étudie d'abord comment le code existant avant de décider. Ne prévois pas : . Montre-moi : - les changements de schéma et les migrations - les fichiers qui changent - les responsabilités côté serveur - ce qui vient du client et ce qui ne doit jamais en venir - comment on vérifiera l'implémentation, cas refusés compris N'implémente rien. ``` ## Simplifier un plan trop ambitieux ```text C'est plus complexe que ce dont l'application a besoin aujourd'hui. Garde et retire ainsi que tout ce qui ne sert pas l'application qu'on construit maintenant. Montre-moi le plan réduit. ``` ## Consigner une convention approuvée ```text Mets à jour AGENTS.md avec les conventions du plan qu'on vient d'approuver. Reste court. N'ajoute rien que l'agent puisse découvrir facilement dans le code. ``` ## Fournir un secret sans le montrer ```text est prêt et est défini dans .env.local. Utilise process.env. là où c'est nécessaire, sans lire le fichier d'environnement. Continue le plan approuvé. ``` ## Implémenter un plan approuvé ```text Implémente le plan approuvé, et seulement lui. Ne fais pas confiance aux valeurs fournies par le client pour : relis-les depuis le serveur. N'ajoute aucune fonctionnalité hors du plan. Lance les contrôles et vérifie le comportement sur l'application quand tu as fini. ``` ## Vérifier contre le plan ```text Relis l'implémentation en la confrontant au plan approuvé. Dis-moi : - ce qui a été fait correctement - ce qui a été fait autrement - ce qui manque encore - les problèmes reproductibles N'élargis pas le périmètre. Corrige uniquement ce qu'il faut pour que le plan approuvé soit complet. ``` Puis lis le diff toi-même : `git diff`, ou `/diff`. ## Enquêtes parallèles ```text Avant d'implémenter , enquête avec des sous-agents séparés : - un sous-agent sur - un sous-agent sur - un sous-agent sur Chacun rend : comportement actuel, fichiers concernés, risques, recommandation. N'implémente rien. Rassemble leurs conclusions en une synthèse courte. ``` Utile seulement si les enquêtes sont réellement indépendantes. ## Relecture fraîche d'une feature ```text Fais relire par un sous-agent neuf, sans modifier le code. Concentre la relecture sur : . Classe les constats en Critique, Majeur, Mineur, et dis ce qui n'a pas pu être vérifié. Ne change rien : rends la relecture d'abord. ``` ## Vérifier un constat ```text Confie ce constat à un sous-agent neuf. Vérifie s'il est réellement reproductible avant de toucher au code. Rends : - reproductible ou non - les étapes exactes de reproduction - les fichiers concernés - la cause probable Ne corrige rien. ``` ## Corriger seulement ce qui est confirmé ```text Corrige uniquement les problèmes confirmés de la relecture. Ne refonds pas la feature et n'élargis pas son périmètre. Relance les vérifications après les corrections et résume exactement ce qui a changé. ``` ## Trier des constats externes Pour CodeRabbit ou tout autre outil de revue : ```text Confronte ces constats à l'implémentation réelle. Pour chaque constat important, détermine s'il est pertinent et reproductible. Classe-les en : - problèmes confirmés - constats à vérifier plus avant - faux positifs ou hors sujet Ne change pas le code. ``` ## Revue d'ensemble Avant une livraison (phase 3), sur une session neuve : ```text Relis l'application dans son ensemble : . Cherche : - des fonctionnalités cassées - des flux de données incohérents - de la duplication inutile - une validation serveur manquante - des erreurs d'autorisation - des données client crues à tort - des conventions périmées dans AGENTS.md - des vérifications manquantes N'ajoute aucune fonctionnalité. Rends les constats d'abord. ``` ## Vérifier un parcours complet ```text Vérifie le parcours complet sur l'application qui tourne : <étape 1>, <étape 2>, …, . Vérifie aussi qu'un utilisateur ne peut ni accéder aux routes protégées ni déclencher les actions protégées. Signale tout ce qui n'a pas pu être vérifié. N'ajoute aucune fonctionnalité. ``` ## Resynchroniser le contexte En fin de tranche, si `/sync` n'a pas tourné à chaque lot : ```text Relis AGENTS.md en le confrontant au dépôt actuel. Garde uniquement les décisions durables qu'un agent doit retenir. Retire ce qui est périmé. N'ajoute rien que le code dise déjà. ```