v0.2.5-pre.010.fix.001
This commit is contained in:
@@ -1,74 +1,108 @@
|
||||
<!-- file: docs/rules/PROMPT_STRUCTURE.md -->
|
||||
<!-- version: 4 -->
|
||||
<!-- version: 5 -->
|
||||
|
||||
# Structure des prompts KSP
|
||||
|
||||
## Portée
|
||||
|
||||
Ce document définit le contrat normatif des prompts de reprise KSP, leur cycle de vie et les règles de dimensionnement des releases/sessions qu'ils préparent.
|
||||
Ce document définit le contrat normatif des prompts de reprise KSP, leur cycle de vie et les règles de dimensionnement des releases/sessions qu'ils préparent. Un prompt de démarrage est un **contrat opératoire autonome** : une nouvelle session ne doit pas dépendre d'une mémoire implicite pour retrouver les règles déjà acquises.
|
||||
|
||||
## Série, release concrète et session
|
||||
|
||||
Une notation de série telle que `0.1.x` regroupe des fonctionnalités apparentées. Elle n'est pas une unité de session et n'a pas à être réalisable en une seule session.
|
||||
|
||||
Exemple : `0.1.x` peut regrouper plusieurs releases concrètes comme `0.1.1`, `0.1.2`, `0.1.3`, chacune avec son propre cycle de prereleases et, en principe, sa propre session de travail principale.
|
||||
|
||||
Le contrôle de charge s'applique donc d'abord à **la release concrète préparée** et à ses prereleases, pas à toute la série fonctionnelle.
|
||||
Le contrôle de charge s'applique d'abord à **la release concrète préparée** et à ses prereleases. Une release concrète doit être planifiée pour être ouverte et clôturée dans une seule session de chat ; si cette clôture paraît incertaine, elle est scindée avant l'implémentation lourde.
|
||||
|
||||
## Cycle d'une release concrète
|
||||
|
||||
Sauf raison explicitement documentée :
|
||||
|
||||
- `pre.001` = brainstorming/audit si nécessaire + planification + découpage de la release ;
|
||||
- `pre.001` = lectures obligatoires + audit interne/externe + brainstorming + sizing + planification ;
|
||||
- les prereleases intermédiaires = tranches bornées de développement/validation ;
|
||||
- la dernière prerelease = validation finale + documentation + nettoyage/archivage + préparation du prompt/release suivante.
|
||||
- la dernière prerelease = validation finale + documentation + nettoyage/archivage + prompt de la release suivante ;
|
||||
- une `fix` corrige l'étape réellement livrée sans réécrire l'historique.
|
||||
|
||||
## Dimensionnement des prereleases
|
||||
## Dimensionnement
|
||||
|
||||
Lors de `pre.001`, une prerelease intermédiaire estimée à plus d'environ **15 à 20 minutes de travail effectif de session** doit être scindée.
|
||||
Lors de `pre.001`, une prerelease intermédiaire estimée à plus d'environ **15 à 20 minutes de travail effectif** est scindée. Cette durée est un budget de planification, jamais une promesse temporelle.
|
||||
|
||||
Cette durée est un budget de planification et non une promesse d'exécution.
|
||||
La trajectoire initiale est **souple** : elle indique un nombre prévisionnel de prereleases, leur objectif et leur ordre, mais autorise l'insertion de tranches/fixes lorsqu'un audit ou une validation révèle un besoin réel. La fermeture ne doit jamais être forcée pour respecter un numéro prévu.
|
||||
|
||||
Si la complexité réelle augmente, la tranche est redécoupée plutôt que surchargée.
|
||||
## Structure obligatoire d'un prompt de démarrage
|
||||
|
||||
## Dimensionnement d'une release/session
|
||||
Un prompt de nouvelle session contient explicitement, dans un ordre facile à retrouver :
|
||||
|
||||
Avant de finaliser le prompt d'une release concrète, vérifier que son plan complet est compatible avec une session de qualité.
|
||||
1. identité de la release et base exacte requise ;
|
||||
2. mission et résultat attendu ;
|
||||
3. **sources de vérité internes obligatoires et ordre de lecture** ;
|
||||
4. sources externes normatives à réauditer lorsque la fraîcheur importe ;
|
||||
5. état validé à préserver, y compris règles de dépendances et frontières ;
|
||||
6. décisions acquises et questions réellement ouvertes ;
|
||||
7. objectifs/livrables et hors périmètre ;
|
||||
8. contraintes sécurité/API/architecture spécifiques ;
|
||||
9. **première mission `pre.001` détaillée et critères de sortie de ce gate** ;
|
||||
10. **prévision souple initiale des prereleases**, visible et détaillée ;
|
||||
11. règles de versionnement, deltas, commits et tags ;
|
||||
12. procédure d'application/validation opérateur ;
|
||||
13. validations Rust/frontend/Tauri/réseau pertinentes ;
|
||||
14. critères de clôture de la release ;
|
||||
15. release/session suivante envisagée ;
|
||||
16. **instruction d'ouverture** indiquant ce que la prochaine session doit faire en premier et ce qu'elle ne doit pas commencer avant le gate.
|
||||
|
||||
Si une release concrète paraît trop lourde, la scinder en plusieurs releases de la même série lorsque les fonctions restent du même groupe, ou changer de série si une frontière fonctionnelle différente le justifie.
|
||||
## Sources de vérité et reprise
|
||||
|
||||
Exemple : si `0.1.1` devient trop large, créer `0.1.2` plutôt que forcer tout `0.1.x` dans une seule session.
|
||||
- Le prompt ordonne explicitement la lecture de `RULES.md`, `docs/000-README.md`, règles spécialisées, architecture, plan/validation de la release précédente et sources métier pertinentes.
|
||||
- Lorsqu'une archive/base opérateur est fournie, elle est déclarée autoritaire par rapport aux souvenirs, snippets ou artefacts anciens.
|
||||
- Le prompt ne recopie pas toutes les règles, mais rappelle les règles qui conditionnent directement la session et exige la lecture des fichiers normatifs.
|
||||
- Les décisions historiques ne sont pas réinventées lors de la nouvelle session ; une divergence avec la base réelle déclenche un audit, pas une supposition.
|
||||
|
||||
Une série complète peut naturellement s'étendre sur de nombreuses sessions.
|
||||
## Force opératoire du `pre.001`
|
||||
|
||||
Une **release concrète**, en revanche, doit être planifiée pour être ouverte et clôturée dans une seule session de chat. Une version volontairement laissée ouverte pour être reprise dans une autre session n'est pas un découpage acceptable.
|
||||
Le prompt doit rendre impossible une interprétation « commencer à coder immédiatement ». La première tranche exige au minimum :
|
||||
|
||||
Si `pre.001` révèle qu'une clôture dans la session est incertaine, la release est scindée **avant l'implémentation fonctionnelle lourde**. Cette contrainte s'ajoute au budget de 15–20 minutes par prerelease ; elle ne le remplace pas.
|
||||
```text
|
||||
lecture des sources internes obligatoires
|
||||
inventaire de l'état réel de la base
|
||||
récupération des dépendances/versions actuelles si concernées
|
||||
comparaison avec les références historiques utiles
|
||||
brainstorming des risques/frontières
|
||||
sizing de la release et de chaque tranche
|
||||
prévision souple recalibrée
|
||||
liste des validations/gates
|
||||
```
|
||||
|
||||
## Structure recommandée d'un prompt
|
||||
L'implémentation fonctionnelle lourde commence seulement lorsque ce gate est cohérent. Les corrections triviales nécessaires pour rendre l'audit lui-même exécutable restent autorisées.
|
||||
|
||||
1. Identité de la série et de la release concrète visée ;
|
||||
2. Mission ;
|
||||
3. Base requise ;
|
||||
4. État validé à préserver ;
|
||||
5. Sources de vérité internes ;
|
||||
6. Sources externes normatives ;
|
||||
7. Décisions acquises ;
|
||||
8. Objectifs et livrables ;
|
||||
9. Hors périmètre ;
|
||||
10. Méthode de travail ;
|
||||
11. Versionnement/deltas/commits ;
|
||||
12. Contraintes techniques spécifiques ;
|
||||
13. Plan initial souple et prereleases bornées ;
|
||||
14. Validations attendues ;
|
||||
15. Critères de sortie ;
|
||||
16. Préparation de la release/session suivante.
|
||||
## Validation Rust obligatoire dans les prompts
|
||||
|
||||
Toute release susceptible de modifier du Rust rappelle explicitement la séquence KSP :
|
||||
|
||||
```bash
|
||||
cargo fmt --all
|
||||
python3 scripts/audit_rust_workspace_rules.py
|
||||
cargo check --workspace
|
||||
cargo clippy --workspace --all-targets
|
||||
```
|
||||
|
||||
Pendant le développement, les tests ciblés suivent ces contrôles. La fermeture d'une prerelease technique/release inclut `cargo test --workspace` et les `cargo tree` pertinents lorsque le graphe de dépendances a changé ou constitue un gate de la tranche.
|
||||
|
||||
Un prompt interdit de déclarer réussie une commande qui n'a pas réellement été exécutée. Il rappelle que `rustfmt` et Clippy ne remplacent pas l'audit structurel KSP.
|
||||
|
||||
## Dépendances et fraîcheur
|
||||
|
||||
Lorsqu'une tranche ajoute, met à jour ou dépend fortement d'une bibliothèque externe :
|
||||
|
||||
- vérifier la version stable réellement courante au début de la tranche ;
|
||||
- préférer les sources primaires de la crate/projet ;
|
||||
- vérifier les features réellement nécessaires et les contraintes de versions transitives ;
|
||||
- documenter les doublons transitifs acceptés plutôt que forcer artificiellement une unification incompatible ;
|
||||
- ne pas conserver dans un prompt une version historique comme si elle était nécessairement toujours actuelle.
|
||||
|
||||
## Règles de rédaction
|
||||
|
||||
- Le prompt référence les sources canoniques au lieu de recopier inutilement leur contenu.
|
||||
- Une règle normative appartient à `docs/rules/`.
|
||||
- Une décision durable appartient à `docs/architecture/`.
|
||||
- Une idée non décidée appartient à `docs/IDEAS.md`.
|
||||
- Un prompt doit signaler les questions ouvertes plutôt que les résoudre arbitrairement.
|
||||
- Une release concrète manifestement surdimensionnée doit être redécoupée avant ouverture de sa session principale.
|
||||
- Le prompt doit être autoportant sans devenir une copie intégrale des règles.
|
||||
- Les titres `Première mission`, `Prévision souple`, `Validation` et `Instruction d'ouverture` doivent être immédiatement repérables.
|
||||
- Une règle normative appartient à `docs/rules/`, une décision durable à `docs/architecture/`, une idée non décidée à `docs/IDEAS.md`.
|
||||
- Le prompt signale les questions ouvertes au lieu de les résoudre arbitrairement.
|
||||
- Une release surdimensionnée est redécoupée avant ouverture de son développement lourd.
|
||||
- Le prompt conserve les conventions KSP de delta minimal, version de fichiers, Cargo version technique, commits et tags stables.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!-- file: docs/rules/RULES_KSP.md -->
|
||||
<!-- version: 34 -->
|
||||
<!-- version: 35 -->
|
||||
|
||||
# Règles spécifiques à KSP
|
||||
|
||||
@@ -252,7 +252,7 @@
|
||||
- **KSP-REL-006** — Une release ou prerelease trop grosse est scindée plutôt que compressée pour respecter un numéro prévu.
|
||||
- **KSP-REL-007** — La dernière prerelease d'une release fonctionnelle réalise par défaut validations finales, documentation, nettoyage/archivage, changelog et prompt de la release suivante.
|
||||
- **KSP-REL-008** — La première release fonctionnelle sélectionnée est `0.1.1`, dédiée à la stabilisation de `ksp-core-lib`.
|
||||
- **KSP-REL-009** — Après toute modification d'un fichier Rust, la tranche concernée exécute avant livraison au minimum `cargo fmt --all`, `cargo check --workspace` et `cargo clippy --workspace --all-targets`. Une commande non exécutée n'est jamais déclarée réussie.
|
||||
- **KSP-REL-009** — Après toute modification d'un fichier Rust, la tranche concernée exécute avant livraison au minimum `cargo fmt --all`, `python3 scripts/audit_rust_workspace_rules.py`, `cargo check --workspace` et `cargo clippy --workspace --all-targets`, dans cet ordre. L'audit structurel complète rustfmt/Clippy et ne peut être ignoré parce que la compilation est verte. Une commande non exécutée n'est jamais déclarée réussie.
|
||||
- **KSP-REL-010** — Pendant le développement courant d'une crate, les tests Rust privilégient la portée ciblée `cargo test -p <crate>` et, si utile, ses tests d'intégration nommés. `cargo test --workspace` est conservé pour l'ouverture ou la fermeture d'une session/version et pour les validations globales explicitement justifiées.
|
||||
- **KSP-REL-011** — Les validations d'une crate incluent les audits `cargo tree` pertinents pour son graphe réel : arbre normal, doublons et features lorsque ces vues apportent une information utile. Les crates fondamentales/complétées conservent leurs canaries de dépendances.
|
||||
- **KSP-REL-012** — Toute crate ou composant KSP considéré comme complété possède un `README.md` descriptif durable avant clôture de sa release.
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<!-- file: docs/rules/RULES_RUST.md -->
|
||||
<!-- version: 5 -->
|
||||
<!-- version: 6 -->
|
||||
|
||||
# Règles Rust générales
|
||||
|
||||
## Portée
|
||||
|
||||
Les règles `RUST-*` s'appliquent aux crates, sources, tests, exemples et outils Rust de KSP. Elles sont conçues pour rester réutilisables hors de KSP lorsque la règle ne dépend pas de son architecture.
|
||||
Les règles `RUST-*` s'appliquent à tous les fichiers Rust de KSP : crates, sources, tests, exemples et outils. Elles reprennent les règles déjà éprouvées sur les générations précédentes du projet et les rendent explicites afin que `rustfmt` et Clippy ne soient jamais considérés comme des contrôles structurels suffisants.
|
||||
|
||||
## Édition et lints
|
||||
|
||||
@@ -13,33 +13,54 @@ Les règles `RUST-*` s'appliquent aux crates, sources, tests, exemples et outils
|
||||
- **RUST-BASE-002** — Chaque `lib.rs` et `main.rs` contient `#![warn(missing_docs)]`, `#![deny(unreachable_pub)]` et `#![forbid(unsafe_code)]`.
|
||||
- **RUST-BASE-003** — Les lints communs sont déclarés au niveau workspace et hérités par les crates.
|
||||
- **RUST-BASE-004** — Le code `unsafe` est interdit.
|
||||
- **RUST-BASE-005** — Tout fichier Rust possède les en-têtes `// file: ...` et `// version: N`, et se termine par exactement une fin de ligne.
|
||||
|
||||
## Documentation des API
|
||||
## Documentation des API et contrats internes
|
||||
|
||||
- **RUST-DOC-001** — Tout élément `pub` ou `pub(crate)` possède une rustdoc utile au point de déclaration.
|
||||
- **RUST-DOC-002** — Toute réexportation `pub use` ou `pub(crate) use` dans `lib.rs` ou `main.rs` possède également une rustdoc utile.
|
||||
- **RUST-DOC-003** — La façade d'une crate doit permettre de comprendre son API sans dépendre de ses chemins de modules internes.
|
||||
- **RUST-DOC-001** — Tout élément `pub` ou `pub(crate)` possède une rustdoc utile au point de déclaration. Cette règle couvre aussi les méthodes associées et les champs nommés visibles à ces niveaux.
|
||||
- **RUST-DOC-002** — Toute réexportation `pub use` ou `pub(crate) use` dans `lib.rs` ou `main.rs` possède sa propre rustdoc utile et adjacente.
|
||||
- **RUST-DOC-003** — La façade d'une crate doit permettre de comprendre son API publique et ses contrats crate-wide sans dépendre de chemins de modules internes.
|
||||
- **RUST-DOC-004** — Les rustdocs et commentaires du code sont en anglais ; la documentation Markdown KSP reste en français sauf document explicitement destiné à une audience différente.
|
||||
|
||||
## Imports et chemins
|
||||
|
||||
- **RUST-IMPORT-001** — `use` est interdit pour les constantes, fonctions, structures, énumérations, unions, alias de types, modules et macros.
|
||||
- **RUST-IMPORT-002** — `use` est autorisé uniquement pour un trait lorsque la résolution de méthode, une macro de dérivation ou une contrainte du langage l'exige réellement.
|
||||
- **RUST-IMPORT-003** — Un import de trait reste étroit et ne mélange pas de non-traits dans un import groupé.
|
||||
- **RUST-IMPORT-002** — `use` est autorisé uniquement pour un trait lorsqu'une résolution de méthode, une dérivation ou une contrainte du langage l'exige réellement. Le motif est explicité sur la ligne par `rust-rules: trait-import`.
|
||||
- **RUST-IMPORT-003** — Les imports de traits restent étroits ; un import de trait ne mélange jamais d'éléments non-traits.
|
||||
- **RUST-IMPORT-004** — Les glob imports et imports groupés par accolades sont interdits.
|
||||
- **RUST-IMPORT-005** — Pour un élément externe, utiliser directement le chemin public le plus court fourni par la crate propriétaire.
|
||||
- **RUST-IMPORT-006** — Pour un élément `pub` d'une crate KSP, l'API est réexportée au crate-root et consommée depuis une autre crate via `owner_crate::Item`.
|
||||
- **RUST-IMPORT-007** — Dans sa propre crate, un élément `pub` ou `pub(crate)` partagé est consommé via `crate::Item` après réexport approprié.
|
||||
- **RUST-IMPORT-008** — Un helper strictement privé au module reste privé et est appelé localement ; dans un sous-module de tests, un élément privé du module parent est appelé via `super::Item`.
|
||||
- **RUST-IMPORT-009** — Les réexports ne sont pas groupés par accolades et les alias `as` sont interdits dans les réexports.
|
||||
- **RUST-IMPORT-010** — Un réexport d'un module interne commence par `self::`.
|
||||
- **RUST-IMPORT-005** — Les alias `as` sont interdits dans tous les `use`, réexports et déclarations `extern crate`. Le symbole reçoit son nom canonique dans son module propriétaire.
|
||||
- **RUST-IMPORT-006** — Les déclarations `use` sont au niveau du module, dans le bloc d'en-tête avant les déclarations métier. Aucun `use` n'est introduit dans une fonction, méthode, bloc, test ou branche conditionnelle.
|
||||
- **RUST-IMPORT-007** — Pour un élément fourni par une crate externe, utiliser directement le chemin public le plus court exposé par cette crate ; ne pas créer un import non-trait pour raccourcir ce chemin.
|
||||
- **RUST-IMPORT-008** — Pour un élément `pub` d'une crate KSP, la crate propriétaire le réexporte au crate-root. Une autre crate l'appelle via `owner_crate::Item`.
|
||||
- **RUST-IMPORT-009** — Dans sa propre crate, un élément `pub` ou `pub(crate)` partagé est appelé via `crate::Item`, y compris depuis son module de déclaration lorsque le contrat est crate-wide.
|
||||
- **RUST-IMPORT-010** — Un chemin `crate::module::Item` est interdit pour un élément partagé `pub`/`pub(crate)` qui peut être consommé via le crate-root. Le chemin du module interne n'est pas une façade.
|
||||
- **RUST-IMPORT-011** — Un élément strictement privé à un module n'est pas réexporté et est appelé par son nom local dans ce module.
|
||||
- **RUST-IMPORT-012** — Dans un sous-module de tests, `super::Item` est réservé à un élément strictement privé du module parent. Un élément `pub` ou `pub(crate)` continue d'être appelé via `crate::Item`.
|
||||
- **RUST-IMPORT-013** — Les réexports internes commencent par `self::`. Un réexport d'une crate externe peut utiliser directement le chemin externe canonique.
|
||||
- **RUST-IMPORT-014** — Un export correspond à une ligne de réexport distincte ; les accolades ne servent jamais à regrouper une façade.
|
||||
- **RUST-IMPORT-015** — Une crate externe rendue publique uniquement pour l'hygiène d'une macro exportée conserve son nom canonique, porte `#[doc(hidden)]` et ne devient pas une API de consommation. `ksp-logging-lib::tracing` est ce bridge technique pour les macros Logging ; les autres crates KSP n'y accèdent jamais directement.
|
||||
|
||||
## Visibilité et façade de crate
|
||||
|
||||
- **RUST-API-001** — Aucun `pub mod` n'est autorisé ; les modules restent privés et l'API externe est constituée par des réexports explicites au crate-root.
|
||||
- **RUST-API-001** — Aucun `pub mod` n'est autorisé ; les modules restent privés et l'API externe est constituée exclusivement par des réexports explicites au crate-root.
|
||||
- **RUST-API-002** — `pub(in ...)` et `pub(super)` sont interdits.
|
||||
- **RUST-API-003** — Un élément `pub` inaccessible depuis la façade de sa crate est une erreur de conception.
|
||||
- **RUST-API-004** — Un élément `pub(crate)` utilisé hors de son module est réexporté au crate-root via `pub(crate) use`.
|
||||
- **RUST-API-005** — Les chemins internes de modules ne constituent pas une API stable.
|
||||
- **RUST-API-004** — Un élément `pub(crate)` consommé hors de son module est réexporté au crate-root via `pub(crate) use` puis appelé via `crate::Item`.
|
||||
- **RUST-API-005** — Les chemins internes de modules ne constituent jamais une API stable.
|
||||
- **RUST-API-006** — Si deux éléments crate-wide auraient le même nom au crate-root, ils sont renommés dans leurs modules propriétaires avec des noms canoniques non ambigus ; un alias de réexport n'est pas utilisé pour masquer la collision.
|
||||
|
||||
## Formatage, blocs et ordre
|
||||
|
||||
- **RUST-FMT-001** — `rustfmt.toml` à la racine est la configuration canonique du formatage Rust.
|
||||
- **RUST-FMT-002** — `cargo fmt --all` est exécuté après chaque modification Rust avant l'audit structurel et les validations Cargo.
|
||||
- **RUST-FMT-003** — Aucune ligne vide n'est conservée à l'intérieur du corps d'une fonction ou méthode, ni à l'intérieur d'une définition `struct` ou `enum`.
|
||||
- **RUST-FMT-004** — Les lignes vides séparent les fonctions/méthodes, types, blocs `impl` et grandes sections logiques ; elles ne fragmentent pas un bloc homogène de déclarations.
|
||||
- **RUST-FMT-005** — Les blocs homogènes sont ordonnés alphabétiquement par nom lorsque l'ordre n'a pas de signification sémantique.
|
||||
- **RUST-FMT-006** — Les constantes de module forment des blocs sans ligne vide interne, ordonnés par visibilité `pub`, puis `pub(crate)`, puis privée, et alphabétiquement dans chaque niveau.
|
||||
- **RUST-FMT-007** — Dans une façade, le bloc `pub use` précède le bloc `pub(crate) use`; une seule ligne vide sépare les deux blocs, aucune ligne vide n'existe à l'intérieur d'un bloc, et les symboles sont ordonnés alphabétiquement.
|
||||
- **RUST-FMT-008** — Les déclarations `mod` d'un même bloc sont ordonnées alphabétiquement ; les modules de tests conditionnels restent après les modules de production.
|
||||
- **RUST-FMT-009** — Lorsqu'un `struct` et ses blocs `impl` forment une unité locale sans contrainte de séparation, l'implémentation suit la structure. Les éléments visibles précèdent les helpers privés lorsqu'aucun ordre métier ou protocolaire n'impose l'inverse.
|
||||
- **RUST-FMT-010** — L'ordre alphabétique n'écrase jamais un ordre contractuel ou sémantique : wire fields, comptes Solana, étapes de protocole, priorités, transitions d'état, tableaux de dispatch et séquences explicitement normatives conservent leur ordre défini.
|
||||
|
||||
## Contrôle de flux et erreurs
|
||||
|
||||
@@ -49,15 +70,7 @@ Les règles `RUST-*` s'appliquent aux crates, sources, tests, exemples et outils
|
||||
- **RUST-ERR-004** — `anyhow` et `thiserror` ne sont pas utilisés par défaut ; leur introduction exige une justification architecturale.
|
||||
- **RUST-ERR-005** — Les erreurs publiques sont typées lorsque leur contrat est stable.
|
||||
- **RUST-ERR-006** — Les tests peuvent utiliser `unwrap` ou `expect` uniquement dans la limite explicitement autorisée par la configuration Clippy.
|
||||
- **RUST-ERR-007** — Avant d’attacher une erreur externe comme `source` de `ksp_core_lib::Error`, la crate propriétaire vérifie que sa chaîne `Debug`/`source` ne peut pas exposer de secret ou de donnée sensible. Lorsqu’une dépendance fournit une primitive de neutralisation, elle est appliquée avant `with_source`; en particulier une `reqwest::Error` issue d’une requête vers un endpoint potentiellement credential-bearing est attachée uniquement après `without_url()`.
|
||||
|
||||
## Formatage
|
||||
|
||||
- **RUST-FMT-001** — `rustfmt.toml` à la racine est la configuration canonique du formatage Rust.
|
||||
- **RUST-FMT-002** — `cargo fmt --all` est exécuté après chaque modification Rust avant les validations de compilation et de test.
|
||||
- **RUST-FMT-003** — Les fichiers Rust ne contiennent pas de lignes vides à l'intérieur d'une fonction, structure, énumération ou implémentation courte.
|
||||
- **RUST-FMT-004** — Les lignes vides séparent uniquement des fonctions, types, blocs `impl` ou sections logiques distinctes.
|
||||
- **RUST-FMT-005** — Les groupes homogènes de `pub use` ou `pub(crate) use` ne contiennent pas de ligne vide interne ; `pub use` précède `pub(crate) use` lorsqu'ils coexistent.
|
||||
- **RUST-ERR-007** — Avant d'attacher une erreur externe comme `source` de `ksp_core_lib::Error`, la crate propriétaire vérifie que sa chaîne `Debug`/`source` ne peut pas exposer de secret. Lorsqu'une dépendance fournit une primitive de neutralisation, elle est appliquée avant `with_source`.
|
||||
|
||||
## Helpers et duplication
|
||||
|
||||
@@ -71,31 +84,40 @@ Les règles `RUST-*` s'appliquent aux crates, sources, tests, exemples et outils
|
||||
- **RUST-DEP-002** — Une dépendance uniquement utilisée par les tests reste dans `[dev-dependencies]`.
|
||||
- **RUST-DEP-003** — Les features sont minimales et explicites.
|
||||
- **RUST-DEP-004** — Les lockfiles de dépendances ne sont pas versionnés dans KSP.
|
||||
- **RUST-DEP-005** — KSP privilégie les versions récentes compatibles. Toute version volontairement contrainte ou ancienne doit être documentée avec sa raison et la condition permettant de lever la contrainte.
|
||||
- **RUST-DEP-005** — KSP privilégie les versions récentes compatibles. Toute version volontairement contrainte ou ancienne est documentée avec sa raison et la condition permettant de lever la contrainte.
|
||||
|
||||
## Assertions de collections
|
||||
## Assertions et organisation des tests
|
||||
|
||||
- **RUST-TEST-001** — Un test vérifiant uniquement l'appartenance à un ensemble peut trier les valeurs obtenues et attendues avant `assert_eq!` lorsque l'ordre n'est pas contractuel.
|
||||
- **RUST-TEST-002** — Une collection n'est jamais triée artificiellement dans un test lorsque l'ordre fait partie du contrat, notamment pour comptes Solana, metas, instructions, signers, événements, étapes de pipeline, priorités ou journaux ordonnés.
|
||||
- **RUST-TEST-002** — Une collection n'est jamais triée artificiellement lorsque l'ordre fait partie du contrat, notamment pour comptes Solana, metas, instructions, signers, événements, étapes de pipeline, priorités ou journaux ordonnés.
|
||||
- **RUST-TEST-003** — Les tests unitaires sont placés autant que possible dans `unit_tests/` et reflètent l'arborescence de `src/`.
|
||||
- **RUST-TEST-004** — Un fichier `unit_tests/...` est rattaché explicitement au module de production via `#[cfg(test)]` et `#[path = ...]`; il peut tester les éléments privés de ce module.
|
||||
- **RUST-TEST-005** — `tests/` est réservé aux vrais tests d'intégration consommant uniquement l'API publique de la crate.
|
||||
- **RUST-TEST-006** — Toute partie pertinente de l'API publique est couverte, lorsque possible, par un test d'intégration afin de valider les réexports et la visibilité réellement consommables.
|
||||
- **RUST-TEST-007** — La colocalisation d'un test unitaire dans le fichier de production reste une exception justifiée.
|
||||
|
||||
## Organisation des tests
|
||||
## Audit structurel automatisé
|
||||
|
||||
- **RUST-TEST-003** — Les sources de tests unitaires sont placées autant que possible dans un répertoire `unit_tests/` à la racine de la crate et reflètent autant que possible l'arborescence et les noms des modules sous `src/`.
|
||||
- **RUST-TEST-004** — Un fichier sous `unit_tests/` reste un vrai test unitaire : il est rattaché explicitement sous `#[cfg(test)]` au module de production qu'il teste et peut donc tester ses éléments privés.
|
||||
- **RUST-TEST-005** — Le répertoire Cargo standard `tests/` est réservé aux tests d'intégration. Les fichiers qui y sont découverts comme cibles d'intégration testent la crate comme un consommateur externe et n'utilisent que son API publique.
|
||||
- **RUST-TEST-006** — Toute partie pertinente de l'API publique d'une bibliothèque KSP doit, lorsque cela est techniquement possible, être couverte par de vrais tests d'intégration sous `tests/`, afin de valider notamment les réexports, la visibilité et le contrat réellement consommable depuis une autre crate.
|
||||
- **RUST-TEST-007** — La séparation physique sous `unit_tests/` est la convention préférée et doit être utilisée au maximum. La colocalisation d'un test unitaire dans le fichier/module de production n'est autorisée qu'en dernier recours lorsqu'un rattachement externe serait techniquement impossible, incorrect ou créerait une complexité disproportionnée clairement justifiable.
|
||||
- **RUST-TEST-008** — Un test unitaire séparé suit autant que possible le même chemin relatif et le même nom que le module testé, afin que la correspondance `src/...` ↔ `unit_tests/...` soit immédiatement identifiable.
|
||||
- **RUST-AUDIT-001** — `scripts/audit_rust_workspace_rules.py` est le point d'entrée obligatoire de l'audit Rust KSP. Il exécute les audits généraux, la complétude des réexports/chemins et les frontières KSP sans fusionner leurs responsabilités.
|
||||
- **RUST-AUDIT-002** — L'audit est dependency-free côté Python standard et échoue avec un code non nul dès qu'une violation mécanique est détectée.
|
||||
- **RUST-AUDIT-003** — L'audit contrôle au minimum : headers/version/newline, lints de crate-root, visibilité interdite, `use`/aliases/groupes/globs/scope, rustdocs visibles, ordre des imports/réexports/constantes, lignes vides dans fonctions/structs/enums, complétude des réexports crate-root, chemins `crate::module::Item`, usage de `super::` dans les tests séparés et frontières KSP directement vérifiables.
|
||||
- **RUST-AUDIT-004** — Les règles contextuelles qui ne peuvent pas être prouvées sans interpréter la sémantique restent des critères de revue humaine ; le script ne doit pas produire de faux sentiment de complétude.
|
||||
|
||||
## Contrôle de clôture Rust
|
||||
## Contrôle avant livraison
|
||||
|
||||
Lorsqu'une tranche contient du Rust, les contrôles minimaux sont :
|
||||
Après toute modification Rust, la séquence minimale est :
|
||||
|
||||
```bash
|
||||
cargo fmt --all
|
||||
python3 scripts/audit_rust_workspace_rules.py
|
||||
cargo check --workspace
|
||||
cargo test --workspace
|
||||
cargo clippy --workspace --all-targets
|
||||
```
|
||||
|
||||
Les audits structurels automatisés seront ajoutés lorsqu'ils existeront dans KSP ; une règle ne doit pas prétendre qu'un script inexistant a été exécuté.
|
||||
Pendant le développement, des tests ciblés suivent ce gate. À la fermeture d'une prerelease technique/release, exécuter également :
|
||||
|
||||
```bash
|
||||
cargo test --workspace
|
||||
```
|
||||
|
||||
Une commande non exécutée n'est jamais déclarée réussie. `rustfmt`, `cargo check` et Clippy ne remplacent pas l'audit structurel KSP.
|
||||
|
||||
Reference in New Issue
Block a user