0.0.4-alpha.4

This commit is contained in:
2026-09-24 14:48:17 +02:00
parent 5471ea6283
commit c0735d1d63
7 changed files with 634 additions and 6 deletions

View File

@@ -0,0 +1,206 @@
<!-- file: docs/skeletons/002-RUST_CARGO_WORKSPACE.md -->
<!-- version: 1 -->
# Skeleton — Rust/Cargo workspace
## Objectif
Cette specification décrit la specialization Rust/Cargo d'un projet gouverné par PGR lorsque plusieurs packages Rust partagent réellement une même unité de release, une politique Cargo commune ou une validation de workspace commune.
Elle se compose avec [`001-PROJECT_GOVERNANCE_FOUNDATION.md`](001-PROJECT_GOVERNANCE_FOUNDATION.md), sélectionne les profils [`../rules/500-LANGUAGES.md`](../rules/500-LANGUAGES.md) et [`../rules/510-RUST_CARGO.md`](../rules/510-RUST_CARGO.md), puis utilise les templates et guides Rust/Cargo déjà présents dans PGR. Le contrat transversal des skeletons reste possédé par [`../rules/220-SKELETONS.md`](../rules/220-SKELETONS.md).
Cette specification ne transforme pas PGR en générateur Cargo et ne crée aucune dépendance build ou runtime vers le dépôt PGR après instanciation.
## Applicabilité et composition
Appliquer ce skeleton lorsqu'un projet utilise Rust avec Cargo et qu'un workspace représente réellement son unité de gouvernance ou de release.
La composition normale est :
```text
001-PROJECT_GOVERNANCE_FOUNDATION
↓
500-LANGUAGES
↓
510-RUST_CARGO
↓
002-RUST_CARGO_WORKSPACE
```
Un dépôt contenant plusieurs unités de release indépendantes ne doit pas être forcé dans un workspace à version globale fictive. Un framework, une plateforme, WASM, Android, Tauri, une FFI ou un autre scope plus spécifique peut ajouter ses propres règles sans modifier le contrat Rust/Cargo général.
## Owners, guides et artefacts sélectionnés
Les responsabilités générales de version, workflow, documentation et validation sont déjà couvertes par la fondation `001`. La présente specialization ajoute :
```text
docs/rules/500-LANGUAGES.md
contrat commun langage/écosystème
docs/rules/510-RUST_CARGO.md
workspace, manifests, dépendances, lints, safety, formatage et validation Cargo
docs/templates/001-RUST_CARGO_TOOLING.md
adaptation de rustfmt.toml, clippy.toml et .cargo/config.toml
docs/templates/002-CARGO_MANIFESTS.md
adaptation du manifest workspace et du manifest membre
```
Les cinq artefacts techniques copiables sélectionnés sont :
```text
templates/rust-cargo/rustfmt.toml
templates/rust-cargo/clippy.toml
templates/rust-cargo/.cargo/config.toml
templates/rust-cargo/Cargo.toml
templates/rust-cargo/crates/project-core-lib/Cargo.toml
```
[`../validation/002-RUST_STYLE_AUDITS.md`](../validation/002-RUST_STYLE_AUDITS.md) est seulement une option supplémentaire. Les scripts `audit_rust_blank_lines.py`, `audit_rust_const_blocks.py` et `_rust_audit_common.py` ne sont copiés que si le projet choisit explicitement les conventions correspondantes et sait quels fichiers Rust doivent être audités.
## Décisions destinataire avant copie
Avant de considérer la specialization comme instanciée, résoudre explicitement au minimum :
1. le release unit gouverné et la relation entre son `VERSION` et `[workspace.package].version` ;
2. la liste réelle des packages membres, leurs noms, leurs rôles et leurs chemins ;
3. l'édition Rust, le resolver Cargo et la toolchain stable compatible ;
4. la politique de publication et les métadonnées réelles communes (`license`, `repository`, `authors`) lorsqu'elles existent ;
5. les dépendances réellement partagées, leurs contraintes de version et les features qui doivent rester locales à chaque membre ;
6. la politique de versionnement de `Cargo.lock` adaptée au type de produit ;
7. les niveaux de lints hérités, les éventuelles exceptions locales et tout besoin réel d'`unsafe` dans un scope étroit ;
8. les paramètres `rustfmt.toml` et `clippy.toml` à conserver ou adapter ;
9. l'emplacement des artefacts Cargo et l'identifiant unique utilisé dans `.cargo/config.toml` si cette politique externe au dépôt est retenue ;
10. les audits de style Rust facultatifs réellement adoptés et leur corpus exact ;
11. les validations Cargo réellement nécessaires au code et aux manifests créés.
Les valeurs `0.1.0`, `2024`, `project-name`, `project-core-lib`, les seuils Clippy et les chemins de build présents dans les templates sont des exemples ou baselines à revoir. Ils ne deviennent jamais des valeurs universelles par simple copie.
## Matérialisation du workspace
### Fondation gouvernée
Appliquer d'abord la fondation `001` et résoudre ses décisions générales. Ne recopier ni le workflow ni la structure documentaire complète de PGR lorsqu'ils ne sont pas nécessaires au projet destinataire.
La version canonique du release unit doit être décidée avant d'adapter les manifests. Pour un train de release Cargo unique, `[workspace.package].version` reflète cette version selon `510-RUST_CARGO.md`.
### Manifest workspace
Copier `templates/rust-cargo/Cargo.toml` vers `Cargo.toml`, puis :
- adapter le header `# file:` et démarrer la révision locale selon la convention documentaire retenue ;
- remplacer `members` par les packages réellement présents ;
- remplacer la version d'exemple par la version du release unit lorsque le workspace partage une seule release ;
- aligner `edition` et `resolver` sur la toolchain réellement choisie ;
- décider explicitement `publish` et les métadonnées communes ;
- ajouter sous `[workspace.dependencies]` uniquement les dépendances réellement partagées ;
- conserver, adapter ou documenter les niveaux de lints selon le profil local retenu.
Le projet ne doit pas remplir les champs manquants avec des identités fictives provenant de PGR, KSP ou Games.
### Packages membres
Pour chaque crate réellement nécessaire, utiliser `templates/rust-cargo/crates/project-core-lib/Cargo.toml` comme exemple de manifest membre puis adapter son chemin et son nom.
`project-core-lib` n'est pas un nom de crate imposé. Une crate bibliothèque, binaire ou spécialisée doit conserver le layout et les héritages qui correspondent à son rôle réel.
Lorsque le membre hérite de la politique commune, `version.workspace = true`, `edition.workspace = true`, `publish.workspace = true` et `[lints] workspace = true` restent cohérents. Une exception locale, notamment de lint ou de safety, doit suivre le contrat de `510-RUST_CARGO.md` et ne pas affaiblir silencieusement les autres membres.
Le code source minimal requis par Cargo appartient au projet destinataire. PGR ne fournit pas de `src/lib.rs` ou `src/main.rs` universel, car leur contenu dépend du rôle réel de la crate.
### Outillage Rust/Cargo
Copier et adapter :
```text
rustfmt.toml
clippy.toml
.cargo/config.toml
```
Suivre [`../templates/001-RUST_CARGO_TOOLING.md`](../templates/001-RUST_CARGO_TOOLING.md) pour leurs décisions d'adaptation.
L'édition de `rustfmt.toml` doit rester cohérente avec le workspace. Les seuils de `clippy.toml` doivent être revus au regard des API réelles. Dans `.cargo/config.toml`, remplacer `project-name` ou choisir un autre emplacement d'artefacts ; ne pas copier un chemin machine ou un identifiant appartenant à un autre projet.
### Cargo.lock
Décider explicitement si `Cargo.lock` est versionné selon le type de produit, le mode de publication et le besoin de reproductibilité. La présence ou l'absence du lockfile dans un projet source historique ne constitue pas une règle suffisante pour le nouveau workspace.
### Audits de style facultatifs
Si le projet adopte les conventions documentées dans [`../validation/002-RUST_STYLE_AUDITS.md`](../validation/002-RUST_STYLE_AUDITS.md), copier les trois scripts concernés et adapter leurs headers à leurs chemins locaux.
La sélection des fichiers doit rester explicite. En particulier, l'audit des blocs de constantes ne doit jamais réordonner une table de protocole, une séquence de migrations ou toute autre structure dont l'ordre possède une sémantique propre.
Ne pas copier ces scripts uniquement parce qu'ils existent dans PGR.
## Validation initiale
Une instanciation minimale doit d'abord prouver que les manifests adaptés décrivent bien le workspace voulu, puis que les outils Rust/Cargo retenus acceptent la baseline réelle.
Lorsque la toolchain est disponible et que du code source minimal ou réel existe, la séquence normale comprend :
```bash
cargo metadata --format-version 1 --no-deps
cargo fmt --all -- --check
cargo check --workspace
cargo clippy --workspace --all-targets --all-features -- -D warnings
```
Ajouter des tests ciblés pour les crates qui possèdent déjà un comportement à vérifier. Un `cargo build` n'est nécessaire que lorsqu'un artefact de build doit réellement être produit.
Si les audits de style facultatifs ont été sélectionnés, les exécuter après le formatage sur les seuls chemins concernés.
La validation doit aussi confirmer :
```text
CHECK VERSION et workspace.package.version cohérents pour un train de release unique
CHECK aucun placeholder project-name/project-core-lib non résolu dans les fichiers adoptés
CHECK édition Rust cohérente entre Cargo.toml et rustfmt.toml
CHECK membres du workspace existants et correctement nommés
CHECK politique Cargo.lock explicitement décidée
CHECK artefacts Cargo hors des livraisons source selon la politique locale
REVIEW dépendances/features, lints et métadonnées réellement nécessaires
REVIEW aucune specialization plateforme/framework ajoutée sans besoin réel
```
Pour valider les templates PGR eux-mêmes, une instanciation temporaire minimale peut remplacer les placeholders, créer une crate source triviale et exécuter les commandes Cargo ci-dessus. Cette preuve vérifie l'adoption des templates sans transformer le dépôt PGR en workspace Rust.
Une prévalidation PGR ou générateur ne remplace jamais la gate opérateur autoritaire du projet destinataire.
## Ordre de composition et extensions
La specialization Rust/Cargo doit être appliquée après `001` lorsqu'elle l'utilise comme fondation. Les profils plateforme ou framework viennent ensuite uniquement s'ils sont applicables.
Une specialization plus précise peut :
- ajouter des packages ou cibles spécifiques ;
- imposer une matrice de toolchain ou de SDK ;
- raffiner la politique d'artefacts ou de lockfile ;
- ajouter des features, dépendances ou validations propres à son scope ;
- définir une exception locale de safety strictement justifiée.
Elle ne doit pas réécrire les règles générales Cargo ou inventer un nouveau workspace composite si les owners existants suffisent.
## Overrides et exceptions
Toute divergence par rapport aux templates ou au profil `510` doit identifier le choix concerné, son scope et sa raison lorsqu'elle affecte le contrat durable du projet.
Un projet peut notamment choisir un layout sans `crates/`, un autre chemin d'artefacts, une autre largeur Rustfmt, une politique de lockfile différente, des seuils Clippy différents ou une crate à lints locaux. Ces choix restent locaux et ne modifient pas les defaults PGR pour les autres projets.
## Hors scope
Cette specification ne définit pas :
- un nom universel de workspace ou de crate ;
- une version Rust ou Cargo exacte à pinner sans justification ;
- une liste universelle de dépendances ou features ;
- une politique `Cargo.lock` identique pour bibliothèques et applications ;
- une architecture applicative au-delà du workspace Cargo ;
- une plateforme, un framework, WASM, Android, Tauri ou une FFI ;
- un CI/CD, packaging ou mécanisme de publication universel ;
- une obligation de copier les audits Rust facultatifs ;
- un `src/lib.rs` ou `src/main.rs` générique sans rôle réel.
Les spécialisations futures doivent rester composables au-dessus de ce skeleton plutôt que modifier rétroactivement son scope.