


Créer des services Rust asynchrones qui résistent aux annulations et aux pannes
Pour les services Rust asynchrones : l’IA termine le vrai code sans simulations, gère les erreurs et les annulations sans risque, teste via la vraie interface du service et passe toutes les vérifications avant d’annoncer la fin.
Pour utiliser ces règles d'IA
## Terminer le vrai code au lieu d’utiliser des simulations ou des stubs
Réalisez entièrement le comportement demandé, du début à la fin. Ne remplacez pas une logique de production manquante par des objets simulés, des implémentations de repli, des squelettes ou des raccourcis réservés aux tests.
- Utilisez les véritables dépendances et le chemin d’intégration réel.
- Ne manipulez pas les tests pour dissimuler une implémentation défaillante.
- Évitez les solutions de contournement de l’environnement qui court-circuitent la configuration requise.
- Consignez explicitement tout travail incomplet inévitable dans le plan ou la spécification qui en résulte.
- N’affirmez jamais qu’une fonctionnalité marche sans preuve issue du parcours réellement suivi par les utilisateurs.
L’exécution autonome consiste à suivre le parcours rigoureux jusqu’au bout, et non à réduire la définition de ce qui est terminé.
## Appliquer les mêmes choix de conception à tous les types de données liés
Lorsqu’un système traite plusieurs familles connexes de signaux ou de données, concevez un comportement commun pour toutes, même si une famille constitue la priorité actuelle.
- Déterminez la sémantique commune à l’ingestion, au stockage, à la recherche, à l’analyse et à la gestion du cycle de vie.
- Isolez les optimisations propres à chaque famille derrière des limites explicites.
- Vérifiez que les décisions communes ne favorisent pas accidentellement la première famille implémentée.
- Maintenez un comportement cohérent en matière d’erreurs, de configuration et d’observabilité sur tous les chemins.
- Documentez les différences intentionnelles au lieu de laisser les implémentations diverger.
La priorisation peut déterminer l’ordre de livraison, mais elle ne doit pas restreindre silencieusement l’architecture.
## Mettre la sûreté d’abord, puis la vitesse, puis la commodité
Appliquez cet ordre de priorité technique : premièrement la sûreté, deuxièmement les performances et troisièmement la commodité pour les développeurs. N’optimisez qu’après avoir compris les invariants et le comportement en cas de défaillance.
- Rejetez les entrées non valides aux limites publiques.
- Définissez des limites explicites sous forme de constantes nommées et renvoyez des erreurs structurées lorsqu’elles sont dépassées.
- Ne masquez pas une défaillance d’une dépendance, du stockage ou du réseau par une solution de repli apparemment réussie.
- Traitez tout état inattendu comme une erreur ou une violation d’invariant, et non comme une opération sans effet considérée comme réussie.
- N’autorisez l’absence de données facultatives que si le contrat les définit explicitement comme telles.
Les travaux d’amélioration des performances doivent préserver la correction lors d’une défaillance, d’une nouvelle tentative, d’une annulation ou d’une progression partielle.
## Utiliser des assertions de débogage pour les règles internes et des erreurs pour les entrées invalides
Utilisez des assertions actives uniquement pendant le débogage pour documenter les invariants internes que les personnes chargées de la révision peuvent analyser. Utilisez des résultats d’erreur récupérables pour les entrées utilisateur non valides, les données externes et les conditions d’exécution, car les assertions de débogage peuvent disparaître des versions optimisées.
- Propagez les erreurs de bibliothèque avec `Result` et l’opérateur `?`.
- Évitez les méthodes d’extraction inconditionnelle dans le code de bibliothèque réutilisable.
- Conservez des types d’erreurs significatifs au lieu d’aplanir toutes les défaillances.
- Utilisez des opérations faillibles sur le système de fichiers et les métadonnées lorsque les erreurs apportent des informations.
- Ajoutez du contexte sans éliminer la cause initiale.
- N’ignorez jamais silencieusement une erreur au moyen d’une affectation inutilisée.
Un état impossible doit échouer de manière suffisamment visible pour permettre le diagnostic.
## Garder le code asynchrone sûr quand des tâches sont annulées
Supposez que le travail asynchrone puisse être annulé à n’importe quel point de suspension. Structurez les transitions d’état afin qu’une annulation ne puisse ni exposer un état partiellement mis à jour ni perdre des données.
- Privilégiez la possession selon le modèle d’acteurs et l’échange de messages pour les états mutables sensibles à l’annulation.
- Ne conservez pas un verrou au-delà d’un point d’attente asynchrone.
- Utilisez des sections critiques synchrones lorsque la modification doit être atomique.
- Annulez de façon coopérative au moyen d’un signal d’annulation plutôt que d’interrompre arbitrairement des tâches.
- Dans les boucles de sélection, épinglez puis reprenez un calcul futur en cours au lieu de le recréer et de l’abandonner.
- Rendez l’arrêt et le nettoyage idempotents.
Préférez un clonage plus simple ou une possession partagée dans le code asynchrone et le code fondé sur le modèle d’acteurs lorsque cela renforce la sûreté de la possession et de l’annulation.
## Garder des types et une possession clairs, et découper les gros fichiers
Utilisez les identifiants de domaine et les alias de types établis au lieu de transmettre des chaînes de caractères brutes pour de nouveaux concepts. Laissez le système de types distinguer les valeurs qui ne doivent pas être mélangées.
- Évitez de masquer des noms au sein d’une fonction lorsque cela obscurcit les transitions d’état.
- Renvoyez des références lorsque la possession reste locale et que le clonage est inutile.
- Utilisez explicitement la possession partagée lorsque des valeurs franchissent les limites des tâches.
- Préférez les boucles impératives lorsque les chaînes d’itérateurs rendent difficile la lecture d’un flux de contrôle faillible.
- Divisez les fichiers et les fonctions trop volumineux selon des responsabilités cohérentes.
- Séparez les interfaces publiques des détails d’implémentation.
La lisibilité est un outil de fiabilité lorsque le code coordonne un état asynchrone.
## Tester via la vraie interface du service utilisée par les utilisateurs
Ne déclarez pas une fonctionnalité terminée avant de l’avoir exercée au travers de la véritable pile publique. Si les utilisateurs accèdent à un comportement par un protocole réseau, une passerelle ou une limite de service, testez-le au travers de cette limite plutôt que d’appeler directement une fonction interne.
1. Démarrez le véritable service avec une configuration représentative.
2. Envoyez l’entrée par l’interface d’ingestion ou de commande prise en charge.
3. Récupérez le résultat par l’interface de requête ou de réponse prise en charge.
4. Vérifiez la persistance, la correspondance des erreurs et les effets secondaires observables.
5. Confirmez que les comportements interne et public concordent.
Les tests internes sont utiles, mais ils ne remplacent pas une preuve obtenue par le chemin de production.
## Choisir le type de test selon le but, y compris les tests de panne
Utilisez des tests unitaires rapides pour la logique isolée, des tests fondés sur les propriétés pour de vastes espaces d’états, des tests par injection de défaillances pour la résilience et des tests d’intégration pour le comportement complet du service.
- Restreignez suffisamment les entrées des tests fondés sur les propriétés pour produire des contre-exemples utiles.
- Utilisez des dispositifs de test reposant sur le véritable service lorsque le comportement du stockage ou du protocole importe.
- Limitez les nouvelles tentatives aux suites qui tolèrent intentionnellement un ordonnancement non déterministe.
- Mesurez la couverture des points de défaillance lorsque des modifications touchent la récupération ou les transitions d’état.
- Ajoutez un test d’intégration pour chaque nouveau point de terminaison public.
- Testez le chemin d’erreur aussi délibérément que le chemin de réussite.
Ne laissez pas des tentatives répétées transformer un défaut déterministe en réussite apparente.
## Lancer les vérifications avec la chaîne d’outils fixée et les commandes du dépôt
Exécutez les compilations, le formatage, les analyses statiques, les tests, les vérifications de documentation et de licences, les audits de dépendances et les vérifications orthographiques au moyen des commandes définies par le dépôt.
- Utilisez la chaîne d’outils aux versions imposées et le canal requis de l’outil de formatage.
- Démarrez les services locaux déclarés avant les suites d’intégration, puis arrêtez-les.
- Transmettez la configuration des tests par les variables d’environnement documentées sans intégrer de véritables données d’authentification.
- Exécutez d’abord le paquet concerné dans un périmètre étroit, puis la suite de tout l’espace de travail avec toutes les fonctionnalités.
- Traitez chaque avertissement de l’analyse statique comme un travail à résoudre ou justifiez-le par la dérogation ciblée la plus limitée.
- Vérifiez que chaque modification peut être compilée indépendamment, et pas seulement comme partie d’une modification ultérieure empilée.
Les commandes directes ne sont acceptables que si elles préservent la configuration effectuée par le processus de référence.
## Consigner les changements d’architecture dans trois types de registres
Suivez l’évolution architecturale au moyen de trois registres complémentaires :
- **caractéristiques :** exigences proactives auxquelles l’architecture doit répondre ;
- **lacunes :** limites découvertes à la suite d’incidents, de tests ou du comportement en production ;
- **déviations :** écarts intentionnels par rapport à l’architecture privilégiée, avec leur justification et leurs contraintes.
Reliez les modifications du code au registre pertinent lorsqu’elles changent les garanties du système. Maintenez distincts les modèles formels, les processus de simulation, les registres de décisions et l’état de l’implémentation afin qu’une conception visée ne soit pas confondue avec un comportement achevé.
Actualisez le registre lorsque de nouvelles preuves modifient l’architecture, et pas seulement lors de l’annonce d’une nouvelle fonctionnalité.
## Répondre aux commentaires de revue dans leur fil existant
Facilitez la révision des modifications en limitant les différences au sujet traité et en rattachant les explications à la décision concernée.
- Répondez à un commentaire de révision dans son fil existant au lieu de créer un commentaire séparé au même endroit.
- Vérifiez au moyen de l’interface de la plateforme d’hébergement que la réponse est liée au commentaire parent prévu.
- Expliquez pourquoi un invariant, une dérogation, un clonage ou une déviation non évidente est nécessaire.
- Séparez les remaniements sans rapport des modifications fonctionnelles.
- Actualisez les recommandations évolutives lorsqu’un schéma de défaillance récurrent révèle une règle durable.
La rigueur des révisions préserve le contexte et empêche que le même problème soit résolu dans des conversations parallèles.
## Passer toutes les vérifications du diff final avant d’annoncer la fin
Avant d’annoncer l’achèvement, examinez les différences finales et confirmez que :
- toutes les analyses statiques applicables réussissent sans avertissement inexpliqué ;
- les vérifications de formatage réussissent pour chaque fichier source et chaque fichier de test modifiés ;
- aucune extraction inconditionnelle, suppression silencieuse d’erreur ou clonage injustifié ne subsiste ;
- les tests des interfaces de production et les tests d’intégration concernés réussissent ;
- les en-têtes requis, les conventions de journalisation, la documentation et les audits de dépendances réussissent ;
- les nouveaux fichiers et les nouvelles fonctions restent ciblés et faciles à maintenir ;
- aucune donnée d’authentification ni aucune valeur sensible n’est présente.
Corrigez les défaillances à leur source. Ne désactivez pas les vérifications, n’affaiblissez pas les tests et ne contournez pas le chemin de production pour obtenir un résultat positif.
