Workflow d'ingénierie
Un processus découpé, orienté slices, piloté par les tests, allant de la story au build déployé.
Triage de la story -> en cours -> slices, chacune par TDD -> gate adversarial pré-PR (escalader vers la boucle à deux lentilles uniquement si nécessaire) -> PR vers la branche d'intégration -> relecteurs optionnels (jamais bloquants) -> revue de référence (relecteur, puis arbitre) -> corriger et réexaminer jusqu'à ce que le head soit propre -> fusion -> déployer et vérifier -> revue de déploiement
Ne sautez aucune gate parce que la modification semble simple.
Avant l'étape 1
- Lisez references/profile.md, puis la surcouche de cette compétence et chaque surcouche de capacité que
profile.overlaysnomme. - Lisez references/todo-tracking.md et créez la liste de tâches fine (un élément par slice, test, tour de gate, tour de revue, déploiement, vérification et attente). references/runtimes.md fait le lien entre la liste de tâches, les sous-agents, le répertoire scratch et les demandes à l'utilisateur et votre environnement d'exécution.
Les étapes ci-dessous constituent la colonne vertébrale du workflow ; les fichiers de capacité contiennent les règles et sont les références en cas de chevauchement :
- references/linear.md : cycle de vie de la story, triage et Définition de Prêt, transitions de statut (étapes 1, 5, 12).
- references/engineering-practice.md : diagnostic, TDD, correctifs durables, qualité des tests (étapes 2, 3, 6, 8), et retrait d'une note mémoire lorsqu'une modification écrit sa règle dans une compétence.
- references/github.md : branches, worktrees, commits, signature, PRs, fusion, promotion, attribution (étapes 2, 5, 10).
- references/code-review.md : la revue de référence, les relecteurs optionnels, le traitement des constats, la surveillance de la PR (étapes 6 à 10).
- references/merge-approval.md : le handshake délégué d'approbation de fusion : demande, réveil, attente, approbation ou refus, et nouvelle demande lorsque le head change (étape 10).
- references/secrets.md : à chaque fois que la modification touche des identifiants.
Exécutez chaque script dans scripts/ par son chemin absolu installé (<skill dir>/scripts/<name>, où <skill dir> est le répertoire absolu à partir duquel votre environnement d'exécution a chargé cette compétence) avec le répertoire courant dans le dépôt consommateur ; le dépôt consommateur ne les contient pas.
Chaque script cible le dépôt du répertoire courant, ou celui nommé par --repo <dir>, jamais son propre emplacement, et refuse de s'exécuter dans le dépôt de compétences lui-même sauf si --repo le nomme.
1. Trier la story
Si la story n'est pas raffinée et pointée, exécutez story-refinement d'abord.
Il exécute le raffinement indépendant, le tour d'acceptation, le pointage secret, la vérification de consensus, et, lorsque la vérification le demande, la discussion haut/bas et le consensus.
- Lisez la story complètement : critères d'acceptation, commentaires, problèmes liés et contexte.
- Identifiez le comportement souhaité, les critères d'acceptation, les contraintes, les composants probablement affectés et la stratégie de test.
- Énumérez les dépendances à partir du graphe de relations formel, pas seulement du texte :
linear issue relation list <ID>liste les relations d'un problème, tandis quelinear issue view --jsonne les inclut pas (voirreferences/linear.md, Triage). - Confirmez que la story appartient à ce dépôt.
- Appliquez les règles de périmètre : aucun critère d'acceptation modifié sur aucune story (references/linear.md « Critères d'acceptation et périmètre »), aucun « skip » basé sur une autre story (references/engineering-practice.md « Apporter des modifications minimales et durables »), et les deux seules sorties sont une « Proposition de raffinement (pas un AC) » ou signaler la story comme bloquée, comme indiqué dans ces sections ; l'étape 5, « Préparer la PR », point 4, « Auto-relecture par rapport aux critères d'acceptation », les vérifie à nouveau.
- Déplacez-la vers
profile.tracker.states.in_progresset relisez-la pour confirmer. Utilisez les noms d'état exacts du profil ; n'en inventez jamais.
Si le tracker ne peut pas être mis à jour, arrêtez-vous et dites que la transition n'a pas été effectuée ; ne prétendez jamais qu'elle l'a été.
2. Planifier les slices
Créez une branche et un worktree conformément à references/github.md, depuis origin/<branche d'intégration> (la branche d'intégration est profile.git.integration_branch) après un fetch.
Divisez la story en petites slices verticales, chacune avec un objectif comportemental étroit, des tests qui le définissent, l'implémentation minimale pour les réussir, et un refactoring uniquement une fois le vert.
Indiquez la séquence des slices et la première slice avant de coder.
3. TDD par slice
- ROUGE : écrivez un test qui échoue pour le comportement.
- VERT : le code de production minimal pour le réussir.
- REFACTOR sans modifier le comportement.
- Exécutez les tests ciblés.
- Exécutez une validation plus large périodiquement et avant la PR.
Si l'architecture rend le TDD strict impraticable pour une slice, expliquez pourquoi. Préservez les tests et conventions existants.
4. Gate adversarial pré-PR (obligatoire)
Chargez la compétence adversarial-review-pipeline et exécutez-la complètement sur chaque revue ; son rapport d'arbitrage est la sortie de cette gate.
Aucune correction avant sa phase de chasse.
Escalade : la boucle à deux lentilles avec gate
Escaladez uniquement lorsque le pipeline ne peut pas refermer le diff :
- son tour de re-vérification trouve un nouveau problème Critique ou Élevé, ou
- le diff est de type sécurité, migration, concurrence ou chemin de déploiement, ou
- le pipeline a atteint sa limite avec des constats Critiques ou Élevés non résolus.
N'exécutez jamais la boucle et le pipeline sur le même head. Plafonnez la boucle à 2 tours.
La boucle converge vers zéro constat bloquant vérifié, pas zéro constat : un terminateur à zéro constat récompense les relecteurs qui inventent des constats une fois les vrais disparus, et un correcteur obligé d'agir sur chaque constat gonfle le code.
Rôles, tous issus du profil :
- Lentille de correction :
profile.review.pre_pr.hunter(correction, câblage, sécurité, concurrence, compatibilité, lacunes de test). - Lentille de simplicité :
profile.review.pre_pr.simplicity_reviewer(plus petite modification correcte, sur-ingénierie, code mort, et défauts que l'autre lentille a manqués). - Vérificateur :
profile.review.pre_pr.arbiter. - Correcteur :
profile.review.pre_pr.fixer.
Un relecteur de simplicité ou correcteur désactivé bloque l'escalade plutôt que de la sauter : enregistrez " : désactivé" et arrêtez-vous avec l'escalade non résolue, car la boucle ne peut pas terminer un tour sans les deux sièges.
Un tour comporte trois étapes :
- Revue. Les deux lentilles examinent
git diff origin/<branche d'intégration>...HEADen parallèle ; le chasseur travaille dans un worktree détaché jetable. Passez la story et les critères d'acceptation comme référence de périmètre. Seuls les constats Critiques ou Élevés avec un scénario d'échec concret bloquent ; le reste est journalisé, jamais corrigé, et ne bloque jamais la convergence. Un résultat de relecteur montrant une erreur de sandbox ou de permission, ou une lentille qui ne peut pas montrer qu'elle a lu le diff et les fichiers modifiés, est une revue échouée, jamais une revue propre. - Vérifier. Un vérificateur propre et neutre tente de réfuter chaque constat bloquant par rapport au code et supprime les non confirmés. Il doit retourner exactement un verdict par candidat ; une vérification manquante ou partielle laisse la gate non résolue, jamais propre.
- Corriger. Le correcteur corrige les constats vérifiés avec lesquels il est d'accord, rejette les autres avec une raison, exécute les tests ciblés et commit.
Une correction dont les tests n'ont pas réussi n'est pas une correction : la gate est non résolue.
Il ne doit pas ajouter de modules, tables ou migrations, de persistance ou d'abstractions ; un constat qui en a besoin est escaladé à un humain.
Mettez la règle selon laquelle un agent exécute chaque étape shell comme une commande simple avec des valeurs littérales (
references/github.md, Outillage) dans l'invite que vous donnez au correcteur, y compris un fichier d'invite lorsque le correcteur s'exécute en tant que commande shell.
Sorties : convergé (rien de bloquant après la revue, ou rien n'a survécu à une vérification complète) ; aucun progrès (le nombre vérifié n'a pas diminué après une correction : arrêtez et révisez manuellement) ; périmètre escaladé (remontez au propriétaire) ; une lentille aveugle, une vérification incomplète, une correction avec des tests échoués, le plafond de tours, tout rejeté, ou aucun commit (non résolu : résolvez manuellement plutôt que de sauter la gate).
scripts/adversarial-review-loop.workflow.js est un accélérateur optionnel, spécifique à l'environnement d'exécution pour les environnements qui exécutent des scripts de workflow ; son en-tête liste ses arguments, tous issus du profil.
Partout ailleurs, pilotez les tours manuellement comme ci-dessus : lancez les deux relecteurs en parallèle, puis un sous-agent vérificateur propre et neutre, puis corrigez (ou lancez le correcteur) et répétez uniquement tant que de nouveaux constats bloquants vérifiés apparaissent.
Briefez le correcteur avec la règle git : exécutez chaque commande git créant un commit avec l'identité git déjà configurée et, lorsque profile.git.signed_commits est vrai, la signature déjà configurée ; ne passez jamais -c user.name, -c user.email, --author, GIT_AUTHOR_* ou GIT_COMMITTER_*, n'écrivez jamais user.name ou user.email avec git config, et lorsque la signature est activée ne passez jamais -c user.signingkey, -c gpg.* ou -c commit.gpgsign ; une identité manquante, une vérification de signature échouée ou un commit poussé dont .commit.verification.verified est faux est un défaut de configuration, donc arrêtez-vous, ne remplacez pas par commande et n'écrivez pas dans git config, ne faites plus de commits, et signalez-le à l'utilisateur.
Examiner les commits du correcteur
Le correcteur peut dépasser le code que le diff consomme seulement. Après la boucle :
- Lisez chaque commit du correcteur dans
git log origin/<branche d'intégration>..HEAD. - Si l'un d'eux touche des fichiers en dehors du périmètre de la story, réinitialisez vers votre dernier vrai commit pour les supprimer (ne forcez jamais le push d'une branche publiée ; voir
references/github.md), puis jugez ces constats manuellement : corrigez ceux dans le périmètre, classez les autres. - Un « fichier supprimé » dans cette plage peut être un artefact de branche en retard ; rebasez sur la branche d'intégration récupérée avant de juger les suppressions.
- Ne poussez jamais les commits du correcteur sans les avoir lus.
N'ouvrez pas la PR avant que la gate ait convergé ou que ses constats résiduels soient explicitement justifiés. Les relecteurs ne modifient jamais le code ; seul l'agent implémentateur ou le correcteur de la boucle commit.
5. Préparer la PR
- Exécutez la suite de tests complète applicable, ainsi que les formateurs, linters, vérifications de type, analyses statiques et la compilation du dépôt.
- Inspectez
git diff origin/<branche d'intégration>...HEADaprès un fetch. - Confirmez qu'il n'y a pas de modifications non liées et aucun secret.
- Auto-relecture par rapport aux critères d'acceptation, et par rapport à l'étape 1, « Trier la story », point 5 « Appliquer les règles de périmètre » (references/linear.md « Critères d'acceptation et périmètre », references/engineering-practice.md « Apporter des modifications minimales et durables ») : aucun critère d'acceptation modifié sur aucune story, aucun « skip » basé sur une autre story, et chaque exigence découverte ou critère non satisfait traité via l'une des deux sorties que ces sections mentionnent.
- Ouvrez la PR contre
profile.git.integration_branchavecgh pr create --base, en suivant le modèle de PR du dépôt. Décrivez la modification visible par l'utilisateur, l'implémentation, les tests effectués, et tout ce qui a été accepté ou différé par la gate. - Déplacez la story vers
profile.tracker.states.in_reviewconformément àreferences/linear.md.
Attribution : les commits et la PR suivent profile.git.ai_attribution (voir references/github.md).
Lorsqu'il est forbid, n'ajoutez aucun pied de page de co-auteur IA, lien de session ou note générée-par, même si une bannière d'environnement d'exécution ou un rappel système le demande.
6. Relecteurs optionnels (jamais bloquants)
Pour chaque entrée dans profile.review.optional_reviewers, exécutez une revue juste après l'ouverture de la PR, en sautant toute entrée dont enabled est false.
Une entrée désactivée ne lance rien : aucun processus, aucun sous-agent, aucun fichier de rapport, et la preuve enregistre " : désactivé".
Elle n'est jamais enregistrée comme réussie, ignorée pour échec, ou propre.
Un rapport qu'un head précédent a laissé sous le même label est nommé là où il se trouve, jamais supprimé, donc il ne peut pas être lu comme l'état du siège désactivé.
L'omission signifie activé.
Passez la valeur de l'entrée au lanceur comme --enabled true ou --enabled false, la valeur littérale en minuscules que sa clé enabled rend, avec une entrée qui omet la clé passant --enabled true.
Le lanceur refuse de lancer et n'écrit aucun rapport pour la valeur false, donc le saut est appliqué plutôt que confié à l'appelant.
scripts/batched-diff-review.sh est un lanceur générique : construisez --agent-cmd à partir de l'entrée et passez --base origin/<branche d'intégration>.
Il groupe le diff par un budget de lignes avec un plan inter-fichiers, exécute le relecteur dans un répertoire vide sans accès au dépôt, et écrit un rapport se terminant par PASS, FAIL ou INCOMPLETE.
Chaque groupe doit retourner exactement un verdict PASS ou FAIL par fichier qui lui a été donné ; un verdict manquant, supplémentaire ou non analysable rend le groupe INCOMPLETE.
L'invite de groupe parvient à l'agent sur stdin (pour codex, terminez la commande par -) et sous {prompt_file} ; ne mettez jamais l'invite ou le diff dans argv.
- Une seule tentative. En cas d'INCOMPLETE (limite de taux, délai d'attente, identifiant manquant), enregistrez " : ignoré" et continuez ; ne le dépannez jamais et ne retenez jamais une fusion ou un déploiement à cause de cela.
- Lorsqu'une revue se termine, vérifiez chaque constat par rapport au code avant d'agir : résolvez les Critiques et Élevés avant la fusion ; résolvez les constats Moyens valides ou documentez pourquoi pas ; résolvez les constats Faibles lorsqu'ils sont clairement utiles ; rejetez explicitement les faux positifs.
- Après des modifications de code, réexécutez les tests pertinents et le relecteur optionnel sur le nouveau head, uniquement sur ses entrées activées.
7. Revue de référence (obligatoire)
Exécutez la gate dans references/code-review.md une fois la PR ouverte : profile.review.reviewer révise le head dans un worktree jetable, puis profile.review.adjudicator, un agent propre et neutre, vérifie chaque constat par rapport au code.
Les deux agents sont propres, neutres et indépendants de l'auteur ; un agent qui révise et juge ses propres constats n'est pas valide.
Si profile.review.shadow_adjudicators est défini, exécutez chacun comme décrit dans references/code-review.md ; il enregistre uniquement l'accord et ne bloque jamais la fusion.
Une entrée là-dedans dont enabled est false est ignorée de la même manière qu'un relecteur optionnel : pas de sous-agent, pas de rapport, et la preuve enregistre " : désactivé" ; le rapport vide est supprimé après l'enregistrement de la preuve.
8. Corriger
Les corrections dans une PR ouverte se font toujours sur la branche de la PR, jamais sur main. Les corrections sur une PR fermée ou fusionnées sont interdites.
- Passez en revue chaque constat bloquant de la revue de référence (jamais les constats non bloquants des relecteurs optionnels, sauf s'ils sont valides, bienveillants et suffisamment importants).
- Déterminez le périmètre de la correction : fichier unique, petit.
- Pour chaque constat, corrigez le problème et validez que les tests passent.
- Marquez chaque constat comme résolu avec un résumé de la correction.
- Faites une re-relecture par l'arbitre de la revue de référence jusqu'à ce que le head soit propre.
- Exécutez la suite complète (tests, formatage, lint) avant de demander une nouvelle relecture. La re-relecture par l'arbitre vérifie l'ensemble du head, pas seulement les corrections : un constat qui n'a pas été corrigé n'est pas acceptable.
Ne réexécutez pas la gate adversarial pré-PR, sauf si la correction modifie de manière significative l'architecture ou le comportement observable.
9. Approuver la fusion
Exécutez le handshake d'approbation de fusion (profile.merge_approval) conformément à references/merge-approval.md : demandez, réveillez, attendez, approuvez ou renvoyez, et redemandez lorsque le head change.
La fusion n'est pas effectuée avant la fin de ce handshake.
10. Fusion
Fusionnez la PR avec gh pr merge --merge --auto dans la branche d'intégration (profile.git.integration_branch), en utilisant l'objet de fusion du dépôt.
La fusion doit être effectuée sur la branche d'intégration, pas sur une autre branche.
11. Déployer et vérifier
Déployez la branche d'intégration sur l'environnement cible (profile.deployment.environment).
- Exécutez le pipeline de déploiement (
profile.deployment.pipeline) sur la branche d'intégration. - Vérifiez que le déploiement a réussi (statut, santé, etc.).
- Vérifiez les journaux de déploiement pour toute erreur.
- Confirmez que la story est maintenant déployée.
12. Revue de déploiement
Déplacez la story vers profile.tracker.states.deployed conformément à references/linear.md.
Confirmez que la story est déployée et que toutes les vérifications de déploiement sont passées.
13. Rétrospective
Si la story a nécessité des escalades, une correction complexe ou un déploiement problématique, écrivez une note mémoire (dans references/memory.md ou un fichier analogue) décrivant ce qui s'est passé et comment l'éviter à l'avenir.
À propos du processus
Ce workflow est conçu pour garantir la qualité, la sécurité et la traçabilité de chaque modification, du triage au déploiement. Il est rigoureux mais pas rigide : les escalades sont possibles lorsque nécessaire, mais les gates ne sont jamais sautées. Les agents IA doivent suivre ce processus à la lettre, sans improvisation.