Que fait Application des Règles de Code ?
Aperçu
Un contrôle est jugé par ce qu'il refuse lorsque quelqu'un tente de le contourner, et non par le fait qu'il passe son chemin de test nominal. Les deux modes d'échec qui survivent à une relecture sont un contrôle qui inspecte une représentation de la valeur dangereuse au lieu de la valeur elle-même, et un contrôle qui renvoie un succès parce qu'il n'a pas pu s'exécuter. Les deux semblent verts dans tous les tests écrits à partir des propres hypothèses de l'auteur.
Utilisation
Suivez les étapes ci-dessous lors de l'écriture ou de la modification d'un hook, d'un garde, d'un validateur, d'une vérification de permission, d'une règle de lint ou d'une porte CI — avant d'ouvrir le fichier, car l'étape 1 change souvent l'endroit où le code doit se trouver.
Cas typiques : "bloquer rm -rf en dehors du dépôt" (l'étape 1 déplace la décision de la chaîne de commande), "échouer la CI quand une migration n'a pas de rollback" (les étapes 3 et 4 empêchent la porte de passer lorsque la liste des migrations revient vide), "refuser un push sans commit signé" (l'étape 5 énumère l'alias, le --no-verify et le second dépôt distant).
Étapes
- Nommer la cible. Écrivez la valeur exacte qui atteint ce que vous protégez : les argv développés, le corps de la requête, le paramètre SQL, le chemin résolu. Validez cette valeur.
- Vérifier si vous pouvez réellement la voir. Si le code ne dispose que d'une représentation de la valeur — une chaîne de commande shell, un diff, une ligne de log, un message de commit — la décision est heuristique, pas une vérification. Mentionnez-le dans un commentaire et dans la note de livraison, et qualifiez cette couche d'indicative. Ne laissez pas une heuristique être la seule barrière pour une conséquence que vous ne pouvez pas annuler.
- Échouer en mode fermé. Runtime manquant, entrée illisible, exception d'analyse, variable non résolue, résultat vide : refusez, et nommez ce qui manque. Une garde qui sort avec 0 parce qu'elle n'a pas pu s'exécuter est une garde désactivée, et elle reste désactivée silencieusement pendant des mois.
- Rendre l'échec de la sonde visible. Pas de
2>/dev/nullsur la commande qui décide si la garde peut s'exécuter, et pas de branche qui transforme un résultat vide en succès. Si la sonde peut échouer silencieusement, l'étape 3 n'est pas applicable. - Énumérer les contournements avant d'écrire la correction. Listez comment le contrôle peut être satisfait ou contourné : commande composée, drapeaux en double, une deuxième invocation, un alias ou une fonction, un interpréteur manquant, un autre hôte, un sous-shell, un fichier renommé. Gardez la liste dans le corps du commit ou dans le fichier de test.
- Transformez chaque entrée de cette liste en un cas de test intégré aux vérifications automatisées du projet. Un auto-test manuel ne compte pas : il disparaît avec la session qui l'a exécuté.
- Lorsqu'un contournement est bon marché et sa conséquence réelle, effectuez un passage adversaire. Déléguez un sous-agent en contexte frais dont le mandat est de casser la garde, pas de la relire ; sa sortie est la liste des tentatives et leurs résultats. Ignorez cette étape pour un contrôle dont le pire cas est un avertissement.
Pièges
- Analyser une commande shell pour décider. Les guillemets,
$(),&&, les alias et les préfixesenvchangent tous ce qui s'exécute finalement. Une telle couche est un dos d'âne ; la vraie vérification appartient là où l'effet de la commande atterrit. - Gardes basées sur
command -v.if command -v tool > /dev/null; then check; fiignore silencieusement la vérification sur toute machine manquant l'outil — exactement la machine qui en a le plus besoin. Inversez-la : refusez lorsque l'outil est absent. - Une étape de découverte qui ne trouve rien.
git grep -Ene supporte pas\b, donc un tel motif correspond à zéro fichier sans erreur, et la porte passe sans avoir rien lu. Protégez l'étape avec un canari : un fichier que vous savez devoir apparaître dans sa sortie. - Tester uniquement le refus que vous avez implémenté. Le test intéressant est l'entrée à laquelle vous n'avez pas pensé ; c'est ce que produit l'étape 5.
- Une garde testée uniquement à la main. Elle passe sur la machine de l'auteur, puis pourrit. Si le projet n'a aucun endroit pour intégrer le test, ce manque d'infrastructure fait partie du travail.
- Le contexte qui a écrit la garde ne peut pas la casser. Il partage les angles morts qui ont produit la faille et confirmera sa propre conception. Seul un contexte frais est adversaire.
Contraintes
- Ne jamais décider sur un proxy de la valeur protégée lorsque la valeur elle-même est accessible.
- Ne jamais sortir avec 0 sur un chemin où la garde n'a pas pu faire son travail ; refusez et nommez la cause.
- Ne jamais supprimer les erreurs de la sonde qui établit si la garde peut s'exécuter.
- Chaque contournement énuméré doit exister comme un test automatisé avant la livraison.
- Indiquez clairement quelle couche est indicative et laquelle est exécutoire ; une heuristique présentée comme une garantie est pire qu'aucune garde.