noahwhite/engineering-workflow

Piloter une story du triage au déploiement via un processus découpé, piloté par les tests et validé par des gates : triage vers « en cours », TDD par slice, gate adversarial pré-PR (avec une boucle à deux lentilles plafonnée en escalade), PR vers la branche d'intégration, relecteurs optionnels, revue de référence (relecteur indépendant puis arbitre séparé), correction, fusion, déploiement, et passage en revue de déploiement. À utiliser quand on demande d'implémenter, compléter, préparer, relire, fusionner ou déployer une story. Un triage ou raffinement de backlog sans code relève d'une compétence product-owner.

Qu'est-ce que engineering-workflow ?

Cette compétence définit un workflow technique complet et rigoureux pour transformer une story logicielle en build déployé, en suivant un processus découpé (« slice »), piloté par les tests et validé par plusieurs gates obligatoires. Le processus débute par le triage de la story, où sont vérifiés le périmètre, les critères d'acceptation et les dépendances, avant de passer à l'état « en cours ». Ensuite, la story est décomposée en slices verticales de petite taille, chacune développée en TDD strict (Rouge-Vert-Refactor). Une étape clé est la « gate adversarial pré-PR » : elle exige l'exécution complète d'une revue adversarial (via le skill `adversarial-review-pipeline`), et, en cas de constats non résolus, une boucle d'escalade plafonnée à deux tours impliquant une lentille de correction, une lentille de simplicité, un vérificateur neutre et un correcteur. Une fois la gate passée, la PR est préparée et ouverte sur la branche d'intégration, avec une auto-relecture contre les critères d'acceptation. S'ensuit une phase de relecture optionnelle (non bloquante), suivie de la revue de référence obligatoire : un relecteur indépendant examine le code, puis un arbitre neutre vérifie chaque constat. Après corrections et re-revues éventuelles, la fusion et le déploiement sont réalisés, avec une vérification post-déploiement et une revue de déploiement finale. Le workflow est conçu pour être exécuté par des agents IA (Claude Code, Cursor, Codex) et repose sur des scripts et des fichiers de référence qui détaillent chaque capacité (gestion Linear, pratiques d'ingénierie, GitHub, revue de code, fusion, secrets). Les règles sont strictes : ne sauter aucune gate, ne pas introduire de modifications hors périmètre, et garantir l'intégrité des commits et des branches.

Compatible avec~Claude Code✓Codex CLI~Cursor
npx skills add https://github.com/noahwhite/agent-skills/tree/HEAD/skills/engineering-workflow

Installed? Explore more Développement et programmation skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Documentation

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

  1. Lisez references/profile.md, puis la surcouche de cette compétence et chaque surcouche de capacité que profile.overlays nomme.
  2. 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.

  1. Lisez la story complètement : critères d'acceptation, commentaires, problèmes liés et contexte.
  2. Identifiez le comportement souhaité, les critères d'acceptation, les contraintes, les composants probablement affectés et la stratégie de test.
  3. É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 que linear issue view --json ne les inclut pas (voir references/linear.md, Triage).
  4. Confirmez que la story appartient à ce dépôt.
  5. 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.
  6. Déplacez-la vers profile.tracker.states.in_progress et 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

  1. ROUGE : écrivez un test qui échoue pour le comportement.
  2. VERT : le code de production minimal pour le réussir.
  3. REFACTOR sans modifier le comportement.
  4. Exécutez les tests ciblés.
  5. 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 :

  1. Revue. Les deux lentilles examinent git diff origin/<branche d'intégration>...HEAD en 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.
  2. 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.
  3. 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

  1. 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.
  2. Inspectez git diff origin/<branche d'intégration>...HEAD après un fetch.
  3. Confirmez qu'il n'y a pas de modifications non liées et aucun secret.
  4. 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.
  5. Ouvrez la PR contre profile.git.integration_branch avec gh 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.
  6. Déplacez la story vers profile.tracker.states.in_review conformé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.

  1. 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).
  2. Déterminez le périmètre de la correction : fichier unique, petit.
  3. Pour chaque constat, corrigez le problème et validez que les tests passent.
  4. Marquez chaque constat comme résolu avec un résumé de la correction.
  5. Faites une re-relecture par l'arbitre de la revue de référence jusqu'à ce que le head soit propre.
  6. 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).

  1. Exécutez le pipeline de déploiement (profile.deployment.pipeline) sur la branche d'intégration.
  2. Vérifiez que le déploiement a réussi (statut, santé, etc.).
  3. Vérifiez les journaux de déploiement pour toute erreur.
  4. 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.

Skills associés