This commit is contained in:
2026-08-13 16:09:07 +02:00
parent 5f6c2ef45e
commit 199550bc82
25 changed files with 1233 additions and 1 deletions

View File

@@ -0,0 +1,57 @@
<!-- file: docs/rules/FILE_CONTRACTS.md -->
<!-- version: 6 -->
# Contrats des fichiers
## Portée
Les règles `FILE-*` définissent la responsabilité et le mode de modification des principales familles de fichiers KSP. Un nouveau type de fichier durable doit recevoir un contrat avant de devenir une convention répétée.
## Fichiers racine et configuration Cargo
| Fichier | Responsabilité | Règle de modification |
|----------------------|-----------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `.gitignore` | Exclure uniquement les artefacts non versionnés décidés par le projet. | Ajouter une exclusion lorsqu'un besoin réel apparaît ; éviter les exclusions spéculatives. |
| `README.md` | Présenter KSP, sa finalité, son périmètre général, ses principes et les points d'entrée. | Mettre à jour lorsqu'une définition structurante du projet change ; ne pas y consigner l'historique des versions. |
| `RULES.md` | Indexer les règles normatives. | Modifier uniquement lorsque la structure normative ou ses points d'entrée changent. |
| `Cargo.toml` | Définir le workspace, sa version Cargo, les métadonnées héritées et les lints communs. | Modifier lors de toute prerelease/release non-fix, lors d'un correctif touchant le code/build/runtime/configuration/migrations, lorsqu'une crate entre/sort du workspace ou lorsqu'un contrat Cargo commun change. Un correctif purement documentaire ou de référence non consommée par le runtime ne force pas un changement de version Cargo. |
| `.cargo/config.toml` | Définir les réglages Cargo propres au workspace qui ne relèvent pas du manifeste, notamment l'emplacement des artefacts de build. | Modifier lorsqu'un réglage Cargo commun change ; ne pas y placer de secret ni de configuration spécifique à une machine particulière. |
| `rustfmt.toml` | Définir le formatage Rust commun. | Modifier comme changement normatif, avec justification dans le delta. |
| `clippy.toml` | Définir les paramètres Clippy communs. | Modifier comme changement normatif, avec justification dans le delta. |
| `ROADMAP.md` | Décrire les objectifs globaux et les grandes étapes prévues par phase/version, avec leur état synthétique. | Modifier lorsqu'un objectif, une grande étape, un report, une annulation ou un état global change ; ne pas y recopier le détail des prereleases prévu dans les plans de version. |
| `CHANGELOG.md` | Résumer les releases stables dans un ordre chronologique décroissant, sous forme d'un ou plusieurs paragraphes par release. | Synchroniser lors de la phase documentaire finale ; ne pas dupliquer les deltas ni créer de changelog par crate/module. |
## Répertoire `docs/`
| Fichier/famille | Responsabilité | Règle de modification |
|---------------------------------|----------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `docs/000-README.md` | Indexer et expliquer la documentation tout en restant en tête des listings et arbres de fichiers. | Modifier lorsque l'organisation durable de `docs/` change ; `000-README.md` reste prioritaire lorsqu'un ordre numérique existe. |
| `docs/rules/*.md` | Définir les règles normatives par portée. | Modifier uniquement pour une décision normative ; incrémenter la version du fichier à chaque enregistrement modifiant son contenu. |
| `docs/IDEAS.md` | Conserver les idées, pistes, questions et alternatives à explorer qui ne sont pas encore des engagements du roadmap. | Ajouter une idée dès qu'elle mérite d'être conservée ; mettre à jour son statut lorsqu'elle est explorée, retenue, rejetée ou transférée vers un plan, le roadmap, une règle ou une décision. |
| futurs documents d'architecture | Décrire l'architecture courante décidée. | Ne pas utiliser comme journal de livraison ; reporter les décisions depuis les deltas/plans. |
| futurs documents de référence | Définir vocabulaire, identifiants et références canoniques. | Mettre à jour quand la référence canonique évolue. |
| futurs plans | Organiser une phase ou version complexe. | Ils peuvent évoluer pendant la phase ; leur statut normatif doit être explicite. |
| futures validations | Conserver des résultats réellement exécutés. | Ne jamais enregistrer une validation supposée comme réussie. |
## Répertoire `deltas/`
| Fichier | Responsabilité | Règle de modification |
|----------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `deltas/<X.Y.Z>/<delta-name>.md` | Tracer une livraison précise, sa base, son contenu, ses suppressions, validations et questions ouvertes, regroupée sous la version cible `X.Y.Z`. | Créé avec la livraison ; une livraison déjà publiée n'est pas réécrite silencieusement. Les prereleases utilisent `pre.NNN`, leurs correctifs `pre.NNN-fix.NNN`, et les publications de release utilisent `rel.NNN`. |
## Rust
| Fichier/famille | Responsabilité | Règle de modification |
|----------------------------|-----------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------|
| `crates/<name>/Cargo.toml` | Définir un package Rust et ses dépendances/features propres. | Toute dépendance doit correspondre à un usage réel ; les contraintes de version inhabituelles sont documentées. |
| `src/lib.rs` | Définir la façade d'une bibliothèque. | Les modules restent privés ; l'API est réexportée explicitement. |
| `src/main.rs` | Définir le point d'entrée d'un exécutable Rust. | Ne doit pas devenir un conteneur de logique métier réutilisable. |
| modules Rust | Porter une responsabilité cohérente. | Un module est séparé ou fusionné selon ses invariants et responsabilités, pas uniquement selon sa taille. |
| `unit_tests/` | Porter les tests unitaires physiquement séparés du code de production, en miroir de `src/` autant que possible. | Les fichiers restent rattachés sous `#[cfg(test)]` au module testé afin de conserver l'accès au privé ; cette séparation est utilisée au maximum. |
| `tests/` | Porter exclusivement les tests d'intégration Cargo de la crate. | Les tests consomment uniquement l'API publique ; les contrats publics pertinents y sont testés lorsque techniquement possible. |
## Fichiers générés
- **FILE-GEN-001** — Un fichier généré n'est jamais modifié manuellement lorsque sa source de vérité est un générateur.
- **FILE-GEN-002** — Le choix de versionner ou ignorer une famille générée est décidé explicitement lorsqu'elle apparaît.
- **FILE-GEN-003** — Les futurs artefacts Tauri `bindings/` et `gen/` ne sont pas encore une convention KSP en `0.0.2-pre.001-fix.001`.

View File

@@ -0,0 +1,48 @@
<!-- file: docs/rules/RULES_DOCUMENTATION.md -->
<!-- version: 4 -->
# Règles de documentation
## Portée
Les règles `DOC-*` s'appliquent aux documents Markdown internes et à leur organisation.
## Principes
- **DOC-ROOT-001** — `README.md` à la racine décrit KSP, sa finalité, ses principes structurants et les points d'entrée du dépôt ; il ne sert ni de changelog ni de plan détaillé de version.
- **DOC-ROOT-002** — Le point d'entrée d'un répertoire documentaire utilisant une priorité explicite se nomme `000-README.md`. Le préfixe `000-` garantit qu'il reste en première position dans les listings et arbres de fichiers lorsque le volume documentaire devient important.
- **DOC-ROOT-003** — Dans un répertoire documentaire où un ordre de lecture, de priorité ou d'affichage est utile, les autres documents prioritaires peuvent être préfixés `001-`, `002-`, etc. Le préfixe numérique n'est pas appliqué mécaniquement à tous les fichiers.
- **DOC-ROOT-004** — La convention `000-`, `001-`, `002-`, etc. ne s'applique pas aux fichiers situés à la racine du dépôt. `README.md`, `RULES.md`, `ROADMAP.md`, `CHANGELOG.md` et les autres fichiers racine conservent leur nom canonique sans préfixe numérique.
- **DOC-ROOT-005** — `RULES.md` est le seul index normatif à la racine et renvoie vers les règles détaillées sous `docs/rules/`.
- **DOC-ROOT-006** — KSP utilisera au plus un `CHANGELOG.md` général à la racine ; aucun changelog spécifique par crate ou module n'est créé par défaut.
- **DOC-ROOT-007** — `ROADMAP.md` décrit les objectifs et grandes étapes globales par phase/version. Chaque bloc peut comporter un `Status` optionnel et utilise la légende `[ ]` prévu, `[/]` en cours, `[X]` réalisé et validé, `[C]` annulé et `[R]` reporté.
- **DOC-ROOT-008** — `CHANGELOG.md` contient les releases stables dans un ordre chronologique décroissant. Chaque release est résumée par un ou plusieurs paragraphes ; le changelog général ne recopie pas le détail des deltas.
## Deltas et documents durables
- **DOC-DELTA-001** — Les fichiers `deltas/<X.Y.Z>/<delta-name>.md` sont des journaux de livraison versionnés et commités ; ils ne sont pas placés sous `docs/`.
- **DOC-DELTA-002** — Aucun second système de fichiers de version n'est créé sous `docs/`.
- **DOC-DELTA-003** — Les décisions devenues durables sont reportées dans les documents normatifs, architecturaux ou de référence appropriés ; le delta reste une trace historique de la livraison.
- **DOC-DELTA-004** — Le changelog général, lorsqu'il sera défini et introduit, synthétisera les changements significatifs sans dupliquer chaque détail des deltas.
## Idées à explorer
- **DOC-IDEAS-001** — `docs/IDEAS.md` conserve les idées, pistes, alternatives et questions qui doivent rester visibles sans constituer encore une décision ou un engagement de développement.
- **DOC-IDEAS-002** — Une idée peut utiliser les statuts `À explorer`, `En exploration`, `Retenue`, `Rejetée`, `Transférée au roadmap` ou `Transférée vers une décision/règle`.
- **DOC-IDEAS-003** — Lorsqu'une idée devient un engagement, elle est transférée vers le roadmap ou un plan ; lorsqu'elle devient une décision durable, elle est reportée dans le document normatif ou architectural approprié. `IDEAS.md` conserve une trace concise de son issue.
- **DOC-IDEAS-004** — `IDEAS.md` ne doit pas devenir un second roadmap ni une liste de tâches de développement promises.
## Contenu et exactitude
- **DOC-CONTENT-001** — Une documentation décrit l'état réellement décidé ou validé et distingue explicitement les hypothèses, propositions, TODO et questions ouvertes.
- **DOC-CONTENT-002** — Une validation non exécutée est identifiée comme telle.
- **DOC-CONTENT-003** — Une source historique est synthétisée et réévaluée ; elle n'est pas copiée mécaniquement comme documentation KSP active.
- **DOC-CONTENT-004** — Les exemples de chemins et noms suivent la nomenclature KSP active au moment de l'écriture.
## Documents de crates
- **DOC-CRATE-001** — Il est préférable qu'une crate dispose de `README.md`, `TODO.md` et surtout `USAGE.md`, mais leur présence n'est pas imposée mécaniquement lorsque le fichier n'apporte encore aucune information utile.
- **DOC-CRATE-002** — `README.md` décrit la responsabilité, le périmètre, les frontières et les principaux points d'entrée d'une crate.
- **DOC-CRATE-003** — `TODO.md` conserve les tâches, lacunes et vérifications propres à la crate afin d'éviter les oublis ; il ne remplace pas la planification globale ou les deltas.
- **DOC-CRATE-004** — `USAGE.md` documente l'utilisation concrète de la crate, ses préconditions, ses principaux contrats et des exemples pertinents ; il est particulièrement recommandé dès qu'une crate possède une API consommable.
- **DOC-CRATE-005** — Aucun `CHANGELOG.md` de crate n'est créé par défaut ; la traçabilité détaillée est assurée par `deltas/` et, lorsqu'il sera défini, par le changelog général.

View File

@@ -0,0 +1,37 @@
<!-- file: docs/rules/RULES_GENERAL.md -->
<!-- version: 2 -->
# Règles générales du projet
## Portée
Les règles `GEN-*` s'appliquent à l'ensemble du dépôt, sauf lorsqu'une règle indique explicitement une portée plus étroite.
## Hiérarchie normative
- **GEN-RULE-001** — `RULES.md` est l'index normatif racine et ne duplique pas le détail des autres fichiers de règles.
- **GEN-RULE-002** — Les règles sont cumulatives. Une règle spécifique peut renforcer une règle générale mais ne peut pas l'assouplir sans exception explicite.
- **GEN-RULE-003** — Toute exception est locale, bornée, justifiée et traçable.
- **GEN-RULE-004** — Une décision non validée reste une question ouverte ; elle ne doit pas être transformée en règle par supposition.
- **GEN-RULE-005** — Une validation n'est déclarée réussie que si elle a réellement été exécutée.
## Noms et fichiers texte
- **GEN-FILE-001** — Les noms de fichiers et de répertoires sont en anglais, sans accent, espace ou caractère spécial inutile, sauf format imposé par un outil externe.
- **GEN-FILE-002** — Tout fichier texte qui supporte des commentaires commence par son chemin relatif puis par une version entière du fichier.
- **GEN-FILE-003** — Un script exécutable nécessitant un shebang conserve celui-ci en première ligne ; les lignes `file:` et `version:` suivent immédiatement.
- **GEN-FILE-004** — La version d'un fichier est incrémentée à chaque enregistrement qui modifie son contenu, quelle que soit l'importance de la modification. Une modification enregistrée puis annulée par une modification ultérieure consomme donc deux versions distinctes. Une version déjà utilisée n'est jamais réutilisée et la version d'un fichier ne diminue jamais.
- **GEN-FILE-005** — Les fichiers texte se terminent par exactement une fin de ligne lorsque leur formatter le permet.
## Langues
- **GEN-LANG-001** — Les noms de code, chemins, identifiants, commentaires de code et rustdocs sont en anglais.
- **GEN-LANG-002** — Les documents Markdown internes KSP sont rédigés en français, sauf contrat externe, citation, extrait ou documentation technique dont la langue doit être conservée.
## Travail et validation
- **GEN-WORK-001** — Une tranche de travail traite un périmètre cohérent et suffisamment petit pour être revu et validé sans devenir une livraison monolithique.
- **GEN-WORK-002** — Lors de la planification, une tranche dont le budget de travail prévu dépasse approximativement quinze à vingt minutes doit être découpée avant exécution en tranches plus petites et cohérentes.
- **GEN-WORK-003** — Les erreurs locales révélées par une validation sont corrigées dans la tranche qui les introduit ou explicitement reportées avant de continuer.
- **GEN-WORK-004** — Une erreur métier ou architecturale ne doit pas être masquée par une exception globale de lint, de test ou de validation.
- **GEN-WORK-005** — Les outils d'audit du dépôt sont en lecture seule vis-à-vis des fichiers qu'ils contrôlent. Ils peuvent détecter et signaler mais ne corrigent pas automatiquement le workspace.

47
docs/rules/RULES_KSP.md Normal file
View File

@@ -0,0 +1,47 @@
<!-- file: docs/rules/RULES_KSP.md -->
<!-- version: 1 -->
# Règles spécifiques à KSP
## Portée
Les règles `KSP-*` s'appliquent à l'architecture, la nomenclature et l'organisation propres à `khadhroony-solana-project`.
## Succession des projets précédents
- **KSP-LINEAGE-001** — KSP succède aux projets Khadhroony Solana précédents mais ne les duplique pas mécaniquement.
- **KSP-LINEAGE-002** — Une reprise de code, structure, dépendance ou documentation historique doit être justifiée par un besoin KSP actuel.
- **KSP-LINEAGE-003** — Une architecture historique n'est jamais considérée comme normative uniquement parce qu'elle a fonctionné dans `khadhroony-bot3` ou un prédécesseur.
## Nomenclature des crates et exécutables
- **KSP-NAME-001** — Une bibliothèque Rust réutilisable se nomme `ksp-<role>-lib`.
- **KSP-NAME-002** — Une application se nomme `ksp-app-<role>-<interface>` lorsque l'interface doit être indiquée.
- **KSP-NAME-003** — Un worker se nomme `ksp-worker-<role>`.
- **KSP-NAME-004** — Une démonstration se termine par `-demo`.
- **KSP-NAME-005** — Les interfaces d'application utilisent des tokens courts et stables, notamment `cli` pour une interface en ligne de commande et `desk` pour une application desktop.
- **KSP-NAME-006** — Les crates Rust sont placées directement sous `crates/` ; aucun sous-répertoire de catégories n'est utilisé pour les regrouper.
- **KSP-NAME-007** — Les applications sont placées sous `apps/` lorsqu'elles sont introduites.
## Environnements des démonstrations
- **KSP-DEMO-001** — Une demo limitée à un environnement encode explicitement cet environnement dans son nom avant le token d'interface et avant `-demo`.
- **KSP-DEMO-002** — Les tokens d'environnement initiaux sont `mainnet`, `devnet`, `testnet`, `local-validator` et `synthetic`.
- **KSP-DEMO-003** — Une demo sans token d'environnement est conçue pour permettre le choix de l'environnement parmi ceux qu'elle supporte ; l'absence de token ne signifie pas implicitement `mainnet`.
- **KSP-DEMO-004** — Exemples de forme : `ksp-app-<role>-devnet-cli-demo`, `ksp-app-<role>-local-validator-desk-demo`, `ksp-app-<role>-synthetic-cli-demo` et `ksp-app-<role>-desk-demo` pour une demo à environnement sélectionnable.
- **KSP-DEMO-005** — Une demo ne doit pas agréger plusieurs responsabilités indépendantes uniquement pour constituer une application de démonstration universelle.
## Frontières architecturales déjà décidées
- **KSP-ARCH-001** — `ksp-core-lib` regroupe les fondations réellement transversales, y compris la responsabilité autrefois séparée des identifiants de programmes ; il ne doit pas devenir un conteneur générique de tout code partagé.
- **KSP-ARCH-002** — Une bibliothèque commune dédiée aux interfaces/wire on-chain doit exister ; son nom de travail est `ksp-interface-lib` jusqu'à validation définitive.
- **KSP-ARCH-003** — La matérialisation constitue une responsabilité distincte des interfaces/wire et du traitement des programmes.
- **KSP-ARCH-004** — Le regroupement ou la séparation définitive du decoder, de la construction d'instructions et de l'exécution réseau reste une décision d'architecture ouverte ; aucune structure historique ne doit être recopiée avant cette décision.
- **KSP-ARCH-005** — Une bibliothèque comme le wallet reste indépendante de son interface utilisateur ; les applications et demos qui la manipulent consomment la bibliothèque au lieu d'y être intégrées.
- **KSP-ARCH-006** — La configuration doit disposer d'une bibliothèque propriétaire de ses contrats et pourra disposer d'une application dédiée à l'inspection et la modification des profils et valeurs autorisées.
## Dépendances et outils
- **KSP-TOOL-001** — Aucun `rust-toolchain.toml` n'est utilisé dans KSP.
- **KSP-TOOL-002** — Les lockfiles de dépendances sont ignorés et non livrés.
- **KSP-TOOL-003** — Les répertoires et fichiers générés ne sont ajoutés au `.gitignore` qu'après apparition d'un besoin réel et décision explicite ; les futurs `bindings/` et `gen/` Tauri seront traités à ce moment.

100
docs/rules/RULES_RUST.md Normal file
View File

@@ -0,0 +1,100 @@
<!-- file: docs/rules/RULES_RUST.md -->
<!-- version: 4 -->
# 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.
## Édition et lints
- **RUST-BASE-001** — L'édition Rust est Rust 2024, sauf contrainte externe explicitement documentée.
- **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.
## Documentation des API
- **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.
## 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-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::`.
## 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-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.
## Contrôle de flux et erreurs
- **RUST-ERR-001** — `unwrap`, `expect` et `panic` sont interdits dans le code de production.
- **RUST-ERR-002** — L'opérateur `?` est interdit dans le code de production ; les chemins d'erreur utilisent un contrôle de flux explicite.
- **RUST-ERR-003** — Les retours sont explicites conformément au lint `clippy::implicit_return`.
- **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.
## 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.
## Helpers et duplication
- **RUST-HELP-001** — Un helper répété dans plusieurs modules d'une même crate est déplacé dans un module commun dont le nom décrit la responsabilité la plus précise possible.
- **RUST-HELP-002** — Un helper réellement général et réutilisable par plusieurs crates est déplacé dans la bibliothèque KSP appropriée.
- **RUST-HELP-003** — La mutualisation ne doit pas créer de dépendance cyclique ni déplacer une logique métier spécifique dans une bibliothèque générique.
## Dépendances
- **RUST-DEP-001** — Une dépendance n'est ajoutée que si elle est réellement utilisée dans le chemin de compilation concerné.
- **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.
## Assertions de collections
- **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.
## Organisation des tests
- **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.
## Contrôle de clôture Rust
Lorsqu'une tranche contient du Rust, les contrôles minimaux sont :
```bash
cargo fmt --all
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é.

View File

@@ -0,0 +1,74 @@
<!-- file: docs/rules/VERSION_WORKFLOW.md -->
<!-- version: 5 -->
# Versionnement, sessions et livraisons
## Portée
Les règles `VER-*` définissent la progression des versions KSP, les identifiants de livraison, les deltas et la norme de travail par session.
## Versions du projet
- **VER-PROJECT-001** — `0.0.x` est la phase fondatrice : dépôt, squelette, règles, architecture, planification et préparation de la première phase fonctionnelle.
- **VER-PROJECT-002** — `0.0.1` contient uniquement le `.gitignore` initial.
- **VER-PROJECT-003** — `0.0.2` installe le squelette minimal, les règles initiales, `README.md`, `Cargo.toml`, `rustfmt.toml` et `clippy.toml`, sans développement métier.
- **VER-PROJECT-004** — `0.0.3` et les versions fondatrices suivantes poursuivent le brainstorming, l'architecture, la nomenclature, le plan global et la préparation du prompt de `0.1.x`.
- **VER-PROJECT-005** — `0.1.x` ouvre la première phase de développement fonctionnel seulement après clôture de la session fondatrice.
## Version Cargo et identifiant de livraison
- **VER-ID-001** — Les versions Cargo respectent strictement SemVer et utilisent des identifiants numériques sans zéro initial, par exemple `0.0.2-pre.1`.
- **VER-ID-002** — Une livraison de prerelease utilise l'identifiant `X.Y.Z-pre.NNN`, par exemple `0.0.2-pre.001`.
- **VER-ID-003** — Un correctif d'une prerelease utilise `X.Y.Z-pre.NNN-fix.NNN` ; la numérotation `fix.NNN` recommence à `001` pour chaque nouvelle prerelease.
- **VER-ID-004** — Une livraison correspondant à la publication d'une release finale utilise l'identifiant de livraison `X.Y.Z-rel.NNN`. Le marqueur `rel` appartient au système de livraison/delta et non à la version Cargo finale.
- **VER-ID-005** — Pour une release finale, `workspace.package.version` utilise la version SemVer finale `X.Y.Z`, sans suffixe `rel`, car une version Cargo `X.Y.Z-rel.N` serait elle-même une prerelease SemVer et non la release finale.
- **VER-ID-006** — Un nouveau numéro de prerelease correspond à une nouvelle tranche planifiée ; un correctif corrige la tranche existante sans en redéfinir le périmètre fonctionnel principal.
- **VER-ID-007** — Lorsqu'un correctif modifie au moins un fichier participant au code, au build, au runtime, à la configuration exécutable ou à une migration de données, `workspace.package.version` dans le `Cargo.toml` racine est synchronisé avec l'identifiant technique du delta. Cela couvre notamment les sources `.rs`, `.ts`, les ressources `.html` utilisées au runtime, les fichiers `.toml` de projet/configuration, les migrations SQL et tout autre artefact effectivement consommé par le système.
- **VER-ID-008** — Un correctif limité à de la documentation ou à des fichiers externes/de référence non consommés par le build ou le runtime ne modifie pas `workspace.package.version`. Le décalage entre l'identifiant du delta et la version Cargo indique alors volontairement qu'aucun changement de code/runtime n'a eu lieu.
- **VER-ID-009** — Toute publication non-fix d'une prerelease ou d'une release synchronise `workspace.package.version` avec la version correspondante, même lorsque la dernière tranche de travail ne contient que de la documentation.
- **VER-ID-010** — La représentation Cargo d'un correctif de prerelease conserve l'ordre SemVer avec des identifiants séparés par des points : la livraison `0.0.2-pre.001-fix.003` correspond à la version Cargo `0.0.2-pre.1.fix.3`.
- **VER-ID-011** — Les crates qui héritent `version.workspace = true` ne redéfinissent pas localement cette version.
- **VER-ID-012** — Avant `0.1.x`, les prereleases et releases sont les points de commit normaux ; les correctifs intermédiaires peuvent rester des livraisons d'échange non commitées.
- **VER-ID-013** — À partir de `0.1.x`, chaque delta est commité, y compris lorsqu'il contient un état imparfait qui sera corrigé par un delta `fix` ultérieur. L'historique Git doit conserver la séquence réelle des travaux et corrections.
- **VER-ID-014** — Une livraison `rel.NNN` peut être corrigée avant la publication stable par `rel.NNN-fix.NNN` ou remplacée par une nouvelle livraison `rel.NNN` selon le besoin. Une release déjà considérée comme stable et taguée `vX.Y.Z` n'est normalement pas réécrite ; une correction fonctionnelle ultérieure ouvre une nouvelle version appropriée.
## Git
- **VER-GIT-001** — Les commits correspondant aux livraisons utilisent un libellé versionné de forme `vX.Y.Z-pre.NNN`, `vX.Y.Z-pre.NNN-fix.NNN`, `vX.Y.Z-rel.NNN` ou, si nécessaire avant publication stable, `vX.Y.Z-rel.NNN-fix.NNN`.
- **VER-GIT-002** — Les prereleases, fixes et livraisons `rel` n'ont pas besoin d'un tag Git dédié.
- **VER-GIT-003** — Le dernier commit validé comme release stable reçoit le tag Git `vX.Y.Z`.
- **VER-GIT-004** — La suppression technique d'un tag créé prématurément ne supprime pas le commit visé ; néanmoins une release déjà publiée comme stable ne doit normalement pas être réécrite.
## Deltas
- **VER-DELTA-001** — Il existe un seul arbre `deltas/` pour tout le dépôt, indépendamment du type de fichiers modifiés.
- **VER-DELTA-002** — Les deltas sont regroupés sous la version cible : `deltas/<X.Y.Z>/`.
- **VER-DELTA-003** — Une prerelease est tracée par `deltas/<X.Y.Z>/pre.NNN.md` et son correctif par `deltas/<X.Y.Z>/pre.NNN-fix.NNN.md`.
- **VER-DELTA-004** — Une livraison de release finale est tracée par `deltas/<X.Y.Z>/rel.NNN.md`.
- **VER-DELTA-005** — Un delta indique au minimum : base requise, objectif, fichiers ajoutés, fichiers modifiés, fichiers supprimés, validations exécutées, validations non exécutées, décisions prises et questions ouvertes.
- **VER-DELTA-006** — Une suppression est explicitement listée ; l'extraction d'une archive ne constitue jamais une suppression implicite.
- **VER-DELTA-007** — Une livraison publiée n'est jamais remplacée silencieusement sous le même identifiant.
## Archives d'échange
- **VER-ARCHIVE-001** — Une livraison pouvant toucher la racine, le code et/ou la documentation se nomme `ksp-general-<delivery-id>.zip`.
- **VER-ARCHIVE-002** — Une livraison limitée à `docs/` et/ou aux prompts se nomme `ksp-doc-<delivery-id>.zip`.
- **VER-ARCHIVE-003** — Le type `general` ou `doc` ne crée aucun versionnement parallèle ; les deux utilisent le même identifiant et le même répertoire `deltas/`.
- **VER-ARCHIVE-004** — L'archive contient uniquement les fichiers ajoutés ou modifiés par la livraison, plus son fichier `deltas/<X.Y.Z>/<delta-name>.md`.
- **VER-ARCHIVE-005** — Les lockfiles, caches, secrets, sorties de compilation et autres artefacts explicitement ignorés ne sont pas livrés.
## Norme de session
- **VER-SESSION-001** — Toute nouvelle session fonctionnelle commence par une phase de brainstorming puis une phase de planification avant toute modification de développement.
- **VER-SESSION-002** — Après validation du plan, la session peut enchaîner développement, validations/tests, documentation finale puis préparation du prompt de la session suivante.
- **VER-SESSION-003** — La session fondatrice actuelle remplace la phase de développement par la définition des règles, de l'architecture, du squelette et du plan nécessaires à KSP.
- **VER-SESSION-004** — La session fondatrice doit se terminer avec un workspace initial cohérent, la documentation/règles nécessaires, un plan de poursuite et un prompt permettant d'ouvrir `0.1.x`.
- **VER-SESSION-005** — Le changelog général, lorsqu'il existe, est synchronisé en fin de session à partir des deltas validés et ne remplace pas les deltas détaillés.
## Première et dernière prerelease d'une phase de développement
- **VER-LIFECYCLE-001** — La première prerelease d'une nouvelle phase fonctionnelle est prioritairement consacrée au brainstorming, à l'inventaire, aux risques, dépendances, hors-périmètre, critères de validation et plan de travail.
- **VER-LIFECYCLE-002** — Une phase importante ne commence pas directement par des modifications fonctionnelles dispersées sans cadrage.
- **VER-LIFECYCLE-003** — La dernière prerelease d'une phase est prioritairement consacrée aux validations finales, écarts résiduels, documentation finale, synthèse changelog et prompt de reprise.
- **VER-LIFECYCLE-004** — Le document de planification établi ou révisé pendant `pre.001` d'une version détaille une prévision souple des prereleases de cette version : objectifs de chaque tranche, ordre envisagé, dépendances, validations et éventuels hors-périmètre. Cette prévision peut être réorganisée lorsque la réflexion ou le développement le justifie ; le delta trace ces changements.
- **VER-LIFECYCLE-005** — Le `ROADMAP.md` n'est pas obligé de reprendre une entrée par prerelease. Il décrit la trajectoire globale ; le plan de version porte le découpage prévisionnel plus fin des prereleases.