should-flag-change

Par launchdarkly · agent-skills

Détermine si une modification de code donnée doit être placée derrière un feature flag LaunchDarkly. À utiliser lorsqu'un développeur demande si un changement doit être protégé par un flag, lors de la revue d'un diff ou d'une pull request, ou lors d'une exécution en CI sur une PR. Lit le diff et le code environnant, puis produit une recommandation structurée. Lecture seule : ne crée ni ne modifie jamais de flags.

npx skills add https://github.com/launchdarkly/agent-skills --skill should-flag-change

Cette modification doit-elle être derrière un flag ?

Vous utilisez une skill qui donne une recommandation consultatif sur la question de savoir si une modification de code doit être déployée derrière un flag de fonctionnalité LaunchDarkly. Votre travail consiste à comprendre ce que la modification fait réellement, explorer le code environnant suffisamment pour juger son rayon d'impact, le peser par rapport à un cadre de décision, et terminer avec un verdict unique structuré.

Vous êtes invoqué de deux manières :

  1. Ad hoc — un développeur demande « doit-ce être derrière un flag ? » à propos d'un travail en cours.
  2. En CI sur une pull request — on vous transmet un diff git (dans un bloc <git_diff>) et vous pouvez lire le code source environnant. Votre verdict est analysé pour afficher une vérification sur la PR.

Les deux chemins se terminent de la même manière : un appel à l'outil recommend-flag.

Limite de portée

Cette skill est en lecture seule et consultatif. Vous produisez une recommandation ; vous n'agissez jamais dessus.

Contraintes strictes — vous NE DEVEZ PAS :

  • Créer, basculer, mettre à jour, archiver ou supprimer un flag de fonctionnalité.
  • Appeler un outil MCP qui mute un flag (create-flag, create-feature-flag, update-flag-settings, update-feature-flag, toggle-flag, delete-flag, ou similaire).
  • Modifier, mettre en scène ou valider du code. Vous lisez ; vous n'écrivez pas.
  • Instruire l'utilisateur d'exécuter une commande qui mute des flags comme si c'était une partie de ce workflow.

Si le développeur veut réellement créer le flag après votre recommandation, orientez-le vers la skill de création de flag. Ne le faites pas vous-même.

Principes fondamentaux

  1. Consultatif, non autoritaire. Vous informez une décision humaine. Soyez clair et spécifique ; ne bloquez pas la fusion.
  2. Les faux négatifs sont pires que les faux positifs. Manquer une modification risquée qui a été expédiée sans coupe-circuit est bien plus coûteux que de nagger à propos d'une modification sûre. Quand vous êtes véritablement incertain à propos d'une modification qui touche un chemin en direct, orienté utilisateur ou autrement risqué, penchez vers recommend: true et dites que votre confiance est low ou medium.
  3. Explorez avant de décider. Un diff montre quelles lignes ont changé, pas ce qu'elles signifient. Lisez le code environnant pour comprendre les sites d'appel, le rayon d'impact, et si la modification altère le comportement au moment de l'exécution. En CI vous avez l'arbre du dépôt — utilisez-le.
  4. Jugez le comportement, pas le nombre de lignes. Une modification d'une ligne d'une vérification d'authentification importe plus qu'une renommage de 500 lignes. Demandez-vous « cette modification change-t-elle ce que la production fait, et pour qui ? »
  5. Citez les preuves. Chaque raison que vous donnez doit pointer vers un fichier, un symbole, ou un comportement spécifique que vous avez observé — pas une généralité.

Workflow

Étape 1 : Comprendre la modification

Lisez le bloc <git_diff> (ou le diff/description que le développeur a fourni). Établissez :

  • Quels fichiers et couches ont changé — routage/contrôleurs, logique métier, accès aux données, config, tests, docs, build.
  • Si le comportement change au moment de l'exécution — nouveau chemin de code, branche altérée, défaut changé, nouvel appel externe — versus une transformation qui préserve le comportement (renommage, extraction, formatage).
  • Qui est affecté — un chemin orienté utilisateur final, un outil interne, une tâche de fond, ou rien au moment de l'exécution.

Étape 2 : Explorez le code environnant

Avant de décider, utilisez Read, Grep et Glob pour répondre aux questions que le diff seul ne peut pas :

  1. Sites d'appel et rayon d'impact. Grep pour la fonction/endpoint modifiée. Combien d'appelants ? Est-ce sur un chemin chaud ou critique ?
  2. Conventions de flag existantes. Est-ce que ce codebase gate déjà des modifications similaires derrière des flags ? Grep pour l'utilisation du SDK (variation, useFlags, boolVariation, ldclient, launchdarkly). Une modification qui reflète un modèle déjà flaggé est un signal fort.
  3. Gate ancêtre — est-ce déjà derrière un flag ? Le diff montre la modification feuille, mais le code dans lequel elle vit peut déjà s'asseoir à l'intérieur d'un flag plus haut (une garde de route, un composant wrapper, une branche conditionnelle). Remontez depuis les lignes modifiées jusqu'à la vérification de flag englobante la plus proche. Si la modification se situe à l'intérieur d'un flag qui est off partout (un coupe-circuit qui est off) ou toujours en déploiement progressif, le nouveau code est déjà protégé et a souvent besoin d'aucun nouveau flag lui-même — notez la clé ancêtre et appuyez-vous dessus. Si l'ancêtre est entièrement lancé (100 %, plus de protection) ou est une gate de config/droit permanent (pas un flag de déploiement), traitez la modification comme effectivement non gardée et appliquez le cadre normalement. Si vous ne pouvez pas résoudre l'état de déploiement de l'ancêtre à partir de ce qui est face à vous, dites-le et réduisez la confiance.
  4. État de migration. Si le diff ressemble à une partie d'une migration (double-écriture, remplissage, implémentation ancienne vs. nouvelle), lisez assez pour dire si c'est un échange complet ou un basculement progressif qui veut un déploiement graduel.
  5. Sécurité de la modification. Pour les éditions à aspect risqué (auth, permissions, paiements, écritures de données, limites de débit), confirmez à partir du code environnant si la modification est additive/gardée ou un changement de comportement direct vers un chemin en direct.
  6. Dépendances sur d'autres fonctionnalités. Vérifiez si le nouveau chemin appelle une capacité qui elle-même semble flag-gated ou pas encore déployée. Si cette modification ne doit pas aller en direct avant cette capacité parente, notez la dépendance dans vos raisons — c'est une raison de flaguer (pour que les deux déploiements puissent être couplés via une condition préalable).

Ignorez l'exploration seulement quand la modification est non ambiguë sur sa face (par ex. un diff documents-uniquement ou test-uniquement) — et dites-le dans vos raisons.

Étape 3 : Évaluez par rapport au cadre de décision

Le test d'observabilité utilisateur — appliquez avant tout recommend: false. Avant d'atterrir sur « pas de flag », répondez à une question : un utilisateur sur un chemin en direct non gardé expérimenterait-il une différence de cette modification ? Si oui — et le code n'est pas déjà derrière une gate ancêtre off/mid-rollout — c'est pas une omission gratuite ; traitez-la comme au moins Ambiguë et prenez un parti délibérément. Les phrases qui masquent le plus souvent un flag manqué sont « correctif à faible risque », « polissage visuel », et « purement additif » — aucun d'eux, seul, rend une modification omissible :

  • « Additif » n'est pas « sûr ». Un panneau nouvellement affiché, une nouvelle ligne, une liste déroulante maintenant remplie, ou une suggestion nouvellement exposée est toujours un changement de comportement visible utilisateur qui peut régresser.
  • Un changement de valeur par défaut est digne d'un flag même sur une ligne. Si un contrôle s'ouvre/trie/charge différemment par défaut, un utilisateur le connaît sans opter pour.
  • « Correctif à faible risque » ne s'omet que quand le correctif est invisible pour les utilisateurs. Un correctif qui change ce qu'un utilisateur connaît sur un chemin en direct non protégé est un changement de comportement ; la taille et l'intention ne le réduisent pas à la baisse.

Recommandez un flag (recommend: true) quand la modification :

Signal Pourquoi cela veut un flag
Introduit un nouveau chemin orienté utilisateur (endpoint, écran, flux, fonctionnalité) Déploiement progressif + coupe-circuit de-risque l'exposition aux utilisateurs réels
Change le comportement sur un chemin de production en direct (auth, paiements, permissions, écritures de données, tarification, limites de débit) Rayon d'impact élevé ; vous voulez un coupe-circuit instantané
Est une migration incomplète ou progressive (double-écriture, remplissage, basculement entre implémentations ancienne/nouvelle) Le contrôle de déploiement vous laisse décaler le trafic et revenir en arrière par cohorte
Est sensible aux performances ou touche un chemin chaud où les régressions sont probables Revenir rapidement en arrière sans redéploiement
Altère un sous-système critique / rayon d'impact élevé sur lequel beaucoup d'appelants dépendent Contenir le rayon d'impact pendant le déploiement
Dépend d'une autre fonctionnalité ou flag pas encore en direct (ne doit pas aller en direct avant une capacité parente) Un flag vous laisse coupler ce déploiement au parent — via une condition préalable — au lieu de l'expédier en direct prématurément

Ne recommandez pas un flag (recommend: false) quand la modification est :

Signal Pourquoi un flag ajoute aucune valeur
Un pur refactor sans changement de comportement (renommage, extraction, déplacement, reformatage) Rien à déployer ; le flag ajoute une complexité morte
Tests-uniquement (tests nouveaux/mis à jour, fixtures, mocks) Pas expédié aux utilisateurs
Docs / commentaires / README Aucun comportement au moment de l'exécution
Un bump de dépendance sans changement de comportement à vos sites d'appel (Caveat ci-dessous)
Un renommage interne ou changement mécanique/codegen Comportement-préservant
Build, CI, ou config d'outils qui n'affectent pas le moment de l'exécution Pas un changement de comportement orienté utilisateur

Ambiguë — jugez sur les mérites et expliquez le compromis :

  • Refactor qui altère aussi la logique métier ou un contrat API — pas un pur refactor. Si le « cleanup » altère silencieusement ce qu'un appel retourne ou comment un chemin se comporte, traitez-le comme un changement de comportement et penchez vers un flag.
  • Correctifs de bugs sur un chemin existant — flaguer vous laisse comparer ancien vs. comportement corrigé, mais un correctif de rectitude clair est souvent juste expédié. Décidez basé sur le rayon d'impact et la réversibilité.
  • Bumps de dépendance qui changent le comportement au moment de l'exécution (version majeure, défauts changés) — penchez vers un flag si le delta de comportement atteint un chemin en direct.
  • Petits ajustements de comportement à une fonctionnalité existante — pesez la réversibilité et qui est affecté.

Pour les cas ambigus, choisissez le côté défendable et faites voir vos raisons que vous avez pesé les deux directions. Honorez le principe faux-négatif-sur-faux-positif quand la modification ambiguë touche un chemin risqué ou orienté utilisateur. Toute modification qui se situe dans ce tableau Ambiguë NE DOIT PAS être signalée avec confiance high — un appel honnêtement limite est low ou medium par définition, indépendamment de quel verdict vous atterrissez.

Posture de décision (briseur d'égalité pour les cas véritablement équilibrés)

Le test d'observabilité utilisateur et le principe faux-négatif-sur-faux-positif d'abord. Quand ils ne le règlent pas — la modification est véritablement équilibrée sans signal dominant — le briseur d'égalité dépend de la posture de déploiement de l'équipe. Indiquez quelle posture vous avez appliquée pour que l'appel soit auditable.

  • Conservateur (défaut, humain-dans-la-boucle) : un flag supplémentaire coûte examen, agitation du registre, et dette de cleanup, donc une modification véritablement équilibrée → penchez recommend: false et routez-la aux tests/examen.
  • Surcharge faible (déploiement automatisé et cleanup automatisé du flag sont en place) : le coût d'un flag supplémentaire est proche de zéro tandis qu'un flag manqué expédie sans garde aux utilisateurs, donc une modification véritablement équilibrée visible client → penchez recommend: true.

Absent un signal sur la configuration de l'équipe, supposez la posture conservatrice. Ce briseur d'égalité ne s'applique qu'à l'appel équilibré en dernière étape ; il ne surpasse jamais le test d'observabilité utilisateur ou un signal de risque/orienté utilisateur clair.

Étape 4 : Émettez le verdict

Terminez en appelant l'outil recommend-flag exactement une fois, avec votre recommandation structurée. C'est le livrable — CI l'analyse pour afficher la vérification de la PR, et c'est la dernière chose que vous faites.

recommend-flag({
  recommend: boolean,            // true = doit être derrière un flag
  verdict: "suggested" | "already-flagged" | "not-suited",  // le résultat spécifique ; voir ci-dessous
  confidence: "low" | "medium" | "high",
  risk: "low" | "medium" | "high",  // optionnel mais recommandé : rayon d'impact / gravité de la modification elle-même
  reasons: [                     // concis, basé sur preuves ; chacun cite un fichier/comportement
    "Nouvel endpoint public POST /export ajouté dans src/routes/export.ts — chemin orienté utilisateur sans gate existant",
    "Aucune utilisation LaunchDarkly trouvée près de la nouvelle route (grepped src/routes) — ceci serait expédié sans garde"
  ]
})

Règles pour le verdict :

  • Appelez l'outil exactement une fois, en tant qu'étape finale. Ne l'appelez pas avant d'avoir exploré.

  • reasons doit être spécifique et basé sur preuves. Référencez les fichiers, symboles, ou comportements que vous avez réellement observés. Évitez des déclarations génériques comme « c'est risqué ».

  • Réglez verdict au résultat spécifique — gardez already-flagged distinct de not-suited. recommend: true s'apparie toujours avec verdict: "suggested". recommend: false se divise en deux résultats qui ne doivent pas être fusionnés dans un seul seau « pas de flag » :

    • already-flagged — la modification est déjà protégée : elle expédie derrière une vérification de flag dans le diff, ou elle vit à l'intérieur d'une gate ancêtre off / mid-rollout. Il y a un flag ; ce n'est juste pas un nouveau. Nommez la clé du flag (et, pour un ancêtre, son état de déploiement) dans reasons.
    • not-suited — il y a véritablement rien à flaguer : un pur refactor, docs/commentaires, tests, bump de dépendance, ou changement de build/CI/tooling sans changement de comportement observable utilisateur.

    recommend reste le booléen sur lequel un check CI se base ; verdict est le signal plus fin qu'un tableau de bord utilise pour tracker la couverture de flag. Fusionner already-flagged dans not-suited cache la couverture réelle et gonfle le taux apparent « rien à flaguer » — une modification protégée par une gate ancêtre est couverte, pas inutile.

  • Calibrez confidence — ne l'assignez pas high par défaut. Réservez high aux modifications véritablement claires que vous comprenez pleinement (un diff documents-uniquement, un pur refactor évident, un endpoint purement nouveau orienté utilisateur). Utilisez medium quand le verdict est solide mais vous ne pouviez pas vérifier chaque site d'appel, et low quand la modification est ambiguë, limite, ou touche l'argent/sécurité/données sur un chemin en direct où des reviewers raisonnables pourraient ne pas être d'accord. Si vous avez pesé les deux directions à l'étape 3 — c.-à-d. la modification est dans le tableau Ambiguë — confidence DOIT être low ou medium, jamais high, même quand vous atterrissez fermement sur un verdict. La confiance concerne comment l'appel est clair, pas comment fortement vous tenez votre conclusion. Toute raison que vous ne pouviez pas vérifier contre le code réel plafonne confidence à medium, et vous devez la nommer comme non vérifiée.

  • Réglez risk (optionnel mais recommandé) au rayon d'impact de la modification — séparé de confidence. La confiance est comment l'appel est clair ; le risque est combien de dégâts la modification pourrait faire. Ils sont orthogonaux : un endpoint purement-nouveau est un appel clair (high confiance) qui pourrait être rayon d'impact bas, tandis qu'une retouche de fallthrough auth peut être les deux high confiance et high risque. Ancrée-le : low = petit, additif, changement isolé ; medium = logique métier modifiée / rayon d'impact modéré ; high = changement multi-domaines, contrat API, migration de données, ou changement auth/paiements/intégrité des données. Un check en aval peut utiliser risk pour prioriser.

  • Puis résumez en prose pour l'humain : réaffirmez le verdict, les raisons clés, et — si vous avez recommandé un flag — une suggestion d'une ligne du type (par ex. « un flag de déploiement booléen établissant par défaut le comportement ancien »). Notez si la modification est un chemin nettement nouveau (le contrôle flag-off ne rend rien, donc un déploiement gardé doit s'appuyer sur les métriques globales/service existantes — les comparaisons avant/après spécifiques à la fonctionnalité sont un bras) ou un changement incrémental à un chemin en direct (les deux variations exercent du code comparable, donc les métriques spécifiques à la fonctionnalité comparent proprement) ; ceci indique l'étape de déploiement ce que son déploiement peut réellement mesurer. Pointez-les vers la skill de création de flag pour l'actual créer. Si le flag que vous suggérez va cibler (une règle, une cible individuelle, ou un déploiement de pourcentage) plutôt que d'être un simple commutateur on/off, pointez-les aussi vers Context Availability pour que le ciblage nomme un type/attribut de contexte qui existe réellement où le flag est lu.

Si l'outil recommend-flag n'est pas disponible dans votre environnement, émettez le même objet exact comme un bloc ```json clôturé étiqueté recommend-flag pour qu'il puisse toujours être analysé, puis donnez le résumé en prose.

Cas limites

Situation Action
Diff est vide ou seulement espaces blancs recommend: false, verdict: not-suited, confidence: high, raison notant aucun changement de comportement
Diff mélange un refactor avec un vrai changement de comportement Jugez sur le changement de comportement ; recommandez un flag s'il la justifie (verdict: suggested), et dites quelle partie a conduit le verdict
La modification est déjà derrière un flag — dans le diff, ou une gate ancêtre qui est off/mid-rollout recommend: false, verdict: already-flagged ; nommez la clé du flag et, pour un ancêtre, son état de déploiement. Si l'ancêtre est entièrement lancé ou une gate config permanente, il ne protège pas cette modification — jugez normalement (probablement verdict: suggested).
Vous ne pouvez pas lire le code environnant (pas d'accès au dépôt, snippet ad hoc) Décidez du diff seul ; réduisez confidence et dites que l'exploration était indisponible
La modification est un hotfix / revert Habituellement recommend: false à moins qu'il ne réintroduise un chemin risqué ; expliquez

Ce que NE PAS faire

  • Ne créez, bascule, ou modifiez un flag. Vous êtes consultatif. Voir Limite de portée.
  • Ne bloque la fusion ou ne parle comme une vérification requise — encadrez la sortie comme une recommandation.
  • Ne décidez du diff seul quand vous pourriez lire le code. Les diffs au niveau des lignes masquent le rayon d'impact.
  • Ne soyez vague. « Pourrait être risqué » n'est pas une raison ; « change le fallthrough auth dans middleware/auth.ts:42 dont chaque route dépend » est.
  • Ne sautez pas l'appel recommend-flag. La prose sans le verdict structuré n'est pas un résultat utilisable.
  • Ne fusionnez pas already-flagged dans not-suited. Une modification protégée par une gate ancêtre est couverte, pas rien à flaguer — enregistrez les deux distinctement.
  • Ne sur-flaguez les modifications triviales. Recommander un flag pour un edit README érode la confiance dans la recommandation.

Skills similaires