Compare commits
51 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9a7f4f7c67 | |||
| 436680207f | |||
| 390dd63e21 | |||
| c97ca5f21a | |||
| 5a83968813 | |||
| 9f596f30b2 | |||
| c331da5114 | |||
| ecd9de4d4e | |||
| ac03b78708 | |||
| 4e1c1cd6f0 | |||
| b7e65d9100 | |||
| 33bf835b7f | |||
| 0f6a2e21eb | |||
| 81c7a720f5 | |||
| f03f8640d4 | |||
| defc9ca4b5 | |||
| a954d7f90a | |||
| 1b1a7092e5 | |||
| d7282dc33b | |||
| 3ca2518c5c | |||
| bd9aadf0cf | |||
| c6af96b6bc | |||
| 3f8fa6b34e | |||
| fdaaa357d4 | |||
| ea80396828 | |||
| c0735d1d63 | |||
| 5471ea6283 | |||
| 7408616909 | |||
| bf306daea6 | |||
| 1e10feba95 | |||
| ec3a101d9b | |||
| 47114fa96b | |||
| dee864e22b | |||
| 584a0d1586 | |||
| 8ad4987d38 | |||
| b3230b4da9 | |||
| a8dd8ae349 | |||
| 883e20e3c5 | |||
| 3472fe7094 | |||
| 1b37d2752a | |||
| 3ba513da16 | |||
| 8272cfe33d | |||
| d0ac83569f | |||
| 0719955875 | |||
| ead2e879ef | |||
| 368dedbed9 | |||
| 70ff272b79 | |||
| 34ac3a9286 | |||
| 5f9b84c980 | |||
| 1a5dd0908c | |||
| d3f1e13c84 |
36
CHANGELOG.md
36
CHANGELOG.md
@@ -1,5 +1,5 @@
|
||||
<!-- file: CHANGELOG.md -->
|
||||
<!-- version: 2 -->
|
||||
<!-- version: 9 -->
|
||||
|
||||
# Changelog Project Governance Rules
|
||||
|
||||
@@ -7,6 +7,40 @@ Ce fichier décrit les changements utiles aux utilisateurs ou intégrateurs des
|
||||
|
||||
Les tranches `alpha`, `beta`, `rc`, fixes, validations, audits et détails de développement appartiennent aux plans, deltas et historiques. Ils ne sont pas recopiés ici par défaut.
|
||||
|
||||
## 0.0.5
|
||||
|
||||
- consolide le lifecycle inter-release de PGR : prompts de reprise versionnés, contrats locaux de fichiers/familles, responsabilités de fermeture et revue d'horizon sans création artificielle de releases futures ;
|
||||
- renforce le profil Rust/Cargo des nouveaux projets contrôlés avec Rust 2024, chemins explicites, façade crate-root, contrats de suffixes de crates, séparation bibliothèque/exécutable, erreurs explicites et ownership du tracing ;
|
||||
- ajoute et sépare les validations Rust structurelles utiles : complétude des réexports/chemins `crate::Item`, espacement des items, ordre des modules, blocs d'imports de traits et blocs de réexports, tout en conservant les contrôles à ordre sémantique comme opt-in ;
|
||||
- active les profils framework et Tauri 2, avec host Rust direct, frontière frontend explicite, TS-RS pour les DTO partagés, plugins/capabilities gouvernés, versions produit classifiées et exception Tauri encadrée au principe de séparation `lib`/`bin` ;
|
||||
- enregistre le skeleton Tauri contrôlé comme trajectoire `DEFER` jusqu'à matérialisation d'owners Web suffisants, sans créer de skeleton décoratif ni réserver une release ;
|
||||
- réconcilie les décisions avec les corpus KSP/Games, conserve leurs architectures métier locales hors du noyau PGR et prépare le prompt de reprise `006` vers la première baseline réutilisable `0.1.0`.
|
||||
|
||||
## 0.0.4
|
||||
|
||||
- définit un contrat transversal de skeleton specifications pour sélectionner et composer règles, profils, templates, décisions destinataire, overrides et validation sans dupliquer les propriétaires normatifs ;
|
||||
- ajoute une fondation composable de gouvernance locale pour initialiser version, documentation minimale, workflow retenu et validation proportionnée d'un projet utilisant PGR ;
|
||||
- ajoute une spécialisation Rust/Cargo workspace composant la fondation avec les profils `500 + 510` et les cinq templates Rust/Cargo existants ;
|
||||
- explicite les décisions à adapter avant instanciation, notamment version, édition/toolchain, membres, métadonnées, dépendances/features, `Cargo.lock`, lints, chemins d'artefacts et audits facultatifs ;
|
||||
- conserve Java/Maven/Gradle, Android, Web, JNI, Tauri et les autres familles insuffisamment matérialisées comme domaines différés plutôt que créer des skeletons prématurés.
|
||||
|
||||
## 0.0.3
|
||||
|
||||
- fournit cinq fichiers modèles Rust/Cargo : `rustfmt.toml`, `clippy.toml`, `.cargo/config.toml`, un manifest workspace et un manifest de crate membre, avec instructions d'adaptation ;
|
||||
- explicite l'héritage des métadonnées et lints Cargo, ainsi que les exceptions locales motivées ;
|
||||
- ajoute deux audits facultatifs et ciblés du style Rust, pour l'espacement des lignes vides et les blocs de constantes racine sans ordre sémantique, sans remplacer Rustfmt ni Clippy ;
|
||||
- ajoute un audit read-only des headers `file` et `version` des fichiers Markdown gouvernés par PGR ;
|
||||
- fournit une spécification courte pour rédiger le message manuel de reprise après publication d'une stable.
|
||||
|
||||
## 0.0.2
|
||||
|
||||
- introduit le modèle de profils PGR avec ownership normatif, applicabilité, composition du général vers le spécifique et overrides bornés ;
|
||||
- matérialise les familles `500 — languages / ecosystems` et `600 — platforms` sans créer prématurément les familles frameworks ou architecture ;
|
||||
- ajoute les premiers profils réutilisables `510 — Rust / Cargo`, `520 — Java / Maven / Gradle` et `610 — Android` ;
|
||||
- formalise notamment les politiques de toolchain/target, dépendances et build, visibilité/API, safety/FFI, structure canonique, compatibilité Android, packaging et niveaux de preuve ;
|
||||
- ajoute deux audits PGR read-only et monotâches : alignement des tableaux Markdown et existence des cibles de liens Markdown locaux ;
|
||||
- confirme que Rust/JNI, Web/Vite/WASM, Tauri, C/C++/CMake, PHP/Composer et Python restent différés jusqu'à une release où leur contenu justifie un owner réel.
|
||||
|
||||
## 0.0.1
|
||||
|
||||
- établit la fondation normative de PGR : force `MUST` / `SHOULD` / `MAY`, hiérarchie des scopes et principe de proportionnalité ;
|
||||
|
||||
12
README.md
12
README.md
@@ -1,5 +1,5 @@
|
||||
<!-- file: README.md -->
|
||||
<!-- version: 3 -->
|
||||
<!-- version: 14 -->
|
||||
|
||||
# Project Governance Rules
|
||||
|
||||
@@ -13,7 +13,7 @@ Le dépôt officiel est `https://git.sasedev.com/Sasedev/pgr`.
|
||||
|
||||
PGR est actuellement en phase de fondation `0.0.x`.
|
||||
|
||||
La version courante est définie par [`VERSION`](VERSION). La release `0.0.1` établit la gouvernance normative et documentaire de PGR lui-même ; les releases suivantes de la série `0.0.x` introduisent progressivement profils technologiques, templates techniques et spécifications de skeletons.
|
||||
La version courante est définie par [`VERSION`](VERSION). La release `0.0.1` établit la gouvernance normative et documentaire de PGR lui-même. La release `0.0.2` ajoute les premiers profils réutilisables Rust/Cargo, Java/Maven/Gradle et Android, ainsi que deux audits Markdown. La release `0.0.3` fournit les premiers modèles Rust/Cargo, deux audits de style Rust facultatifs, l'audit des headers Markdown et la spécification du message manuel de reprise. La release `0.0.4` définit le contrat transversal des skeleton specifications, ajoute une fondation composable de gouvernance locale et une première spécialisation Rust/Cargo workspace fondée sur les profils `500 + 510` et les cinq templates existants. La release `0.0.5` réconcilie PGR avec les baselines réelles de `khadhroony-solana-project` et `sasedev-games` : prompts versionnés, contrats documentaires locaux, lifecycle inter-release, profil Rust strict et audits monotâches, premier profil Tauri 2 et décision explicite de différer son skeleton complet jusqu'à matérialisation d'owners Web suffisants.
|
||||
|
||||
## Entrées principales
|
||||
|
||||
@@ -25,6 +25,14 @@ La version courante est définie par [`VERSION`](VERSION). La release `0.0.1` é
|
||||
- [`docs/architecture/001-PROJECT_PROFILE.md`](docs/architecture/001-PROJECT_PROFILE.md) — profil applicable au dépôt PGR ;
|
||||
- [`docs/architecture/002-GOVERNANCE_ARCHITECTURE.md`](docs/architecture/002-GOVERNANCE_ARCHITECTURE.md) — architecture du référentiel ;
|
||||
- [`docs/plans/001-V0_0_1_FOUNDATION_PLAN.md`](docs/plans/001-V0_0_1_FOUNDATION_PLAN.md) — plan historique de fondation `0.0.1` ;
|
||||
- [`docs/plans/002-V0_0_2_RULE_PROFILES_PLAN.md`](docs/plans/002-V0_0_2_RULE_PROFILES_PLAN.md) — plan historique des premiers profils `0.0.2` ;
|
||||
- [`docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md`](docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md) — plan historique des templates et audits `0.0.3` ;
|
||||
- [`docs/plans/004-V0_0_4_SKELETONS_PLAN.md`](docs/plans/004-V0_0_4_SKELETONS_PLAN.md) — plan historique des skeleton specifications `0.0.4` ;
|
||||
- [`docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md`](docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md) — plan historique de réconciliation `0.0.5` ;
|
||||
- [`docs/studies/001-KSP_GAMES_RECONCILIATION.md`](docs/studies/001-KSP_GAMES_RECONCILIATION.md) — étude de réconciliation et classification des écarts entre PGR, KSP et Games ;
|
||||
- [`docs/skeletons/000-README.md`](docs/skeletons/000-README.md) — index des skeleton specifications et de leur contrat de composition ;
|
||||
- [`docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md`](docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md) — fondation composable de gouvernance locale pour un projet adoptant PGR ;
|
||||
- [`docs/skeletons/002-RUST_CARGO_WORKSPACE.md`](docs/skeletons/002-RUST_CARGO_WORKSPACE.md) — specialization composable pour un workspace Rust/Cargo gouverné ;
|
||||
- [`docs/validation/001-VALIDATION_MATRIX.md`](docs/validation/001-VALIDATION_MATRIX.md) — matrice de validation.
|
||||
|
||||
## Langue et nomenclature
|
||||
|
||||
24
ROADMAP.md
24
ROADMAP.md
@@ -1,22 +1,34 @@
|
||||
<!-- file: ROADMAP.md -->
|
||||
<!-- version: 2 -->
|
||||
<!-- version: 8 -->
|
||||
|
||||
# Roadmap Project Governance Rules
|
||||
|
||||
Le roadmap décrit le découpage macro des releases PGR. Il ne remplace ni les objectifs globaux du projet ni les plans détaillés de version.
|
||||
Le roadmap décrit le découpage macro engagé des releases PGR. Il ne remplace ni les objectifs globaux du projet ni les plans détaillés de version et ne sert pas à inventer des versions futures uniquement pour prolonger l'horizon.
|
||||
|
||||
Statuts : `( )` planifié, `(x)` terminé, `(d)` différé, `(c)` annulé.
|
||||
|
||||
## Fondation `0.0.x`
|
||||
|
||||
- `(x) 0.0.1` — fondation normative et documentaire : gouvernance, lifecycle des releases, rôles documentaires, workflow delta/history/handoff et validation proportionnée ;
|
||||
- `( ) 0.0.2` — profils de règles par langage, plateforme, framework et type de projet ;
|
||||
- `( ) 0.0.3` — templates techniques initiaux et premiers patterns d'audit réutilisables issus de besoins réels ;
|
||||
- `( ) 0.0.4` — spécifications Markdown de skeletons et règles de composition des profils/templates ;
|
||||
- `( ) 0.0.5` — réconciliation réelle de PGR avec `khadhroony-solana-project` et `sasedev-games`.
|
||||
- `(x) 0.0.2` — premiers profils de règles réutilisables : Rust/Cargo, Java/Maven/Gradle et Android, avec modèle de composition et audits Markdown initiaux ;
|
||||
- `(x) 0.0.3` — templates techniques initiaux et premiers patterns d'audit réutilisables issus de besoins réels ;
|
||||
- `(x) 0.0.4` — spécifications Markdown de skeletons et règles de composition des profils/templates ;
|
||||
- `(x) 0.0.5` — réconciliation réelle de PGR avec `khadhroony-solana-project` et `sasedev-games`, incluant la consolidation du lifecycle inter-release et de la revue d'horizon.
|
||||
|
||||
## Première baseline réutilisable
|
||||
|
||||
- `( ) 0.1.0` — première baseline PGR destinée à initialiser de nouveaux projets à partir de règles, templates et skeleton specifications éprouvés.
|
||||
|
||||
## Horizon après `0.1.0`
|
||||
|
||||
L'horizon est volontairement ouvert. PGR ne réserve pas encore `0.1.1`, `0.2.0` ou une autre release sans objectif suffisamment décidé.
|
||||
|
||||
### Trajectoire explicitement différée
|
||||
|
||||
- `(d) skeleton Tauri pour projets contrôlés` — la décision `0.0.5-alpha.9` conserve le candidat, mais sa matérialisation attend des owners Web suffisants pour TypeScript, Vite, Sass/CSS et leur validation. Aucun numéro de release n'est réservé pour ce travail et `0.1.0` ne doit pas le considérer comme obligatoire par défaut.
|
||||
|
||||
Cette entrée conserve une décision de report réelle ; elle ne transforme pas les autres candidats d'horizon en engagements. Les profils techniques supplémentaires, les projets documentaires/spécifications et l'audit de généricité hors logiciel restent chez leurs owners actuels tant qu'une revue d'horizon n'a pas décidé leur entrée dans la trajectoire engagée.
|
||||
|
||||
Le plan de `0.1.0` devra programmer une revue d'horizon avant sa clôture, à un moment où la première baseline réutilisable sera assez établie pour juger la suite. Cette revue pourra se tenir dans une session stratégique séparée sans modifier `VERSION`. Elle décidera soit d'étendre la présente roadmap, soit de maintenir explicitement l'horizon ouvert avec un nouveau déclencheur de revue, soit de requalifier/différer/mettre en pause une trajectoire concernée.
|
||||
|
||||
Le contenu détaillé et le nombre de tranches de chaque release sont définis par son plan actif, créé ou consolidé pendant `alpha.1`.
|
||||
|
||||
14
RULES.md
14
RULES.md
@@ -1,5 +1,5 @@
|
||||
<!-- file: RULES.md -->
|
||||
<!-- version: 5 -->
|
||||
<!-- version: 11 -->
|
||||
|
||||
# Index normatif Project Governance Rules
|
||||
|
||||
@@ -72,12 +72,22 @@ Les traductions complètes éventuelles vivent dans des dépôts distincts (`pgr
|
||||
|
||||
Les règles détaillées sont structurées progressivement sous [`docs/rules/`](docs/rules/).
|
||||
|
||||
Famille actuellement active :
|
||||
Familles actuellement actives :
|
||||
|
||||
- [`docs/rules/200-GOVERNANCE.md`](docs/rules/200-GOVERNANCE.md) — versioning, lifecycle des releases, fixes, cadrage, replan et abandon/supersession.
|
||||
- [`docs/rules/210-WORKFLOW.md`](docs/rules/210-WORKFLOW.md) — plans, deltas, histories, prompts, handoffs, manifests, commits, baselines et reprise de session.
|
||||
- [`docs/rules/220-SKELETONS.md`](docs/rules/220-SKELETONS.md) — sélection, composition, adaptation et validation des skeleton specifications.
|
||||
- [`docs/rules/300-DOCUMENTATION.md`](docs/rules/300-DOCUMENTATION.md) — rôles documentaires, taxonomie, révisions internes, documents vivants et conservation historique.
|
||||
- [`docs/rules/400-VALIDATION.md`](docs/rules/400-VALIDATION.md) — sélection proportionnelle des preuves, catégories de validation, tests utiles, doubles de test et autorité opérateur.
|
||||
- [`docs/rules/500-LANGUAGES.md`](docs/rules/500-LANGUAGES.md) — contrat commun des profils langage, écosystème et spécialisations de build associées.
|
||||
- [`docs/rules/510-RUST_CARGO.md`](docs/rules/510-RUST_CARGO.md) — profil Rust/Cargo : workspace, manifests, dépendances, lints, API, formatage, tests et validation spécialisée.
|
||||
- [`docs/rules/520-JAVA_MAVEN_GRADLE.md`](docs/rules/520-JAVA_MAVEN_GRADLE.md) — profil Java et spécialisations Maven/Gradle : toolchain LTS, structure, dépendances, tests et validation de build.
|
||||
- [`docs/rules/600-PLATFORMS.md`](docs/rules/600-PLATFORMS.md) — contrat commun des profils plateforme et de leur compatibilité de target/runtime.
|
||||
- [`docs/rules/610-ANDROID.md`](docs/rules/610-ANDROID.md) — profil Android : structure, toolchain/SDK, compatibilité, packaging, configuration locale et validation plateforme.
|
||||
- [`docs/rules/700-FRAMEWORKS.md`](docs/rules/700-FRAMEWORKS.md) — contrat commun des profils framework et de leur orchestration avec langages, plateformes et outils de build.
|
||||
- [`docs/rules/710-TAURI.md`](docs/rules/710-TAURI.md) — profil Tauri 2 : host Rust, configuration/capabilities, hooks frontend, version produit, artefacts générés et validation d'intégration.
|
||||
|
||||
Le modèle de composition et d'ownership des profils est défini dans [`docs/architecture/003-RULE_PROFILE_MODEL.md`](docs/architecture/003-RULE_PROFILE_MODEL.md).
|
||||
|
||||
Une famille de règles n'est créée que lorsqu'elle possède un contenu réel ; aucun répertoire vide n'est requis pour anticiper une future technologie.
|
||||
|
||||
|
||||
180
deltas/0.0.2/alpha.1.fix.1.md
Normal file
180
deltas/0.0.2/alpha.1.fix.1.md
Normal file
@@ -0,0 +1,180 @@
|
||||
<!-- file: deltas/0.0.2/alpha.1.fix.1.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Delta 0.0.2-alpha.1.fix.1 — correction du cadrage, sizing et audit Markdown
|
||||
|
||||
## Baseline
|
||||
|
||||
Version attendue avant application :
|
||||
|
||||
```text
|
||||
0.0.2-alpha.1
|
||||
```
|
||||
|
||||
La baseline doit correspondre au commit de `alpha.1` après application de `history/0.0.2/alpha.1.md` en statut `FAIL`.
|
||||
|
||||
Version après application :
|
||||
|
||||
```text
|
||||
0.0.2-alpha.1.fix.1
|
||||
```
|
||||
|
||||
## Objet
|
||||
|
||||
Corriger exclusivement les défauts identifiés dans le cadrage `alpha.1` avant de commencer `alpha.2` :
|
||||
|
||||
- corriger l'alignement source du tableau `Inventaire des profils candidats` ;
|
||||
- reconnaître la preuve post-tag `publish.001` déjà disponible sans modifier rétroactivement `v0.0.1` ;
|
||||
- réduire le forecast `0.0.2` à un ensemble de profils compatible avec le sizing d'une session ;
|
||||
- introduire le premier audit PGR monotâche réellement justifié par un défaut observé ;
|
||||
- enregistrer cet audit dans la matrice de validation.
|
||||
|
||||
Aucune règle technologique détaillée n'est introduite par ce fix.
|
||||
|
||||
## Rapport post-tag reconnu
|
||||
|
||||
Le rapport externe à la baseline source :
|
||||
|
||||
```text
|
||||
pgr-0.0.1-publish.001-report.md
|
||||
```
|
||||
|
||||
est connu comme preuve post-publication `PASS` de l'archive `pgr-v0.0.1.zip`.
|
||||
|
||||
Il ne fait pas partie du tag stable et ne doit pas être copié dans le dépôt rétroactivement.
|
||||
|
||||
Le besoin futur d'indiquer automatiquement, dans le handoff/prompt manuel de reprise, si un rapport `publish.*` doit être fourni est conservé comme amélioration de workflow hors scope de `0.0.2`.
|
||||
|
||||
## Sizing corrigé
|
||||
|
||||
Le forecast actif devient :
|
||||
|
||||
```text
|
||||
alpha.2 Rule profile model
|
||||
alpha.3 Rust / Cargo
|
||||
alpha.4 Java / Maven / Gradle
|
||||
alpha.5 Android
|
||||
beta.1 Profile reconciliation
|
||||
rc.1 Rule profiles release candidate
|
||||
stable 0.0.2
|
||||
```
|
||||
|
||||
Les profils/compositions suivants restent explicitement différés :
|
||||
|
||||
```text
|
||||
Rust + Android / JNI
|
||||
Web / TypeScript / Vite / WASM / Rust server
|
||||
Tauri desktop/mobile
|
||||
C / C++ / CMake
|
||||
PHP / Composer
|
||||
Python 3 application/package
|
||||
```
|
||||
|
||||
Leur différé ne vaut ni rejet ni oubli.
|
||||
|
||||
## Premier audit PGR matérialisé
|
||||
|
||||
Le fichier suivant est ajouté :
|
||||
|
||||
```text
|
||||
scripts/audit_markdown_tables.py
|
||||
```
|
||||
|
||||
Son contrat est volontairement limité :
|
||||
|
||||
```text
|
||||
INPUT
|
||||
fichiers/répertoires Markdown explicitement fournis
|
||||
|
||||
OUTPUT
|
||||
diagnostics texte
|
||||
exit code
|
||||
|
||||
SIDE EFFECTS
|
||||
aucun
|
||||
```
|
||||
|
||||
Il vérifie uniquement :
|
||||
|
||||
- la reconnaissance des tableaux hors fenced code blocks ;
|
||||
- le nombre cohérent de colonnes ;
|
||||
- l'alignement vertical des cellules dans le source ;
|
||||
- la largeur des séparateurs ;
|
||||
- le padding conforme à l'alignement Markdown.
|
||||
|
||||
Il ne vérifie pas les blank lines, headers `file/version`, liens, orthographe ou responsabilités documentaires. Ces propriétés appartiennent à d'autres contrôles présents ou futurs.
|
||||
|
||||
Il utilise uniquement la bibliothèque standard Python et doit être exécuté avec `python3 -B` afin de ne pas créer `__pycache__` ou `.pyc`.
|
||||
|
||||
## Scope
|
||||
|
||||
REPLACE :
|
||||
|
||||
```text
|
||||
VERSION
|
||||
docs/plans/002-V0_0_2_RULE_PROFILES_PLAN.md
|
||||
docs/validation/001-VALIDATION_MATRIX.md
|
||||
```
|
||||
|
||||
ADD :
|
||||
|
||||
```text
|
||||
scripts/audit_markdown_tables.py
|
||||
deltas/0.0.2/alpha.1.fix.1.md
|
||||
```
|
||||
|
||||
DELETE : aucun.
|
||||
|
||||
Aucun manifest de suppression n'est nécessaire.
|
||||
|
||||
## Validation opérateur
|
||||
|
||||
```bash
|
||||
test "$(cat VERSION)" = "0.0.2-alpha.1.fix.1"
|
||||
|
||||
test -f scripts/audit_markdown_tables.py
|
||||
test -f deltas/0.0.2/alpha.1.fix.1.md
|
||||
|
||||
grep -F '### Preuve post-tag `publish.001`' docs/plans/002-V0_0_2_RULE_PROFILES_PLAN.md
|
||||
grep -F '### alpha.5 — Android' docs/plans/002-V0_0_2_RULE_PROFILES_PLAN.md
|
||||
grep -F 'Rust + Android / JNI' docs/plans/002-V0_0_2_RULE_PROFILES_PLAN.md
|
||||
grep -F '`PGR-MD-TABLE-001`' docs/validation/001-VALIDATION_MATRIX.md
|
||||
|
||||
python3 -B scripts/audit_markdown_tables.py README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
|
||||
git diff --check
|
||||
|
||||
git add VERSION docs/plans/002-V0_0_2_RULE_PROFILES_PLAN.md docs/validation/001-VALIDATION_MATRIX.md scripts/audit_markdown_tables.py deltas/0.0.2/alpha.1.fix.1.md
|
||||
|
||||
git diff --cached --check
|
||||
|
||||
git status --short
|
||||
```
|
||||
|
||||
La sortie attendue avant ajout du history du fix est :
|
||||
|
||||
```text
|
||||
M VERSION
|
||||
A deltas/0.0.2/alpha.1.fix.1.md
|
||||
M docs/plans/002-V0_0_2_RULE_PROFILES_PLAN.md
|
||||
M docs/validation/001-VALIDATION_MATRIX.md
|
||||
A scripts/audit_markdown_tables.py
|
||||
```
|
||||
|
||||
Revue opérateur complémentaire :
|
||||
|
||||
- confirmer que le tableau `Inventaire des profils candidats` est lisible et aligné dans le source ;
|
||||
- confirmer que le report `publish.001` est traité comme preuve post-tag externe et non comme fichier manquant du tag ;
|
||||
- confirmer que le scope réduit reste suffisamment représentatif sans chercher à matérialiser les profils différés ;
|
||||
- confirmer que l'audit Python est read-only et monotâche ;
|
||||
- confirmer qu'aucune règle technologique de `alpha.2+` n'a été introduite.
|
||||
|
||||
## Transition
|
||||
|
||||
### PASS
|
||||
|
||||
Créer et appliquer séparément `history/0.0.2/alpha.1.fix.1.md`, committer le fix, puis seulement préparer `0.0.2-alpha.2` consacré au modèle de profils.
|
||||
|
||||
### FAIL
|
||||
|
||||
Rester dans `0.0.2-alpha.1.fix.M`. À partir de `.fix.3`, réexaminer obligatoirement le plan et la nécessité d'un REPLAN conformément aux règles PGR.
|
||||
171
deltas/0.0.2/alpha.1.md
Normal file
171
deltas/0.0.2/alpha.1.md
Normal file
@@ -0,0 +1,171 @@
|
||||
<!-- file: deltas/0.0.2/alpha.1.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Delta 0.0.2-alpha.1 — audit de baseline et cadrage des profils
|
||||
|
||||
## Baseline
|
||||
|
||||
Archive source fournie par l'opérateur comme téléchargement du tag stable Gitea :
|
||||
|
||||
```text
|
||||
v0.0.1
|
||||
```
|
||||
|
||||
Cette archive constitue la baseline autoritaire de la tranche. L'absence de `.git` y est normale ; aucun état provenant d'un workspace local ou d'une conversation antérieure n'est utilisé comme état courant s'il n'est pas confirmé par l'archive ou par `prompts/002-V0_0_2_START_PROMPT.md`.
|
||||
|
||||
Version attendue avant application :
|
||||
|
||||
```text
|
||||
0.0.1
|
||||
```
|
||||
|
||||
Version après application :
|
||||
|
||||
```text
|
||||
0.0.2-alpha.1
|
||||
```
|
||||
|
||||
## Objet
|
||||
|
||||
Exécuter le gate de framing imposé par le prompt `0.0.2` avant toute consolidation technologique :
|
||||
|
||||
- vérifier la baseline stable `v0.0.1` ;
|
||||
- auditer les règles, la gouvernance, la structure documentaire, les deltas/histories et la cohérence générale ;
|
||||
- confronter le prompt `0.0.2` à l'état réel du dépôt ;
|
||||
- inventorier les profils technologiques candidats ;
|
||||
- limiter le scope aux profils utiles à cette première release ;
|
||||
- dimensionner les tranches suivantes ;
|
||||
- créer le plan actif `0.0.2`.
|
||||
|
||||
Aucune règle technologique détaillée n'est introduite dans `alpha.1`.
|
||||
|
||||
## Résultat de l'audit de baseline
|
||||
|
||||
La prévalidation de l'archive a constaté :
|
||||
|
||||
- archive ZIP lisible, racine unique `pgr/`, sans doublon, traversal ou symlink ;
|
||||
- `44` fichiers et `13` répertoires ;
|
||||
- `VERSION` égal à `0.0.1` ;
|
||||
- absence normale de `.git` ;
|
||||
- aucun cache/build connu ou secret local distribué ;
|
||||
- headers `file/version` cohérents sur tous les Markdown ;
|
||||
- aucun lien Markdown local cassé parmi les liens vérifiés ;
|
||||
- `12` deltas et `12` histories `0.0.1` appariés exactement ;
|
||||
- chaîne PASS/FAIL/fix cohérente jusqu'à `rel.001` PASS ;
|
||||
- plan `0.0.1` clôturé, roadmap/changelog cohérents et prompt `0.0.2` présent ;
|
||||
- compteurs internes des documents vivants cohérents avec les opérations de deltas observées.
|
||||
|
||||
Aucun défaut bloquant n'impose de `0.0.1` correctif avant le démarrage de `0.0.2`.
|
||||
|
||||
Une observation non bloquante est conservée dans le plan : le history stable mentionne un contrôle post-tag `publish.001`, mais aucune preuve versionnée correspondante ne peut être déduite de cette archive. `alpha.1` n'invente ni ne reconstruit cette preuve.
|
||||
|
||||
## Cadrage retenu
|
||||
|
||||
`0.0.2` matérialisera d'abord :
|
||||
|
||||
```text
|
||||
profile model / composition
|
||||
Rust / Cargo
|
||||
Java / Maven / Gradle
|
||||
Android
|
||||
Rust + Android / JNI
|
||||
Web / TypeScript / Vite / WASM / Rust server composition
|
||||
Tauri desktop/mobile
|
||||
```
|
||||
|
||||
Les profils suivants sont examinés mais différés de cette release afin d'éviter une taxonomie exhaustive sans nécessité immédiate :
|
||||
|
||||
```text
|
||||
C / C++ / CMake
|
||||
PHP / Composer
|
||||
Python 3 application/package
|
||||
```
|
||||
|
||||
Ils restent des candidats futurs et ne sont pas rejetés.
|
||||
|
||||
Les règles cross-cutting ne recevront un propriétaire `800 — architecture` que lorsqu'une règle réellement commune à plusieurs profils n'est pas déjà possédée par un owner général existant.
|
||||
|
||||
## Scope
|
||||
|
||||
REPLACE :
|
||||
|
||||
```text
|
||||
VERSION
|
||||
```
|
||||
|
||||
ADD :
|
||||
|
||||
```text
|
||||
docs/plans/002-V0_0_2_RULE_PROFILES_PLAN.md
|
||||
deltas/0.0.2/alpha.1.md
|
||||
```
|
||||
|
||||
DELETE : aucun.
|
||||
|
||||
Aucun manifest de suppression n'est nécessaire.
|
||||
|
||||
## Documents volontairement inchangés
|
||||
|
||||
Les documents suivants ne sont pas modifiés uniquement pour refléter le passage à `0.0.2-alpha.1` :
|
||||
|
||||
```text
|
||||
README.md
|
||||
RULES.md
|
||||
ROADMAP.md
|
||||
CHANGELOG.md
|
||||
docs/000-README.md
|
||||
docs/rules/000-README.md
|
||||
```
|
||||
|
||||
Leur contenu courant reste cohérent : la roadmap annonce déjà `0.0.2`, les règles possèdent déjà le framing `alpha.1` et la hiérarchie général → spécifique, et le changelog ne journalise pas les prereleases internes.
|
||||
|
||||
## Validation opérateur
|
||||
|
||||
```bash
|
||||
test "$(cat VERSION)" = "0.0.2-alpha.1"
|
||||
|
||||
test -f docs/plans/002-V0_0_2_RULE_PROFILES_PLAN.md
|
||||
test -f deltas/0.0.2/alpha.1.md
|
||||
|
||||
grep -F 'Plan actif créé pendant `0.0.2-alpha.1`' docs/plans/002-V0_0_2_RULE_PROFILES_PLAN.md
|
||||
grep -F 'Aucun défaut bloquant de gouvernance' docs/plans/002-V0_0_2_RULE_PROFILES_PLAN.md
|
||||
grep -F '### alpha.2 — Rule profile model' docs/plans/002-V0_0_2_RULE_PROFILES_PLAN.md
|
||||
grep -F '### alpha.8 — Tauri desktop/mobile' docs/plans/002-V0_0_2_RULE_PROFILES_PLAN.md
|
||||
|
||||
grep -F -- '- `( ) 0.0.2`' ROADMAP.md
|
||||
grep -F 'v0.0.1' prompts/002-V0_0_2_START_PROMPT.md
|
||||
|
||||
git diff --check
|
||||
|
||||
git add VERSION docs/plans/002-V0_0_2_RULE_PROFILES_PLAN.md deltas/0.0.2/alpha.1.md
|
||||
|
||||
git diff --cached --check
|
||||
|
||||
git status --short
|
||||
```
|
||||
|
||||
La sortie attendue avant ajout du history est :
|
||||
|
||||
```text
|
||||
M VERSION
|
||||
A deltas/0.0.2/alpha.1.md
|
||||
A docs/plans/002-V0_0_2_RULE_PROFILES_PLAN.md
|
||||
```
|
||||
|
||||
Revue opérateur complémentaire :
|
||||
|
||||
- confirmer que l'archive `v0.0.1` utilisée est bien celle téléchargée depuis le tag Gitea déclaré ;
|
||||
- confirmer que l'absence de `.git` n'est pas traitée comme une anomalie ;
|
||||
- vérifier que le plan n'introduit aucune règle technologique comme déjà normative ;
|
||||
- vérifier que les profils différés ne sont ni oubliés ni artificiellement matérialisés ;
|
||||
- vérifier que `README.md`, `RULES.md`, `ROADMAP.md`, `CHANGELOG.md` et les historiques `0.0.1` ne sont pas modifiés par cette tranche.
|
||||
|
||||
## Transition
|
||||
|
||||
### PASS
|
||||
|
||||
Créer et appliquer séparément `history/0.0.2/alpha.1.md`, committer `alpha.1`, puis seulement préparer `0.0.2-alpha.2` consacré au modèle documentaire et à la composition des profils.
|
||||
|
||||
### FAIL
|
||||
|
||||
Rester dans le scope de cadrage avec `0.0.2-alpha.1.fix.1`. Le fix corrige uniquement les défauts du framing/audit/plan ; aucune règle technologique de `alpha.2+` ne doit y être absorbée.
|
||||
180
deltas/0.0.2/alpha.2.md
Normal file
180
deltas/0.0.2/alpha.2.md
Normal file
@@ -0,0 +1,180 @@
|
||||
<!-- file: deltas/0.0.2/alpha.2.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Delta 0.0.2-alpha.2 — rule profile model
|
||||
|
||||
## Baseline
|
||||
|
||||
Version attendue avant application :
|
||||
|
||||
```text
|
||||
0.0.2-alpha.1.fix.1
|
||||
```
|
||||
|
||||
Le history `history/0.0.2/alpha.1.fix.1.md` MUST avoir été appliqué et committé avant ce delta.
|
||||
|
||||
Version après application :
|
||||
|
||||
```text
|
||||
0.0.2-alpha.2
|
||||
```
|
||||
|
||||
## Objet
|
||||
|
||||
Formaliser le modèle de profils PGR avant toute consolidation technologique détaillée.
|
||||
|
||||
Cette tranche définit :
|
||||
|
||||
- la notion de profil et son propriétaire normatif ;
|
||||
- l'applicabilité d'un profil à partir de faits réels du projet ;
|
||||
- la composition du général vers le spécifique ;
|
||||
- la résolution des overrides et des conflits ;
|
||||
- la non-duplication des règles héritées ;
|
||||
- le traitement des spécialisations internes et profils composites ;
|
||||
- la distinction entre règle décidée et choix encore ouvert ;
|
||||
- les contrats communs des familles `500 — languages / ecosystems` et `600 — platforms` nécessaires au scope réduit de `0.0.2`.
|
||||
|
||||
Aucune règle Rust, Cargo, Java, Maven, Gradle ou Android détaillée n'est encore introduite.
|
||||
|
||||
## Modèle retenu
|
||||
|
||||
La composition de référence reste :
|
||||
|
||||
```text
|
||||
GENERAL
|
||||
↓
|
||||
ecosystem / language
|
||||
↓
|
||||
platform
|
||||
↓
|
||||
framework
|
||||
↓
|
||||
project type / subsystem
|
||||
↓
|
||||
project-specific
|
||||
↓
|
||||
explicit exception
|
||||
```
|
||||
|
||||
Chaque règle durable possède un seul owner normatif. Les profils spécifiques héritent des règles générales et ne les recopient pas.
|
||||
|
||||
Une contradiction volontaire doit être un override explicite, borné et justifié. Deux règles applicables de même niveau qui se contredisent sans relation explicite constituent un défaut à résoudre ; l'ordre des fichiers ne crée aucune priorité.
|
||||
|
||||
Les profils composites ne sont créés que si l'intersection de plusieurs profils possède un contrat propre réel. La simple coexistence de deux technologies ne suffit pas.
|
||||
|
||||
## Familles activées
|
||||
|
||||
`alpha.2` active uniquement les familles nécessaires aux prochaines tranches :
|
||||
|
||||
```text
|
||||
500 — languages / ecosystems
|
||||
600 — platforms
|
||||
```
|
||||
|
||||
Les familles suivantes restent réservées et non matérialisées :
|
||||
|
||||
```text
|
||||
700 — frameworks
|
||||
800 — architecture
|
||||
```
|
||||
|
||||
Les règles project-specific continuent d'appartenir au dépôt qui les possède ; PGR ne crée pas de placeholder `900` sans contenu réel.
|
||||
|
||||
## Scope
|
||||
|
||||
REPLACE :
|
||||
|
||||
```text
|
||||
VERSION
|
||||
RULES.md
|
||||
docs/plans/002-V0_0_2_RULE_PROFILES_PLAN.md
|
||||
docs/rules/000-README.md
|
||||
```
|
||||
|
||||
ADD :
|
||||
|
||||
```text
|
||||
docs/architecture/003-RULE_PROFILE_MODEL.md
|
||||
docs/rules/500-LANGUAGES.md
|
||||
docs/rules/600-PLATFORMS.md
|
||||
deltas/0.0.2/alpha.2.md
|
||||
```
|
||||
|
||||
DELETE : aucun.
|
||||
|
||||
Aucun manifest de suppression n'est nécessaire.
|
||||
|
||||
## Validation opérateur
|
||||
|
||||
```bash
|
||||
test "$(cat VERSION)" = "0.0.2-alpha.2"
|
||||
|
||||
test -f docs/architecture/003-RULE_PROFILE_MODEL.md
|
||||
test -f docs/rules/500-LANGUAGES.md
|
||||
test -f docs/rules/600-PLATFORMS.md
|
||||
test -f deltas/0.0.2/alpha.2.md
|
||||
|
||||
grep -F 'Toute règle durable doit posséder un seul propriétaire normatif canonique.' docs/architecture/003-RULE_PROFILE_MODEL.md
|
||||
grep -F "L'ordre des fichiers dans un répertoire ne crée jamais une priorité normative." docs/architecture/003-RULE_PROFILE_MODEL.md
|
||||
grep -F 'PGR ne crée pas automatiquement un profil composite pour chaque combinaison possible.' docs/architecture/003-RULE_PROFILE_MODEL.md
|
||||
|
||||
grep -F 'Les profils spécifiques utilisent la plage `510` à `599`.' docs/rules/500-LANGUAGES.md
|
||||
grep -F 'Une spécialisation de build tool ne devient pas une règle du langage entier.' docs/rules/500-LANGUAGES.md
|
||||
|
||||
grep -F 'La modernité de la toolchain de build et la version minimale du runtime ou de la target sont deux décisions distinctes.' docs/rules/600-PLATFORMS.md
|
||||
grep -F 'Les profils spécifiques utilisent la plage `610` à `699`.' docs/rules/600-PLATFORMS.md
|
||||
|
||||
grep -F '500-LANGUAGES.md' RULES.md
|
||||
grep -F '600-PLATFORMS.md' RULES.md
|
||||
grep -F '003-RULE_PROFILE_MODEL.md' docs/rules/000-README.md
|
||||
grep -F 'famille `500 — languages / ecosystems`' docs/plans/002-V0_0_2_RULE_PROFILES_PLAN.md
|
||||
|
||||
python3 -B scripts/audit_markdown_tables.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
|
||||
git diff --check
|
||||
|
||||
git add VERSION RULES.md \
|
||||
docs/architecture/003-RULE_PROFILE_MODEL.md \
|
||||
docs/plans/002-V0_0_2_RULE_PROFILES_PLAN.md \
|
||||
docs/rules/000-README.md \
|
||||
docs/rules/500-LANGUAGES.md \
|
||||
docs/rules/600-PLATFORMS.md \
|
||||
deltas/0.0.2/alpha.2.md
|
||||
|
||||
git diff --cached --check
|
||||
|
||||
git status --short
|
||||
```
|
||||
|
||||
La sortie attendue avant ajout du history est :
|
||||
|
||||
```text
|
||||
M RULES.md
|
||||
M VERSION
|
||||
A deltas/0.0.2/alpha.2.md
|
||||
A docs/architecture/003-RULE_PROFILE_MODEL.md
|
||||
M docs/plans/002-V0_0_2_RULE_PROFILES_PLAN.md
|
||||
M docs/rules/000-README.md
|
||||
A docs/rules/500-LANGUAGES.md
|
||||
A docs/rules/600-PLATFORMS.md
|
||||
```
|
||||
|
||||
Revue opérateur complémentaire :
|
||||
|
||||
- confirmer que le modèle permet de déterminer où une règle doit être possédée sans utiliser l'ordre des fichiers comme priorité ;
|
||||
- confirmer que les spécialisations Maven/Gradle pourront rester locales à Java/build et qu'une contrainte Android ne contaminera pas Java en général ;
|
||||
- confirmer que les familles `700` et `800` ne sont pas créées prématurément ;
|
||||
- confirmer qu'aucune règle technologique détaillée prévue pour `alpha.3+` n'a été absorbée dans cette tranche.
|
||||
|
||||
## Transition
|
||||
|
||||
### PASS
|
||||
|
||||
Créer et appliquer séparément `history/0.0.2/alpha.2.md`, committer la tranche, puis préparer `0.0.2-alpha.3` consacré au premier profil réel `Rust / Cargo`.
|
||||
|
||||
`alpha.3` reste le point de mesure prévu par le plan : si le coût réel d'un profil complet invalide le sizing, effectuer un REPLAN avant `alpha.4`.
|
||||
|
||||
### FAIL
|
||||
|
||||
Rester dans `0.0.2-alpha.2.fix.M` tant que le modèle de profil lui-même n'est pas cohérent. Ne pas commencer le profil Rust/Cargo sur un modèle non validé.
|
||||
166
deltas/0.0.2/alpha.3.md
Normal file
166
deltas/0.0.2/alpha.3.md
Normal file
@@ -0,0 +1,166 @@
|
||||
<!-- file: deltas/0.0.2/alpha.3.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Delta 0.0.2-alpha.3 — premier profil Rust / Cargo
|
||||
|
||||
## Baseline
|
||||
|
||||
Version attendue avant application :
|
||||
|
||||
```text
|
||||
0.0.2-alpha.2
|
||||
```
|
||||
|
||||
Le history `history/0.0.2/alpha.2.md` MUST avoir été appliqué et committé avant ce delta.
|
||||
|
||||
Version après application :
|
||||
|
||||
```text
|
||||
0.0.2-alpha.3
|
||||
```
|
||||
|
||||
## Objet
|
||||
|
||||
Matérialiser le premier profil technologique réel de PGR : `Rust / Cargo`.
|
||||
|
||||
Cette tranche sert aussi de point de mesure prévu par le plan `0.0.2`. Elle doit consolider uniquement les règles Rust/Cargo suffisamment générales pour être réutilisables, sans recopier les particularités métier ou les micro-conventions propres à KSP ou `sasedev-games`.
|
||||
|
||||
## Réconciliation des corpus sources
|
||||
|
||||
Les deux corpus historiques de référence convergent notamment sur :
|
||||
|
||||
- l'utilisation d'un workspace Cargo structuré ;
|
||||
- la centralisation des métadonnées/lints et des dépendances réellement partagées ;
|
||||
- l'activation locale des features selon le besoin de la crate ;
|
||||
- une politique Rust stricte autour de `unsafe`, `unwrap`, `expect`, retours explicites et Clippy ;
|
||||
- une façade de crate explicite plutôt qu'une exposition accidentelle des modules internes ;
|
||||
- `rustfmt.toml` comme propriétaire du formatage ;
|
||||
- la séparation des tests unitaires et d'intégration ;
|
||||
- une gate `fmt` / audit applicable / `check` / `clippy`, avec tests ciblés par défaut et tests workspace aux gates larges ;
|
||||
- l'absence d'exécution opportuniste de `cargo update`, `cargo tree`, `cargo build` ou `cargo clean` sans besoin correspondant.
|
||||
|
||||
La consolidation ne promeut pas automatiquement les divergences ou conventions trop spécifiques :
|
||||
|
||||
- l'interdiction KSP de tous les imports `use` non-traits n'est pas élevée au profil Rust général ;
|
||||
- les micro-règles KSP de lignes vides/ordre interne ne remplacent pas `rustfmt` au niveau PGR ;
|
||||
- aucune dépendance, crate, version de bibliothèque ou règle Solana/games n'est reprise ;
|
||||
- la politique historique commune d'ignorer `Cargo.lock` n'est pas rendue universelle : le profil exige une politique explicite selon le type de produit ;
|
||||
- l'exception `unsafe` Android/JNI de games reste un exemple de spécialisation FFI locale et non une permission Rust générale ;
|
||||
- le chemin externe des artefacts Cargo n'est pas figé avant les futures règles de skeleton/layout.
|
||||
|
||||
## Profil créé
|
||||
|
||||
Le nouveau propriétaire normatif est :
|
||||
|
||||
```text
|
||||
docs/rules/510-RUST_CARGO.md
|
||||
```
|
||||
|
||||
Il couvre :
|
||||
|
||||
- toolchain et édition ;
|
||||
- workspace et unités de release ;
|
||||
- manifests, dépendances et features ;
|
||||
- politique explicite de `Cargo.lock` ;
|
||||
- lints communs et safety ;
|
||||
- API, visibilité et rustdoc ;
|
||||
- contrôle de flux/erreurs du profil strict ;
|
||||
- `rustfmt.toml` ;
|
||||
- `.cargo/config.toml` et artefacts générés ;
|
||||
- organisation des tests ;
|
||||
- commandes de validation Rust/Cargo ;
|
||||
- stratégie future d'audits Rust monotâches.
|
||||
|
||||
Aucun script Rust supplémentaire n'est créé dans cette tranche. PGR ne possède actuellement aucun workspace Rust réel à auditer ; introduire maintenant une copie simplifiée des auditeurs games/KSP créerait une gate sans sujet réel. Le premier audit PGR déjà matérialisé reste l'audit Markdown monotâche introduit lorsque son besoin a été observé.
|
||||
|
||||
## Scope
|
||||
|
||||
REPLACE :
|
||||
|
||||
```text
|
||||
VERSION
|
||||
RULES.md
|
||||
docs/rules/000-README.md
|
||||
```
|
||||
|
||||
ADD :
|
||||
|
||||
```text
|
||||
docs/rules/510-RUST_CARGO.md
|
||||
deltas/0.0.2/alpha.3.md
|
||||
```
|
||||
|
||||
DELETE : aucun.
|
||||
|
||||
Aucun manifest de suppression n'est nécessaire.
|
||||
|
||||
## Validation opérateur
|
||||
|
||||
```bash
|
||||
test "$(cat VERSION)" = "0.0.2-alpha.3"
|
||||
|
||||
test -f docs/rules/510-RUST_CARGO.md
|
||||
test -f deltas/0.0.2/alpha.3.md
|
||||
|
||||
grep -F 'PGR MUST NOT imposer un pin exact de toolchain uniquement parce qu' docs/rules/510-RUST_CARGO.md
|
||||
grep -F 'le fichier PGR `VERSION` reste la version canonique de l' docs/rules/510-RUST_CARGO.md
|
||||
grep -F 'Une crate membre SHOULD consommer cette dépendance avec `workspace = true`' docs/rules/510-RUST_CARGO.md
|
||||
grep -F 'PGR ne généralise pas automatiquement la politique de lockfile' docs/rules/510-RUST_CARGO.md
|
||||
grep -F 'unsafe_code = "forbid"' docs/rules/510-RUST_CARGO.md
|
||||
grep -F 'PGR ne généralise pas l'"'"'interdiction KSP plus stricte de tous les `use` non-traits' docs/rules/510-RUST_CARGO.md
|
||||
grep -F 'cargo clippy --workspace --all-targets --all-features -- -D warnings' docs/rules/510-RUST_CARGO.md
|
||||
grep -F 'PGR SHOULD préférer plusieurs audits monotâches et lisibles' docs/rules/510-RUST_CARGO.md
|
||||
|
||||
grep -F '510-RUST_CARGO.md' RULES.md
|
||||
grep -F '510-RUST_CARGO.md' docs/rules/000-README.md
|
||||
|
||||
python3 -B scripts/audit_markdown_tables.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
|
||||
git diff --check
|
||||
|
||||
git add VERSION RULES.md \
|
||||
docs/rules/000-README.md \
|
||||
docs/rules/510-RUST_CARGO.md \
|
||||
deltas/0.0.2/alpha.3.md
|
||||
|
||||
git diff --cached --check
|
||||
|
||||
git status --short
|
||||
```
|
||||
|
||||
La sortie attendue avant ajout du history est :
|
||||
|
||||
```text
|
||||
M RULES.md
|
||||
M VERSION
|
||||
A deltas/0.0.2/alpha.3.md
|
||||
M docs/rules/000-README.md
|
||||
A docs/rules/510-RUST_CARGO.md
|
||||
```
|
||||
|
||||
Revue opérateur complémentaire :
|
||||
|
||||
- confirmer que le profil distingue bien les règles Rust/Cargo générales des conventions strictement KSP ou games ;
|
||||
- confirmer que la politique de lockfile reste explicitement project-type-specific et n'est pas généralisée uniquement parce que les deux corpus historiques ignoraient `Cargo.lock` ;
|
||||
- confirmer que les contraintes FFI/plateforme restent des overrides locaux ;
|
||||
- confirmer qu'aucune version de crate ou de toolchain historique n'a été recopiée comme pin universel ;
|
||||
- confirmer qu'aucun audit Rust complexe n'a été ajouté avant d'avoir un sujet réel et une propriété mono-responsabilité à contrôler.
|
||||
|
||||
## Point de mesure / REPLAN
|
||||
|
||||
`alpha.3` est le point de mesure explicite prévu par le plan.
|
||||
|
||||
Le profil Rust/Cargo tient dans une tranche documentaire autonome sans nécessiter de famille supplémentaire, de script d'audit complexe ou de sous-profil framework/plateforme. Le forecast `alpha.4 — Java / Maven / Gradle` reste donc raisonnable à ce stade.
|
||||
|
||||
Si la validation de cette tranche révèle au contraire une dérive importante du modèle ou plusieurs corrections substantielles, effectuer un REPLAN avant `alpha.4` plutôt que poursuivre mécaniquement.
|
||||
|
||||
## Transition
|
||||
|
||||
### PASS
|
||||
|
||||
Créer et appliquer séparément `history/0.0.2/alpha.3.md`, committer la tranche, puis préparer `0.0.2-alpha.4` consacré à `Java / Maven / Gradle`.
|
||||
|
||||
### FAIL
|
||||
|
||||
Rester dans `0.0.2-alpha.3.fix.M` tant que le premier profil réel ne respecte pas le modèle `alpha.2`. Un défaut de dimensionnement significatif peut déclencher un REPLAN avant toute tranche Java.
|
||||
106
deltas/0.0.2/alpha.4.fix.1.md
Normal file
106
deltas/0.0.2/alpha.4.fix.1.md
Normal file
@@ -0,0 +1,106 @@
|
||||
<!-- file: deltas/0.0.2/alpha.4.fix.1.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Delta 0.0.2-alpha.4.fix.1 — cohérence de la gate Java
|
||||
|
||||
## Baseline
|
||||
|
||||
Version attendue avant application :
|
||||
|
||||
```text
|
||||
0.0.2-alpha.4
|
||||
```
|
||||
|
||||
Le history `history/0.0.2/alpha.4.md` MUST avoir été appliqué avant ce correctif.
|
||||
|
||||
Version après application :
|
||||
|
||||
```text
|
||||
0.0.2-alpha.4.fix.1
|
||||
```
|
||||
|
||||
## Objet
|
||||
|
||||
Corriger uniquement le défaut de cohérence détecté pendant la gate opérateur de `alpha.4`.
|
||||
|
||||
Le profil décrivait déjà la structure Java canonique sous forme d'arbre, mais la validation cherchait littéralement :
|
||||
|
||||
```text
|
||||
src/main/
|
||||
```
|
||||
|
||||
sans que cette chaîne existe telle quelle dans le document.
|
||||
|
||||
Le correctif ajoute une phrase explicite listant les chemins canoniques déjà impliqués par l'arborescence :
|
||||
|
||||
```text
|
||||
src/main/java/
|
||||
src/main/resources/
|
||||
src/test/java/
|
||||
src/test/resources/
|
||||
```
|
||||
|
||||
Aucune règle Java, Maven ou Gradle nouvelle n'est introduite.
|
||||
|
||||
## Scope
|
||||
|
||||
REPLACE :
|
||||
|
||||
```text
|
||||
VERSION
|
||||
docs/rules/520-JAVA_MAVEN_GRADLE.md
|
||||
```
|
||||
|
||||
ADD :
|
||||
|
||||
```text
|
||||
deltas/0.0.2/alpha.4.fix.1.md
|
||||
```
|
||||
|
||||
DELETE : aucun.
|
||||
|
||||
## Validation opérateur
|
||||
|
||||
```bash
|
||||
test "$(cat VERSION)" = "0.0.2-alpha.4.fix.1"
|
||||
|
||||
test -f docs/rules/520-JAVA_MAVEN_GRADLE.md
|
||||
test -f deltas/0.0.2/alpha.4.fix.1.md
|
||||
|
||||
grep -F 'src/main/java/' docs/rules/520-JAVA_MAVEN_GRADLE.md
|
||||
grep -F 'src/main/resources/' docs/rules/520-JAVA_MAVEN_GRADLE.md
|
||||
grep -F 'src/test/java/' docs/rules/520-JAVA_MAVEN_GRADLE.md
|
||||
grep -F 'src/test/resources/' docs/rules/520-JAVA_MAVEN_GRADLE.md
|
||||
|
||||
grep -F 'le JDK de développement SHOULD être une version LTS' docs/rules/520-JAVA_MAVEN_GRADLE.md
|
||||
grep -F 'PGR MUST NOT ajouter un Maven Wrapper uniquement par cérémonie.' docs/rules/520-JAVA_MAVEN_GRADLE.md
|
||||
grep -F 'Un Gradle Wrapper SHOULD être versionné lorsqu' docs/rules/520-JAVA_MAVEN_GRADLE.md
|
||||
|
||||
python3 -B scripts/audit_markdown_tables.py README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
|
||||
git diff --check
|
||||
|
||||
git add VERSION docs/rules/520-JAVA_MAVEN_GRADLE.md deltas/0.0.2/alpha.4.fix.1.md
|
||||
|
||||
git diff --cached --check
|
||||
|
||||
git status --short
|
||||
```
|
||||
|
||||
La sortie attendue avant ajout du history est :
|
||||
|
||||
```text
|
||||
M VERSION
|
||||
A deltas/0.0.2/alpha.4.fix.1.md
|
||||
M docs/rules/520-JAVA_MAVEN_GRADLE.md
|
||||
```
|
||||
|
||||
## Transition
|
||||
|
||||
### PASS
|
||||
|
||||
Créer et appliquer séparément `history/0.0.2/alpha.4.fix.1.md`, committer le correctif, puis préparer `0.0.2-alpha.5` consacré au profil Android.
|
||||
|
||||
### FAIL
|
||||
|
||||
Rester dans `0.0.2-alpha.4.fix.M`. Le correctif MUST rester limité à la cohérence de la tranche Java/Maven/Gradle.
|
||||
162
deltas/0.0.2/alpha.4.md
Normal file
162
deltas/0.0.2/alpha.4.md
Normal file
@@ -0,0 +1,162 @@
|
||||
<!-- file: deltas/0.0.2/alpha.4.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Delta 0.0.2-alpha.4 — profil Java / Maven / Gradle
|
||||
|
||||
## Baseline
|
||||
|
||||
Version attendue avant application :
|
||||
|
||||
```text
|
||||
0.0.2-alpha.3
|
||||
```
|
||||
|
||||
Le history `history/0.0.2/alpha.3.md` MUST avoir été appliqué et committé avant ce delta.
|
||||
|
||||
Version après application :
|
||||
|
||||
```text
|
||||
0.0.2-alpha.4
|
||||
```
|
||||
|
||||
## Objet
|
||||
|
||||
Matérialiser le deuxième profil technologique de PGR : `Java / Maven / Gradle`.
|
||||
|
||||
Cette tranche conserve une frontière explicite entre :
|
||||
|
||||
```text
|
||||
Java
|
||||
→ règles du langage et de l'API
|
||||
|
||||
Maven / Gradle
|
||||
→ spécialisations de build
|
||||
|
||||
Android / frameworks futurs
|
||||
→ contraintes plus spécifiques qui pourront surcharger localement Java ou Gradle
|
||||
```
|
||||
|
||||
Aucune règle Android, AGP, SDK, `minSdk`, `targetSdk`, `versionCode`, APK/AAB ou JNI n'est absorbée dans ce profil.
|
||||
|
||||
## Réconciliation retenue
|
||||
|
||||
Le profil reprend les principes déjà établis par PGR et les corpus de conception revus pour cette release :
|
||||
|
||||
- JDK LTS par défaut, dernière LTS compatible utilisée en priorité ;
|
||||
- bascule vers une LTS plus ancienne lorsqu'une dépendance ou un outil l'exige ;
|
||||
- non-LTS uniquement par exception justifiée ;
|
||||
- séparation entre JDK de build et niveau Java/runtime supporté ;
|
||||
- structure standard `src/main/java`, `src/main/resources`, `src/test/java`, `src/test/resources` ;
|
||||
- packages orientés responsabilités et visibilité minimale ;
|
||||
- imports explicites ;
|
||||
- interfaces uniquement lorsqu'une vraie frontière existe ;
|
||||
- pas de Lombok/convenience codegen implicite par défaut, sans interdire les annotations fonctionnelles de frameworks ;
|
||||
- nullabilité et exceptions explicites ;
|
||||
- tests unitaires/intégration/environnement séparables ;
|
||||
- politique Maven centralisée dans le parent/root ;
|
||||
- `dependencyManagement` / `pluginManagement` utilisés pour la politique commune sans ajouter artificiellement les dépendances aux modules ;
|
||||
- Maven Wrapper conditionnel selon le besoin de reproductibilité ;
|
||||
- configuration Gradle commune centralisée ;
|
||||
- version catalog Gradle uniquement si la complexité le justifie ;
|
||||
- contrainte Gradle exprimée comme minimum, range, pin exact ou latest compatible selon la vraie matrice ;
|
||||
- Gradle Wrapper recommandé lorsqu'il apporte une reproductibilité réelle, sans interdire un Gradle système explicitement contraint ;
|
||||
- un DSL Gradle cohérent par projet, sans transformer Groovy/Kotlin DSL en préférence de langage applicatif ;
|
||||
- tâches ciblées pendant le développement, gates globales lorsque leur preuve devient utile ;
|
||||
- `clean` traité comme maintenance ;
|
||||
- outputs/caches/état local hors Git, avec wrappers comme exception volontaire lorsqu'ils sont retenus.
|
||||
|
||||
## Profil créé
|
||||
|
||||
Le nouveau propriétaire normatif est :
|
||||
|
||||
```text
|
||||
docs/rules/520-JAVA_MAVEN_GRADLE.md
|
||||
```
|
||||
|
||||
Il complète la famille `500 — languages / ecosystems` et n'introduit pas de nouvelle famille de navigation.
|
||||
|
||||
Aucun audit Java/Maven/Gradle n'est ajouté : le dépôt PGR ne contient actuellement aucun projet de ce type sur lequel une telle gate fournirait une preuve réelle.
|
||||
|
||||
## Scope
|
||||
|
||||
REPLACE :
|
||||
|
||||
```text
|
||||
VERSION
|
||||
RULES.md
|
||||
docs/rules/000-README.md
|
||||
```
|
||||
|
||||
ADD :
|
||||
|
||||
```text
|
||||
docs/rules/520-JAVA_MAVEN_GRADLE.md
|
||||
deltas/0.0.2/alpha.4.md
|
||||
```
|
||||
|
||||
DELETE : aucun.
|
||||
|
||||
Aucun manifest de suppression n'est nécessaire.
|
||||
|
||||
## Validation opérateur
|
||||
|
||||
```bash
|
||||
test "$(cat VERSION)" = "0.0.2-alpha.4"
|
||||
|
||||
test -f docs/rules/520-JAVA_MAVEN_GRADLE.md
|
||||
test -f deltas/0.0.2/alpha.4.md
|
||||
|
||||
grep -F 'le JDK de développement SHOULD être une version LTS' docs/rules/520-JAVA_MAVEN_GRADLE.md
|
||||
grep -F 'JDK utilisé pour construire' docs/rules/520-JAVA_MAVEN_GRADLE.md
|
||||
grep -F 'src/main/' docs/rules/520-JAVA_MAVEN_GRADLE.md
|
||||
grep -F 'Lombok et les outils équivalents de convenience/codegen implicite SHOULD NOT être utilisés par défaut' docs/rules/520-JAVA_MAVEN_GRADLE.md
|
||||
grep -F 'Le fichier PGR `VERSION` reste la version canonique de l' docs/rules/520-JAVA_MAVEN_GRADLE.md
|
||||
grep -F 'PGR MUST NOT ajouter un Maven Wrapper uniquement par cérémonie.' docs/rules/520-JAVA_MAVEN_GRADLE.md
|
||||
grep -F 'minimum seulement' docs/rules/520-JAVA_MAVEN_GRADLE.md
|
||||
grep -F 'Un Gradle Wrapper SHOULD être versionné lorsqu' docs/rules/520-JAVA_MAVEN_GRADLE.md
|
||||
grep -F 'Groovy DSL et Kotlin DSL sont tous deux reconnus.' docs/rules/520-JAVA_MAVEN_GRADLE.md
|
||||
grep -F 'gradle clean` est une opération de maintenance' docs/rules/520-JAVA_MAVEN_GRADLE.md
|
||||
grep -F 'Aucune commande Maven/Gradle n' docs/rules/520-JAVA_MAVEN_GRADLE.md
|
||||
|
||||
grep -F '520-JAVA_MAVEN_GRADLE.md' RULES.md
|
||||
grep -F '520-JAVA_MAVEN_GRADLE.md' docs/rules/000-README.md
|
||||
|
||||
python3 -B scripts/audit_markdown_tables.py README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
|
||||
git diff --check
|
||||
|
||||
git add VERSION RULES.md docs/rules/000-README.md docs/rules/520-JAVA_MAVEN_GRADLE.md deltas/0.0.2/alpha.4.md
|
||||
|
||||
git diff --cached --check
|
||||
|
||||
git status --short
|
||||
```
|
||||
|
||||
La sortie attendue avant ajout du history est :
|
||||
|
||||
```text
|
||||
M RULES.md
|
||||
M VERSION
|
||||
A deltas/0.0.2/alpha.4.md
|
||||
M docs/rules/000-README.md
|
||||
A docs/rules/520-JAVA_MAVEN_GRADLE.md
|
||||
```
|
||||
|
||||
Revue opérateur complémentaire :
|
||||
|
||||
- confirmer que les règles Java restent distinctes des contraintes propres à Maven/Gradle ;
|
||||
- confirmer que les contraintes Android restent hors de ce profil et pourront surcharger localement Gradle/JDK en `alpha.5` ;
|
||||
- confirmer que la politique JDK privilégie les LTS sans pin exact arbitraire ;
|
||||
- confirmer que Lombok/convenience codegen est distingué des annotations fonctionnelles de frameworks ;
|
||||
- confirmer que Maven Wrapper et Gradle Wrapper sont des choix de reproductibilité justifiés, pas des obligations cérémonielles universelles ;
|
||||
- confirmer qu'aucune commande Maven/Gradle réelle n'est exigée pour valider cette tranche documentaire dans le dépôt PGR lui-même.
|
||||
|
||||
## Transition
|
||||
|
||||
### PASS
|
||||
|
||||
Créer et appliquer séparément `history/0.0.2/alpha.4.md`, committer la tranche, puis préparer `0.0.2-alpha.5` consacré au profil plateforme Android.
|
||||
|
||||
### FAIL
|
||||
|
||||
Rester dans `0.0.2-alpha.4.fix.M` tant que les frontières Java/build tool ou les politiques de compatibilité restent incorrectes. Effectuer un REPLAN si la tranche révèle une dérive significative du scope.
|
||||
142
deltas/0.0.2/alpha.5.md
Normal file
142
deltas/0.0.2/alpha.5.md
Normal file
@@ -0,0 +1,142 @@
|
||||
<!-- file: deltas/0.0.2/alpha.5.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Delta 0.0.2-alpha.5 — profil plateforme Android
|
||||
|
||||
## Baseline
|
||||
|
||||
Version attendue avant application :
|
||||
|
||||
```text
|
||||
0.0.2-alpha.4.fix.1
|
||||
```
|
||||
|
||||
Le history `history/0.0.2/alpha.4.fix.1.md` MUST avoir été appliqué et committé avant ce delta.
|
||||
|
||||
Version après application :
|
||||
|
||||
```text
|
||||
0.0.2-alpha.5
|
||||
```
|
||||
|
||||
## Objet
|
||||
|
||||
Matérialiser le premier profil plateforme de PGR :
|
||||
|
||||
```text
|
||||
docs/rules/610-ANDROID.md
|
||||
```
|
||||
|
||||
La tranche consolide les règles Android réutilisables sans absorber les spécialisations Rust/JNI ou Tauri.
|
||||
|
||||
## Frontières retenues
|
||||
|
||||
Le profil Android possède notamment :
|
||||
|
||||
- la structure Android dans un dépôt mono- ou multi-plateforme ;
|
||||
- Java comme défaut applicatif PGR lorsque rien n'impose un autre langage ;
|
||||
- la matrice AGP / Gradle / JDK ;
|
||||
- la séparation `compileSdk` / `targetSdk` / `minSdk` ;
|
||||
- `VERSION` / `versionName` / `versionCode` ;
|
||||
- configuration locale, signing et secrets ;
|
||||
- modules et dépendances Android ;
|
||||
- ABI lorsqu'un code natif existe, sans définir JNI ;
|
||||
- niveaux de tests Android et ordre de validation ;
|
||||
- manifest, permissions et ressources ;
|
||||
- APK/AAB et packaging de distribution.
|
||||
|
||||
Restent hors scope :
|
||||
|
||||
```text
|
||||
Rust / Android / JNI
|
||||
Tauri desktop
|
||||
Tauri mobile
|
||||
Web / WASM
|
||||
```
|
||||
|
||||
Ces compositions ne doivent pas être introduites implicitement dans `610-ANDROID.md`.
|
||||
|
||||
## Scope
|
||||
|
||||
REPLACE :
|
||||
|
||||
```text
|
||||
VERSION
|
||||
RULES.md
|
||||
docs/rules/000-README.md
|
||||
```
|
||||
|
||||
ADD :
|
||||
|
||||
```text
|
||||
docs/rules/610-ANDROID.md
|
||||
deltas/0.0.2/alpha.5.md
|
||||
```
|
||||
|
||||
DELETE : aucun.
|
||||
|
||||
## Validation opérateur
|
||||
|
||||
```bash
|
||||
test "$(cat VERSION)" = "0.0.2-alpha.5"
|
||||
|
||||
test -f docs/rules/610-ANDROID.md
|
||||
test -f deltas/0.0.2/alpha.5.md
|
||||
|
||||
grep -F 'Les profils Rust/JNI et Tauri ne sont pas définis ici.' docs/rules/610-ANDROID.md
|
||||
grep -F 'Dans un dépôt multi-plateforme où une zone Android distincte est nécessaire' docs/rules/610-ANDROID.md
|
||||
grep -F 'Java est le langage applicatif Android par défaut du profil PGR' docs/rules/610-ANDROID.md
|
||||
grep -F 'Android Gradle Plugin' docs/rules/610-ANDROID.md
|
||||
grep -F 'PGR MUST NOT déduire une hausse de `minSdk`' docs/rules/610-ANDROID.md
|
||||
grep -F '`versionCode` est un compteur Android monotone distinct du SemVer.' docs/rules/610-ANDROID.md
|
||||
grep -F '`local.properties` est un fichier local Android typique' docs/rules/610-ANDROID.md
|
||||
grep -F 'Les secrets de signature ne sont jamais versionnés.' docs/rules/610-ANDROID.md
|
||||
grep -F 'Une ABI annoncée comme supportée doit disposer d' docs/rules/610-ANDROID.md
|
||||
grep -F 'JVM unit' docs/rules/610-ANDROID.md
|
||||
grep -F '`AndroidManifest.xml` MUST déclarer uniquement les permissions' docs/rules/610-ANDROID.md
|
||||
grep -F 'APK debug' docs/rules/610-ANDROID.md
|
||||
grep -F 'PGR lui-même ne contient actuellement aucun projet Android' docs/rules/610-ANDROID.md
|
||||
|
||||
grep -F '610-ANDROID.md' RULES.md
|
||||
grep -F '610-ANDROID.md' docs/rules/000-README.md
|
||||
|
||||
python3 -B scripts/audit_markdown_tables.py README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
|
||||
git diff --check
|
||||
|
||||
git add VERSION RULES.md docs/rules/000-README.md docs/rules/610-ANDROID.md deltas/0.0.2/alpha.5.md
|
||||
|
||||
git diff --cached --check
|
||||
|
||||
git status --short
|
||||
```
|
||||
|
||||
La sortie attendue avant ajout du history est :
|
||||
|
||||
```text
|
||||
M RULES.md
|
||||
M VERSION
|
||||
A deltas/0.0.2/alpha.5.md
|
||||
M docs/rules/000-README.md
|
||||
A docs/rules/610-ANDROID.md
|
||||
```
|
||||
|
||||
Revue opérateur complémentaire :
|
||||
|
||||
- confirmer que le profil reste Android général et n'absorbe ni JNI ni Tauri ;
|
||||
- confirmer que `compileSdk`, `targetSdk` et `minSdk` restent des contrats distincts ;
|
||||
- confirmer que l'usage d'une toolchain moderne ne relève pas automatiquement `minSdk` ;
|
||||
- confirmer que `versionCode` reste un compteur Android distinct de SemVer ;
|
||||
- confirmer que les secrets et configurations locales restent hors Git ;
|
||||
- confirmer que les niveaux de preuve unit/instrumented/smoke ne sont pas confondus ;
|
||||
- confirmer qu'aucune validation Android réelle n'est revendiquée pour PGR lui-même en l'absence de projet Android.
|
||||
|
||||
## Transition
|
||||
|
||||
### PASS
|
||||
|
||||
Créer et appliquer séparément `history/0.0.2/alpha.5.md`, committer la tranche, puis passer à `0.0.2-beta.1` pour la réconciliation des profils.
|
||||
|
||||
### FAIL
|
||||
|
||||
Rester dans `0.0.2-alpha.5.fix.M` jusqu'à correction. Un REPLAN n'est nécessaire que si la correction révèle un élargissement substantiel du scope.
|
||||
91
deltas/0.0.2/beta.1.fix.1.md
Normal file
91
deltas/0.0.2/beta.1.fix.1.md
Normal file
@@ -0,0 +1,91 @@
|
||||
<!-- file: deltas/0.0.2/beta.1.fix.1.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Delta 0.0.2-beta.1.fix.1 — correction du quoting de la gate beta
|
||||
|
||||
## Baseline
|
||||
|
||||
Version attendue avant application :
|
||||
|
||||
```text
|
||||
0.0.2-beta.1
|
||||
```
|
||||
|
||||
Le history `history/0.0.2/beta.1.md` MUST avoir été appliqué et committé avant ce delta.
|
||||
|
||||
Version après application :
|
||||
|
||||
```text
|
||||
0.0.2-beta.1.fix.1
|
||||
```
|
||||
|
||||
## Objet
|
||||
|
||||
Corriger uniquement la commande Bash invalide observée dans la gate de `beta.1`.
|
||||
|
||||
La commande précédente utilisait une chaîne délimitée par apostrophes simples contenant elle-même l'apostrophe de `L'interdiction`, ce qui ouvrait une invite Bash de continuation.
|
||||
|
||||
Le document `docs/rules/610-ANDROID.md` est correct et n'est pas modifié.
|
||||
|
||||
La vérification est remplacée par une recherche littérale équivalente ne contenant aucune apostrophe conflictuelle :
|
||||
|
||||
```bash
|
||||
grep -F 'reste possédée par `RULES.md`.' docs/rules/610-ANDROID.md
|
||||
```
|
||||
|
||||
Aucune règle, aucun profil et aucun audit n'est ajouté ou modifié par ce fix.
|
||||
|
||||
## Scope
|
||||
|
||||
REPLACE :
|
||||
|
||||
```text
|
||||
VERSION
|
||||
```
|
||||
|
||||
ADD :
|
||||
|
||||
```text
|
||||
deltas/0.0.2/beta.1.fix.1.md
|
||||
```
|
||||
|
||||
DELETE : aucun.
|
||||
|
||||
## Validation opérateur
|
||||
|
||||
```bash
|
||||
test "$(cat VERSION)" = "0.0.2-beta.1.fix.1"
|
||||
|
||||
test -f deltas/0.0.2/beta.1.fix.1.md
|
||||
|
||||
grep -F 'reste possédée par `RULES.md`.' docs/rules/610-ANDROID.md
|
||||
|
||||
python3 -B scripts/audit_markdown_tables.py README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
|
||||
python3 -B scripts/audit_markdown_links.py README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
|
||||
git diff --check
|
||||
|
||||
git add VERSION deltas/0.0.2/beta.1.fix.1.md
|
||||
|
||||
git diff --cached --check
|
||||
|
||||
git status --short
|
||||
```
|
||||
|
||||
La sortie attendue avant ajout du history est exactement :
|
||||
|
||||
```text
|
||||
M VERSION
|
||||
A deltas/0.0.2/beta.1.fix.1.md
|
||||
```
|
||||
|
||||
## Transition
|
||||
|
||||
### PASS
|
||||
|
||||
Créer et appliquer séparément `history/0.0.2/beta.1.fix.1.md`, committer le fix, puis préparer `0.0.2-rc.1`.
|
||||
|
||||
### FAIL
|
||||
|
||||
Rester dans `0.0.2-beta.1.fix.M`. Le scope du correctif MUST rester limité à la cohérence de la gate beta.
|
||||
154
deltas/0.0.2/beta.1.md
Normal file
154
deltas/0.0.2/beta.1.md
Normal file
@@ -0,0 +1,154 @@
|
||||
<!-- file: deltas/0.0.2/beta.1.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Delta 0.0.2-beta.1 — réconciliation des profils
|
||||
|
||||
## Baseline
|
||||
|
||||
Version attendue avant application :
|
||||
|
||||
```text
|
||||
0.0.2-alpha.5
|
||||
```
|
||||
|
||||
Le history `history/0.0.2/alpha.5.md` MUST avoir été appliqué et committé avant ce delta.
|
||||
|
||||
Version après application :
|
||||
|
||||
```text
|
||||
0.0.2-beta.1
|
||||
```
|
||||
|
||||
## Objet
|
||||
|
||||
Exécuter la réconciliation prévue après matérialisation des trois profils de `0.0.2` :
|
||||
|
||||
```text
|
||||
510 — Rust / Cargo
|
||||
520 — Java / Maven / Gradle
|
||||
610 — Android
|
||||
```
|
||||
|
||||
La tranche ne crée aucun nouveau profil technologique.
|
||||
|
||||
Elle vérifie et consolide l'ownership normatif, la composition général → langage/build → plateforme, l'absence de contradiction non résolue, la non-duplication des règles générales et la navigation documentaire.
|
||||
|
||||
## Résultat de la réconciliation
|
||||
|
||||
Aucune famille `700 — frameworks` ou `800 — architecture` n'est nécessaire pour fermer `0.0.2`.
|
||||
|
||||
Aucun profil composite n'est créé.
|
||||
|
||||
La composition actuellement démontrée reste :
|
||||
|
||||
```text
|
||||
Rust ordinaire
|
||||
→ GENERAL + 500 + 510
|
||||
|
||||
Java/Gradle Android
|
||||
→ GENERAL + 500 + 520 + 600 + 610
|
||||
```
|
||||
|
||||
Android peut raffiner les contraintes JDK/Gradle dans son scope lorsque la matrice AGP/Gradle/JDK l'exige. Cette spécialisation ne modifie pas le profil Java/Gradle hors Android.
|
||||
|
||||
Le profil Android est ajusté pour ne plus présenter l'interdiction générale des secrets comme une règle dont il serait propriétaire : `RULES.md` conserve l'ownership, tandis que `610-ANDROID.md` décrit les artefacts de signing Android qui tombent sous cette règle.
|
||||
|
||||
## Audit de navigation monotâche
|
||||
|
||||
La réconciliation doit vérifier réellement la navigation locale. PGR ajoute donc :
|
||||
|
||||
```text
|
||||
scripts/audit_markdown_links.py
|
||||
```
|
||||
|
||||
Cet audit est volontairement séparé de `audit_markdown_tables.py`.
|
||||
|
||||
Il contrôle uniquement l'existence des cibles de liens Markdown locaux inline. Il ne contrôle pas les anchors, les headers `file/version`, les responsabilités documentaires, les tableaux ou les URLs externes.
|
||||
|
||||
`PGR-NAV-001` devient l'owner de ce contrôle automatisé dans la matrice de validation.
|
||||
|
||||
`PGR-DOC-001` reste un contrôle de revue pour les headers, chemins et responsabilités documentaires, sans dupliquer la vérification des liens locaux.
|
||||
|
||||
## Scope
|
||||
|
||||
REPLACE :
|
||||
|
||||
```text
|
||||
VERSION
|
||||
docs/architecture/003-RULE_PROFILE_MODEL.md
|
||||
docs/plans/002-V0_0_2_RULE_PROFILES_PLAN.md
|
||||
docs/rules/610-ANDROID.md
|
||||
docs/validation/001-VALIDATION_MATRIX.md
|
||||
```
|
||||
|
||||
ADD :
|
||||
|
||||
```text
|
||||
scripts/audit_markdown_links.py
|
||||
deltas/0.0.2/beta.1.md
|
||||
```
|
||||
|
||||
DELETE : aucun.
|
||||
|
||||
## Validation opérateur
|
||||
|
||||
```bash
|
||||
test "$(cat VERSION)" = "0.0.2-beta.1"
|
||||
|
||||
test -f scripts/audit_markdown_links.py
|
||||
test -f deltas/0.0.2/beta.1.md
|
||||
|
||||
grep -F 'Aucune contradiction non résolue de même niveau' docs/architecture/003-RULE_PROFILE_MODEL.md
|
||||
grep -F 'GENERAL + 500 + 520 + 600 + 610' docs/architecture/003-RULE_PROFILE_MODEL.md
|
||||
grep -F 'Aucune famille `700` ou `800` n' docs/plans/002-V0_0_2_RULE_PROFILES_PLAN.md
|
||||
grep -F 'L'interdiction générale de versionner ou distribuer des secrets reste possédée par `RULES.md`.' docs/rules/610-ANDROID.md
|
||||
|
||||
grep -F '`PGR-NAV-001`' docs/validation/001-VALIDATION_MATRIX.md
|
||||
grep -F 'audit_markdown_links.py' docs/validation/001-VALIDATION_MATRIX.md
|
||||
grep -F 'plusieurs audits simples avec une responsabilité identifiable' docs/validation/001-VALIDATION_MATRIX.md
|
||||
|
||||
python3 -B scripts/audit_markdown_tables.py README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
|
||||
python3 -B scripts/audit_markdown_links.py README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
|
||||
git diff --check
|
||||
|
||||
git add VERSION docs/architecture/003-RULE_PROFILE_MODEL.md docs/plans/002-V0_0_2_RULE_PROFILES_PLAN.md docs/rules/610-ANDROID.md docs/validation/001-VALIDATION_MATRIX.md scripts/audit_markdown_links.py deltas/0.0.2/beta.1.md
|
||||
|
||||
git diff --cached --check
|
||||
|
||||
git status --short
|
||||
```
|
||||
|
||||
La sortie attendue avant ajout du history est :
|
||||
|
||||
```text
|
||||
M VERSION
|
||||
A deltas/0.0.2/beta.1.md
|
||||
M docs/architecture/003-RULE_PROFILE_MODEL.md
|
||||
M docs/plans/002-V0_0_2_RULE_PROFILES_PLAN.md
|
||||
M docs/rules/610-ANDROID.md
|
||||
M docs/validation/001-VALIDATION_MATRIX.md
|
||||
A scripts/audit_markdown_links.py
|
||||
```
|
||||
|
||||
## Revue opérateur complémentaire
|
||||
|
||||
- confirmer que beta n'introduit aucun profil technologique nouveau ;
|
||||
- confirmer que `510`, `520` et `610` possèdent toujours des scopes distincts et compréhensibles ;
|
||||
- confirmer qu'Android raffine Java/Gradle sans faire remonter ses contraintes vers tous les projets Java ;
|
||||
- confirmer qu'aucun owner `700` ou `800` n'est créé sans contenu nécessaire ;
|
||||
- confirmer que le nouvel audit reste strictement monotâche et read-only ;
|
||||
- confirmer que la validation des liens locaux est désormais automatisée sans transformer `PGR-DOC-001` en wrapper multifonction.
|
||||
|
||||
## Transition
|
||||
|
||||
### PASS
|
||||
|
||||
Créer et appliquer séparément `history/0.0.2/beta.1.md`, committer la tranche, puis préparer `0.0.2-rc.1`.
|
||||
|
||||
`rc.1` devra geler le scope, préparer l'entrée candidate `0.0.2` du changelog, finaliser le prompt manuel de reprise `0.0.3` et exécuter la gate documentaire complète.
|
||||
|
||||
### FAIL
|
||||
|
||||
Rester dans `0.0.2-beta.1.fix.M` jusqu'à correction. Aucun nouveau profil majeur ne doit être absorbé dans un fix beta.
|
||||
120
deltas/0.0.2/rc.1.fix.1.md
Normal file
120
deltas/0.0.2/rc.1.fix.1.md
Normal file
@@ -0,0 +1,120 @@
|
||||
<!-- file: deltas/0.0.2/rc.1.fix.1.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Delta 0.0.2-rc.1.fix.1 — correction de l'audit inline des headers
|
||||
|
||||
## Baseline
|
||||
|
||||
Version attendue avant application :
|
||||
|
||||
```text
|
||||
0.0.2-rc.1
|
||||
```
|
||||
|
||||
Le history `history/0.0.2/rc.1.md` MUST avoir été appliqué et committé avant ce delta.
|
||||
|
||||
Version après application :
|
||||
|
||||
```text
|
||||
0.0.2-rc.1.fix.1
|
||||
```
|
||||
|
||||
## Objet
|
||||
|
||||
Corriger uniquement le script Python inline invalide observé dans la gate de `rc.1`.
|
||||
|
||||
La gate précédente matérialisait une chaîne Python sur deux lignes et produisait :
|
||||
|
||||
```text
|
||||
SyntaxError: unterminated string literal
|
||||
```
|
||||
|
||||
Le correctif n'ajoute pas de troisième audit PGR permanent : le scope RC reste gelé sur les audits `tables` et `liens locaux`.
|
||||
|
||||
L'audit ponctuel des headers est rejoué avec une forme sans échappement ambigu.
|
||||
|
||||
## Scope
|
||||
|
||||
REPLACE :
|
||||
|
||||
```text
|
||||
VERSION
|
||||
```
|
||||
|
||||
ADD :
|
||||
|
||||
```text
|
||||
deltas/0.0.2/rc.1.fix.1.md
|
||||
```
|
||||
|
||||
DELETE : aucun.
|
||||
|
||||
## Validation opérateur
|
||||
|
||||
```bash
|
||||
test "$(cat VERSION)" = "0.0.2-rc.1.fix.1"
|
||||
|
||||
test -f deltas/0.0.2/rc.1.fix.1.md
|
||||
|
||||
python3 -B scripts/audit_markdown_tables.py README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
|
||||
python3 -B scripts/audit_markdown_links.py README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
|
||||
python3 -B - <<'PY'
|
||||
from pathlib import Path
|
||||
import re
|
||||
|
||||
roots = [Path(name) for name in ('README.md', 'RULES.md', 'ROADMAP.md', 'CHANGELOG.md')]
|
||||
for directory in ('docs', 'deltas', 'history', 'prompts'):
|
||||
roots.extend(Path(directory).rglob('*.md'))
|
||||
|
||||
paths = sorted(set(roots))
|
||||
errors = []
|
||||
for path in paths:
|
||||
lines = path.read_text(encoding='utf-8').splitlines()
|
||||
expected = f'<!-- file: {path.as_posix()} -->'
|
||||
if len(lines) < 2 or lines[0] != expected:
|
||||
errors.append(f'{path}: invalid file header')
|
||||
elif re.fullmatch(r'<!-- version: [1-9][0-9]* -->', lines[1]) is None:
|
||||
errors.append(f'{path}: invalid version header')
|
||||
|
||||
if errors:
|
||||
for error in errors:
|
||||
print(error)
|
||||
raise SystemExit(1)
|
||||
|
||||
print(f'Markdown header audit: clean ({len(paths)} file(s))')
|
||||
PY
|
||||
|
||||
git diff --check
|
||||
|
||||
git add VERSION deltas/0.0.2/rc.1.fix.1.md
|
||||
|
||||
git diff --cached --check
|
||||
|
||||
git status --short
|
||||
```
|
||||
|
||||
La sortie attendue avant ajout du history est exactement :
|
||||
|
||||
```text
|
||||
M VERSION
|
||||
A deltas/0.0.2/rc.1.fix.1.md
|
||||
```
|
||||
|
||||
## Revue opérateur complémentaire
|
||||
|
||||
- confirmer que les deux audits PGR existants restent propres ;
|
||||
- confirmer que l'audit ponctuel des headers s'exécute réellement et annonce un résultat `clean` ;
|
||||
- confirmer qu'aucun contenu fonctionnel de `rc.1` n'est modifié ;
|
||||
- confirmer que le scope RC reste gelé.
|
||||
|
||||
## Transition
|
||||
|
||||
### PASS
|
||||
|
||||
Créer et appliquer séparément `history/0.0.2/rc.1.fix.1.md`, committer le fix, puis préparer la tranche stable `0.0.2` selon le workflow de release.
|
||||
|
||||
### FAIL
|
||||
|
||||
Rester dans `0.0.2-rc.1.fix.M`. À partir de `.fix.3`, appliquer la revue de plan/diagnostic imposée par la gouvernance.
|
||||
158
deltas/0.0.2/rc.1.md
Normal file
158
deltas/0.0.2/rc.1.md
Normal file
@@ -0,0 +1,158 @@
|
||||
<!-- file: deltas/0.0.2/rc.1.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Delta 0.0.2-rc.1 — gel des profils et préparation de release
|
||||
|
||||
## Baseline
|
||||
|
||||
Version attendue avant application :
|
||||
|
||||
```text
|
||||
0.0.2-beta.1.fix.1
|
||||
```
|
||||
|
||||
Le history `history/0.0.2/beta.1.fix.1.md` MUST avoir été appliqué et committé avant ce delta.
|
||||
|
||||
Version après application :
|
||||
|
||||
```text
|
||||
0.0.2-rc.1
|
||||
```
|
||||
|
||||
## Objet
|
||||
|
||||
Entrer en release candidate après réconciliation beta.
|
||||
|
||||
La tranche :
|
||||
|
||||
- gèle le scope `0.0.2` ;
|
||||
- prépare l'entrée candidate stable `0.0.2` du changelog ;
|
||||
- met à jour le plan avec l'état réellement observé de la beta et le freeze RC ;
|
||||
- ajoute `prompts/003-V0_0_3_START_PROMPT.md` ;
|
||||
- inclut dans ce prompt le texte manuel canonique de reprise et la règle de transmission du futur rapport `publish.001` ;
|
||||
- exécute la gate documentaire complète applicable à PGR.
|
||||
|
||||
Aucun nouveau profil technologique, famille de règles ou audit n'est ajouté en RC.
|
||||
|
||||
## Scope gelé
|
||||
|
||||
Les owners technologiques de la release restent exactement :
|
||||
|
||||
```text
|
||||
510 — Rust / Cargo
|
||||
520 — Java / Maven / Gradle
|
||||
610 — Android
|
||||
```
|
||||
|
||||
Les audits PGR ajoutés pendant la release restent exactement :
|
||||
|
||||
```text
|
||||
scripts/audit_markdown_tables.py
|
||||
scripts/audit_markdown_links.py
|
||||
```
|
||||
|
||||
Les profils différés restent différés.
|
||||
|
||||
## Scope
|
||||
|
||||
REPLACE :
|
||||
|
||||
```text
|
||||
VERSION
|
||||
CHANGELOG.md
|
||||
docs/plans/002-V0_0_2_RULE_PROFILES_PLAN.md
|
||||
```
|
||||
|
||||
ADD :
|
||||
|
||||
```text
|
||||
prompts/003-V0_0_3_START_PROMPT.md
|
||||
deltas/0.0.2/rc.1.md
|
||||
```
|
||||
|
||||
DELETE : aucun.
|
||||
|
||||
## Validation opérateur
|
||||
|
||||
```bash
|
||||
test "$(cat VERSION)" = "0.0.2-rc.1"
|
||||
|
||||
test -f prompts/003-V0_0_3_START_PROMPT.md
|
||||
test -f deltas/0.0.2/rc.1.md
|
||||
|
||||
grep -F '## 0.0.2' CHANGELOG.md
|
||||
grep -F '510 — Rust / Cargo' CHANGELOG.md
|
||||
grep -F '520 — Java / Maven / Gradle' CHANGELOG.md
|
||||
grep -F '610 — Android' CHANGELOG.md
|
||||
|
||||
grep -F 'Le scope RC est gelé' docs/plans/002-V0_0_2_RULE_PROFILES_PLAN.md
|
||||
grep -F 'beta.1.fix.1 PASS' docs/plans/002-V0_0_2_RULE_PROFILES_PLAN.md
|
||||
|
||||
grep -F 'pgr-0.0.2-publish.001-report.md' prompts/003-V0_0_3_START_PROMPT.md
|
||||
grep -F 'Prompt manuel de nouvelle session' prompts/003-V0_0_3_START_PROMPT.md
|
||||
grep -F 'Partir de v0.0.2' prompts/003-V0_0_3_START_PROMPT.md
|
||||
grep -F 'Ce texte doit être présenté spontanément' prompts/003-V0_0_3_START_PROMPT.md
|
||||
|
||||
python3 -B scripts/audit_markdown_tables.py README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
|
||||
python3 -B scripts/audit_markdown_links.py README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
|
||||
python3 -B - <<'PY'
|
||||
from pathlib import Path
|
||||
import re
|
||||
|
||||
roots = [Path(name) for name in ('README.md', 'RULES.md', 'ROADMAP.md', 'CHANGELOG.md')]
|
||||
for directory in ('docs', 'deltas', 'history', 'prompts'):
|
||||
roots.extend(Path(directory).rglob('*.md'))
|
||||
|
||||
errors = []
|
||||
for path in sorted(set(roots)):
|
||||
lines = path.read_text(encoding='utf-8').splitlines()
|
||||
expected = f'<!-- file: {path.as_posix()} -->'
|
||||
if len(lines) < 2 or lines[0] != expected:
|
||||
errors.append(f'{path}: invalid file header')
|
||||
elif re.fullmatch(r'<!-- version: [1-9][0-9]* -->', lines[1]) is None:
|
||||
errors.append(f'{path}: invalid version header')
|
||||
|
||||
if errors:
|
||||
raise SystemExit('
|
||||
'.join(errors))
|
||||
print(f'Markdown header audit: clean ({len(set(roots))} file(s))')
|
||||
PY
|
||||
|
||||
git diff --check
|
||||
|
||||
git add VERSION CHANGELOG.md docs/plans/002-V0_0_2_RULE_PROFILES_PLAN.md prompts/003-V0_0_3_START_PROMPT.md deltas/0.0.2/rc.1.md
|
||||
|
||||
git diff --cached --check
|
||||
|
||||
git status --short
|
||||
```
|
||||
|
||||
La sortie attendue avant ajout du history est exactement :
|
||||
|
||||
```text
|
||||
M CHANGELOG.md
|
||||
M VERSION
|
||||
A deltas/0.0.2/rc.1.md
|
||||
M docs/plans/002-V0_0_2_RULE_PROFILES_PLAN.md
|
||||
A prompts/003-V0_0_3_START_PROMPT.md
|
||||
```
|
||||
|
||||
## Revue opérateur complémentaire
|
||||
|
||||
- confirmer qu'aucun nouveau profil n'est introduit en RC ;
|
||||
- confirmer que le changelog décrit la release utilement sans recopier la chronologie des fixes ;
|
||||
- confirmer que le prompt `0.0.3` impose une nouvelle vérification de l'archive taggée plutôt que de faire confiance au report précédent ;
|
||||
- confirmer que le prompt manuel de nouvelle session est fourni spontanément et précise explicitement le report `publish.001` à joindre après publication ;
|
||||
- confirmer que `0.0.3` reste centré sur templates initiaux et patterns d'audit, sans absorber les skeleton specifications de `0.0.4`.
|
||||
|
||||
## Transition
|
||||
|
||||
### PASS
|
||||
|
||||
Créer et appliquer séparément `history/0.0.2/rc.1.md`, committer la RC, puis préparer la promotion stable `rel.001`.
|
||||
|
||||
### FAIL
|
||||
|
||||
Rester dans `0.0.2-rc.1.fix.M` jusqu'à correction. Aucun nouveau scope fonctionnel ne doit être introduit dans un fix RC.
|
||||
154
deltas/0.0.2/rel.001.md
Normal file
154
deltas/0.0.2/rel.001.md
Normal file
@@ -0,0 +1,154 @@
|
||||
<!-- file: deltas/0.0.2/rel.001.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Delta 0.0.2 rel.001 — promotion stable
|
||||
|
||||
## Baseline
|
||||
|
||||
Version attendue avant application :
|
||||
|
||||
```text
|
||||
0.0.2-rc.1.fix.1
|
||||
```
|
||||
|
||||
Le history `history/0.0.2/rc.1.fix.1.md` MUST avoir été appliqué et committé avant ce delta.
|
||||
|
||||
Version après application :
|
||||
|
||||
```text
|
||||
0.0.2
|
||||
```
|
||||
|
||||
`rel.001` est l'identifiant opérationnel de cette clôture stable ; il ne fait pas partie de la version SemVer produit.
|
||||
|
||||
## Objet
|
||||
|
||||
Promouvoir mécaniquement la release candidate validée vers la stable `0.0.2`, finaliser les métadonnées vivantes de la release et préparer le commit/tag stable.
|
||||
|
||||
Cette tranche n'introduit aucune nouvelle règle normative, aucun nouveau profil, aucun nouvel audit et aucun nouveau scope fonctionnel.
|
||||
|
||||
## Scope
|
||||
|
||||
REPLACE :
|
||||
|
||||
```text
|
||||
VERSION
|
||||
README.md
|
||||
ROADMAP.md
|
||||
docs/plans/002-V0_0_2_RULE_PROFILES_PLAN.md
|
||||
```
|
||||
|
||||
ADD :
|
||||
|
||||
```text
|
||||
deltas/0.0.2/rel.001.md
|
||||
```
|
||||
|
||||
DELETE : aucun.
|
||||
|
||||
## Changements
|
||||
|
||||
- `VERSION` devient `0.0.2` ;
|
||||
- `README.md` présente `0.0.2` comme la première release matérialisant des profils technologiques réutilisables et référence son plan historique ;
|
||||
- `ROADMAP.md` marque `0.0.2` terminé ;
|
||||
- le plan `0.0.2` est clôturé après `rc.1.fix.1` et rappelle la séparation entre `rel.001` pré-tag et `publish.001` post-tag ;
|
||||
- `CHANGELOG.md` n'est pas modifié : l'entrée stable `0.0.2` préparée en RC est déjà finalisée ;
|
||||
- `prompts/003-V0_0_3_START_PROMPT.md` n'est pas modifié : il cible déjà `v0.0.2` et demande explicitement le rapport post-tag lorsqu'il existe.
|
||||
|
||||
## Validation opérateur
|
||||
|
||||
```bash
|
||||
test "$(cat VERSION)" = "0.0.2"
|
||||
|
||||
grep -F 'La release `0.0.2` ajoute le premier modèle de profils réutilisables' README.md
|
||||
grep -F 'plan historique des premiers profils `0.0.2`' README.md
|
||||
grep -F -- '- `(x) 0.0.2`' ROADMAP.md
|
||||
grep -F 'Plan clôturé par la promotion stable `0.0.2` après validation de `0.0.2-rc.1.fix.1`.' docs/plans/002-V0_0_2_RULE_PROFILES_PLAN.md
|
||||
grep -F 'Le contrôle post-tag `publish.001` reste une preuve séparée' docs/plans/002-V0_0_2_RULE_PROFILES_PLAN.md
|
||||
grep -Fx '## 0.0.2' CHANGELOG.md
|
||||
|
||||
test -f prompts/003-V0_0_3_START_PROMPT.md
|
||||
grep -F 'v0.0.2' prompts/003-V0_0_3_START_PROMPT.md
|
||||
grep -F 'pgr-0.0.2-publish.001-report.md' prompts/003-V0_0_3_START_PROMPT.md
|
||||
|
||||
for delta in deltas/0.0.2/*.md; do
|
||||
name="${delta##*/}"
|
||||
if [ "$name" = 'rel.001.md' ]; then
|
||||
continue
|
||||
fi
|
||||
test -f "history/0.0.2/$name" || {
|
||||
echo "Missing history for ${delta}" >&2
|
||||
exit 1
|
||||
}
|
||||
done
|
||||
|
||||
python3 -B scripts/audit_markdown_tables.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
|
||||
python3 -B scripts/audit_markdown_links.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
|
||||
python3 -B - <<'PY'
|
||||
from pathlib import Path
|
||||
import re
|
||||
|
||||
roots = [Path(name) for name in ('README.md', 'RULES.md', 'ROADMAP.md', 'CHANGELOG.md')]
|
||||
for directory in ('docs', 'deltas', 'history', 'prompts'):
|
||||
roots.extend(Path(directory).rglob('*.md'))
|
||||
|
||||
paths = sorted(set(roots))
|
||||
errors = []
|
||||
for path in paths:
|
||||
lines = path.read_text(encoding='utf-8').splitlines()
|
||||
expected = f'<!-- file: {path.as_posix()} -->'
|
||||
if len(lines) < 2 or lines[0] != expected:
|
||||
errors.append(f'{path}: invalid file header')
|
||||
elif re.fullmatch(r'<!-- version: [1-9][0-9]* -->', lines[1]) is None:
|
||||
errors.append(f'{path}: invalid version header')
|
||||
|
||||
if errors:
|
||||
for error in errors:
|
||||
print(error)
|
||||
raise SystemExit(1)
|
||||
|
||||
print(f'Markdown header audit: clean ({len(paths)} file(s))')
|
||||
PY
|
||||
|
||||
git diff --check
|
||||
|
||||
git add VERSION README.md ROADMAP.md \
|
||||
docs/plans/002-V0_0_2_RULE_PROFILES_PLAN.md \
|
||||
deltas/0.0.2/rel.001.md
|
||||
|
||||
git diff --cached --check
|
||||
|
||||
git status --short
|
||||
```
|
||||
|
||||
La sortie attendue avant ajout du history est exactement :
|
||||
|
||||
```text
|
||||
M README.md
|
||||
M ROADMAP.md
|
||||
M VERSION
|
||||
A deltas/0.0.2/rel.001.md
|
||||
M docs/plans/002-V0_0_2_RULE_PROFILES_PLAN.md
|
||||
```
|
||||
|
||||
## Revue opérateur complémentaire
|
||||
|
||||
- confirmer que la promotion stable ne contient aucun changement fonctionnel ou normatif nouveau ;
|
||||
- confirmer que `0.0.2` clôt uniquement les profils `510`, `520` et `610` retenus par le plan ;
|
||||
- confirmer que les profils différés restent différés ;
|
||||
- confirmer que le prompt `0.0.3` demande explicitement l'archive taggée et le rapport `publish.001` lorsqu'il existe ;
|
||||
- confirmer que `CHANGELOG.md` décrit la stable utilement sans recopier les détails de prerelease.
|
||||
|
||||
## Transition
|
||||
|
||||
### PASS
|
||||
|
||||
Créer et appliquer séparément `history/0.0.2/rel.001.md`, committer la stable `0.0.2`, créer le tag `v0.0.2`, pousser commit et tag, puis télécharger l'archive source produite depuis ce tag et exécuter la vérification post-tag `publish.001`.
|
||||
|
||||
### FAIL
|
||||
|
||||
Ne pas créer le tag. Corriger la promotion stable dans une nouvelle tranche de clôture explicite avant toute publication.
|
||||
122
deltas/0.0.3/alpha.1.fix.1.md
Normal file
122
deltas/0.0.3/alpha.1.fix.1.md
Normal file
@@ -0,0 +1,122 @@
|
||||
<!-- file: deltas/0.0.3/alpha.1.fix.1.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Delta 0.0.3-alpha.1.fix.1 — périmètre Rust/Cargo du plan
|
||||
|
||||
## Baseline et version
|
||||
|
||||
Baseline : tranche `0.0.3-alpha.1` validée par l'opérateur, avec `history/0.0.3/alpha.1.md` appliqué et committé. Ce fix ne doit pas être appliqué sur un état où le history `alpha.1` n'est pas encore dans le commit de base.
|
||||
|
||||
Version avant application :
|
||||
|
||||
```text
|
||||
0.0.3-alpha.1
|
||||
```
|
||||
|
||||
Version après application :
|
||||
|
||||
```text
|
||||
0.0.3-alpha.1.fix.1
|
||||
```
|
||||
|
||||
## Motif et observations
|
||||
|
||||
Le delta `alpha.1` a passé sa gate mécanique. La revue du plan ensuite a montré que la tranche Rust prévue autour du seul `rustfmt.toml` n'intégrait pas les réglages Clippy et les deux manifests Cargo communs déjà décrits dans `510-RUST_CARGO.md` et pratiqués dans KSP et Games.
|
||||
|
||||
Les archives de référence supplémentaires inspectées sont :
|
||||
|
||||
```text
|
||||
khadhroony-solana-project-v0.3.16.zip SHA-256 db3cc1b3fc3fb07ee864b02e2a7346c673d4cf63b33e8e872aca6c6458856ca0
|
||||
games-v0.3.5.zip SHA-256 5f5fdee1a271386766d059657d6eaa831acdc263b3e722fed738808335c0a105
|
||||
```
|
||||
|
||||
Les deux projets centralisent lints et métadonnées Cargo, et conservent `rustfmt.toml` ainsi qu'un `clippy.toml`. Les scripts Rust des projets mêlent plusieurs politiques ; le plan corrigé en tire des candidats de propriétés isolées sans les recopier. La seule exception de lints locaux constatée parmi les `45` crates inspectées concerne la frontière Android de Games.
|
||||
|
||||
## Scope
|
||||
|
||||
REPLACE :
|
||||
|
||||
```text
|
||||
VERSION
|
||||
docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md
|
||||
```
|
||||
|
||||
ADD :
|
||||
|
||||
```text
|
||||
deltas/0.0.3/alpha.1.fix.1.md
|
||||
```
|
||||
|
||||
DELETE : aucun.
|
||||
|
||||
Le plan passe de `<!-- version: 1 -->` à `<!-- version: 2 -->` pour sa révision réelle. Les snapshots `deltas/0.0.3/alpha.1.md` et `history/0.0.3/alpha.1.md` restent inchangés. Aucun template, script, règle normative ou manifest de suppression n'est ajouté dans ce fix.
|
||||
|
||||
## Contenu corrigé
|
||||
|
||||
- le template Rust prévu couvre `rustfmt.toml`, les niveaux de lint Rust/Clippy dans Cargo, les manifests workspace/membre et, seulement si justifié, des paramètres distincts dans `clippy.toml` ;
|
||||
- le plan compare les deux corpus réels, relève l'héritage explicite des lints et son exception Android bornée, distingue les options communes des seuils ou dépendances propres à un projet ;
|
||||
- les tranches sont redimensionnées : `alpha.2` formatage/Clippy, `alpha.3` manifests Cargo, `alpha.4` audit de headers Markdown, puis décision conditionnelle sur un template de workflow ;
|
||||
- les scripts Rust KSP/Games servent de corpus de comparaison pour des audits futurs read-only et monotâches, sans transfert direct de leurs règles locales vers PGR.
|
||||
|
||||
## Validation opérateur
|
||||
|
||||
Après application sur le commit `alpha.1` :
|
||||
|
||||
```bash
|
||||
test "$(cat VERSION)" = '0.0.3-alpha.1.fix.1'
|
||||
git cat-file -e HEAD:history/0.0.3/alpha.1.md
|
||||
test -f deltas/0.0.3/alpha.1.fix.1.md
|
||||
test -f history/0.0.3/alpha.1.md
|
||||
test ! -e history/0.0.3/alpha.1.fix.1.md
|
||||
|
||||
grep -Fx '<!-- version: 2 -->' docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md
|
||||
grep -F 'Les `22` crates KSP héritent des lints workspace' docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md
|
||||
grep -F '### alpha.2 — formatage et configuration Clippy' docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md
|
||||
grep -F '### alpha.3 — manifests Cargo workspace et crate membre' docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md
|
||||
grep -F '### alpha.4 — audit de headers Markdown' docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md
|
||||
|
||||
python3 -B scripts/audit_markdown_tables.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_links.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
|
||||
python3 -B - <<'PY'
|
||||
from pathlib import Path
|
||||
import re
|
||||
|
||||
files = [Path(name) for name in ('README.md', 'RULES.md', 'ROADMAP.md', 'CHANGELOG.md')]
|
||||
for directory in ('docs', 'deltas', 'history', 'prompts'):
|
||||
files.extend(Path(directory).rglob('*.md'))
|
||||
files = sorted(set(files))
|
||||
for path in files:
|
||||
lines = path.read_text(encoding='utf-8').splitlines()
|
||||
assert len(lines) >= 2 and lines[0] == f'<!-- file: {path.as_posix()} -->', path
|
||||
assert re.fullmatch(r'<!-- version: [1-9][0-9]* -->', lines[1]), path
|
||||
print(f'Markdown header audit: clean ({len(files)} file(s))')
|
||||
PY
|
||||
|
||||
git diff --check
|
||||
git add VERSION docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md deltas/0.0.3/alpha.1.fix.1.md
|
||||
git diff --cached --check
|
||||
git status --short
|
||||
```
|
||||
|
||||
Avant ajout du history du fix, le scope indexé attendu est :
|
||||
|
||||
```text
|
||||
M VERSION
|
||||
A deltas/0.0.3/alpha.1.fix.1.md
|
||||
M docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md
|
||||
```
|
||||
|
||||
Revue complémentaire : confirmer que la correction ne copie pas de version de dépendance, de path Cargo ou de seuil Clippy arbitraire ; vérifier que le plan reste une prévision et que `alpha.1` demeure un snapshot historique inchangé.
|
||||
|
||||
## Transition
|
||||
|
||||
### PASS
|
||||
|
||||
Produire et appliquer séparément `history/0.0.3/alpha.1.fix.1.md` avec les résultats réellement observés, puis committer ce fix avant tout delta `alpha.2`.
|
||||
|
||||
### FAIL
|
||||
|
||||
Consigner le résultat réel dans le history du fix et poursuivre par `alpha.1.fix.2` limité au cadrage, ou engager un REPLAN explicite si le scope Rust doit changer davantage.
|
||||
101
deltas/0.0.3/alpha.1.md
Normal file
101
deltas/0.0.3/alpha.1.md
Normal file
@@ -0,0 +1,101 @@
|
||||
<!-- file: deltas/0.0.3/alpha.1.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Delta 0.0.3-alpha.1 — audit de baseline et cadrage
|
||||
|
||||
## Baseline
|
||||
|
||||
Archive fournie `pgr-v0.0.2.zip`, déclarée téléchargée du tag Gitea `v0.0.2`, vérifiée avec SHA-256 :
|
||||
|
||||
```text
|
||||
8dc5c979a4d722b4ef6ec84b6227c8cbfffb3f865f4ea9063c03ecb1e365cdc4
|
||||
```
|
||||
|
||||
Le rapport post-tag externe `pgr-0.0.2-publish.001-report.md` indique `PASS` et le même hash. Il n'est pas ajouté rétroactivement à la stable. Aucun `.git` n'est attendu dans l'archive source.
|
||||
|
||||
Version avant application : `0.0.2`.
|
||||
|
||||
Version après application : `0.0.3-alpha.1`.
|
||||
|
||||
## Objet
|
||||
|
||||
Exécuter le cadrage demandé par `prompts/003-V0_0_3_START_PROMPT.md` : audit complet de la stable, vérification des règles et de la chaîne historique, inventaire des sujets utiles, choix d'un scope initial et découpage proportionné dans un plan actif.
|
||||
|
||||
Le résultat détaillé de l'audit, ses limites et les décisions de scope sont consignés dans `docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md`. L'archive est cohérente dans les contrôles réalisés ; aucune correction rétroactive de `0.0.2` n'est nécessaire avant cette tranche.
|
||||
|
||||
## Scope
|
||||
|
||||
REPLACE :
|
||||
|
||||
```text
|
||||
VERSION
|
||||
```
|
||||
|
||||
ADD :
|
||||
|
||||
```text
|
||||
docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md
|
||||
deltas/0.0.3/alpha.1.md
|
||||
```
|
||||
|
||||
DELETE : aucun.
|
||||
|
||||
L'archive delta contient exactement les fichiers complets ci-dessus, avec les mêmes chemins relatifs. Aucun manifest de suppression, history, nouveau template ou script d'audit n'appartient à cette tranche.
|
||||
|
||||
Les index et les documents historiques restent conformes sans mise à jour cérémonielle : la roadmap annonce déjà `0.0.3`, le changelog conserve les releases stables et les index documentaires pointent vers les collections existantes.
|
||||
|
||||
## Validation opérateur
|
||||
|
||||
Appliquer l'archive delta à la copie de travail du dépôt fondée sur `v0.0.2`. Depuis sa racine :
|
||||
|
||||
```bash
|
||||
test "$(cat VERSION)" = '0.0.3-alpha.1'
|
||||
test -f docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md
|
||||
test -f deltas/0.0.3/alpha.1.md
|
||||
test ! -e history/0.0.3/alpha.1.md
|
||||
|
||||
python3 -B scripts/audit_markdown_tables.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_links.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
|
||||
python3 -B - <<'PY'
|
||||
from pathlib import Path
|
||||
import re
|
||||
|
||||
files = [Path(name) for name in ('README.md', 'RULES.md', 'ROADMAP.md', 'CHANGELOG.md')]
|
||||
for directory in ('docs', 'deltas', 'history', 'prompts'):
|
||||
files.extend(Path(directory).rglob('*.md'))
|
||||
files = sorted(set(files))
|
||||
for path in files:
|
||||
lines = path.read_text(encoding='utf-8').splitlines()
|
||||
assert len(lines) >= 2 and lines[0] == f'<!-- file: {path.as_posix()} -->', path
|
||||
assert re.fullmatch(r'<!-- version: [1-9][0-9]* -->', lines[1]), path
|
||||
print(f'Markdown header audit: clean ({len(files)} file(s))')
|
||||
PY
|
||||
|
||||
git diff --check
|
||||
git add VERSION docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md deltas/0.0.3/alpha.1.md
|
||||
git diff --cached --check
|
||||
git status --short
|
||||
```
|
||||
|
||||
Avant d'ajouter le history, le scope attendu des fichiers indexés est :
|
||||
|
||||
```text
|
||||
M VERSION
|
||||
A docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md
|
||||
A deltas/0.0.3/alpha.1.md
|
||||
```
|
||||
|
||||
L'opérateur confirme également que la baseline provient bien du tag déclaré, que le hash concorde avec la preuve post-tag, que les `24` couples historiques antérieurs sont conservés, que les profils différés ne sont pas matérialisés, et que le plan ne fait pas passer une prévision pour une règle déjà active.
|
||||
|
||||
## Transition
|
||||
|
||||
### PASS
|
||||
|
||||
Rédiger et livrer séparément `history/0.0.3/alpha.1.md` avec les résultats réellement observés ; l'appliquer et committer la tranche. Préparer seulement ensuite `0.0.3-alpha.2`.
|
||||
|
||||
### FAIL
|
||||
|
||||
Enregistrer le résultat réellement observé dans le history de `alpha.1`, puis corriger le cadrage dans `0.0.3-alpha.1.fix.1` ou produire un REPLAN motivé. Aucune implémentation `alpha.2` ne doit être absorbée dans le fix.
|
||||
123
deltas/0.0.3/alpha.2.md
Normal file
123
deltas/0.0.3/alpha.2.md
Normal file
@@ -0,0 +1,123 @@
|
||||
<!-- file: deltas/0.0.3/alpha.2.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Delta 0.0.3-alpha.2 — outillage Rust/Cargo partagé
|
||||
|
||||
## Baseline et version
|
||||
|
||||
Baseline : `0.0.3-alpha.1.fix.1` avec `history/0.0.3/alpha.1.fix.1.md` appliqué et committé. Ce delta MUST NOT être appliqué avant ce commit.
|
||||
|
||||
Version avant application :
|
||||
|
||||
```text
|
||||
0.0.3-alpha.1.fix.1
|
||||
```
|
||||
|
||||
Version après application :
|
||||
|
||||
```text
|
||||
0.0.3-alpha.2
|
||||
```
|
||||
|
||||
## Objet
|
||||
|
||||
Matérialiser trois configurations Rust/Cargo directement issues des pratiques éprouvées dans KSP et Games, avec des instructions explicites d'adaptation. L'opérateur a précisé après le gate de `alpha.1.fix.1` que la sortie Cargo est généralement déportée vers `../builds/<projet>/target/` et que Rustfmt/Clippy constituent des conventions de départ qu'il réutilise avec des adaptations mineures.
|
||||
|
||||
Le `clippy.toml` livré conserve les réglages communs utiles aux deux corpus, sans copier leurs listes d'identifiants propres ni leurs entrées vides. Les niveaux des lints appartiendront aux templates `Cargo.toml` de `alpha.3`, conformément au profil `510`.
|
||||
|
||||
## Scope
|
||||
|
||||
REPLACE :
|
||||
|
||||
```text
|
||||
VERSION
|
||||
docs/000-README.md
|
||||
docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md
|
||||
```
|
||||
|
||||
ADD :
|
||||
|
||||
```text
|
||||
templates/rust-cargo/rustfmt.toml
|
||||
templates/rust-cargo/clippy.toml
|
||||
templates/rust-cargo/.cargo/config.toml
|
||||
docs/templates/001-RUST_CARGO_TOOLING.md
|
||||
deltas/0.0.3/alpha.2.md
|
||||
```
|
||||
|
||||
DELETE : aucun.
|
||||
|
||||
Les fichiers complets sont livrés dans l'archive delta. Aucun history `alpha.2`, manifest de suppression, crate PGR ou script d'audit nouveau n'y est inclus.
|
||||
|
||||
## Validation opérateur
|
||||
|
||||
Depuis la racine du dépôt après application du delta :
|
||||
|
||||
```bash
|
||||
test "$(cat VERSION)" = '0.0.3-alpha.2'
|
||||
git cat-file -e HEAD:history/0.0.3/alpha.1.fix.1.md
|
||||
test ! -e history/0.0.3/alpha.2.md
|
||||
|
||||
python3 -B - <<'PY'
|
||||
from pathlib import Path
|
||||
import tomllib
|
||||
|
||||
root = Path('templates/rust-cargo')
|
||||
rustfmt = tomllib.loads((root / 'rustfmt.toml').read_text(encoding='utf-8'))
|
||||
clippy = tomllib.loads((root / 'clippy.toml').read_text(encoding='utf-8'))
|
||||
cargo = tomllib.loads((root / '.cargo/config.toml').read_text(encoding='utf-8'))
|
||||
assert rustfmt['edition'] == '2024'
|
||||
assert rustfmt['max_width'] == 160
|
||||
assert clippy['allow-unwrap-in-tests'] is True
|
||||
assert clippy['allowed-idents-below-min-chars'] == ['id']
|
||||
assert cargo['build']['target-dir'] == '../builds/project-name/target'
|
||||
assert cargo['build']['build-dir'] == cargo['build']['target-dir']
|
||||
for path in (root / 'rustfmt.toml', root / 'clippy.toml', root / '.cargo/config.toml'):
|
||||
lines = path.read_text(encoding='utf-8').splitlines()
|
||||
assert lines[0] == f'# file: {path.as_posix()}', path
|
||||
assert lines[1] == '# version: 1', path
|
||||
print('Rust/Cargo template TOML audit: clean (3 file(s))')
|
||||
PY
|
||||
|
||||
python3 -B scripts/audit_markdown_tables.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_links.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
|
||||
python3 -B - <<'PY'
|
||||
from pathlib import Path
|
||||
import re
|
||||
|
||||
files = [Path(name) for name in ('README.md', 'RULES.md', 'ROADMAP.md', 'CHANGELOG.md')]
|
||||
for directory in ('docs', 'deltas', 'history', 'prompts'):
|
||||
files.extend(Path(directory).rglob('*.md'))
|
||||
files = sorted(set(files))
|
||||
for path in files:
|
||||
lines = path.read_text(encoding='utf-8').splitlines()
|
||||
assert len(lines) >= 2 and lines[0] == f'<!-- file: {path.as_posix()} -->', path
|
||||
assert re.fullmatch(r'<!-- version: [1-9][0-9]* -->', lines[1]), path
|
||||
print(f'Markdown header audit: clean ({len(files)} file(s))')
|
||||
PY
|
||||
|
||||
git diff --check
|
||||
git add VERSION docs/000-README.md docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md \
|
||||
docs/templates/001-RUST_CARGO_TOOLING.md deltas/0.0.3/alpha.2.md \
|
||||
templates/rust-cargo/rustfmt.toml templates/rust-cargo/clippy.toml \
|
||||
templates/rust-cargo/.cargo/config.toml
|
||||
git diff --cached --check
|
||||
git status --short
|
||||
```
|
||||
|
||||
Scope attendu avant ajout du history : les trois `REPLACE` et les cinq `ADD` énumérés ci-dessus, sans modification des deltas ou histories précédents.
|
||||
|
||||
Revue opérateur : confirmer que la convention de sortie Cargo vers un dossier frère est expliquée avec son chemin relatif réel, que `project-name` est à remplacer avant copie et que les lints de niveau Cargo et les manifests restent bien au scope de `alpha.3`. La gate de cette tranche reste documentaire/TOML : PGR ne contient aucun workspace Rust à compiler.
|
||||
|
||||
## Transition
|
||||
|
||||
### PASS
|
||||
|
||||
Produire séparément `history/0.0.3/alpha.2.md` avec les sorties réellement observées, l'appliquer et committer avant de préparer `alpha.3` consacré aux manifests Cargo.
|
||||
|
||||
### FAIL
|
||||
|
||||
Enregistrer la défaillance réelle puis corriger ces seuls templates ou instructions dans `alpha.2.fix.1`, sauf besoin de REPLAN justifié.
|
||||
118
deltas/0.0.3/alpha.3.md
Normal file
118
deltas/0.0.3/alpha.3.md
Normal file
@@ -0,0 +1,118 @@
|
||||
<!-- file: deltas/0.0.3/alpha.3.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Delta 0.0.3-alpha.3 — audits de style Rust ciblés
|
||||
|
||||
## Baseline et version
|
||||
|
||||
Baseline : `0.0.3-alpha.2`, avec `history/0.0.3/alpha.2.md` appliqué et committé. Ce delta MUST NOT être appliqué tant que ce commit n'existe pas.
|
||||
|
||||
Version avant application :
|
||||
|
||||
```text
|
||||
0.0.3-alpha.2
|
||||
```
|
||||
|
||||
Version après application :
|
||||
|
||||
```text
|
||||
0.0.3-alpha.3
|
||||
```
|
||||
|
||||
## Objet et REPLAN
|
||||
|
||||
Après la gate PASS de `alpha.2`, l'opérateur a signalé les audits Python de style Rust de KSP et Games et demandé leur découpage en scripts plus petits et monotâches. L'examen de leurs `audit_rust_general_rules.py` montre qu'ils combinent blancs, constantes, ordre de modules, headers, rustdoc et règles de façade. Résultat REPLAN : `SPLIT`. Les deux contrôles de style apportant une preuve autonome passent à `alpha.3` ; les manifests Cargo initialement prévus ici passent à `alpha.4`, l'audit des headers Markdown à `alpha.5` et la décision workflow à `alpha.6`.
|
||||
|
||||
Ajouter un contrôle facultatif d'espacement des lignes vides et un contrôle facultatif des blocs de constantes racine, avec un helper lexical commun sans politique autonome. Le profil `510` possède leurs conventions optionnelles, la documentation de validation explicite leur adoption et leurs limites ; la matrice répertorie leur test ciblé. Rustfmt reste propriétaire du tri interne qu'il effectue déjà ; Clippy garde ses lints. Aucun script KSP/Games complet ni gate Rust obligatoire n'est copié dans PGR.
|
||||
|
||||
## Scope
|
||||
|
||||
REPLACE :
|
||||
|
||||
```text
|
||||
VERSION
|
||||
docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md
|
||||
docs/rules/510-RUST_CARGO.md
|
||||
docs/templates/001-RUST_CARGO_TOOLING.md
|
||||
docs/validation/001-VALIDATION_MATRIX.md
|
||||
```
|
||||
|
||||
ADD :
|
||||
|
||||
```text
|
||||
docs/validation/002-RUST_STYLE_AUDITS.md
|
||||
scripts/_rust_audit_common.py
|
||||
scripts/audit_rust_blank_lines.py
|
||||
scripts/audit_rust_const_blocks.py
|
||||
tests/test_rust_audits.py
|
||||
deltas/0.0.3/alpha.3.md
|
||||
```
|
||||
|
||||
DELETE : aucun.
|
||||
|
||||
Les fichiers complets figurent dans l'archive delta. Aucun history `alpha.3`, changement rétroactif de delta/history, manifest Cargo, suppression ou modification des corpus de référence n'est inclus.
|
||||
|
||||
## Limites et prévalidation
|
||||
|
||||
Les audits sont read-only, sélectionnent explicitement des fichiers `.rs` et signalent les violations avec chemin et ligne. La prévalidation hors dépôt PGR a porté sur `300` sources KSP et `59` sources Games : l'audit des blancs est propre sur les deux ; l'audit des constantes est propre sur Games mais affiche `17` signaux KSP lorsqu'il est lancé globalement. Des séquences KSP portent un ordre métier ou de schéma ; l'ordre alphabétique ne leur est pas imposé. La sélection du projet doit donc exclure les fichiers ayant une sémantique d'ordre incompatible. Les scripts ne parsèrent pas intégralement Rust et ne remplacent ni Rustfmt ni Clippy.
|
||||
|
||||
Cette prévalidation de corpus n'est pas une validation opérateur de la tranche. Le dépôt PGR ne contient ni crate Rust ni fichiers Rust sujets à un audit produit. Les cas de test Python du delta vérifient les contrats réellement livrés, y compris échecs attendus et statut CLI.
|
||||
|
||||
## Validation opérateur
|
||||
|
||||
Après application sur le commit `alpha.2` :
|
||||
|
||||
```bash
|
||||
test "$(cat VERSION)" = '0.0.3-alpha.3'
|
||||
git cat-file -e HEAD:history/0.0.3/alpha.2.md
|
||||
test -f history/0.0.3/alpha.2.md
|
||||
test -f deltas/0.0.3/alpha.3.md
|
||||
test ! -e history/0.0.3/alpha.3.md
|
||||
|
||||
grep -Fx '<!-- version: 4 -->' docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md
|
||||
grep -F '### alpha.4 — manifests Cargo workspace et crate membre' docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md
|
||||
grep -F '### alpha.5 — audit de headers Markdown' docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md
|
||||
|
||||
python3 -B -m unittest discover -s tests -p test_rust_audits.py -v
|
||||
python3 -B scripts/audit_markdown_tables.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_links.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
|
||||
python3 -B - <<'PY'
|
||||
from pathlib import Path
|
||||
import re
|
||||
|
||||
files = [Path(name) for name in ('README.md', 'RULES.md', 'ROADMAP.md', 'CHANGELOG.md')]
|
||||
for directory in ('docs', 'deltas', 'history', 'prompts'):
|
||||
files.extend(Path(directory).rglob('*.md'))
|
||||
files = sorted(set(files))
|
||||
for path in files:
|
||||
lines = path.read_text(encoding='utf-8').splitlines()
|
||||
assert len(lines) >= 2 and lines[0] == f'<!-- file: {path.as_posix()} -->', path
|
||||
assert re.fullmatch(r'<!-- version: [1-9][0-9]* -->', lines[1]), path
|
||||
print(f'Markdown header audit: clean ({len(files)} file(s))')
|
||||
PY
|
||||
|
||||
git diff --check
|
||||
git add VERSION docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md \
|
||||
docs/rules/510-RUST_CARGO.md docs/templates/001-RUST_CARGO_TOOLING.md \
|
||||
docs/validation/001-VALIDATION_MATRIX.md docs/validation/002-RUST_STYLE_AUDITS.md \
|
||||
scripts/_rust_audit_common.py scripts/audit_rust_blank_lines.py \
|
||||
scripts/audit_rust_const_blocks.py tests/test_rust_audits.py \
|
||||
deltas/0.0.3/alpha.3.md
|
||||
git diff --cached --check
|
||||
git status --short
|
||||
```
|
||||
|
||||
Scope attendu avant ajout du history : cinq `REPLACE` et six `ADD` exactement comme ci-dessus. Revue opérateur : vérifier le rôle facultatif des deux scripts, leur dépendance commune, la sélection des fichiers Rust et la priorité de l'ordre sémantique ; confirmer que les manifests Cargo restent prévus en `alpha.4`.
|
||||
|
||||
## Transition
|
||||
|
||||
### PASS
|
||||
|
||||
Produire séparément `history/0.0.3/alpha.3.md` avec les résultats réellement exécutés, l'appliquer et committer cette tranche avant tout delta `alpha.4`.
|
||||
|
||||
### FAIL
|
||||
|
||||
Consigner le diagnostic dans le history `alpha.3`, puis corriger ce scope dans `alpha.3.fix.1` ou engager un nouveau REPLAN si la séparation des contrôles n'est plus adaptée.
|
||||
191
deltas/0.0.3/alpha.4.md
Normal file
191
deltas/0.0.3/alpha.4.md
Normal file
@@ -0,0 +1,191 @@
|
||||
<!-- file: deltas/0.0.3/alpha.4.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Delta 0.0.3-alpha.4 — manifests Cargo workspace et membre
|
||||
|
||||
## Baseline et version
|
||||
|
||||
Baseline : `0.0.3-alpha.3`, avec `history/0.0.3/alpha.3.md` appliqué et committé. Ce delta MUST NOT être appliqué avant ce commit.
|
||||
|
||||
Version avant application :
|
||||
|
||||
```text
|
||||
0.0.3-alpha.3
|
||||
```
|
||||
|
||||
Version après application :
|
||||
|
||||
```text
|
||||
0.0.3-alpha.4
|
||||
```
|
||||
|
||||
## Objet
|
||||
|
||||
Fournir les deux manifests Cargo prévus dans le plan après son REPLAN `SPLIT` : un workspace virtuel à release commune et une crate bibliothèque membre. Les sections d'héritage, les lints Rust/Clippy communs, la version de release et le périmètre des dépendances doivent être compréhensibles sans figer les identités KSP/Games ni une liste de dépendances tierces.
|
||||
|
||||
Le manifest racine reprend les trois lints Rust et les `18` niveaux Clippy effectivement communs aux deux projets. Il déclare un bloc `[workspace.dependencies]` initialement vide. Le membre hérite explicitement des métadonnées présentes et des lints par `[lints] workspace = true`. La documentation distingue l'adaptation ordinaire d'une exception FFI locale, qui ne peut combiner cet héritage avec des lints locaux dans une même crate. La version `0.1.0` et le nom `project-core-lib` sont des exemples à remplacer, pas des valeurs de PGR ou d'un projet tiers.
|
||||
|
||||
Le plan vivant reçoit deux corrections factuelles : PGR possède désormais plus de deux utilitaires Python et la famille énumère cinq responsabilités, et non quatre. Ces corrections n'altèrent aucun delta ni history précédent.
|
||||
|
||||
## Scope
|
||||
|
||||
REPLACE :
|
||||
|
||||
```text
|
||||
VERSION
|
||||
docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md
|
||||
docs/templates/001-RUST_CARGO_TOOLING.md
|
||||
```
|
||||
|
||||
ADD :
|
||||
|
||||
```text
|
||||
templates/rust-cargo/Cargo.toml
|
||||
templates/rust-cargo/crates/project-core-lib/Cargo.toml
|
||||
docs/templates/002-CARGO_MANIFESTS.md
|
||||
deltas/0.0.3/alpha.4.md
|
||||
```
|
||||
|
||||
DELETE : aucun.
|
||||
|
||||
L'archive contient uniquement ces fichiers complets. Aucun fichier source Rust, history `alpha.4`, suppression, dépendance de build de PGR ou version tierce n'est introduit.
|
||||
|
||||
## Validation opérateur
|
||||
|
||||
Après application sur le commit `alpha.3` :
|
||||
|
||||
```bash
|
||||
test "$(cat VERSION)" = '0.0.3-alpha.4'
|
||||
git cat-file -e HEAD:history/0.0.3/alpha.3.md
|
||||
test -f history/0.0.3/alpha.3.md
|
||||
test ! -e history/0.0.3/alpha.4.md
|
||||
test -f deltas/0.0.3/alpha.4.md
|
||||
|
||||
python3 -B - <<'PY'
|
||||
from pathlib import Path
|
||||
import json
|
||||
import shutil
|
||||
import subprocess
|
||||
import tempfile
|
||||
import tomllib
|
||||
|
||||
source = Path('templates/rust-cargo')
|
||||
root_file = source / 'Cargo.toml'
|
||||
member_file = source / 'crates/project-core-lib/Cargo.toml'
|
||||
root = tomllib.loads(root_file.read_text(encoding='utf-8'))
|
||||
member = tomllib.loads(member_file.read_text(encoding='utf-8'))
|
||||
assert root['workspace']['resolver'] == '3'
|
||||
assert root['workspace']['members'] == ['crates/project-core-lib']
|
||||
assert root['workspace']['package']['version'] == '0.1.0' # Explicit example.
|
||||
assert root['workspace']['package']['edition'] == '2024'
|
||||
assert root['workspace']['package']['publish'] is False
|
||||
assert root['workspace']['dependencies'] == {}
|
||||
assert root['workspace']['lints']['rust'] == {
|
||||
'missing_docs': 'warn', 'unreachable_pub': 'deny', 'unsafe_code': 'forbid'
|
||||
}
|
||||
clippy = root['workspace']['lints']['clippy']
|
||||
assert len(clippy) == 18 and clippy['implicit_return'] == 'deny'
|
||||
assert clippy['needless_return'] == 'allow' and clippy['unwrap_used'] == 'deny'
|
||||
assert member['package']['name'] == 'project-core-lib'
|
||||
for field in ('version', 'edition', 'publish'):
|
||||
assert member['package'][field] == {'workspace': True}, field
|
||||
assert member['dependencies'] == {} and member['lints'] == {'workspace': True}
|
||||
for path in (root_file, member_file):
|
||||
lines = path.read_text(encoding='utf-8').splitlines()
|
||||
assert lines[:2] == [f'# file: {path.as_posix()}', '# version: 1'], path
|
||||
print('Cargo manifest TOML audit: clean (2 file(s))')
|
||||
|
||||
if shutil.which('cargo') is None:
|
||||
print('Cargo workspace smoke: toolchain unavailable; TOML audit only')
|
||||
else:
|
||||
with tempfile.TemporaryDirectory(prefix='pgr-cargo-manifests-') as folder:
|
||||
workspace = Path(folder)
|
||||
crate = workspace / 'crates/project-core-lib'
|
||||
(crate / 'src').mkdir(parents=True)
|
||||
shutil.copy2(root_file, workspace / 'Cargo.toml')
|
||||
shutil.copy2(member_file, crate / 'Cargo.toml')
|
||||
(crate / 'src/lib.rs').write_text(
|
||||
'//! Minimal template check.\n\n/// Return one.\n'
|
||||
'pub fn value() -> u8 {\n return 1;\n}\n', encoding='utf-8'
|
||||
)
|
||||
command = ['cargo', 'metadata', '--manifest-path', str(workspace / 'Cargo.toml'),
|
||||
'--format-version', '1', '--no-deps', '--offline']
|
||||
result = subprocess.run(command, cwd=workspace, text=True,
|
||||
capture_output=True, check=True)
|
||||
package = json.loads(result.stdout)['packages'][0]
|
||||
assert package['name'] == 'project-core-lib'
|
||||
assert package['version'] == '0.1.0' and package['edition'] == '2024'
|
||||
subprocess.run(['cargo', 'check', '--workspace', '--offline'],
|
||||
cwd=workspace, check=True)
|
||||
if subprocess.run(['cargo', 'clippy', '--version'], capture_output=True).returncode == 0:
|
||||
subprocess.run(['cargo', 'clippy', '--workspace', '--all-targets',
|
||||
'--all-features', '--offline', '--', '-D', 'warnings'],
|
||||
cwd=workspace, check=True)
|
||||
|
||||
# Inherited forbid must reject unsafe code before a local FFI exception.
|
||||
(crate / 'src/lib.rs').write_text(
|
||||
'//! Minimal FFI exception check.\n\n/// Return one.\n'
|
||||
'pub fn value() -> u8 {\n'
|
||||
' let value: u8 = 1;\n let ptr: *const u8 = &value;\n'
|
||||
' unsafe { return *ptr; }\n}\n', encoding='utf-8'
|
||||
)
|
||||
rejected = subprocess.run(['cargo', 'check', '--workspace', '--offline'],
|
||||
cwd=workspace, capture_output=True, text=True)
|
||||
assert rejected.returncode != 0 and 'unsafe' in rejected.stderr
|
||||
|
||||
# Cargo must accept a local lint table in place of inheritance.
|
||||
local = member_file.read_text(encoding='utf-8').replace(
|
||||
'[lints]\nworkspace = true\n',
|
||||
'[lints.rust]\nmissing_docs = "warn"\n'
|
||||
'unreachable_pub = "deny"\nunsafe_code = "allow"\n\n'
|
||||
'[lints.clippy]\n' + ''.join(
|
||||
f'{name} = {json.dumps(level)}\n' for name, level in clippy.items()
|
||||
)
|
||||
)
|
||||
assert '[lints.rust]' in local and '[lints]\nworkspace = true' not in local
|
||||
(crate / 'Cargo.toml').write_text(local, encoding='utf-8')
|
||||
subprocess.run(['cargo', 'check', '--workspace', '--offline'],
|
||||
cwd=workspace, check=True)
|
||||
print('Cargo workspace smoke: clean (inherited and local lints)')
|
||||
PY
|
||||
|
||||
python3 -B scripts/audit_markdown_tables.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_links.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
|
||||
python3 -B - <<'PY'
|
||||
from pathlib import Path
|
||||
import re
|
||||
|
||||
files = [Path(name) for name in ('README.md', 'RULES.md', 'ROADMAP.md', 'CHANGELOG.md')]
|
||||
for directory in ('docs', 'deltas', 'history', 'prompts'):
|
||||
files.extend(Path(directory).rglob('*.md'))
|
||||
files = sorted(set(files))
|
||||
for path in files:
|
||||
lines = path.read_text(encoding='utf-8').splitlines()
|
||||
assert len(lines) >= 2 and lines[0] == f'<!-- file: {path.as_posix()} -->', path
|
||||
assert re.fullmatch(r'<!-- version: [1-9][0-9]* -->', lines[1]), path
|
||||
print(f'Markdown header audit: clean ({len(files)} file(s))')
|
||||
PY
|
||||
|
||||
git diff --check
|
||||
git add VERSION docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md \
|
||||
docs/templates/001-RUST_CARGO_TOOLING.md docs/templates/002-CARGO_MANIFESTS.md \
|
||||
templates/rust-cargo/Cargo.toml templates/rust-cargo/crates/project-core-lib/Cargo.toml \
|
||||
deltas/0.0.3/alpha.4.md
|
||||
git diff --cached --check
|
||||
git status --short
|
||||
```
|
||||
|
||||
Scope attendu avant ajout du history : les trois `REPLACE` et les quatre `ADD` ci-dessus. Revue opérateur : vérifier que le manifest membre hérite seulement des champs racine présents, que les lints Clippy sont ceux des deux corpus et que la version d'exemple ainsi que le nom de crate doivent être remplacés lors d'une adoption réelle. Si Cargo n'est pas disponible dans l'environnement de PGR, le smoke workspace est indiqué comme non exécuté et le parsing TOML reste la preuve locale ; l'adoption dans un projet Rust doit exécuter sa propre gate Cargo.
|
||||
|
||||
## Transition
|
||||
|
||||
### PASS
|
||||
|
||||
Fournir séparément `history/0.0.3/alpha.4.md` avec les sorties réellement observées, l'appliquer et committer la tranche avant le delta `alpha.5` relatif aux headers Markdown.
|
||||
|
||||
### FAIL
|
||||
|
||||
Consigner le défaut dans le history, puis corriger manifests ou instructions dans `alpha.4.fix.1` sauf besoin justifié d'un nouveau REPLAN.
|
||||
90
deltas/0.0.3/alpha.5.md
Normal file
90
deltas/0.0.3/alpha.5.md
Normal file
@@ -0,0 +1,90 @@
|
||||
<!-- file: deltas/0.0.3/alpha.5.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Delta 0.0.3-alpha.5 — audit des headers Markdown
|
||||
|
||||
## Baseline et version
|
||||
|
||||
Baseline : `0.0.3-alpha.4`, avec `history/0.0.3/alpha.4.md` appliqué et committé. Ce delta MUST NOT être appliqué avant ce commit.
|
||||
|
||||
Version avant application :
|
||||
|
||||
```text
|
||||
0.0.3-alpha.4
|
||||
```
|
||||
|
||||
Version après application :
|
||||
|
||||
```text
|
||||
0.0.3-alpha.5
|
||||
```
|
||||
|
||||
## Objet
|
||||
|
||||
Extraire le contrôle des headers Markdown répété en Python inline dans les gates précédentes. `scripts/audit_markdown_headers.py` vérifie une seule propriété documentaire : les deux premières lignes de chaque fichier choisi doivent déclarer son chemin relatif canonique et une révision interne positive. Le script accepte des chemins explicites depuis la racine du projet, lit sans modifier, produit des erreurs déterministes avec chemin et ligne et distingue violation de sélection invalide.
|
||||
|
||||
`docs/rules/300-DOCUMENTATION.md` possède la convention pour le corpus Markdown de PGR. La matrice inscrit l'audit mécanique séparément de la revue des rôles documentaires, de l'audit des tableaux et de celui des liens. Une révision positive ne démontre pas qu'elle a été incrémentée à bon escient : cela reste une décision de revue.
|
||||
|
||||
## Scope
|
||||
|
||||
REPLACE :
|
||||
|
||||
```text
|
||||
VERSION
|
||||
docs/rules/300-DOCUMENTATION.md
|
||||
docs/validation/001-VALIDATION_MATRIX.md
|
||||
```
|
||||
|
||||
ADD :
|
||||
|
||||
```text
|
||||
scripts/audit_markdown_headers.py
|
||||
tests/test_markdown_headers.py
|
||||
deltas/0.0.3/alpha.5.md
|
||||
```
|
||||
|
||||
DELETE : aucun.
|
||||
|
||||
L'archive livre uniquement ces fichiers complets. Aucun history `alpha.5`, réécriture historique, nouveau profil de langage ou autre audit Markdown n'est inclus.
|
||||
|
||||
## Validation opérateur
|
||||
|
||||
Après application sur le commit `alpha.4`, depuis la racine du dépôt :
|
||||
|
||||
```bash
|
||||
test "$(cat VERSION)" = '0.0.3-alpha.5'
|
||||
git cat-file -e HEAD:history/0.0.3/alpha.4.md
|
||||
test -f history/0.0.3/alpha.4.md
|
||||
test -f deltas/0.0.3/alpha.5.md
|
||||
test ! -e history/0.0.3/alpha.5.md
|
||||
|
||||
grep -Fx '<!-- version: 2 -->' docs/rules/300-DOCUMENTATION.md
|
||||
grep -Fx '<!-- version: 8 -->' docs/validation/001-VALIDATION_MATRIX.md
|
||||
|
||||
python3 -B -m unittest discover -s tests -p test_markdown_headers.py -v
|
||||
python3 -B scripts/audit_markdown_headers.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_tables.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_links.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
|
||||
git diff --check
|
||||
git add VERSION docs/rules/300-DOCUMENTATION.md \
|
||||
docs/validation/001-VALIDATION_MATRIX.md scripts/audit_markdown_headers.py \
|
||||
tests/test_markdown_headers.py deltas/0.0.3/alpha.5.md
|
||||
git diff --cached --check
|
||||
git status --short
|
||||
```
|
||||
|
||||
Scope attendu avant ajout du history : trois `REPLACE` et trois `ADD`, sans toucher à un delta ou history antérieur. Vérifier que le nouveau script reste monotâche, traite les headers faux et les chemins absents, et ne remplace ni la revue des documents ni les deux autres audits Markdown.
|
||||
|
||||
## Transition
|
||||
|
||||
### PASS
|
||||
|
||||
Produire séparément `history/0.0.3/alpha.5.md` avec les preuves réellement observées, l'appliquer et committer avant la tranche `alpha.6`, consacrée à la décision conditionnelle sur le template de workflow.
|
||||
|
||||
### FAIL
|
||||
|
||||
Enregistrer la défaillance et corriger ce scope dans `alpha.5.fix.1`, sauf REPLAN explicitement justifié.
|
||||
92
deltas/0.0.3/alpha.6.md
Normal file
92
deltas/0.0.3/alpha.6.md
Normal file
@@ -0,0 +1,92 @@
|
||||
<!-- file: deltas/0.0.3/alpha.6.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Delta 0.0.3-alpha.6 — prompt manuel de reprise
|
||||
|
||||
## Baseline et version
|
||||
|
||||
Baseline : `0.0.3-alpha.5`, avec `history/0.0.3/alpha.5.md` appliqué et committé. Ce delta MUST NOT être appliqué avant ce commit.
|
||||
|
||||
Version avant application :
|
||||
|
||||
```text
|
||||
0.0.3-alpha.5
|
||||
```
|
||||
|
||||
Version après application :
|
||||
|
||||
```text
|
||||
0.0.3-alpha.6
|
||||
```
|
||||
|
||||
## Décision et objet
|
||||
|
||||
La comparaison des prompts `002` et `003` et des règles `210-WORKFLOW.md` confirme une répétition utile : baseline taggée, version cible, première tranche et consigne d'audit à la reprise. `003` ajoute une preuve de vérification post-tag distincte et une phrase manuelle à remettre à l'opérateur. La décision conditionnelle de la tranche est donc **retenir** une spécification courte dans `docs/templates/003-NEW_SESSION_PROMPT.md`.
|
||||
|
||||
Ce document rassemble les champs à renseigner et une forme de message manuel, avec une branche claire lorsque le rapport post-tag manque ou n'est pas `PASS`. Il ne génère rien, ne fige aucun nom de projet ni preuve et ne prépare pas encore le prompt versionné de `0.0.4`. `docs/rules/210-WORKFLOW.md` reste propriétaire de la séquence delta/history/commit et de la publication après tag ; le plan vivant enregistre la décision.
|
||||
|
||||
## Scope
|
||||
|
||||
REPLACE :
|
||||
|
||||
```text
|
||||
VERSION
|
||||
docs/rules/210-WORKFLOW.md
|
||||
docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md
|
||||
```
|
||||
|
||||
ADD :
|
||||
|
||||
```text
|
||||
docs/templates/003-NEW_SESSION_PROMPT.md
|
||||
deltas/0.0.3/alpha.6.md
|
||||
```
|
||||
|
||||
DELETE : aucun.
|
||||
|
||||
L'archive contient uniquement ces fichiers complets. Aucun history `alpha.6`, prompt `004`, générateur, modification de prompts historiques ou changement de configuration Rust/Cargo n'est inclus.
|
||||
|
||||
## Validation opérateur
|
||||
|
||||
Après application sur le commit `alpha.5`, depuis la racine du dépôt :
|
||||
|
||||
```bash
|
||||
test "$(cat VERSION)" = '0.0.3-alpha.6'
|
||||
git cat-file -e HEAD:history/0.0.3/alpha.5.md
|
||||
test -f history/0.0.3/alpha.5.md
|
||||
test -f deltas/0.0.3/alpha.6.md
|
||||
test -f docs/templates/003-NEW_SESSION_PROMPT.md
|
||||
test ! -e history/0.0.3/alpha.6.md
|
||||
test ! -e prompts/004-V0_0_4_START_PROMPT.md
|
||||
|
||||
grep -Fx '<!-- version: 3 -->' docs/rules/210-WORKFLOW.md
|
||||
grep -Fx '<!-- version: 6 -->' docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md
|
||||
grep -F '### Retenu : spécification courte du prompt manuel de nouvelle session' \
|
||||
docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md
|
||||
|
||||
python3 -B scripts/audit_markdown_headers.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_tables.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_links.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
|
||||
git diff --check
|
||||
git add VERSION docs/rules/210-WORKFLOW.md \
|
||||
docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md \
|
||||
docs/templates/003-NEW_SESSION_PROMPT.md deltas/0.0.3/alpha.6.md
|
||||
git diff --cached --check
|
||||
git status --short
|
||||
```
|
||||
|
||||
Scope attendu avant ajout du history : trois `REPLACE` et deux `ADD`. Revue opérateur : confirmer que le message manuel est actionnable sans supposer un rapport `PASS`, que son contrat versionné est distinct, que les prompts `002`/`003` restent historiques et que la préparation de `0.0.4` n'est pas anticipée.
|
||||
|
||||
## Transition
|
||||
|
||||
### PASS
|
||||
|
||||
Produire séparément `history/0.0.3/alpha.6.md` d'après la gate exécutée, l'appliquer et committer avant de passer à `beta.1` pour la réconciliation de release.
|
||||
|
||||
### FAIL
|
||||
|
||||
Enregistrer le diagnostic puis corriger uniquement cette spécification et ses renvois dans `alpha.6.fix.1`, sauf REPLAN justifié.
|
||||
115
deltas/0.0.3/beta.1.md
Normal file
115
deltas/0.0.3/beta.1.md
Normal file
@@ -0,0 +1,115 @@
|
||||
<!-- file: deltas/0.0.3/beta.1.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Delta 0.0.3-beta.1 — réconciliation documentaire
|
||||
|
||||
## Baseline et version
|
||||
|
||||
Baseline : `0.0.3-alpha.6`, avec `history/0.0.3/alpha.6.md` appliqué et committé. Ce delta MUST NOT être appliqué avant ce commit.
|
||||
|
||||
Version avant application :
|
||||
|
||||
```text
|
||||
0.0.3-alpha.6
|
||||
```
|
||||
|
||||
Version après application :
|
||||
|
||||
```text
|
||||
0.0.3-beta.1
|
||||
```
|
||||
|
||||
## Objet et résultat de la revue
|
||||
|
||||
Réconcilier la navigation, les propriétaires et les contrôles après les six tranches alpha et le fix documentaire. Les sept deltas `alpha.1` à `alpha.6`, fix inclus, ont chacun un history `PASS` fourni par la gate opérateur ; leur chaîne de versions est continue depuis `0.0.2`. La règle `210` possède le workflow ; la règle `300` possède les headers Markdown ; le profil `510` possède les conventions Rust facultatives. Les documents `docs/templates/` expliquent comment adapter les cinq fichiers Rust/Cargo et le message de reprise, tandis que les scripts restent de petits contrôles de propriétés délimitées.
|
||||
|
||||
La revue relève quatre corrections de documents vivants : exposer le plan actif depuis `README.md`, ouvrir la navigation directe depuis `docs/000-README.md` et décrire son template de workflow, actualiser dans le plan l'audit des headers déjà livré, et rendre dans la matrice l'audit des liens applicable à une tranche alpha qui modifie la navigation. La réconciliation n'ajoute aucune famille normative, audit, règle de version universelle, dépendance de build ou prompt `0.0.4`. Les versions et seuils du modèle Cargo restent des exemples ou choix adaptables, et les snapshots antérieurs restent intacts.
|
||||
|
||||
## Scope
|
||||
|
||||
REPLACE :
|
||||
|
||||
```text
|
||||
VERSION
|
||||
README.md
|
||||
docs/000-README.md
|
||||
docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md
|
||||
docs/validation/001-VALIDATION_MATRIX.md
|
||||
```
|
||||
|
||||
ADD :
|
||||
|
||||
```text
|
||||
deltas/0.0.3/beta.1.md
|
||||
```
|
||||
|
||||
DELETE : aucun.
|
||||
|
||||
L'archive contient exactement ces fichiers complets. Le history de `alpha.6` est livré séparément, celui de `beta.1` n'existe pas encore ; `CHANGELOG.md`, les règles, templates techniques, scripts, tests et prompts ne sont pas modifiés.
|
||||
|
||||
## Validation opérateur
|
||||
|
||||
Après application de `history/0.0.3/alpha.6.md` et son commit, appliquer ce delta puis exécuter à la racine :
|
||||
|
||||
```bash
|
||||
test "$(cat VERSION)" = '0.0.3-beta.1'
|
||||
git cat-file -e HEAD:history/0.0.3/alpha.6.md
|
||||
test -f history/0.0.3/alpha.6.md
|
||||
test -f deltas/0.0.3/beta.1.md
|
||||
test ! -e history/0.0.3/beta.1.md
|
||||
test ! -e prompts/004-V0_0_4_START_PROMPT.md
|
||||
|
||||
grep -Fx '<!-- version: 5 -->' README.md
|
||||
grep -Fx '<!-- version: 3 -->' docs/000-README.md
|
||||
grep -Fx '<!-- version: 7 -->' docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md
|
||||
grep -Fx '<!-- version: 9 -->' docs/validation/001-VALIDATION_MATRIX.md
|
||||
|
||||
python3 -B -m unittest discover -s tests -p 'test_*.py' -v
|
||||
python3 -B scripts/audit_markdown_headers.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_tables.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_links.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
|
||||
python3 -B - <<'PY'
|
||||
from pathlib import Path
|
||||
import re
|
||||
import tomllib
|
||||
|
||||
tranches = ['alpha.1', 'alpha.1.fix.1', 'alpha.2', 'alpha.3',
|
||||
'alpha.4', 'alpha.5', 'alpha.6']
|
||||
version = '0.0.2'
|
||||
for name in tranches:
|
||||
delta = Path(f'deltas/0.0.3/{name}.md').read_text(encoding='utf-8')
|
||||
history = Path(f'history/0.0.3/{name}.md').read_text(encoding='utf-8')
|
||||
assert re.search(r'## Statut\s+PASS\s', history), name
|
||||
assert f'Version avant application : `{version}`.' in delta or \
|
||||
f'Version avant application :\n\n```text\n{version}\n```' in delta, name
|
||||
version = f'0.0.3-{name}'
|
||||
assert f'Version après application : `{version}`.' in delta or \
|
||||
f'Version après application :\n\n```text\n{version}\n```' in delta, name
|
||||
for path in sorted(Path('templates/rust-cargo').rglob('*.toml')):
|
||||
tomllib.loads(path.read_text(encoding='utf-8'))
|
||||
print(f'Reconciliation audit: clean ({len(tranches)} PASS histories, 5 TOML files)')
|
||||
PY
|
||||
|
||||
git diff --check
|
||||
git add VERSION README.md docs/000-README.md \
|
||||
docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md \
|
||||
docs/validation/001-VALIDATION_MATRIX.md deltas/0.0.3/beta.1.md
|
||||
git diff --cached --check
|
||||
git status --short
|
||||
```
|
||||
|
||||
Scope attendu avant ajout du history : cinq `REPLACE` et un `ADD` exactement comme ci-dessus. Revue opérateur : confirmer que les liens pointent vers les documents propriétaires et que les valeurs du template Cargo restent des exemples adaptables ; les gates alpha déjà observées ne sont pas réinterprétées et la RC n'est pas déclarée acquise par cette prévalidation.
|
||||
|
||||
## Transition
|
||||
|
||||
### PASS
|
||||
|
||||
Produire séparément `history/0.0.3/beta.1.md` avec les résultats réellement observés, l'appliquer et committer `beta.1` avant de préparer `rc.1`.
|
||||
|
||||
### FAIL
|
||||
|
||||
Enregistrer le diagnostic dans le history de `beta.1`, puis corriger la réconciliation dans `beta.1.fix.1` ou faire un REPLAN explicite si le scope a changé.
|
||||
117
deltas/0.0.3/rc.1.md
Normal file
117
deltas/0.0.3/rc.1.md
Normal file
@@ -0,0 +1,117 @@
|
||||
<!-- file: deltas/0.0.3/rc.1.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Delta 0.0.3-rc.1 — gel du scope et préparation de release
|
||||
|
||||
## Baseline et version
|
||||
|
||||
Baseline : `0.0.3-beta.1`, avec `history/0.0.3/beta.1.md` appliqué et committé. Ce delta MUST NOT être appliqué avant ce commit.
|
||||
|
||||
Version avant application :
|
||||
|
||||
```text
|
||||
0.0.3-beta.1
|
||||
```
|
||||
|
||||
Version après application :
|
||||
|
||||
```text
|
||||
0.0.3-rc.1
|
||||
```
|
||||
|
||||
## Objet et gel
|
||||
|
||||
La gate de `beta.1` est `PASS`. La RC gèle le scope fonctionnel : cinq modèles Rust/Cargo adaptables, deux audits facultatifs de style Rust, un audit de headers Markdown et une spécification du message manuel de reprise. La candidate `0.0.3` du changelog décrit ces résultats sans détailler les fixes ; le plan enregistre le gel et l'état observé de beta.
|
||||
|
||||
Le prompt `004` prépare le cadrage de `0.0.4` consacré aux skeleton specifications Markdown et à la composition des profils/templates. Il demande un audit de la future archive taggée `v0.0.3` et traite son rapport post-tag comme une preuve conditionnelle, jamais acquise en RC. Son message manuel doit être ajusté et remis après la publication et son contrôle réel. Aucun skeleton complet, générateur, règle normative nouvelle, audit nouveau ni projet source modifié n'appartient à `rc.1`.
|
||||
|
||||
## Scope
|
||||
|
||||
REPLACE :
|
||||
|
||||
```text
|
||||
VERSION
|
||||
CHANGELOG.md
|
||||
docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md
|
||||
```
|
||||
|
||||
ADD :
|
||||
|
||||
```text
|
||||
prompts/004-V0_0_4_START_PROMPT.md
|
||||
deltas/0.0.3/rc.1.md
|
||||
```
|
||||
|
||||
DELETE : aucun.
|
||||
|
||||
L'archive contient exactement ces fichiers complets. Le history `beta.1` est livré séparément ; le history `rc.1` sera produit après la gate opérateur. Les histories et deltas antérieurs, les règles, modèles techniques, scripts, tests et `ROADMAP.md` restent inchangés.
|
||||
|
||||
## Gate opérateur de release candidate
|
||||
|
||||
Après application sur le commit `beta.1`, depuis la racine du dépôt :
|
||||
|
||||
```bash
|
||||
test "$(cat VERSION)" = '0.0.3-rc.1'
|
||||
git cat-file -e HEAD:history/0.0.3/beta.1.md
|
||||
test -f history/0.0.3/beta.1.md
|
||||
test -f deltas/0.0.3/rc.1.md
|
||||
test -f prompts/004-V0_0_4_START_PROMPT.md
|
||||
test ! -e history/0.0.3/rc.1.md
|
||||
|
||||
grep -Fx '<!-- version: 4 -->' CHANGELOG.md
|
||||
grep -Fx '## 0.0.3 (candidate)' CHANGELOG.md
|
||||
grep -Fx '<!-- version: 8 -->' docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md
|
||||
grep -F 'La gate opérateur de `beta.1` est `PASS`' docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md
|
||||
grep -F 'pgr-0.0.3-publish.001-report.md' prompts/004-V0_0_4_START_PROMPT.md
|
||||
grep -F "Si le rapport manque ou n'est pas PASS" prompts/004-V0_0_4_START_PROMPT.md
|
||||
|
||||
python3 -B -m unittest discover -s tests -p 'test_*.py' -v
|
||||
python3 -B scripts/audit_markdown_headers.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_tables.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_links.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
|
||||
python3 -B - <<'PY'
|
||||
from pathlib import Path
|
||||
import re
|
||||
import tomllib
|
||||
|
||||
names = ['alpha.1', 'alpha.1.fix.1', 'alpha.2', 'alpha.3',
|
||||
'alpha.4', 'alpha.5', 'alpha.6', 'beta.1']
|
||||
version = '0.0.2'
|
||||
for name in names:
|
||||
delta = Path(f'deltas/0.0.3/{name}.md').read_text(encoding='utf-8')
|
||||
history = Path(f'history/0.0.3/{name}.md').read_text(encoding='utf-8')
|
||||
assert re.search(r'## Statut\s+PASS\s', history), name
|
||||
assert f'Version avant application : `{version}`.' in delta or \
|
||||
f'Version avant application :\n\n```text\n{version}\n```' in delta, name
|
||||
version = f'0.0.3-{name}'
|
||||
assert f'Version après application : `{version}`.' in delta or \
|
||||
f'Version après application :\n\n```text\n{version}\n```' in delta, name
|
||||
assert {p.stem for p in Path('deltas/0.0.3').glob('*.md')} - \
|
||||
{p.stem for p in Path('history/0.0.3').glob('*.md')} == {'rc.1'}
|
||||
for path in Path('templates/rust-cargo').rglob('*.toml'):
|
||||
tomllib.loads(path.read_text(encoding='utf-8'))
|
||||
print(f'RC integration audit: clean ({len(names)} PASS histories, 5 TOML files)')
|
||||
PY
|
||||
|
||||
git diff --check
|
||||
git add VERSION CHANGELOG.md docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md \
|
||||
prompts/004-V0_0_4_START_PROMPT.md deltas/0.0.3/rc.1.md
|
||||
git diff --cached --check
|
||||
git status --short
|
||||
```
|
||||
|
||||
Scope attendu avant ajout du history : trois `REPLACE` et deux `ADD`. Revue opérateur : contrôler que le changelog décrit la release et non les tranches, que les exemples Cargo restent adaptables, que `004` concerne exclusivement la future `0.0.4` et que sa preuve post-tag n'est pas présumée. Une gate RC PASS n'est pas un tag ni une vérification de l'archive publiée.
|
||||
|
||||
## Transition
|
||||
|
||||
### PASS
|
||||
|
||||
Produire séparément `history/0.0.3/rc.1.md` d'après la gate observée, l'appliquer puis committer la RC avant la promotion stable `rel.001`.
|
||||
|
||||
### FAIL
|
||||
|
||||
Consigner les échecs dans le history RC et corriger le scope gelé dans `rc.1.fix.1` ; réviser le plan si un changement fonctionnel plus large s'impose.
|
||||
116
deltas/0.0.3/rel.001.md
Normal file
116
deltas/0.0.3/rel.001.md
Normal file
@@ -0,0 +1,116 @@
|
||||
<!-- file: deltas/0.0.3/rel.001.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Delta 0.0.3 rel.001 — promotion stable pré-tag
|
||||
|
||||
## Baseline et version
|
||||
|
||||
Baseline : `0.0.3-rc.1`, avec `history/0.0.3/rc.1.md` appliqué et committé. Ce delta MUST NOT être appliqué avant ce commit.
|
||||
|
||||
Version avant application :
|
||||
|
||||
```text
|
||||
0.0.3-rc.1
|
||||
```
|
||||
|
||||
Version après application :
|
||||
|
||||
```text
|
||||
0.0.3
|
||||
```
|
||||
|
||||
`rel.001` identifie la clôture opérationnelle ; il ne fait pas partie de la version SemVer du produit.
|
||||
|
||||
## Objet
|
||||
|
||||
Promouvoir la RC validée vers la stable `0.0.3`. La tranche finalise la présentation de la release, marque la roadmap terminée, retire la mention « candidate » du changelog et clôt le plan comme référence historique. Le prompt `004`, les règles, les modèles, les audits et les tests sont ceux validés en RC : aucune fonctionnalité, règle ou preuve post-tag nouvelle n'est introduite.
|
||||
|
||||
La validation de cette tranche est **pré-tag**. Ni le tag `v0.0.3` ni une archive téléchargée depuis Gitea ni un rapport `publish.001` ne sont déclarés existants par ce delta. Ils suivent le history PASS, le commit stable et la publication du tag.
|
||||
|
||||
## Scope
|
||||
|
||||
REPLACE :
|
||||
|
||||
```text
|
||||
VERSION
|
||||
README.md
|
||||
ROADMAP.md
|
||||
CHANGELOG.md
|
||||
docs/000-README.md
|
||||
docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md
|
||||
```
|
||||
|
||||
ADD :
|
||||
|
||||
```text
|
||||
deltas/0.0.3/rel.001.md
|
||||
```
|
||||
|
||||
DELETE : aucun.
|
||||
|
||||
L'archive contient uniquement ces fichiers complets. `history/0.0.3/rc.1.md` arrive séparément ; le history de `rel.001` sera rédigé après sa gate. Le rapport post-tag sera hors de l'archive source taggée.
|
||||
|
||||
## Validation opérateur pré-tag
|
||||
|
||||
Après application sur le commit `rc.1`, depuis la racine du dépôt :
|
||||
|
||||
```bash
|
||||
test "$(cat VERSION)" = '0.0.3'
|
||||
git cat-file -e HEAD:history/0.0.3/rc.1.md
|
||||
test -f history/0.0.3/rc.1.md
|
||||
test -f deltas/0.0.3/rel.001.md
|
||||
test -f prompts/004-V0_0_4_START_PROMPT.md
|
||||
test ! -e history/0.0.3/rel.001.md
|
||||
|
||||
grep -Fx '<!-- version: 6 -->' README.md
|
||||
grep -Fx '<!-- version: 4 -->' ROADMAP.md
|
||||
grep -Fx '<!-- version: 5 -->' CHANGELOG.md
|
||||
grep -Fx '<!-- version: 4 -->' docs/000-README.md
|
||||
grep -Fx '<!-- version: 9 -->' docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md
|
||||
grep -F 'La release `0.0.3` fournit les premiers modèles Rust/Cargo' README.md
|
||||
grep -F 'plan historique des templates et audits `0.0.3`' README.md
|
||||
grep -F -- '- `(x) 0.0.3`' ROADMAP.md
|
||||
grep -Fx '## 0.0.3' CHANGELOG.md
|
||||
grep -F 'La gate opérateur de `rc.1` est `PASS`' docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md
|
||||
grep -F "La vérification de l'archive" docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md
|
||||
|
||||
python3 -B - <<'PY'
|
||||
from pathlib import Path
|
||||
import re
|
||||
|
||||
names = ['alpha.1', 'alpha.1.fix.1', 'alpha.2', 'alpha.3',
|
||||
'alpha.4', 'alpha.5', 'alpha.6', 'beta.1', 'rc.1']
|
||||
for name in names:
|
||||
history = Path(f'history/0.0.3/{name}.md')
|
||||
assert Path(f'deltas/0.0.3/{name}.md').is_file(), name
|
||||
assert re.search(r'## Statut\s+PASS\s', history.read_text(encoding='utf-8')), name
|
||||
assert {p.stem for p in Path('deltas/0.0.3').glob('*.md')} - \
|
||||
{p.stem for p in Path('history/0.0.3').glob('*.md')} == {'rel.001'}
|
||||
print(f'Stable history audit: clean ({len(names)} PASS histories, rel.001 pending)')
|
||||
PY
|
||||
|
||||
python3 -B scripts/audit_markdown_headers.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_tables.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_links.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
|
||||
git diff --check
|
||||
git add VERSION README.md ROADMAP.md CHANGELOG.md docs/000-README.md \
|
||||
docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md deltas/0.0.3/rel.001.md
|
||||
git diff --cached --check
|
||||
git status --short
|
||||
```
|
||||
|
||||
Scope attendu avant ajout du history : six `REPLACE` et un `ADD` exactement comme ci-dessus. Revue opérateur : confirmer que le scope RC ne change pas, que la présentation du dépôt, le changelog et la roadmap décrivent la même stable, que le prompt `004` reste conditionnel au rapport post-tag et que les snapshots historiques restent intacts. Les `15` tests et les cinq TOML validés en RC restent des preuves utilisables parce qu'aucun code, script, test ou template n'a changé dans cette promotion.
|
||||
|
||||
## Transition
|
||||
|
||||
### PASS
|
||||
|
||||
Rédiger et livrer séparément `history/0.0.3/rel.001.md` avec le résultat réellement observé ; l'appliquer et committer la stable. Ensuite seulement, créer et publier le tag canonique `v0.0.3`, télécharger son archive source depuis Gitea, vérifier cette archive et conserver séparément la preuve post-tag `publish.001`. Le texte manuel du prompt `004` n'est remis à l'opérateur qu'après vérification de l'archive et d'un rapport post-tag PASS réel.
|
||||
|
||||
### FAIL
|
||||
|
||||
Consigner le diagnostic dans le history de `rel.001`, ne pas tagger, puis corriger la clôture dans une tranche explicite avant publication.
|
||||
150
deltas/0.0.4/alpha.1.md
Normal file
150
deltas/0.0.4/alpha.1.md
Normal file
@@ -0,0 +1,150 @@
|
||||
<!-- file: deltas/0.0.4/alpha.1.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Delta 0.0.4-alpha.1 — audit de baseline et cadrage des skeletons
|
||||
|
||||
## Baseline et version
|
||||
|
||||
Baseline : archive source fournie `pgr-v0.0.3.zip`, déclarée téléchargée depuis le tag Gitea `v0.0.3`, accompagnée du rapport externe `pgr-0.0.3-publish.001-report.md` avec statut `PASS`.
|
||||
|
||||
SHA-256 vérifié de l'archive :
|
||||
|
||||
```text
|
||||
517fb46ada098fdc221ae53a8ff4b409b81e0244ec5ce4d0e6fca0c3da61b866
|
||||
```
|
||||
|
||||
Le rapport post-tag annonce le même hash et reste extérieur à la stable. L'archive sans `.git` est contrôlée par son contenu ; elle n'est pas utilisée comme preuve autonome du commit ou de la référence distante du tag.
|
||||
|
||||
Version avant application :
|
||||
|
||||
```text
|
||||
0.0.3
|
||||
```
|
||||
|
||||
Version après application :
|
||||
|
||||
```text
|
||||
0.0.4-alpha.1
|
||||
```
|
||||
|
||||
## Objet
|
||||
|
||||
Exécuter la gate de cadrage imposée par `prompts/004-V0_0_4_START_PROMPT.md` avant toute matérialisation importante : vérifier la stable, les règles `200` à `610`, la gouvernance documentaire, les templates et audits existants, la chaîne delta/history et les limites annoncées ; déterminer ensuite quels skeletons disposent déjà d'entrées suffisantes et planifier les tranches de `0.0.4`.
|
||||
|
||||
Le résultat détaillé de cette revue et le découpage prévisionnel sont consignés dans `docs/plans/004-V0_0_4_SKELETONS_PLAN.md`. Aucun défaut bloquant de `0.0.3` n'impose une correction rétroactive avant ce cadrage.
|
||||
|
||||
Le plan retient comme premières cibles la fondation composable d'un projet gouverné PGR puis un skeleton Rust/Cargo workspace. Java/Maven/Gradle, Android, Web, JNI, Tauri et les autres familles sans pièces suffisantes restent différés.
|
||||
|
||||
## Scope
|
||||
|
||||
REPLACE :
|
||||
|
||||
```text
|
||||
VERSION
|
||||
README.md
|
||||
docs/000-README.md
|
||||
```
|
||||
|
||||
ADD :
|
||||
|
||||
```text
|
||||
docs/plans/004-V0_0_4_SKELETONS_PLAN.md
|
||||
deltas/0.0.4/alpha.1.md
|
||||
```
|
||||
|
||||
DELETE : aucun.
|
||||
|
||||
L'archive delta contient uniquement ces cinq fichiers complets avec leurs chemins relatifs. Aucun history, skeleton concret, nouvelle règle, template technique, script ou manifest de suppression n'appartient à `alpha.1`.
|
||||
|
||||
`README.md` et `docs/000-README.md` sont des documents vivants : ils ajoutent le plan actif comme point d'entrée. `ROADMAP.md` annonce déjà `0.0.4` comme planifiée et `CHANGELOG.md` reste limité aux releases publiées ; ils n'ont pas besoin d'une modification cérémonielle dans cette tranche.
|
||||
|
||||
## Validation opérateur
|
||||
|
||||
Après application sur le commit stable `0.0.3`, depuis la racine du dépôt :
|
||||
|
||||
```bash
|
||||
test "$(cat VERSION)" = '0.0.4-alpha.1'
|
||||
test -f docs/plans/004-V0_0_4_SKELETONS_PLAN.md
|
||||
test -f deltas/0.0.4/alpha.1.md
|
||||
test ! -e history/0.0.4/alpha.1.md
|
||||
|
||||
grep -Fx '<!-- version: 7 -->' README.md
|
||||
grep -Fx '<!-- version: 5 -->' docs/000-README.md
|
||||
grep -F '004-V0_0_4_SKELETONS_PLAN.md' README.md
|
||||
grep -F '004-V0_0_4_SKELETONS_PLAN.md' docs/000-README.md
|
||||
|
||||
python3 -B -m unittest discover -s tests -v
|
||||
|
||||
python3 -B scripts/audit_markdown_headers.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_tables.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_links.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
|
||||
python3 -B - <<'PY'
|
||||
from pathlib import Path
|
||||
import re
|
||||
import tomllib
|
||||
|
||||
for path in (
|
||||
Path('templates/rust-cargo/rustfmt.toml'),
|
||||
Path('templates/rust-cargo/clippy.toml'),
|
||||
Path('templates/rust-cargo/.cargo/config.toml'),
|
||||
Path('templates/rust-cargo/Cargo.toml'),
|
||||
Path('templates/rust-cargo/crates/project-core-lib/Cargo.toml'),
|
||||
):
|
||||
with path.open('rb') as stream:
|
||||
tomllib.load(stream)
|
||||
|
||||
expected_counts = {'0.0.1': 12, '0.0.2': 12, '0.0.3': 10}
|
||||
for release, expected in expected_counts.items():
|
||||
deltas = {path.name for path in Path('deltas', release).glob('*.md')}
|
||||
histories = {path.name for path in Path('history', release).glob('*.md')}
|
||||
assert len(deltas) == expected, (release, len(deltas))
|
||||
assert deltas == histories, (release, sorted(deltas ^ histories))
|
||||
|
||||
for path in Path('history/0.0.3').glob('*.md'):
|
||||
text = path.read_text(encoding='utf-8')
|
||||
assert re.search(r'## Statut\s+PASS\s', text), path
|
||||
|
||||
for path in (
|
||||
Path('scripts/audit_rust_blank_lines.py'),
|
||||
Path('scripts/audit_rust_const_blocks.py'),
|
||||
Path('scripts/_rust_audit_common.py'),
|
||||
):
|
||||
assert path.is_file(), path
|
||||
|
||||
print('Baseline structural audit: clean (34 prior delta/history pairs, 10/10 histories 0.0.3 PASS, 5 TOML parsed)')
|
||||
PY
|
||||
|
||||
git diff --check
|
||||
git add VERSION README.md docs/000-README.md \
|
||||
docs/plans/004-V0_0_4_SKELETONS_PLAN.md deltas/0.0.4/alpha.1.md
|
||||
git diff --cached --check
|
||||
git status --short
|
||||
```
|
||||
|
||||
Le scope indexé attendu avant ajout du history est :
|
||||
|
||||
```text
|
||||
M README.md
|
||||
M VERSION
|
||||
A deltas/0.0.4/alpha.1.md
|
||||
M docs/000-README.md
|
||||
A docs/plans/004-V0_0_4_SKELETONS_PLAN.md
|
||||
```
|
||||
|
||||
La vérification du ZIP et du rapport post-tag appartient à l'intake de cette tranche et a été utilisée pour préparer le plan. L'opérateur confirme également que les fichiers fournis sont bien ceux téléchargés pour la reprise, que le hash de l'archive concorde avec le rapport, que le rapport est `PASS` et qu'il n'est pas copié dans le dépôt.
|
||||
|
||||
La revue opérateur doit confirmer que le plan ne transforme pas une prévision en règle active, que les valeurs Rust/Cargo d'exemple restent adaptables et que les domaines différés ne sont pas matérialisés par anticipation.
|
||||
|
||||
## Transition
|
||||
|
||||
### PASS
|
||||
|
||||
Rédiger et livrer séparément `history/0.0.4/alpha.1.md` avec les résultats réellement observés ; l'appliquer et committer la tranche. Préparer seulement ensuite `0.0.4-alpha.2` pour le contrat de composition des skeletons.
|
||||
|
||||
### FAIL
|
||||
|
||||
Consigner le résultat réel dans le history de `alpha.1`, puis corriger le cadrage dans `0.0.4-alpha.1.fix.1` ou produire un REPLAN motivé. Aucun contenu de `alpha.2` ne doit être absorbé silencieusement dans un fix.
|
||||
189
deltas/0.0.4/alpha.2.md
Normal file
189
deltas/0.0.4/alpha.2.md
Normal file
@@ -0,0 +1,189 @@
|
||||
<!-- file: deltas/0.0.4/alpha.2.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Delta 0.0.4-alpha.2 — contrat de composition des skeletons
|
||||
|
||||
## Baseline et version
|
||||
|
||||
Baseline : commit opérateur `bf306da` (`0.0.4-alpha.1`) après application de `history/0.0.4/alpha.1.md` avec statut `PASS`, puis push sur `origin/master`.
|
||||
|
||||
La baseline attendue contient donc le delta, le plan et le history de `alpha.1`, sans contenu `alpha.2` préalable.
|
||||
|
||||
Version avant application :
|
||||
|
||||
```text
|
||||
0.0.4-alpha.1
|
||||
```
|
||||
|
||||
Version après application :
|
||||
|
||||
```text
|
||||
0.0.4-alpha.2
|
||||
```
|
||||
|
||||
## Objet
|
||||
|
||||
Matérialiser le contrat transversal annoncé par le plan `0.0.4` sans anticiper les skeletons concrets des tranches suivantes.
|
||||
|
||||
La tranche crée `docs/rules/220-SKELETONS.md` comme propriétaire normatif unique de l'applicabilité, de la sélection, de la composition, des décisions projet, des overrides et de la validation initiale des skeleton specifications. Elle active également `docs/skeletons/` avec un index réel décrivant la responsabilité de la collection.
|
||||
|
||||
Les index normatifs et documentaires ainsi que les deux documents d'architecture concernés sont réconciliés avec ce nouveau propriétaire. Le modèle des profils reste possédé par `docs/architecture/003-RULE_PROFILE_MODEL.md` ; le nouveau document `220` le référence au lieu de dupliquer sa hiérarchie.
|
||||
|
||||
Aucun skeleton de fondation, Rust/Cargo, Java/Android, Web, JNI, Tauri ou autre domaine technologique n'appartient à cette tranche.
|
||||
|
||||
## Scope
|
||||
|
||||
REPLACE :
|
||||
|
||||
```text
|
||||
VERSION
|
||||
README.md
|
||||
RULES.md
|
||||
docs/000-README.md
|
||||
docs/architecture/002-GOVERNANCE_ARCHITECTURE.md
|
||||
docs/architecture/003-RULE_PROFILE_MODEL.md
|
||||
docs/rules/000-README.md
|
||||
```
|
||||
|
||||
ADD :
|
||||
|
||||
```text
|
||||
docs/rules/220-SKELETONS.md
|
||||
docs/skeletons/000-README.md
|
||||
deltas/0.0.4/alpha.2.md
|
||||
```
|
||||
|
||||
DELETE : aucun.
|
||||
|
||||
L'archive delta contient uniquement ces dix fichiers complets avec leurs chemins relatifs. Elle ne contient pas `history/0.0.4/alpha.1.md`, déjà committé dans la baseline, ni `history/0.0.4/alpha.2.md`, qui sera produit après la gate opérateur.
|
||||
|
||||
Le plan `docs/plans/004-V0_0_4_SKELETONS_PLAN.md` n'est pas modifié : la tranche réalise son étape `alpha.2` sans replan ni changement substantiel de trajectoire.
|
||||
|
||||
## Décisions normatives matérialisées
|
||||
|
||||
Le contrat commun impose notamment qu'un skeleton :
|
||||
|
||||
- déclare son objectif et son applicabilité à partir de faits du projet ;
|
||||
- identifie les règles, profils, templates, fichiers, décisions, options, overrides, ordre utile, validation et hors-scope nécessaires ;
|
||||
- référence les owners normatifs existants au lieu de devenir propriétaire implicite de leurs règles ;
|
||||
- conserve les projets instanciés autonomes et sans dépendance runtime/build vers PGR ;
|
||||
- distingue les valeurs obligatoires, exemples, recommandations et choix libres lorsqu'une confusion serait possible ;
|
||||
- n'applique pas tous les profils PGR par défaut ;
|
||||
- n'utilise pas l'ordre de composition comme priorité normative implicite ;
|
||||
- ne crée pas de skeleton composite sans interaction réelle à posséder ;
|
||||
- utilise une validation proportionnée au contenu réellement matérialisé.
|
||||
|
||||
La collection `docs/skeletons/` reste vide de specification concrète dans `alpha.2` hormis son index. Sa création n'est pas un placeholder : l'index documente le contrat de collection réellement activé par le nouveau owner normatif.
|
||||
|
||||
## Validation opérateur
|
||||
|
||||
Après application sur le commit `bf306da`, depuis la racine du dépôt :
|
||||
|
||||
```bash
|
||||
test "$(cat VERSION)" = '0.0.4-alpha.2'
|
||||
test -f history/0.0.4/alpha.1.md
|
||||
test -f deltas/0.0.4/alpha.2.md
|
||||
test -f docs/rules/220-SKELETONS.md
|
||||
test -f docs/skeletons/000-README.md
|
||||
test ! -e history/0.0.4/alpha.2.md
|
||||
|
||||
test ! -e docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md
|
||||
test ! -e docs/skeletons/002-RUST_CARGO_WORKSPACE.md
|
||||
|
||||
grep -Fx '<!-- version: 8 -->' README.md
|
||||
grep -Fx '<!-- version: 10 -->' RULES.md
|
||||
grep -Fx '<!-- version: 6 -->' docs/000-README.md
|
||||
grep -Fx '<!-- version: 3 -->' docs/architecture/002-GOVERNANCE_ARCHITECTURE.md
|
||||
grep -Fx '<!-- version: 3 -->' docs/architecture/003-RULE_PROFILE_MODEL.md
|
||||
grep -Fx '<!-- version: 11 -->' docs/rules/000-README.md
|
||||
grep -Fx '<!-- version: 1 -->' docs/rules/220-SKELETONS.md
|
||||
grep -Fx '<!-- version: 1 -->' docs/skeletons/000-README.md
|
||||
|
||||
grep -F 'docs/rules/220-SKELETONS.md' RULES.md
|
||||
grep -F '220-SKELETONS.md' docs/rules/000-README.md
|
||||
grep -F 'skeletons/' docs/000-README.md
|
||||
grep -F '220-SKELETONS.md' docs/architecture/002-GOVERNANCE_ARCHITECTURE.md
|
||||
grep -F '220-SKELETONS.md' docs/architecture/003-RULE_PROFILE_MODEL.md
|
||||
|
||||
python3 -B -m unittest discover -s tests -v
|
||||
|
||||
python3 -B scripts/audit_markdown_headers.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_tables.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_links.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
|
||||
python3 -B - <<'PY'
|
||||
from pathlib import Path
|
||||
import re
|
||||
|
||||
expected_counts = {'0.0.1': 12, '0.0.2': 12, '0.0.3': 10, '0.0.4': 1}
|
||||
for release, expected in expected_counts.items():
|
||||
histories = {path.name for path in Path('history', release).glob('*.md')}
|
||||
if release == '0.0.4':
|
||||
assert histories == {'alpha.1.md'}, histories
|
||||
continue
|
||||
deltas = {path.name for path in Path('deltas', release).glob('*.md')}
|
||||
assert len(deltas) == expected, (release, len(deltas))
|
||||
assert deltas == histories, (release, sorted(deltas ^ histories))
|
||||
|
||||
text = Path('history/0.0.4/alpha.1.md').read_text(encoding='utf-8')
|
||||
assert re.search(r'## Statut\s+PASS\s', text)
|
||||
|
||||
assert sorted(path.name for path in Path('docs/skeletons').glob('*.md')) == ['000-README.md']
|
||||
|
||||
rule = Path('docs/rules/220-SKELETONS.md').read_text(encoding='utf-8')
|
||||
for phrase in (
|
||||
'## Applicabilité',
|
||||
'## Contenu minimal d\'une specification',
|
||||
'## Sélection des règles et profils',
|
||||
'## Templates et artefacts techniques',
|
||||
'## Décisions propres au projet',
|
||||
'## Composition de plusieurs skeletons',
|
||||
'## Overrides et exceptions',
|
||||
'## Validation de l\'instanciation',
|
||||
):
|
||||
assert phrase in rule, phrase
|
||||
|
||||
print('Skeleton contract audit: clean (alpha.1 PASS baseline, alpha.2 contract/index only)')
|
||||
PY
|
||||
|
||||
git diff --check
|
||||
git add VERSION README.md RULES.md docs/000-README.md \
|
||||
docs/architecture/002-GOVERNANCE_ARCHITECTURE.md \
|
||||
docs/architecture/003-RULE_PROFILE_MODEL.md \
|
||||
docs/rules/000-README.md docs/rules/220-SKELETONS.md \
|
||||
docs/skeletons/000-README.md deltas/0.0.4/alpha.2.md
|
||||
git diff --cached --check
|
||||
git status --short
|
||||
```
|
||||
|
||||
Le scope indexé attendu avant ajout du history est :
|
||||
|
||||
```text
|
||||
M README.md
|
||||
M RULES.md
|
||||
M VERSION
|
||||
A deltas/0.0.4/alpha.2.md
|
||||
M docs/000-README.md
|
||||
M docs/architecture/002-GOVERNANCE_ARCHITECTURE.md
|
||||
M docs/architecture/003-RULE_PROFILE_MODEL.md
|
||||
M docs/rules/000-README.md
|
||||
A docs/rules/220-SKELETONS.md
|
||||
A docs/skeletons/000-README.md
|
||||
```
|
||||
|
||||
La revue opérateur doit également confirmer que `220-SKELETONS.md` reste transversal, ne duplique pas les règles de profils ou de validation et ne matérialise aucun choix technologique futur par anticipation.
|
||||
|
||||
## Transition
|
||||
|
||||
### PASS
|
||||
|
||||
Rédiger et livrer `history/0.0.4/alpha.2.md` avec les résultats réellement observés ; l'appliquer puis committer la tranche. La tranche suivante est `0.0.4-alpha.3`, consacrée à la première skeleton specification de fondation d'un projet gouverné.
|
||||
|
||||
Le history `alpha.2` et le delta `alpha.3` MAY être livrés dans la même réponse après la gate `PASS`, tout en restant deux archives séparées. Le delta `alpha.3` MUST NOT être appliqué avant le commit complet de `alpha.2`.
|
||||
|
||||
### FAIL
|
||||
|
||||
Consigner le résultat réel dans le history de `alpha.2`, puis corriger le contrat dans `0.0.4-alpha.2.fix.1` ou produire un REPLAN motivé. Aucun skeleton concret de `alpha.3` ne doit être absorbé silencieusement dans un fix.
|
||||
167
deltas/0.0.4/alpha.3.md
Normal file
167
deltas/0.0.4/alpha.3.md
Normal file
@@ -0,0 +1,167 @@
|
||||
<!-- file: deltas/0.0.4/alpha.3.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Delta 0.0.4-alpha.3 — fondation de projet gouverné
|
||||
|
||||
## Baseline et version
|
||||
|
||||
Baseline attendue : commit opérateur de `0.0.4-alpha.2`, réalisé après application de `history/0.0.4/alpha.2.md` avec statut `PASS`.
|
||||
|
||||
Le hash de ce commit n'est volontairement pas anticipé : le history `alpha.2` et le présent delta peuvent être livrés dans le même échange, mais restent deux archives séparées et le delta `alpha.3` MUST NOT être appliqué avant le commit de `alpha.2`.
|
||||
|
||||
Version avant application :
|
||||
|
||||
```text
|
||||
0.0.4-alpha.2
|
||||
```
|
||||
|
||||
Version après application :
|
||||
|
||||
```text
|
||||
0.0.4-alpha.3
|
||||
```
|
||||
|
||||
## Objet
|
||||
|
||||
Matérialiser la première skeleton specification concrète prévue par le plan `0.0.4` : une fondation composable de gouvernance locale pour un projet qui adopte PGR, sans sélectionner de langage, plateforme, framework ou architecture applicative.
|
||||
|
||||
La specification doit rendre actionnables les responsabilités générales déjà possédées par `200`, `210`, `300` et `400` : version courante, point d'entrée normatif, documentation minimale, workflow réellement retenu, décisions destinataire, overrides et validation initiale proportionnée.
|
||||
|
||||
Elle ne crée aucun template générique, ne copie pas la structure complète du dépôt PGR et ne précrée aucun répertoire documentaire ou workflow sans contenu réel.
|
||||
|
||||
## Scope
|
||||
|
||||
REPLACE :
|
||||
|
||||
```text
|
||||
VERSION
|
||||
README.md
|
||||
docs/000-README.md
|
||||
docs/skeletons/000-README.md
|
||||
```
|
||||
|
||||
ADD :
|
||||
|
||||
```text
|
||||
docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md
|
||||
deltas/0.0.4/alpha.3.md
|
||||
```
|
||||
|
||||
DELETE : aucun.
|
||||
|
||||
L'archive delta contient uniquement ces six fichiers complets avec leurs chemins relatifs. Elle ne contient ni `history/0.0.4/alpha.2.md`, livré séparément pour clôturer la tranche précédente, ni `history/0.0.4/alpha.3.md`, qui sera produit après la gate opérateur.
|
||||
|
||||
Le plan `docs/plans/004-V0_0_4_SKELETONS_PLAN.md` et la règle `docs/rules/220-SKELETONS.md` ne sont pas modifiés : cette tranche exécute leur trajectoire et leur contrat sans REPLAN.
|
||||
|
||||
## Contenu matérialisé
|
||||
|
||||
`docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md` :
|
||||
|
||||
- déclare son objectif, son applicabilité et son hors-scope ;
|
||||
- sélectionne les owners généraux `200`, `210`, `300` et `400` sans sélectionner de profil technologique ;
|
||||
- distingue le rôle de `220` comme contrat d'instanciation de celui des règles à reprendre localement ;
|
||||
- impose de résoudre les décisions destinataire avant de présenter l'instanciation comme terminée ;
|
||||
- rend le point d'entrée normatif local et la version courante explicites ;
|
||||
- rend `docs/`, `ROADMAP.md`, `CHANGELOG.md` et les collections spécialisées conditionnels à un contenu réel ;
|
||||
- conserve `deltas/`, `history/`, `prompts/`, `handoffs/` et `manifests/` comme répertoires créés à la demande ;
|
||||
- fournit une validation initiale proportionnée sans imposer de copier les scripts PGR ;
|
||||
- définit l'ordre de composition attendu pour les futures spécialisations ;
|
||||
- exclut explicitement architecture applicative, toolchain, CI/CD universel, branching universel et migration rétroactive.
|
||||
|
||||
Aucun template générique n'est nécessaire pour rendre cette specification actionnable : elle décrit les owners, décisions, fichiers conditionnels et preuves à matérialiser sans prétendre générer leur contenu automatiquement. Le point de REPLAN du plan n'est donc pas déclenché par cette tranche.
|
||||
|
||||
## Validation opérateur
|
||||
|
||||
Après avoir appliqué `history/0.0.4/alpha.2.md`, committé `0.0.4-alpha.2`, puis appliqué le présent delta, depuis la racine du dépôt :
|
||||
|
||||
```bash
|
||||
test "$(cat VERSION)" = '0.0.4-alpha.3'
|
||||
test -f history/0.0.4/alpha.2.md
|
||||
test -f deltas/0.0.4/alpha.3.md
|
||||
test -f docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md
|
||||
test ! -e history/0.0.4/alpha.3.md
|
||||
test ! -e docs/skeletons/002-RUST_CARGO_WORKSPACE.md
|
||||
|
||||
grep -Fx '<!-- version: 9 -->' README.md
|
||||
grep -Fx '<!-- version: 7 -->' docs/000-README.md
|
||||
grep -Fx '<!-- version: 2 -->' docs/skeletons/000-README.md
|
||||
grep -Fx '<!-- version: 1 -->' docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md
|
||||
|
||||
grep -F '001-PROJECT_GOVERNANCE_FOUNDATION.md' README.md
|
||||
grep -F '001-PROJECT_GOVERNANCE_FOUNDATION.md' docs/000-README.md
|
||||
grep -F '001-PROJECT_GOVERNANCE_FOUNDATION.md' docs/skeletons/000-README.md
|
||||
|
||||
python3 -B -m unittest discover -s tests -v
|
||||
|
||||
python3 -B scripts/audit_markdown_headers.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_tables.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_links.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
|
||||
python3 -B - <<'PY'
|
||||
from pathlib import Path
|
||||
import re
|
||||
|
||||
histories = {path.name for path in Path('history/0.0.4').glob('*.md')}
|
||||
assert histories == {'alpha.1.md', 'alpha.2.md'}, histories
|
||||
for name in sorted(histories):
|
||||
text = Path('history/0.0.4', name).read_text(encoding='utf-8')
|
||||
assert re.search(r'## Statut\s+PASS\s', text), name
|
||||
|
||||
skeletons = sorted(path.name for path in Path('docs/skeletons').glob('*.md'))
|
||||
assert skeletons == ['000-README.md', '001-PROJECT_GOVERNANCE_FOUNDATION.md'], skeletons
|
||||
|
||||
text = Path('docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md').read_text(encoding='utf-8')
|
||||
for phrase in (
|
||||
'## Applicabilité',
|
||||
'## Owners sélectionnés',
|
||||
'## Décisions destinataire avant matérialisation',
|
||||
'## Baseline locale à matérialiser',
|
||||
'### Version',
|
||||
'### Documentation minimale',
|
||||
'### Workflow retenu',
|
||||
'### Validation initiale',
|
||||
'## Ordre de composition',
|
||||
'## Overrides et exceptions',
|
||||
'## Hors scope',
|
||||
):
|
||||
assert phrase in text, phrase
|
||||
|
||||
for owner in ('200-GOVERNANCE.md', '210-WORKFLOW.md', '300-DOCUMENTATION.md', '400-VALIDATION.md'):
|
||||
assert owner in text, owner
|
||||
|
||||
for forbidden in (
|
||||
'templates/generic',
|
||||
'docs/skeletons/002-RUST_CARGO_WORKSPACE.md',
|
||||
):
|
||||
assert forbidden not in text, forbidden
|
||||
|
||||
print('Governance foundation audit: clean (alpha.1/alpha.2 PASS baseline, one concrete non-technological skeleton)')
|
||||
PY
|
||||
|
||||
git diff --check
|
||||
git add VERSION README.md docs/000-README.md \
|
||||
docs/skeletons/000-README.md \
|
||||
docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md \
|
||||
deltas/0.0.4/alpha.3.md
|
||||
git diff --cached --check
|
||||
git status --short
|
||||
```
|
||||
|
||||
## Revue opérateur
|
||||
|
||||
En complément des commandes, vérifier que :
|
||||
|
||||
- la fondation reste une procedure composable et non un template ou générateur implicite ;
|
||||
- aucun document ou répertoire n'est rendu obligatoire uniquement pour reproduire le layout PGR ;
|
||||
- aucune règle technologique `500+` ou `600+` n'est sélectionnée par défaut ;
|
||||
- les décisions destinataire restent explicites et aucune valeur d'exemple n'est universalisée ;
|
||||
- l'ordre de composition permet au futur skeleton Rust/Cargo d'ajouter ses responsabilités sans dupliquer les owners généraux.
|
||||
|
||||
## Transition
|
||||
|
||||
PASS : produire `history/0.0.4/alpha.3.md`, l'appliquer puis committer `0.0.4-alpha.3`. La tranche suivante prévue par le plan est `0.0.4-alpha.4`, consacrée au skeleton Rust/Cargo workspace et à sa validation d'instanciation.
|
||||
|
||||
FAIL : rester dans le scope de `alpha.3` via `alpha.3.fix.1` sauf si l'échec démontre qu'un template générique ou une nouvelle décision normative est indispensable, auquel cas déclencher le REPLAN prévu par le plan.
|
||||
231
deltas/0.0.4/alpha.4.fix.1.md
Normal file
231
deltas/0.0.4/alpha.4.fix.1.md
Normal file
@@ -0,0 +1,231 @@
|
||||
<!-- file: deltas/0.0.4/alpha.4.fix.1.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Delta 0.0.4-alpha.4.fix.1 — correction du smoke Rust/Cargo
|
||||
|
||||
## Baseline
|
||||
|
||||
Version attendue avant application :
|
||||
|
||||
```text
|
||||
0.0.4-alpha.4
|
||||
```
|
||||
|
||||
Le history `history/0.0.4/alpha.4.md` avec statut `FAIL` MUST avoir été appliqué et committé avant ce correctif.
|
||||
|
||||
Version après application :
|
||||
|
||||
```text
|
||||
0.0.4-alpha.4.fix.1
|
||||
```
|
||||
|
||||
## Objet
|
||||
|
||||
Corriger uniquement la procédure de smoke Rust/Cargo qui a échoué pendant la gate opérateur de `alpha.4`.
|
||||
|
||||
Le workspace temporaire était fonctionnel et les commandes Cargo ont réussi, mais l'adaptation de `.cargo/config.toml` remplaçait les chemins contenant `project-name` sans adapter le commentaire de guidance qui contenait encore ce placeholder. L'assertion d'absence de placeholders échouait donc avant le smoke Cargo.
|
||||
|
||||
Ce fix adapte explicitement ce commentaire dans la fixture temporaire avant de vérifier l'absence de placeholders.
|
||||
|
||||
Aucune règle, aucun skeleton, aucun template et aucun script PGR n'est ajouté ou modifié.
|
||||
|
||||
## Scope
|
||||
|
||||
REPLACE :
|
||||
|
||||
```text
|
||||
VERSION
|
||||
```
|
||||
|
||||
ADD :
|
||||
|
||||
```text
|
||||
deltas/0.0.4/alpha.4.fix.1.md
|
||||
```
|
||||
|
||||
DELETE : aucun.
|
||||
|
||||
Les snapshots suivants restent inchangés :
|
||||
|
||||
```text
|
||||
deltas/0.0.4/alpha.4.md
|
||||
docs/skeletons/002-RUST_CARGO_WORKSPACE.md
|
||||
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 opérateur
|
||||
|
||||
```bash
|
||||
test "$(cat VERSION)" = '0.0.4-alpha.4.fix.1'
|
||||
test -f history/0.0.4/alpha.4.md
|
||||
test -f deltas/0.0.4/alpha.4.md
|
||||
test -f deltas/0.0.4/alpha.4.fix.1.md
|
||||
test -f docs/skeletons/002-RUST_CARGO_WORKSPACE.md
|
||||
test ! -e history/0.0.4/alpha.4.fix.1.md
|
||||
|
||||
grep -A2 '^## Statut$' history/0.0.4/alpha.4.md | grep -Fx 'FAIL'
|
||||
|
||||
python3 -B -m unittest discover -s tests -v
|
||||
|
||||
python3 -B scripts/audit_markdown_headers.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_tables.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_links.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
|
||||
python3 -B - <<'PY'
|
||||
from pathlib import Path
|
||||
import re
|
||||
import tomllib
|
||||
|
||||
expected = {
|
||||
'alpha.1.md': 'PASS',
|
||||
'alpha.2.md': 'PASS',
|
||||
'alpha.3.md': 'PASS',
|
||||
'alpha.4.md': 'FAIL',
|
||||
}
|
||||
histories = {path.name for path in Path('history/0.0.4').glob('*.md')}
|
||||
assert histories == set(expected), histories
|
||||
for name, status in expected.items():
|
||||
text = Path('history/0.0.4', name).read_text(encoding='utf-8')
|
||||
assert re.search(rf'## Statut\s+{status}\s', text), (name, status)
|
||||
|
||||
skeletons = sorted(path.name for path in Path('docs/skeletons').glob('*.md'))
|
||||
assert skeletons == [
|
||||
'000-README.md',
|
||||
'001-PROJECT_GOVERNANCE_FOUNDATION.md',
|
||||
'002-RUST_CARGO_WORKSPACE.md',
|
||||
], skeletons
|
||||
|
||||
for path in (
|
||||
Path('templates/rust-cargo/rustfmt.toml'),
|
||||
Path('templates/rust-cargo/clippy.toml'),
|
||||
Path('templates/rust-cargo/.cargo/config.toml'),
|
||||
Path('templates/rust-cargo/Cargo.toml'),
|
||||
Path('templates/rust-cargo/crates/project-core-lib/Cargo.toml'),
|
||||
):
|
||||
with path.open('rb') as stream:
|
||||
tomllib.load(stream)
|
||||
|
||||
print('Rust/Cargo fix audit: clean (alpha.4 FAIL recorded, skeleton/templates unchanged)')
|
||||
PY
|
||||
|
||||
command -v cargo
|
||||
command -v rustfmt
|
||||
cargo --version
|
||||
rustc --version
|
||||
rustfmt --version
|
||||
cargo clippy --version
|
||||
|
||||
tmp="$(mktemp -d)"
|
||||
trap 'rm -rf "$tmp"' EXIT
|
||||
mkdir -p "$tmp/.cargo" "$tmp/crates/smoke-core-lib/src"
|
||||
cp templates/rust-cargo/Cargo.toml "$tmp/Cargo.toml"
|
||||
cp templates/rust-cargo/rustfmt.toml "$tmp/rustfmt.toml"
|
||||
cp templates/rust-cargo/clippy.toml "$tmp/clippy.toml"
|
||||
cp templates/rust-cargo/.cargo/config.toml "$tmp/.cargo/config.toml"
|
||||
cp templates/rust-cargo/crates/project-core-lib/Cargo.toml "$tmp/crates/smoke-core-lib/Cargo.toml"
|
||||
printf '1.2.3\n' > "$tmp/VERSION"
|
||||
|
||||
python3 -B - "$tmp" <<'PY'
|
||||
from pathlib import Path
|
||||
import sys
|
||||
|
||||
root = Path(sys.argv[1])
|
||||
|
||||
replacements = {
|
||||
root / 'Cargo.toml': (
|
||||
('# file: templates/rust-cargo/Cargo.toml', '# file: Cargo.toml'),
|
||||
('members = ["crates/project-core-lib"]', 'members = ["crates/smoke-core-lib"]'),
|
||||
('version = "0.1.0"', 'version = "1.2.3"'),
|
||||
),
|
||||
root / 'rustfmt.toml': (
|
||||
('# file: templates/rust-cargo/rustfmt.toml', '# file: rustfmt.toml'),
|
||||
),
|
||||
root / 'clippy.toml': (
|
||||
('# file: templates/rust-cargo/clippy.toml', '# file: clippy.toml'),
|
||||
),
|
||||
root / '.cargo/config.toml': (
|
||||
('# file: templates/rust-cargo/.cargo/config.toml', '# file: .cargo/config.toml'),
|
||||
(
|
||||
'# Replace project-name with a unique name before using this configuration.',
|
||||
'# Smoke fixture: project-specific build directory already selected.',
|
||||
),
|
||||
('../builds/project-name/target', 'target-smoke'),
|
||||
),
|
||||
root / 'crates/smoke-core-lib/Cargo.toml': (
|
||||
(
|
||||
'# file: templates/rust-cargo/crates/project-core-lib/Cargo.toml',
|
||||
'# file: crates/smoke-core-lib/Cargo.toml',
|
||||
),
|
||||
('name = "project-core-lib"', 'name = "smoke-core-lib"'),
|
||||
),
|
||||
}
|
||||
|
||||
for path, pairs in replacements.items():
|
||||
text = path.read_text(encoding='utf-8')
|
||||
for old, new in pairs:
|
||||
assert old in text, (path, old)
|
||||
text = text.replace(old, new)
|
||||
path.write_text(text, encoding='utf-8')
|
||||
|
||||
for path in root.rglob('*'):
|
||||
if path.is_file() and path.name != 'Cargo.lock':
|
||||
text = path.read_text(encoding='utf-8')
|
||||
assert 'project-name' not in text, path
|
||||
assert 'project-core-lib' not in text, path
|
||||
|
||||
print('Temporary Rust/Cargo template adaptation: clean')
|
||||
PY
|
||||
|
||||
cat > "$tmp/crates/smoke-core-lib/src/lib.rs" <<'RS'
|
||||
//! Minimal crate used to validate the PGR Rust/Cargo templates.
|
||||
|
||||
/// Returns the deterministic smoke value.
|
||||
pub fn smoke_value() -> u8 {
|
||||
return 1;
|
||||
}
|
||||
RS
|
||||
|
||||
(
|
||||
cd "$tmp"
|
||||
cargo metadata --format-version 1 --no-deps >/dev/null
|
||||
cargo fmt --all -- --check
|
||||
cargo check --workspace
|
||||
cargo clippy --workspace --all-targets --all-features -- -D warnings
|
||||
)
|
||||
|
||||
rm -rf "$tmp"
|
||||
trap - EXIT
|
||||
|
||||
git diff --check
|
||||
|
||||
git add VERSION deltas/0.0.4/alpha.4.fix.1.md
|
||||
|
||||
git diff --cached --check
|
||||
git status --short
|
||||
```
|
||||
|
||||
La sortie Git attendue avant ajout du history du fix est exactement :
|
||||
|
||||
```text
|
||||
M VERSION
|
||||
A deltas/0.0.4/alpha.4.fix.1.md
|
||||
```
|
||||
|
||||
## Transition
|
||||
|
||||
### PASS
|
||||
|
||||
Créer et appliquer séparément `history/0.0.4/alpha.4.fix.1.md`, committer et pousser le correctif, puis reprendre le plan `0.0.4` à la tranche suivante prévue.
|
||||
|
||||
Le history `alpha.4.fix.1` et le delta de la tranche suivante MAY être livrés ensemble sous forme de deux archives séparées après observation de la gate opérateur.
|
||||
|
||||
### FAIL
|
||||
|
||||
Rester dans `0.0.4-alpha.4.fix.M`. Le scope MUST rester limité au smoke Rust/Cargo de cette tranche tant qu'aucun défaut plus large ne justifie un REPLAN.
|
||||
277
deltas/0.0.4/alpha.4.md
Normal file
277
deltas/0.0.4/alpha.4.md
Normal file
@@ -0,0 +1,277 @@
|
||||
<!-- file: deltas/0.0.4/alpha.4.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Delta 0.0.4-alpha.4 — skeleton Rust/Cargo workspace
|
||||
|
||||
## Baseline et version
|
||||
|
||||
Baseline attendue : commit opérateur de `0.0.4-alpha.3`, réalisé après application de `history/0.0.4/alpha.3.md` avec statut `PASS`.
|
||||
|
||||
Le hash de ce commit n'est volontairement pas anticipé : le history `alpha.3` et le présent delta peuvent être livrés dans le même échange, mais restent deux archives séparées et le delta `alpha.4` MUST NOT être appliqué avant le commit de `alpha.3`.
|
||||
|
||||
Version avant application :
|
||||
|
||||
```text
|
||||
0.0.4-alpha.3
|
||||
```
|
||||
|
||||
Version après application :
|
||||
|
||||
```text
|
||||
0.0.4-alpha.4
|
||||
```
|
||||
|
||||
## Objet
|
||||
|
||||
Matérialiser la première specialization technologique prévue par le plan `0.0.4` : un skeleton Rust/Cargo workspace composable avec la fondation `001`, les profils `500 + 510`, les cinq templates Rust/Cargo existants et leurs guides d'adaptation.
|
||||
|
||||
La specification doit rendre explicites les décisions destinataire avant copie, la relation entre `VERSION` et la version Cargo, les membres du workspace, l'édition/toolchain, les métadonnées, les dépendances/features, `Cargo.lock`, les lints, les paramètres Rustfmt/Clippy, les artefacts Cargo et la sélection éventuelle des audits de style Rust.
|
||||
|
||||
Aucun template Rust/Cargo ni owner normatif n'est modifié dans cette tranche : la spécialisation doit composer les pièces déjà éprouvées sans universaliser leurs valeurs d'exemple.
|
||||
|
||||
## Scope
|
||||
|
||||
REPLACE :
|
||||
|
||||
```text
|
||||
VERSION
|
||||
README.md
|
||||
docs/000-README.md
|
||||
docs/skeletons/000-README.md
|
||||
```
|
||||
|
||||
ADD :
|
||||
|
||||
```text
|
||||
docs/skeletons/002-RUST_CARGO_WORKSPACE.md
|
||||
deltas/0.0.4/alpha.4.md
|
||||
```
|
||||
|
||||
DELETE : aucun.
|
||||
|
||||
L'archive delta contient uniquement ces six fichiers complets avec leurs chemins relatifs. Elle ne contient ni `history/0.0.4/alpha.3.md`, livré séparément pour clôturer la tranche précédente, ni `history/0.0.4/alpha.4.md`, qui sera produit après la gate opérateur.
|
||||
|
||||
Les documents suivants restent inchangés :
|
||||
|
||||
```text
|
||||
docs/rules/220-SKELETONS.md
|
||||
docs/rules/500-LANGUAGES.md
|
||||
docs/rules/510-RUST_CARGO.md
|
||||
docs/templates/001-RUST_CARGO_TOOLING.md
|
||||
docs/templates/002-CARGO_MANIFESTS.md
|
||||
docs/validation/002-RUST_STYLE_AUDITS.md
|
||||
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
|
||||
```
|
||||
|
||||
La tranche exécute donc le plan sans REPLAN et sans déplacer les propriétaires existants.
|
||||
|
||||
## Contenu matérialisé
|
||||
|
||||
`docs/skeletons/002-RUST_CARGO_WORKSPACE.md` :
|
||||
|
||||
- se compose explicitement avec `001-PROJECT_GOVERNANCE_FOUNDATION.md` ;
|
||||
- sélectionne `500-LANGUAGES.md` et `510-RUST_CARGO.md` sans absorber leurs règles ;
|
||||
- référence les guides `001-RUST_CARGO_TOOLING.md` et `002-CARGO_MANIFESTS.md` ;
|
||||
- identifie exactement les cinq templates Rust/Cargo copiables existants ;
|
||||
- rend explicites les décisions de release unit, membres, édition/toolchain, publication, métadonnées, dépendances/features, lockfile, lints, formatage, Clippy et artefacts ;
|
||||
- rappelle que `0.1.0`, `2024`, `project-name`, `project-core-lib`, les seuils Clippy et les chemins de build doivent être revus avant adoption ;
|
||||
- ne fournit aucun `src/lib.rs` ou `src/main.rs` universel ;
|
||||
- conserve les audits de style Rust comme option explicitement sélectionnée avec corpus ciblé ;
|
||||
- définit une validation Cargo initiale fondée sur `cargo metadata`, Rustfmt, `cargo check` et Clippy ;
|
||||
- permet aux futurs profils plateforme/framework de s'ajouter après le workspace sans créer un composite artificiel.
|
||||
|
||||
## Validation opérateur
|
||||
|
||||
Après avoir appliqué `history/0.0.4/alpha.3.md`, committé `0.0.4-alpha.3`, puis appliqué le présent delta, depuis la racine du dépôt :
|
||||
|
||||
```bash
|
||||
test "$(cat VERSION)" = '0.0.4-alpha.4'
|
||||
test -f history/0.0.4/alpha.3.md
|
||||
test -f deltas/0.0.4/alpha.4.md
|
||||
test -f docs/skeletons/002-RUST_CARGO_WORKSPACE.md
|
||||
test ! -e history/0.0.4/alpha.4.md
|
||||
|
||||
grep -Fx '<!-- version: 10 -->' README.md
|
||||
grep -Fx '<!-- version: 8 -->' docs/000-README.md
|
||||
grep -Fx '<!-- version: 3 -->' docs/skeletons/000-README.md
|
||||
grep -Fx '<!-- version: 1 -->' docs/skeletons/002-RUST_CARGO_WORKSPACE.md
|
||||
|
||||
grep -F '002-RUST_CARGO_WORKSPACE.md' README.md
|
||||
grep -F '002-RUST_CARGO_WORKSPACE.md' docs/000-README.md
|
||||
grep -F '002-RUST_CARGO_WORKSPACE.md' docs/skeletons/000-README.md
|
||||
|
||||
python3 -B -m unittest discover -s tests -v
|
||||
|
||||
python3 -B scripts/audit_markdown_headers.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_tables.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_links.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
|
||||
python3 -B - <<'PY'
|
||||
from pathlib import Path
|
||||
import re
|
||||
import tomllib
|
||||
|
||||
histories = {path.name for path in Path('history/0.0.4').glob('*.md')}
|
||||
assert histories == {'alpha.1.md', 'alpha.2.md', 'alpha.3.md'}, histories
|
||||
for name in sorted(histories):
|
||||
text = Path('history/0.0.4', name).read_text(encoding='utf-8')
|
||||
assert re.search(r'## Statut\s+PASS\s', text), name
|
||||
|
||||
skeletons = sorted(path.name for path in Path('docs/skeletons').glob('*.md'))
|
||||
assert skeletons == [
|
||||
'000-README.md',
|
||||
'001-PROJECT_GOVERNANCE_FOUNDATION.md',
|
||||
'002-RUST_CARGO_WORKSPACE.md',
|
||||
], skeletons
|
||||
|
||||
text = Path('docs/skeletons/002-RUST_CARGO_WORKSPACE.md').read_text(encoding='utf-8')
|
||||
for phrase in (
|
||||
'## Applicabilité et composition',
|
||||
'## Owners, guides et artefacts sélectionnés',
|
||||
'## Décisions destinataire avant copie',
|
||||
'## Matérialisation du workspace',
|
||||
'### Cargo.lock',
|
||||
'### Audits de style facultatifs',
|
||||
'## Validation initiale',
|
||||
'## Ordre de composition et extensions',
|
||||
'## Overrides et exceptions',
|
||||
'## Hors scope',
|
||||
):
|
||||
assert phrase in text, phrase
|
||||
|
||||
for owner in ('500-LANGUAGES.md', '510-RUST_CARGO.md'):
|
||||
assert owner in text, owner
|
||||
|
||||
for template in (
|
||||
'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',
|
||||
):
|
||||
assert template in text, template
|
||||
|
||||
for path in (
|
||||
Path('templates/rust-cargo/rustfmt.toml'),
|
||||
Path('templates/rust-cargo/clippy.toml'),
|
||||
Path('templates/rust-cargo/.cargo/config.toml'),
|
||||
Path('templates/rust-cargo/Cargo.toml'),
|
||||
Path('templates/rust-cargo/crates/project-core-lib/Cargo.toml'),
|
||||
):
|
||||
with path.open('rb') as stream:
|
||||
tomllib.load(stream)
|
||||
|
||||
print('Rust/Cargo skeleton audit: clean (alpha.1-alpha.3 PASS baseline, five templates parsed)')
|
||||
PY
|
||||
|
||||
command -v cargo
|
||||
command -v rustfmt
|
||||
cargo --version
|
||||
rustc --version
|
||||
rustfmt --version
|
||||
cargo clippy --version
|
||||
|
||||
tmp="$(mktemp -d)"
|
||||
trap 'rm -rf "$tmp"' EXIT
|
||||
mkdir -p "$tmp/.cargo" "$tmp/crates/smoke-core-lib/src"
|
||||
cp templates/rust-cargo/Cargo.toml "$tmp/Cargo.toml"
|
||||
cp templates/rust-cargo/rustfmt.toml "$tmp/rustfmt.toml"
|
||||
cp templates/rust-cargo/clippy.toml "$tmp/clippy.toml"
|
||||
cp templates/rust-cargo/.cargo/config.toml "$tmp/.cargo/config.toml"
|
||||
cp templates/rust-cargo/crates/project-core-lib/Cargo.toml "$tmp/crates/smoke-core-lib/Cargo.toml"
|
||||
printf '1.2.3\n' > "$tmp/VERSION"
|
||||
|
||||
python3 -B - "$tmp" <<'PY'
|
||||
from pathlib import Path
|
||||
import sys
|
||||
|
||||
root = Path(sys.argv[1])
|
||||
|
||||
replacements = {
|
||||
root / 'Cargo.toml': (
|
||||
('# file: templates/rust-cargo/Cargo.toml', '# file: Cargo.toml'),
|
||||
('members = ["crates/project-core-lib"]', 'members = ["crates/smoke-core-lib"]'),
|
||||
('version = "0.1.0"', 'version = "1.2.3"'),
|
||||
),
|
||||
root / 'rustfmt.toml': (
|
||||
('# file: templates/rust-cargo/rustfmt.toml', '# file: rustfmt.toml'),
|
||||
),
|
||||
root / 'clippy.toml': (
|
||||
('# file: templates/rust-cargo/clippy.toml', '# file: clippy.toml'),
|
||||
),
|
||||
root / '.cargo/config.toml': (
|
||||
('# file: templates/rust-cargo/.cargo/config.toml', '# file: .cargo/config.toml'),
|
||||
('../builds/project-name/target', 'target-smoke'),
|
||||
),
|
||||
root / 'crates/smoke-core-lib/Cargo.toml': (
|
||||
('# file: templates/rust-cargo/crates/project-core-lib/Cargo.toml', '# file: crates/smoke-core-lib/Cargo.toml'),
|
||||
('name = "project-core-lib"', 'name = "smoke-core-lib"'),
|
||||
),
|
||||
}
|
||||
|
||||
for path, pairs in replacements.items():
|
||||
text = path.read_text(encoding='utf-8')
|
||||
for old, new in pairs:
|
||||
assert old in text, (path, old)
|
||||
text = text.replace(old, new)
|
||||
path.write_text(text, encoding='utf-8')
|
||||
|
||||
for path in root.rglob('*'):
|
||||
if path.is_file() and path.name != 'Cargo.lock':
|
||||
text = path.read_text(encoding='utf-8')
|
||||
assert 'project-name' not in text, path
|
||||
assert 'project-core-lib' not in text, path
|
||||
PY
|
||||
|
||||
cat > "$tmp/crates/smoke-core-lib/src/lib.rs" <<'RS'
|
||||
//! Minimal crate used to validate the PGR Rust/Cargo templates.
|
||||
|
||||
/// Returns the deterministic smoke value.
|
||||
pub fn smoke_value() -> u8 {
|
||||
return 1;
|
||||
}
|
||||
RS
|
||||
|
||||
(
|
||||
cd "$tmp"
|
||||
cargo metadata --format-version 1 --no-deps >/dev/null
|
||||
cargo fmt --all -- --check
|
||||
cargo check --workspace
|
||||
cargo clippy --workspace --all-targets --all-features -- -D warnings
|
||||
)
|
||||
|
||||
rm -rf "$tmp"
|
||||
trap - EXIT
|
||||
|
||||
git diff --check
|
||||
git add VERSION README.md docs/000-README.md \
|
||||
docs/skeletons/000-README.md \
|
||||
docs/skeletons/002-RUST_CARGO_WORKSPACE.md \
|
||||
deltas/0.0.4/alpha.4.md
|
||||
git diff --cached --check
|
||||
git status --short
|
||||
```
|
||||
|
||||
## Revue opérateur
|
||||
|
||||
En complément des commandes, vérifier que :
|
||||
|
||||
- `002` reste une specialization composable de `001` et ne redéfinit pas les owners généraux ;
|
||||
- les cinq templates sont référencés comme artefacts à adapter, jamais comme valeurs universelles ;
|
||||
- la politique `Cargo.lock`, les membres, dépendances/features, métadonnées et éventuelles exceptions de lints/safety restent des décisions explicites du projet ;
|
||||
- les audits Rust facultatifs ne sont ni copiés ni exécutés sans sélection de leur convention et de leur corpus ;
|
||||
- aucune règle Java/Android/Web/JNI/Tauri ou autre plateforme/framework n'entre dans la tranche ;
|
||||
- l'instanciation temporaire prouve l'adoption minimale des templates sans ajouter de workspace Rust au dépôt PGR.
|
||||
|
||||
## Transition
|
||||
|
||||
PASS : produire `history/0.0.4/alpha.4.md`, l'appliquer puis committer `0.0.4-alpha.4`. La tranche suivante prévue par le plan est `0.0.4-beta.1`, consacrée à la réconciliation interne de la release : ownership, liens, index, duplication normative, valeurs d'exemple, limites des audits et confirmation des domaines différés.
|
||||
|
||||
FAIL : rester dans le scope de `alpha.4` via `alpha.4.fix.1` sauf si l'instanciation démontre qu'un template ou une décision normative existante est insuffisante, auquel cas déclencher le REPLAN prévu par le plan.
|
||||
200
deltas/0.0.4/beta.1.fix.1.md
Normal file
200
deltas/0.0.4/beta.1.fix.1.md
Normal file
@@ -0,0 +1,200 @@
|
||||
<!-- file: deltas/0.0.4/beta.1.fix.1.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Delta 0.0.4-beta.1.fix.1 — correction de la gate de réconciliation
|
||||
|
||||
## Baseline et version
|
||||
|
||||
Baseline : tranche `0.0.4-beta.1` enregistrée `FAIL`, avec `history/0.0.4/beta.1.md` appliqué, committé et poussé. Le delta et le history `beta.1` restent des snapshots historiques et MUST NOT être réécrits.
|
||||
|
||||
Version avant application :
|
||||
|
||||
```text
|
||||
0.0.4-beta.1
|
||||
```
|
||||
|
||||
Version après application :
|
||||
|
||||
```text
|
||||
0.0.4-beta.1.fix.1
|
||||
```
|
||||
|
||||
## Motif
|
||||
|
||||
La gate `beta.1` a échoué avant l'exécution de son audit Python de réconciliation à cause d'une chaîne délimitée par apostrophes simples contenant l'apostrophe de `l'arborescence` :
|
||||
|
||||
```text
|
||||
SyntaxError: unterminated string literal
|
||||
```
|
||||
|
||||
Les tests, audits Markdown et contrôles précédant cette commande ont réussi. Aucun défaut des règles, skeletons, templates ou documents vivants n'a été observé.
|
||||
|
||||
Le présent fix corrige uniquement la gate en utilisant une chaîne Python correctement délimitée, puis rejoue les preuves nécessaires de la réconciliation.
|
||||
|
||||
## Scope
|
||||
|
||||
REPLACE :
|
||||
|
||||
```text
|
||||
VERSION
|
||||
```
|
||||
|
||||
ADD :
|
||||
|
||||
```text
|
||||
deltas/0.0.4/beta.1.fix.1.md
|
||||
```
|
||||
|
||||
DELETE : aucun.
|
||||
|
||||
Aucun document vivant, règle, skeleton, template, script, test ou history antérieur n'est modifié.
|
||||
|
||||
## Validation opérateur
|
||||
|
||||
Après commit et push de `0.0.4-beta.1` avec son history `FAIL`, appliquer ce delta puis exécuter à la racine :
|
||||
|
||||
```bash
|
||||
test "$(cat VERSION)" = '0.0.4-beta.1.fix.1'
|
||||
git cat-file -e HEAD:history/0.0.4/beta.1.md
|
||||
test -f history/0.0.4/beta.1.md
|
||||
test -f deltas/0.0.4/beta.1.md
|
||||
test -f deltas/0.0.4/beta.1.fix.1.md
|
||||
test ! -e history/0.0.4/beta.1.fix.1.md
|
||||
|
||||
grep -A2 '^## Statut$' history/0.0.4/beta.1.md | grep -Fx 'FAIL'
|
||||
grep -A2 '^## Statut$' history/0.0.4/alpha.4.fix.1.md | grep -Fx 'PASS'
|
||||
|
||||
python3 -B -m unittest discover -s tests -v
|
||||
|
||||
python3 -B scripts/audit_markdown_headers.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_tables.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_links.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
|
||||
python3 -B - <<'PY'
|
||||
from pathlib import Path
|
||||
import re
|
||||
import tomllib
|
||||
|
||||
expected_histories = {
|
||||
'alpha.1.md': 'PASS',
|
||||
'alpha.2.md': 'PASS',
|
||||
'alpha.3.md': 'PASS',
|
||||
'alpha.4.md': 'FAIL',
|
||||
'alpha.4.fix.1.md': 'PASS',
|
||||
'beta.1.md': 'FAIL',
|
||||
}
|
||||
histories = {path.name for path in Path('history/0.0.4').glob('*.md')}
|
||||
assert histories == set(expected_histories), histories
|
||||
for name, status in expected_histories.items():
|
||||
text = Path('history/0.0.4', name).read_text(encoding='utf-8')
|
||||
assert re.search(rf'## Statut\s+{status}\s', text), (name, status)
|
||||
|
||||
deltas = {path.name for path in Path('deltas/0.0.4').glob('*.md')}
|
||||
assert deltas == set(expected_histories) | {'beta.1.fix.1.md'}, deltas
|
||||
|
||||
skeletons = sorted(path.name for path in Path('docs/skeletons').glob('*.md'))
|
||||
assert skeletons == [
|
||||
'000-README.md',
|
||||
'001-PROJECT_GOVERNANCE_FOUNDATION.md',
|
||||
'002-RUST_CARGO_WORKSPACE.md',
|
||||
], skeletons
|
||||
|
||||
root_index = Path('README.md').read_text(encoding='utf-8')
|
||||
docs_index = Path('docs/000-README.md').read_text(encoding='utf-8')
|
||||
skel_index = Path('docs/skeletons/000-README.md').read_text(encoding='utf-8')
|
||||
for name in (
|
||||
'001-PROJECT_GOVERNANCE_FOUNDATION.md',
|
||||
'002-RUST_CARGO_WORKSPACE.md',
|
||||
):
|
||||
assert name in root_index, name
|
||||
assert name in docs_index, name
|
||||
assert name in skel_index, name
|
||||
|
||||
foundation = Path('docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md').read_text(encoding='utf-8')
|
||||
for owner in (
|
||||
'200-GOVERNANCE.md',
|
||||
'210-WORKFLOW.md',
|
||||
'300-DOCUMENTATION.md',
|
||||
'400-VALIDATION.md',
|
||||
):
|
||||
assert owner in foundation, owner
|
||||
|
||||
rust = Path('docs/skeletons/002-RUST_CARGO_WORKSPACE.md').read_text(encoding='utf-8')
|
||||
for owner in ('500-LANGUAGES.md', '510-RUST_CARGO.md'):
|
||||
assert owner in rust, owner
|
||||
for value in ('0.1.0', '2024', 'project-name', 'project-core-lib'):
|
||||
assert value in rust, value
|
||||
assert 'Ils ne deviennent jamais des valeurs universelles par simple copie.' in rust
|
||||
assert 'Cargo.lock' in rust
|
||||
|
||||
rule = Path('docs/rules/220-SKELETONS.md').read_text(encoding='utf-8')
|
||||
assert 'Un skeleton sélectionne les owners normatifs applicables ; il ne redéfinit pas leur contenu.' in rule
|
||||
assert 'MUST NOT devenir une valeur universelle par simple copie' in rule
|
||||
|
||||
validation = Path('docs/validation/001-VALIDATION_MATRIX.md').read_text(encoding='utf-8')
|
||||
for audit_id in ('PGR-MD-HEADER-001', 'PGR-MD-TABLE-001', 'PGR-NAV-001'):
|
||||
assert audit_id in validation, audit_id
|
||||
assert "vérifie uniquement l'existence des cibles de liens Markdown locaux inline" in validation
|
||||
|
||||
rust_audits = Path('docs/validation/002-RUST_STYLE_AUDITS.md').read_text(encoding='utf-8')
|
||||
assert 'facultatif' in rust_audits.lower()
|
||||
assert "Les audits ne modifient ni les fichiers inspectés ni l'arborescence de build." in rust_audits
|
||||
|
||||
plan = Path('docs/plans/004-V0_0_4_SKELETONS_PLAN.md').read_text(encoding='utf-8')
|
||||
for deferred in (
|
||||
'Java / Maven / Gradle — différé',
|
||||
'Android — différé',
|
||||
'Web, JNI, Tauri et autres familles absentes — différés',
|
||||
):
|
||||
assert deferred in plan, deferred
|
||||
|
||||
for path in (
|
||||
Path('templates/rust-cargo/rustfmt.toml'),
|
||||
Path('templates/rust-cargo/clippy.toml'),
|
||||
Path('templates/rust-cargo/.cargo/config.toml'),
|
||||
Path('templates/rust-cargo/Cargo.toml'),
|
||||
Path('templates/rust-cargo/crates/project-core-lib/Cargo.toml'),
|
||||
):
|
||||
with path.open('rb') as stream:
|
||||
tomllib.load(stream)
|
||||
|
||||
print('Skeleton beta reconciliation fix audit: clean (beta.1 FAIL recorded, 3 skeleton docs, 5 TOML parsed)')
|
||||
PY
|
||||
|
||||
git diff --check
|
||||
git add VERSION deltas/0.0.4/beta.1.fix.1.md
|
||||
git diff --cached --check
|
||||
git status --short
|
||||
```
|
||||
|
||||
La sortie Git attendue avant ajout du history du fix est exactement :
|
||||
|
||||
```text
|
||||
M VERSION
|
||||
A deltas/0.0.4/beta.1.fix.1.md
|
||||
```
|
||||
|
||||
## Revue opérateur complémentaire
|
||||
|
||||
Confirmer que :
|
||||
|
||||
- le `FAIL beta.1` reste visible et n'est pas réécrit ;
|
||||
- le fix ne change aucune règle, aucun skeleton, aucun template et aucun audit ;
|
||||
- `220` reste le propriétaire du contrat transversal et `001`/`002` restent des orchestrateurs/compositeurs de leurs owners ;
|
||||
- les valeurs de templates restent adaptables et non universelles ;
|
||||
- Java/Android/Web/JNI/Tauri restent différés sans placeholder anticipé.
|
||||
|
||||
## Transition
|
||||
|
||||
### PASS
|
||||
|
||||
Créer et appliquer séparément `history/0.0.4/beta.1.fix.1.md`, committer et pousser le fix, puis préparer `0.0.4-rc.1`.
|
||||
|
||||
Le history du fix et le delta `rc.1` MAY être livrés ensemble sous forme de deux archives séparées après observation de cette gate opérateur.
|
||||
|
||||
### FAIL
|
||||
|
||||
Enregistrer le diagnostic réel dans `history/0.0.4/beta.1.fix.1.md`, puis poursuivre par `beta.1.fix.2` limité à la réconciliation ou faire un REPLAN explicite si un défaut de contenu est réellement découvert.
|
||||
225
deltas/0.0.4/beta.1.md
Normal file
225
deltas/0.0.4/beta.1.md
Normal file
@@ -0,0 +1,225 @@
|
||||
<!-- file: deltas/0.0.4/beta.1.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Delta 0.0.4-beta.1 — réconciliation interne des skeletons
|
||||
|
||||
## Baseline
|
||||
|
||||
Version attendue avant application :
|
||||
|
||||
```text
|
||||
0.0.4-alpha.4.fix.1
|
||||
```
|
||||
|
||||
Le history `history/0.0.4/alpha.4.fix.1.md` avec statut `PASS` MUST avoir été appliqué, committé et poussé avant ce delta. Le `FAIL` de `history/0.0.4/alpha.4.md` reste un snapshot historique et MUST NOT être réécrit.
|
||||
|
||||
Version après application :
|
||||
|
||||
```text
|
||||
0.0.4-beta.1
|
||||
```
|
||||
|
||||
## Objet
|
||||
|
||||
Exécuter la réconciliation interne prévue par `docs/plans/004-V0_0_4_SKELETONS_PLAN.md` après la fondation gouvernée, le skeleton Rust/Cargo et la correction de sa gate d'instanciation.
|
||||
|
||||
La revue porte sur :
|
||||
|
||||
```text
|
||||
ownership normatif
|
||||
navigation et index
|
||||
absence de duplication normative
|
||||
composition 001 -> 002
|
||||
valeurs d'exemple non universalisées
|
||||
limites des audits et de la validation
|
||||
spécialisations technologiques différées
|
||||
continuité delta/history de 0.0.4
|
||||
```
|
||||
|
||||
Cette tranche n'ajoute aucune fonctionnalité, aucun profil, aucun skeleton, aucun template et aucun audit.
|
||||
|
||||
## Résultat de la réconciliation préparatoire
|
||||
|
||||
Aucune correction de document vivant n'est nécessaire pour entrer en beta.
|
||||
|
||||
Le contrat transversal reste possédé par `docs/rules/220-SKELETONS.md`. La fondation `001-PROJECT_GOVERNANCE_FOUNDATION.md` orchestre les owners généraux sans les redéfinir. La specialization `002-RUST_CARGO_WORKSPACE.md` ajoute uniquement `500 + 510`, les guides/templates Rust/Cargo et les décisions de son scope.
|
||||
|
||||
La navigation courante expose les deux specifications depuis `README.md`, `docs/000-README.md` et `docs/skeletons/000-README.md`. Aucun troisième skeleton ou placeholder de skeleton n'existe.
|
||||
|
||||
Les valeurs Rust/Cargo telles que `0.1.0`, `2024`, `project-name`, `project-core-lib`, les seuils Clippy et les chemins de build restent explicitement décrites comme exemples, baselines ou décisions destinataire à revoir. `Cargo.lock` reste une décision propre au type de produit et au besoin de reproductibilité.
|
||||
|
||||
Les limites des audits restent séparées : headers, tableaux et liens Markdown sont des contrôles monotâches ; les audits de style Rust sont facultatifs, read-only et ne remplacent ni Rustfmt, ni Clippy, ni la toolchain Cargo. La validation d'instanciation appartient au skeleton qui prétend matérialiser une baseline utilisable et n'est pas transformée en build global permanent de PGR.
|
||||
|
||||
Java/Maven/Gradle et Android possèdent des profils normatifs mais pas encore les templates/corpus nécessaires à un skeleton concret. Web, JNI, Tauri et les autres domaines insuffisamment cadrés restent également différés. Aucun fichier placeholder n'est créé pour réserver ces futurs scopes.
|
||||
|
||||
Le `FAIL` de `alpha.4` et le `PASS` attendu de `alpha.4.fix.1` forment une chaîne historique explicite ; le fix ne réécrit pas le delta ou le history échoué.
|
||||
|
||||
## Scope
|
||||
|
||||
REPLACE :
|
||||
|
||||
```text
|
||||
VERSION
|
||||
```
|
||||
|
||||
ADD :
|
||||
|
||||
```text
|
||||
deltas/0.0.4/beta.1.md
|
||||
```
|
||||
|
||||
DELETE : aucun.
|
||||
|
||||
Les documents vivants, règles, skeletons, templates, scripts, tests et histories antérieurs restent inchangés. Cette absence de modification supplémentaire est intentionnelle : la réconciliation n'a pas identifié de correction réelle qui justifierait une révision artificielle.
|
||||
|
||||
## Validation opérateur
|
||||
|
||||
Après commit et push de `0.0.4-alpha.4.fix.1`, appliquer ce delta puis exécuter à la racine :
|
||||
|
||||
```bash
|
||||
test "$(cat VERSION)" = '0.0.4-beta.1'
|
||||
git cat-file -e HEAD:history/0.0.4/alpha.4.fix.1.md
|
||||
test -f history/0.0.4/alpha.4.fix.1.md
|
||||
test -f deltas/0.0.4/beta.1.md
|
||||
test ! -e history/0.0.4/beta.1.md
|
||||
|
||||
test -f docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md
|
||||
test -f docs/skeletons/002-RUST_CARGO_WORKSPACE.md
|
||||
test ! -e docs/skeletons/003-JAVA_MAVEN_GRADLE.md
|
||||
test ! -e docs/skeletons/003-ANDROID.md
|
||||
|
||||
grep -A2 '^## Statut$' history/0.0.4/alpha.4.md | grep -Fx 'FAIL'
|
||||
grep -A2 '^## Statut$' history/0.0.4/alpha.4.fix.1.md | grep -Fx 'PASS'
|
||||
|
||||
python3 -B -m unittest discover -s tests -v
|
||||
|
||||
python3 -B scripts/audit_markdown_headers.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_tables.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_links.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
|
||||
python3 -B - <<'PY'
|
||||
from pathlib import Path
|
||||
import re
|
||||
import tomllib
|
||||
|
||||
expected_histories = {
|
||||
'alpha.1.md': 'PASS',
|
||||
'alpha.2.md': 'PASS',
|
||||
'alpha.3.md': 'PASS',
|
||||
'alpha.4.md': 'FAIL',
|
||||
'alpha.4.fix.1.md': 'PASS',
|
||||
}
|
||||
histories = {path.name for path in Path('history/0.0.4').glob('*.md')}
|
||||
assert histories == set(expected_histories), histories
|
||||
for name, status in expected_histories.items():
|
||||
text = Path('history/0.0.4', name).read_text(encoding='utf-8')
|
||||
assert re.search(rf'## Statut\s+{status}\s', text), (name, status)
|
||||
|
||||
deltas = {path.name for path in Path('deltas/0.0.4').glob('*.md')}
|
||||
assert deltas == set(expected_histories) | {'beta.1.md'}, deltas
|
||||
|
||||
skeletons = sorted(path.name for path in Path('docs/skeletons').glob('*.md'))
|
||||
assert skeletons == [
|
||||
'000-README.md',
|
||||
'001-PROJECT_GOVERNANCE_FOUNDATION.md',
|
||||
'002-RUST_CARGO_WORKSPACE.md',
|
||||
], skeletons
|
||||
|
||||
root_index = Path('README.md').read_text(encoding='utf-8')
|
||||
docs_index = Path('docs/000-README.md').read_text(encoding='utf-8')
|
||||
skel_index = Path('docs/skeletons/000-README.md').read_text(encoding='utf-8')
|
||||
for name in (
|
||||
'001-PROJECT_GOVERNANCE_FOUNDATION.md',
|
||||
'002-RUST_CARGO_WORKSPACE.md',
|
||||
):
|
||||
assert name in root_index, name
|
||||
assert name in docs_index, name
|
||||
assert name in skel_index, name
|
||||
|
||||
foundation = Path('docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md').read_text(encoding='utf-8')
|
||||
for owner in (
|
||||
'200-GOVERNANCE.md',
|
||||
'210-WORKFLOW.md',
|
||||
'300-DOCUMENTATION.md',
|
||||
'400-VALIDATION.md',
|
||||
):
|
||||
assert owner in foundation, owner
|
||||
|
||||
rust = Path('docs/skeletons/002-RUST_CARGO_WORKSPACE.md').read_text(encoding='utf-8')
|
||||
for owner in ('500-LANGUAGES.md', '510-RUST_CARGO.md'):
|
||||
assert owner in rust, owner
|
||||
for value in ('0.1.0', '2024', 'project-name', 'project-core-lib'):
|
||||
assert value in rust, value
|
||||
assert 'Ils ne deviennent jamais des valeurs universelles par simple copie.' in rust
|
||||
assert 'Cargo.lock' in rust
|
||||
|
||||
rule = Path('docs/rules/220-SKELETONS.md').read_text(encoding='utf-8')
|
||||
assert 'Un skeleton sélectionne les owners normatifs applicables ; il ne redéfinit pas leur contenu.' in rule
|
||||
assert 'MUST NOT devenir une valeur universelle par simple copie' in rule
|
||||
|
||||
validation = Path('docs/validation/001-VALIDATION_MATRIX.md').read_text(encoding='utf-8')
|
||||
for audit_id in ('PGR-MD-HEADER-001', 'PGR-MD-TABLE-001', 'PGR-NAV-001'):
|
||||
assert audit_id in validation, audit_id
|
||||
assert 'vérifie uniquement l\'existence des cibles de liens Markdown locaux inline' in validation
|
||||
|
||||
rust_audits = Path('docs/validation/002-RUST_STYLE_AUDITS.md').read_text(encoding='utf-8')
|
||||
assert 'facultatif' in rust_audits.lower()
|
||||
assert 'Les audits ne modifient ni les fichiers inspectés ni l'arborescence de build.' in rust_audits
|
||||
|
||||
plan = Path('docs/plans/004-V0_0_4_SKELETONS_PLAN.md').read_text(encoding='utf-8')
|
||||
for deferred in ('Java / Maven / Gradle — différé', 'Android — différé', 'Web, JNI, Tauri et autres familles absentes — différés'):
|
||||
assert deferred in plan, deferred
|
||||
|
||||
for path in (
|
||||
Path('templates/rust-cargo/rustfmt.toml'),
|
||||
Path('templates/rust-cargo/clippy.toml'),
|
||||
Path('templates/rust-cargo/.cargo/config.toml'),
|
||||
Path('templates/rust-cargo/Cargo.toml'),
|
||||
Path('templates/rust-cargo/crates/project-core-lib/Cargo.toml'),
|
||||
):
|
||||
with path.open('rb') as stream:
|
||||
tomllib.load(stream)
|
||||
|
||||
print('Skeleton beta reconciliation audit: clean (5 prior histories, 3 skeleton docs, 5 TOML parsed)')
|
||||
PY
|
||||
|
||||
git diff --check
|
||||
git add VERSION deltas/0.0.4/beta.1.md
|
||||
git diff --cached --check
|
||||
git status --short
|
||||
```
|
||||
|
||||
La sortie Git attendue avant ajout du history `beta.1` est exactement :
|
||||
|
||||
```text
|
||||
M VERSION
|
||||
A deltas/0.0.4/beta.1.md
|
||||
```
|
||||
|
||||
## Revue opérateur complémentaire
|
||||
|
||||
Confirmer que :
|
||||
|
||||
- `220` reste le propriétaire du contrat transversal et que `001`/`002` n'en dupliquent pas les obligations ;
|
||||
- `001` reste sans spécialisation technologique et `002` n'élargit pas `510` vers Android, WASM, Tauri, FFI ou un framework ;
|
||||
- les valeurs de templates restent des exemples adaptables et non des politiques globales ;
|
||||
- les audits documentaires et Rust restent délimités par leur propriété réellement vérifiée ;
|
||||
- Java/Android/Web/JNI/Tauri restent différés faute de pièces suffisantes, sans placeholder ni skeleton composite anticipé ;
|
||||
- le `FAIL alpha.4` reste visible et la correction `alpha.4.fix.1` est enregistrée séparément.
|
||||
|
||||
## Transition
|
||||
|
||||
### PASS
|
||||
|
||||
Créer et appliquer séparément `history/0.0.4/beta.1.md`, committer et pousser `beta.1`, puis préparer `0.0.4-rc.1`.
|
||||
|
||||
La RC doit geler le scope, préparer l'entrée candidate `0.0.4` du changelog et `prompts/005-V0_0_5_START_PROMPT.md` si la trajectoire est confirmée, puis rejouer uniquement les validations réellement invalidées par la release.
|
||||
|
||||
Le history `beta.1` et le delta `rc.1` MAY être livrés ensemble sous forme de deux archives séparées après observation de la gate opérateur.
|
||||
|
||||
### FAIL
|
||||
|
||||
Enregistrer le diagnostic réel dans `history/0.0.4/beta.1.md`, puis corriger uniquement la réconciliation dans `0.0.4-beta.1.fix.N` ou faire un REPLAN explicite si un défaut révèle un changement de scope.
|
||||
265
deltas/0.0.4/rc.1.md
Normal file
265
deltas/0.0.4/rc.1.md
Normal file
@@ -0,0 +1,265 @@
|
||||
<!-- file: deltas/0.0.4/rc.1.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Delta 0.0.4-rc.1 — gel du scope et préparation de release
|
||||
|
||||
## Baseline et version
|
||||
|
||||
Baseline : `0.0.4-beta.1.fix.1`, avec `history/0.0.4/beta.1.fix.1.md` appliqué et committé. Ce delta MUST NOT être appliqué avant ce commit.
|
||||
|
||||
Le commit exact de cette baseline sera celui produit par l'opérateur après la gate `beta.1.fix.1` ; il n'est pas anticipé dans cette livraison simultanée du history et du delta suivant.
|
||||
|
||||
Version avant application :
|
||||
|
||||
```text
|
||||
0.0.4-beta.1.fix.1
|
||||
```
|
||||
|
||||
Version après application :
|
||||
|
||||
```text
|
||||
0.0.4-rc.1
|
||||
```
|
||||
|
||||
## Objet et gel
|
||||
|
||||
La réconciliation `beta.1.fix.1` est `PASS`. La RC gèle le scope fonctionnel de `0.0.4` sur :
|
||||
|
||||
- le contrat transversal des skeleton specifications sous `docs/rules/220-SKELETONS.md` ;
|
||||
- la collection `docs/skeletons/` et son index ;
|
||||
- `001-PROJECT_GOVERNANCE_FOUNDATION.md` comme fondation composable sans spécialisation technologique ;
|
||||
- `002-RUST_CARGO_WORKSPACE.md` comme première spécialisation technologique, composée avec les profils `500 + 510` ;
|
||||
- les cinq templates Rust/Cargo déjà introduits avant `0.0.4`, utilisés avec des décisions destinataire explicites et une instanciation temporaire vérifiable.
|
||||
|
||||
Le changelog reçoit une entrée candidate `0.0.4` orientée utilisateurs. Le plan enregistre les résultats `FAIL → fix PASS` des gates `alpha.4` et `beta.1`, puis le gel RC. Le prompt `005` prépare `0.0.5`, dont la roadmap confirme la mission de réconciliation réelle avec `khadhroony-solana-project` et `sasedev-games` à partir de baselines explicitement fournies.
|
||||
|
||||
Aucun nouveau skeleton, profil, template, audit, générateur ou domaine technologique n'entre en RC. Java/Maven/Gradle, Android, Web, JNI, Tauri et les autres familles différées restent hors scope.
|
||||
|
||||
## Scope
|
||||
|
||||
REPLACE :
|
||||
|
||||
```text
|
||||
VERSION
|
||||
CHANGELOG.md
|
||||
docs/plans/004-V0_0_4_SKELETONS_PLAN.md
|
||||
```
|
||||
|
||||
ADD :
|
||||
|
||||
```text
|
||||
prompts/005-V0_0_5_START_PROMPT.md
|
||||
deltas/0.0.4/rc.1.md
|
||||
```
|
||||
|
||||
DELETE : aucun.
|
||||
|
||||
L'archive contient exactement ces fichiers complets. Le history `beta.1.fix.1` est livré séparément ; le history `rc.1` sera produit après la gate opérateur.
|
||||
|
||||
## Gate opérateur de release candidate
|
||||
|
||||
Après application sur le commit `beta.1.fix.1`, depuis la racine du dépôt :
|
||||
|
||||
```bash
|
||||
test "$(cat VERSION)" = '0.0.4-rc.1'
|
||||
git cat-file -e HEAD:history/0.0.4/beta.1.fix.1.md
|
||||
test -f history/0.0.4/beta.1.fix.1.md
|
||||
test -f deltas/0.0.4/rc.1.md
|
||||
test -f prompts/005-V0_0_5_START_PROMPT.md
|
||||
test ! -e history/0.0.4/rc.1.md
|
||||
|
||||
grep -Fx '<!-- version: 6 -->' CHANGELOG.md
|
||||
grep -Fx '## 0.0.4 (candidate)' CHANGELOG.md
|
||||
grep -Fx '<!-- version: 2 -->' docs/plans/004-V0_0_4_SKELETONS_PLAN.md
|
||||
grep -F '`beta.1.fix.1` a rejoué la réconciliation et est `PASS`' docs/plans/004-V0_0_4_SKELETONS_PLAN.md
|
||||
grep -F 'pgr-v0.0.4.zip' prompts/005-V0_0_5_START_PROMPT.md
|
||||
grep -F 'khadhroony-solana-project' prompts/005-V0_0_5_START_PROMPT.md
|
||||
grep -F 'sasedev-games' prompts/005-V0_0_5_START_PROMPT.md
|
||||
|
||||
python3 -B -m unittest discover -s tests -v
|
||||
|
||||
python3 -B scripts/audit_markdown_headers.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_tables.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_links.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
|
||||
python3 -B - <<'PY'
|
||||
from pathlib import Path
|
||||
import re
|
||||
import tomllib
|
||||
|
||||
expected_histories = {
|
||||
'alpha.1.md': 'PASS',
|
||||
'alpha.2.md': 'PASS',
|
||||
'alpha.3.md': 'PASS',
|
||||
'alpha.4.md': 'FAIL',
|
||||
'alpha.4.fix.1.md': 'PASS',
|
||||
'beta.1.md': 'FAIL',
|
||||
'beta.1.fix.1.md': 'PASS',
|
||||
}
|
||||
histories = {path.name for path in Path('history/0.0.4').glob('*.md')}
|
||||
assert histories == set(expected_histories), histories
|
||||
for name, status in expected_histories.items():
|
||||
text = Path('history/0.0.4', name).read_text(encoding='utf-8')
|
||||
assert re.search(rf'## Statut\s+{status}\s', text), (name, status)
|
||||
|
||||
deltas = {path.name for path in Path('deltas/0.0.4').glob('*.md')}
|
||||
assert deltas == set(expected_histories) | {'rc.1.md'}, deltas
|
||||
|
||||
skeletons = sorted(path.name for path in Path('docs/skeletons').glob('*.md'))
|
||||
assert skeletons == [
|
||||
'000-README.md',
|
||||
'001-PROJECT_GOVERNANCE_FOUNDATION.md',
|
||||
'002-RUST_CARGO_WORKSPACE.md',
|
||||
], skeletons
|
||||
|
||||
rule = Path('docs/rules/220-SKELETONS.md').read_text(encoding='utf-8')
|
||||
assert 'Un skeleton sélectionne les owners normatifs applicables ; il ne redéfinit pas leur contenu.' in rule
|
||||
|
||||
foundation = Path('docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md').read_text(encoding='utf-8')
|
||||
for owner in ('200-GOVERNANCE.md', '210-WORKFLOW.md', '300-DOCUMENTATION.md', '400-VALIDATION.md'):
|
||||
assert owner in foundation, owner
|
||||
|
||||
rust = Path('docs/skeletons/002-RUST_CARGO_WORKSPACE.md').read_text(encoding='utf-8')
|
||||
for owner in ('500-LANGUAGES.md', '510-RUST_CARGO.md'):
|
||||
assert owner in rust, owner
|
||||
assert 'Ils ne deviennent jamais des valeurs universelles par simple copie.' in rust
|
||||
|
||||
for path in (
|
||||
Path('templates/rust-cargo/rustfmt.toml'),
|
||||
Path('templates/rust-cargo/clippy.toml'),
|
||||
Path('templates/rust-cargo/.cargo/config.toml'),
|
||||
Path('templates/rust-cargo/Cargo.toml'),
|
||||
Path('templates/rust-cargo/crates/project-core-lib/Cargo.toml'),
|
||||
):
|
||||
with path.open('rb') as stream:
|
||||
tomllib.load(stream)
|
||||
|
||||
prompt = Path('prompts/005-V0_0_5_START_PROMPT.md').read_text(encoding='utf-8')
|
||||
for value in ('pgr-v0.0.4.zip', 'pgr-0.0.4-publish.001-report.md', '0.0.5-alpha.1', 'khadhroony-solana-project', 'sasedev-games'):
|
||||
assert value in prompt, value
|
||||
assert 'Ne pas déduire leur version, leur commit ou leur contenu' in prompt
|
||||
|
||||
print('RC integration audit: clean (7 prior histories, 3 skeleton docs, 5 TOML parsed, prompt 005 ready)')
|
||||
PY
|
||||
|
||||
command -v cargo
|
||||
command -v rustfmt
|
||||
cargo --version
|
||||
rustc --version
|
||||
rustfmt --version
|
||||
cargo clippy --version
|
||||
|
||||
tmp="$(mktemp -d)"
|
||||
trap 'rm -rf "$tmp"' EXIT
|
||||
mkdir -p "$tmp/.cargo" "$tmp/crates/smoke-core-lib/src"
|
||||
cp templates/rust-cargo/Cargo.toml "$tmp/Cargo.toml"
|
||||
cp templates/rust-cargo/rustfmt.toml "$tmp/rustfmt.toml"
|
||||
cp templates/rust-cargo/clippy.toml "$tmp/clippy.toml"
|
||||
cp templates/rust-cargo/.cargo/config.toml "$tmp/.cargo/config.toml"
|
||||
cp templates/rust-cargo/crates/project-core-lib/Cargo.toml "$tmp/crates/smoke-core-lib/Cargo.toml"
|
||||
printf '1.2.3\n' > "$tmp/VERSION"
|
||||
|
||||
python3 -B - "$tmp" <<'PY'
|
||||
from pathlib import Path
|
||||
import sys
|
||||
|
||||
root = Path(sys.argv[1])
|
||||
replacements = {
|
||||
root / 'Cargo.toml': (
|
||||
('# file: templates/rust-cargo/Cargo.toml', '# file: Cargo.toml'),
|
||||
('members = ["crates/project-core-lib"]', 'members = ["crates/smoke-core-lib"]'),
|
||||
('version = "0.1.0"', 'version = "1.2.3"'),
|
||||
),
|
||||
root / 'rustfmt.toml': (
|
||||
('# file: templates/rust-cargo/rustfmt.toml', '# file: rustfmt.toml'),
|
||||
),
|
||||
root / 'clippy.toml': (
|
||||
('# file: templates/rust-cargo/clippy.toml', '# file: clippy.toml'),
|
||||
),
|
||||
root / '.cargo/config.toml': (
|
||||
('# file: templates/rust-cargo/.cargo/config.toml', '# file: .cargo/config.toml'),
|
||||
(
|
||||
'# Replace project-name with a unique name before using this configuration.',
|
||||
'# Smoke fixture: project-specific build directory already selected.',
|
||||
),
|
||||
('../builds/project-name/target', 'target-smoke'),
|
||||
),
|
||||
root / 'crates/smoke-core-lib/Cargo.toml': (
|
||||
(
|
||||
'# file: templates/rust-cargo/crates/project-core-lib/Cargo.toml',
|
||||
'# file: crates/smoke-core-lib/Cargo.toml',
|
||||
),
|
||||
('name = "project-core-lib"', 'name = "smoke-core-lib"'),
|
||||
),
|
||||
}
|
||||
for path, pairs in replacements.items():
|
||||
text = path.read_text(encoding='utf-8')
|
||||
for old, new in pairs:
|
||||
assert old in text, (path, old)
|
||||
text = text.replace(old, new)
|
||||
path.write_text(text, encoding='utf-8')
|
||||
for path in root.rglob('*'):
|
||||
if path.is_file() and path.name != 'Cargo.lock':
|
||||
text = path.read_text(encoding='utf-8')
|
||||
assert 'project-name' not in text, path
|
||||
assert 'project-core-lib' not in text, path
|
||||
print('RC temporary Rust/Cargo template adaptation: clean')
|
||||
PY
|
||||
|
||||
cat > "$tmp/crates/smoke-core-lib/src/lib.rs" <<'RS'
|
||||
//! Minimal crate used to validate the PGR Rust/Cargo templates.
|
||||
|
||||
/// Returns the deterministic smoke value.
|
||||
pub fn smoke_value() -> u8 {
|
||||
return 1;
|
||||
}
|
||||
RS
|
||||
|
||||
(
|
||||
cd "$tmp"
|
||||
cargo metadata --format-version 1 --no-deps >/dev/null
|
||||
cargo fmt --all -- --check
|
||||
cargo check --workspace
|
||||
cargo clippy --workspace --all-targets --all-features -- -D warnings
|
||||
)
|
||||
|
||||
rm -rf "$tmp"
|
||||
trap - EXIT
|
||||
|
||||
git diff --check
|
||||
git add VERSION CHANGELOG.md docs/plans/004-V0_0_4_SKELETONS_PLAN.md \
|
||||
prompts/005-V0_0_5_START_PROMPT.md deltas/0.0.4/rc.1.md
|
||||
git diff --cached --check
|
||||
git status --short
|
||||
```
|
||||
|
||||
Le scope attendu avant ajout du history est exactement :
|
||||
|
||||
```text
|
||||
M CHANGELOG.md
|
||||
M VERSION
|
||||
A deltas/0.0.4/rc.1.md
|
||||
M docs/plans/004-V0_0_4_SKELETONS_PLAN.md
|
||||
A prompts/005-V0_0_5_START_PROMPT.md
|
||||
```
|
||||
|
||||
## Revue opérateur complémentaire
|
||||
|
||||
Confirmer que le changelog décrit la release et non ses tranches internes, que les deux `FAIL` historiques restent visibles avec leurs fixes `PASS`, que le prompt `005` ne présume aucune version KSP/Games non fournie et que la RC n'étend pas le périmètre fonctionnel.
|
||||
|
||||
Une gate RC `PASS` n'est ni la promotion stable, ni le tag `v0.0.4`, ni la vérification de l'archive publiée après le tag.
|
||||
|
||||
## Transition
|
||||
|
||||
### PASS
|
||||
|
||||
Produire séparément `history/0.0.4/rc.1.md`, l'appliquer puis committer/pousser la RC avant le delta stable `rel.001`.
|
||||
|
||||
Le history RC et le delta stable MAY être livrés ensemble sous forme de deux archives séparées après observation de cette gate opérateur.
|
||||
|
||||
### FAIL
|
||||
|
||||
Consigner l'échec réel dans `history/0.0.4/rc.1.md` et corriger uniquement le scope gelé dans `rc.1.fix.1`, sauf REPLAN explicite si la candidate révèle un défaut fonctionnel plus large.
|
||||
152
deltas/0.0.4/rel.001.md
Normal file
152
deltas/0.0.4/rel.001.md
Normal file
@@ -0,0 +1,152 @@
|
||||
<!-- file: deltas/0.0.4/rel.001.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Delta 0.0.4 rel.001 — promotion stable pré-tag
|
||||
|
||||
## Baseline et version
|
||||
|
||||
Baseline : `0.0.4-rc.1`, avec `history/0.0.4/rc.1.md` appliqué et committé. Ce delta MUST NOT être appliqué avant ce commit.
|
||||
|
||||
Le commit exact de cette baseline sera celui produit par l'opérateur après application du history RC ; il n'est pas anticipé dans cette livraison simultanée du history et du delta stable.
|
||||
|
||||
Version avant application :
|
||||
|
||||
```text
|
||||
0.0.4-rc.1
|
||||
```
|
||||
|
||||
Version après application :
|
||||
|
||||
```text
|
||||
0.0.4
|
||||
```
|
||||
|
||||
`rel.001` identifie la clôture opérationnelle ; il ne fait pas partie de la version SemVer du produit.
|
||||
|
||||
## Objet
|
||||
|
||||
Promouvoir la RC validée vers la stable `0.0.4`. La tranche finalise uniquement la présentation de la release : version stable, roadmap terminée, changelog sans marqueur candidate, index documentaires et plan historique.
|
||||
|
||||
Le scope fonctionnel reste celui validé en RC : contrat transversal des skeleton specifications, fondation gouvernée `001`, spécialisation Rust/Cargo `002`, utilisation gouvernée des cinq templates Rust/Cargo existants et différé explicite des autres familles non suffisamment matérialisées.
|
||||
|
||||
La validation de cette tranche est **pré-tag**. Ni le tag `v0.0.4`, ni l'archive `pgr-v0.0.4.zip` téléchargée depuis Gitea, ni un rapport `pgr-0.0.4-publish.001-report.md` ne sont déclarés existants par ce delta. Ils suivent le history PASS, le commit stable et la publication réelle du tag.
|
||||
|
||||
## Scope
|
||||
|
||||
REPLACE :
|
||||
|
||||
```text
|
||||
VERSION
|
||||
README.md
|
||||
ROADMAP.md
|
||||
CHANGELOG.md
|
||||
docs/000-README.md
|
||||
docs/plans/004-V0_0_4_SKELETONS_PLAN.md
|
||||
```
|
||||
|
||||
ADD :
|
||||
|
||||
```text
|
||||
deltas/0.0.4/rel.001.md
|
||||
```
|
||||
|
||||
DELETE : aucun.
|
||||
|
||||
L'archive contient uniquement ces fichiers complets. `history/0.0.4/rc.1.md` est livré séparément ; le history de `rel.001` sera produit après sa gate. Le rapport post-tag restera extérieur à l'archive source taggée.
|
||||
|
||||
## Validation opérateur pré-tag
|
||||
|
||||
Après application sur le commit `rc.1`, depuis la racine du dépôt :
|
||||
|
||||
```bash
|
||||
test "$(cat VERSION)" = '0.0.4'
|
||||
git cat-file -e HEAD:history/0.0.4/rc.1.md
|
||||
test -f history/0.0.4/rc.1.md
|
||||
test -f deltas/0.0.4/rel.001.md
|
||||
test -f prompts/005-V0_0_5_START_PROMPT.md
|
||||
test ! -e history/0.0.4/rel.001.md
|
||||
|
||||
grep -Fx '<!-- version: 11 -->' README.md
|
||||
grep -Fx '<!-- version: 5 -->' ROADMAP.md
|
||||
grep -Fx '<!-- version: 7 -->' CHANGELOG.md
|
||||
grep -Fx '<!-- version: 9 -->' docs/000-README.md
|
||||
grep -Fx '<!-- version: 3 -->' docs/plans/004-V0_0_4_SKELETONS_PLAN.md
|
||||
grep -F 'La release `0.0.4` définit le contrat transversal des skeleton specifications' README.md
|
||||
grep -F 'plan historique des skeleton specifications `0.0.4`' README.md
|
||||
grep -F -- '- `(x) 0.0.4`' ROADMAP.md
|
||||
grep -Fx '## 0.0.4' CHANGELOG.md
|
||||
grep -F 'périmètre et décisions de la release `0.0.4`' docs/000-README.md
|
||||
grep -F 'La gate opérateur de `rc.1` est `PASS`' docs/plans/004-V0_0_4_SKELETONS_PLAN.md
|
||||
grep -F 'pgr-0.0.4-publish.001-report.md' docs/plans/004-V0_0_4_SKELETONS_PLAN.md
|
||||
|
||||
python3 -B - <<'PY'
|
||||
from pathlib import Path
|
||||
import re
|
||||
|
||||
expected = {
|
||||
'alpha.1.md': 'PASS',
|
||||
'alpha.2.md': 'PASS',
|
||||
'alpha.3.md': 'PASS',
|
||||
'alpha.4.md': 'FAIL',
|
||||
'alpha.4.fix.1.md': 'PASS',
|
||||
'beta.1.md': 'FAIL',
|
||||
'beta.1.fix.1.md': 'PASS',
|
||||
'rc.1.md': 'PASS',
|
||||
}
|
||||
for name, status in expected.items():
|
||||
delta = Path('deltas/0.0.4', name)
|
||||
history = Path('history/0.0.4', name)
|
||||
assert delta.is_file(), name
|
||||
assert history.is_file(), name
|
||||
text = history.read_text(encoding='utf-8')
|
||||
assert re.search(rf'## Statut\s+{status}\s', text), (name, status)
|
||||
|
||||
pending = {p.name for p in Path('deltas/0.0.4').glob('*.md')} - \
|
||||
{p.name for p in Path('history/0.0.4').glob('*.md')}
|
||||
assert pending == {'rel.001.md'}, pending
|
||||
print('Stable history audit: clean (8 prior histories with expected statuses, rel.001 pending)')
|
||||
PY
|
||||
|
||||
python3 -B scripts/audit_markdown_headers.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_tables.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_links.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
|
||||
git diff --check
|
||||
git add VERSION README.md ROADMAP.md CHANGELOG.md docs/000-README.md \
|
||||
docs/plans/004-V0_0_4_SKELETONS_PLAN.md deltas/0.0.4/rel.001.md
|
||||
git diff --cached --check
|
||||
git status --short
|
||||
```
|
||||
|
||||
Le scope attendu avant ajout du history est exactement :
|
||||
|
||||
```text
|
||||
M CHANGELOG.md
|
||||
M README.md
|
||||
M ROADMAP.md
|
||||
M VERSION
|
||||
A deltas/0.0.4/rel.001.md
|
||||
M docs/000-README.md
|
||||
M docs/plans/004-V0_0_4_SKELETONS_PLAN.md
|
||||
```
|
||||
|
||||
Les `15` tests, les cinq TOML et le smoke Rust/Cargo complets validés en RC restent des preuves applicables parce qu'aucun code, script, test, template ou skeleton technique n'est modifié pendant `rel.001`. La gate stable se concentre donc sur l'intégrité de la chaîne historique, la présentation stable et les audits documentaires affectés.
|
||||
|
||||
## Revue opérateur complémentaire
|
||||
|
||||
Confirmer que le scope fonctionnel de la RC ne change pas, que README/roadmap/changelog/index/plan décrivent la même stable, que les `FAIL` historiques restent conservés avec leurs fixes `PASS`, que le prompt `005` reste conditionnel à une vraie publication et à des baselines KSP/Games fournies, et qu'aucune preuve post-tag n'est anticipée.
|
||||
|
||||
## Transition
|
||||
|
||||
### PASS
|
||||
|
||||
Produire séparément `history/0.0.4/rel.001.md`, l'appliquer puis committer la stable. Ensuite seulement créer et publier le tag canonique `v0.0.4`, télécharger son archive source depuis Gitea, vérifier cette archive et conserver séparément la preuve post-tag `pgr-0.0.4-publish.001-report.md`.
|
||||
|
||||
Le message manuel de reprise de `prompts/005-V0_0_5_START_PROMPT.md` n'est remis à l'opérateur qu'après vérification effective de l'archive et d'un rapport post-tag PASS réel.
|
||||
|
||||
### FAIL
|
||||
|
||||
Consigner le diagnostic réel dans `history/0.0.4/rel.001.md`, ne pas tagger et corriger la clôture dans une tranche explicite avant publication.
|
||||
193
deltas/0.0.5/alpha.1.md
Normal file
193
deltas/0.0.5/alpha.1.md
Normal file
@@ -0,0 +1,193 @@
|
||||
<!-- file: deltas/0.0.5/alpha.1.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Delta 0.0.5-alpha.1 — réconciliation des baselines et cadrage
|
||||
|
||||
## Baseline et sources
|
||||
|
||||
Baseline PGR : archive source fournie `pgr-v0.0.4.zip`, déclarée téléchargée depuis le tag Gitea `v0.0.4`, accompagnée du rapport externe `pgr-0.0.4-publish.001-report.md` avec statut `PASS`.
|
||||
|
||||
SHA-256 vérifié :
|
||||
|
||||
```text
|
||||
pgr-v0.0.4.zip 7137bb084f017362323a2043d13ba71490be15b8786adc8d645981bf455b80ae
|
||||
khadhroony-solana-project-v0.3.16.zip db3cc1b3fc3fb07ee864b02e2a7346c673d4cf63b33e8e872aca6c6458856ca0
|
||||
games-v0.3.5.zip 5f5fdee1a271386766d059657d6eaa831acdc263b3e722fed738808335c0a105
|
||||
```
|
||||
|
||||
Les deux archives externes sont des corpus autoritaires de réconciliation pour cette session, pas des projets déjà gouvernés par PGR. Elles ne sont ni modifiées ni incorporées à l'archive delta.
|
||||
|
||||
Version avant application :
|
||||
|
||||
```text
|
||||
0.0.4
|
||||
```
|
||||
|
||||
Version après application :
|
||||
|
||||
```text
|
||||
0.0.5-alpha.1
|
||||
```
|
||||
|
||||
## Objet
|
||||
|
||||
Exécuter la gate de cadrage imposée par `prompts/005-V0_0_5_START_PROMPT.md` : vérifier indépendamment la stable PGR et sa preuve post-tag, contrôler les deux snapshots externes fournis, inventorier leurs responsabilités et audits, puis classer les écarts avant toute modification normative importante.
|
||||
|
||||
L'analyse détaillée vit dans `docs/studies/001-KSP_GAMES_RECONCILIATION.md`. Elle confirme que KSP `v0.3.16` et Games `v0.3.5` n'ont pas encore adopté PGR et ne doivent donc pas être jugés comme des projets non conformes. La plupart des mécanismes de gouvernance, documentation, validation et Rust/Cargo observés sont déjà correctement possédés par PGR.
|
||||
|
||||
Quatre axes communs restent suffisamment étayés pour le plan `0.0.5` : contrat générique des prompts versionnés, pattern facultatif de contrats de fichiers/familles, audit Rust de façade/export completeness, et Tauri comme premier candidat réel à la famille framework `700`.
|
||||
|
||||
Aucun de ces axes n'est matérialisé normativement dans `alpha.1`. Web/Vite/WASM, JNI, les audits composites et les règles métier ou de distribution spécifiques restent différés ou locaux.
|
||||
|
||||
## Vérifications d'intake déjà exécutées
|
||||
|
||||
Le ZIP PGR est lisible, possède une racine unique `pgr/`, `139` fichiers et `28` répertoires, sans doublon, collision de casse, chemin dangereux, lien symbolique ni `.git`. Son hash concorde avec le rapport post-tag.
|
||||
|
||||
Les deux corpus externes passent les contrôles ZIP équivalents. Leurs audits statiques fournis ont également été exécutés avec succès : audits Rust généraux/export/workspace et tableaux Markdown pour KSP ; audits Rust généraux/export/workspace, tableaux Markdown et distribution layout pour Games.
|
||||
|
||||
Sur la stable PGR extraite, les `15` tests Python passent, les trois audits Markdown sont propres et les cinq TOML Rust/Cargo se parsèrent. La toolchain `cargo` n'est pas disponible dans l'environnement de préparation ; aucune commande Cargo externe n'est donc présentée comme exécutée.
|
||||
|
||||
## Scope
|
||||
|
||||
REPLACE :
|
||||
|
||||
```text
|
||||
VERSION
|
||||
README.md
|
||||
docs/000-README.md
|
||||
```
|
||||
|
||||
ADD :
|
||||
|
||||
```text
|
||||
docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||
docs/studies/000-README.md
|
||||
docs/studies/001-KSP_GAMES_RECONCILIATION.md
|
||||
deltas/0.0.5/alpha.1.md
|
||||
```
|
||||
|
||||
DELETE : aucun.
|
||||
|
||||
L'archive delta contient uniquement ces sept fichiers complets avec leurs chemins relatifs. Aucun history, règle normative, script, template technique, profil framework, skeleton ou modification KSP/Games n'appartient à cette tranche.
|
||||
|
||||
`ROADMAP.md` annonce déjà `0.0.5` comme planifiée et `CHANGELOG.md` reste limité aux releases publiées ; aucun changement cérémoniel de ces deux fichiers n'est requis ici.
|
||||
|
||||
## Validation opérateur
|
||||
|
||||
Après application sur le commit stable `0.0.4`, depuis la racine du dépôt :
|
||||
|
||||
```bash
|
||||
test "$(cat VERSION)" = '0.0.5-alpha.1'
|
||||
test -f docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||
test -f docs/studies/000-README.md
|
||||
test -f docs/studies/001-KSP_GAMES_RECONCILIATION.md
|
||||
test -f deltas/0.0.5/alpha.1.md
|
||||
test ! -e history/0.0.5/alpha.1.md
|
||||
|
||||
grep -Fx '<!-- version: 12 -->' README.md
|
||||
grep -Fx '<!-- version: 10 -->' docs/000-README.md
|
||||
grep -F '005-V0_0_5_RECONCILIATION_PLAN.md' README.md docs/000-README.md
|
||||
grep -F '001-KSP_GAMES_RECONCILIATION.md' README.md docs/000-README.md docs/studies/000-README.md
|
||||
|
||||
python3 -B -m unittest discover -s tests -v
|
||||
|
||||
python3 -B scripts/audit_markdown_headers.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_tables.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_links.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
|
||||
python3 -B - <<'PY'
|
||||
from pathlib import Path
|
||||
import re
|
||||
import tomllib
|
||||
|
||||
expected_hashes = {
|
||||
'pgr-v0.0.4.zip': '7137bb084f017362323a2043d13ba71490be15b8786adc8d645981bf455b80ae',
|
||||
'khadhroony-solana-project-v0.3.16.zip': 'db3cc1b3fc3fb07ee864b02e2a7346c673d4cf63b33e8e872aca6c6458856ca0',
|
||||
'games-v0.3.5.zip': '5f5fdee1a271386766d059657d6eaa831acdc263b3e722fed738808335c0a105',
|
||||
}
|
||||
|
||||
study = Path('docs/studies/001-KSP_GAMES_RECONCILIATION.md').read_text(encoding='utf-8')
|
||||
plan = Path('docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md').read_text(encoding='utf-8')
|
||||
for name, digest in expected_hashes.items():
|
||||
assert name in study or name in plan, name
|
||||
assert digest in study or digest in plan, digest
|
||||
|
||||
for path in (
|
||||
Path('templates/rust-cargo/rustfmt.toml'),
|
||||
Path('templates/rust-cargo/clippy.toml'),
|
||||
Path('templates/rust-cargo/.cargo/config.toml'),
|
||||
Path('templates/rust-cargo/Cargo.toml'),
|
||||
Path('templates/rust-cargo/crates/project-core-lib/Cargo.toml'),
|
||||
):
|
||||
with path.open('rb') as stream:
|
||||
tomllib.load(stream)
|
||||
|
||||
expected_counts = {'0.0.1': 12, '0.0.2': 12, '0.0.3': 10, '0.0.4': 9}
|
||||
for release, expected in expected_counts.items():
|
||||
deltas = {path.name for path in Path('deltas', release).glob('*.md')}
|
||||
histories = {path.name for path in Path('history', release).glob('*.md')}
|
||||
assert len(deltas) == expected, (release, len(deltas))
|
||||
assert deltas == histories, (release, sorted(deltas ^ histories))
|
||||
|
||||
statuses_004 = {}
|
||||
for path in Path('history/0.0.4').glob('*.md'):
|
||||
text = path.read_text(encoding='utf-8')
|
||||
match = re.search(r'## Statut\s+(PASS|FAIL|PARTIAL|BLOCKED)\s', text)
|
||||
assert match is not None, path
|
||||
statuses_004[path.name] = match.group(1)
|
||||
assert statuses_004['alpha.4.md'] == 'FAIL'
|
||||
assert statuses_004['alpha.4.fix.1.md'] == 'PASS'
|
||||
assert statuses_004['beta.1.md'] == 'FAIL'
|
||||
assert statuses_004['beta.1.fix.1.md'] == 'PASS'
|
||||
assert statuses_004['rc.1.md'] == 'PASS'
|
||||
assert statuses_004['rel.001.md'] == 'PASS'
|
||||
|
||||
assert 'ne sont pas encore gouvernés par PGR' in plan
|
||||
assert 'aucune migration de KSP ou Games' in plan
|
||||
assert 'Tauri' in plan
|
||||
assert 'audit_rust_export_completeness.py' in study
|
||||
|
||||
print('0.0.5 alpha.1 structural audit: clean (43 prior pairs, 5 TOML parsed, reconciliation sources recorded)')
|
||||
PY
|
||||
|
||||
git diff --check
|
||||
git add VERSION README.md docs/000-README.md \
|
||||
docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md \
|
||||
docs/studies/000-README.md docs/studies/001-KSP_GAMES_RECONCILIATION.md \
|
||||
deltas/0.0.5/alpha.1.md
|
||||
git diff --cached --check
|
||||
git status --short
|
||||
```
|
||||
|
||||
Le scope indexé attendu avant ajout du history est :
|
||||
|
||||
```text
|
||||
M README.md
|
||||
M VERSION
|
||||
A deltas/0.0.5/alpha.1.md
|
||||
M docs/000-README.md
|
||||
A docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||
A docs/studies/000-README.md
|
||||
A docs/studies/001-KSP_GAMES_RECONCILIATION.md
|
||||
```
|
||||
|
||||
La revue opérateur doit en outre confirmer que :
|
||||
|
||||
- les trois archives/hashes consignés correspondent bien aux sources autoritaires fournies pour cette reprise ;
|
||||
- l'étude traite KSP et Games comme corpus non encore migrés vers PGR ;
|
||||
- le plan n'atteste aucun profil Tauri, audit de façade ou template avant sa tranche dédiée ;
|
||||
- les conventions métier et plateforme locales ne sont pas promues en règles PGR par simple similarité ;
|
||||
- aucune modification des deux projets externes n'est cachée dans le delta.
|
||||
|
||||
## Transition
|
||||
|
||||
### PASS
|
||||
|
||||
Rédiger et livrer séparément `history/0.0.5/alpha.1.md` avec les résultats réellement observés ; l'appliquer et committer la tranche. Préparer seulement ensuite `0.0.5-alpha.2` pour le contrat générique des prompts versionnés.
|
||||
|
||||
### FAIL
|
||||
|
||||
Consigner le résultat réel dans le history de `alpha.1`, puis corriger le cadrage dans `0.0.5-alpha.1.fix.1` ou produire un REPLAN motivé. Aucun contenu de `alpha.2` ne doit être absorbé silencieusement dans un fix.
|
||||
179
deltas/0.0.5/alpha.2.md
Normal file
179
deltas/0.0.5/alpha.2.md
Normal file
@@ -0,0 +1,179 @@
|
||||
<!-- file: deltas/0.0.5/alpha.2.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Delta 0.0.5-alpha.2 — contrat générique des prompts de démarrage
|
||||
|
||||
## Baseline et version
|
||||
|
||||
Baseline attendue : commit opérateur de `0.0.5-alpha.1`, réalisé après application de `history/0.0.5/alpha.1.md` avec statut `PASS`.
|
||||
|
||||
Le hash de ce commit n'est volontairement pas anticipé : le history `alpha.1` et le présent delta peuvent être livrés dans le même échange, mais restent deux archives séparées et le delta `alpha.2` MUST NOT être appliqué avant le commit de `alpha.1`.
|
||||
|
||||
Version avant application :
|
||||
|
||||
```text
|
||||
0.0.5-alpha.1
|
||||
```
|
||||
|
||||
Version après application :
|
||||
|
||||
```text
|
||||
0.0.5-alpha.2
|
||||
```
|
||||
|
||||
## Objet
|
||||
|
||||
Exécuter la deuxième tranche du plan `0.0.5` en renforçant l'owner `docs/rules/210-WORKFLOW.md` pour les prompts de démarrage versionnés.
|
||||
|
||||
Les prompts PGR récents et les baselines KSP/Games montrent qu'un bon prompt de reprise ne se limite pas à nommer une baseline et une mission : il doit permettre de reconstruire explicitement l'état utile, les sources à lire, les décisions déjà acquises, les limites de scope, la première gate et la trajectoire de validation sans réimporter toute la documentation du projet.
|
||||
|
||||
La tranche généralise ce contrat sémantique sans copier la structure exhaustive des prompts KSP/Games. Elle ne crée ni nouveau template manuel ni nouveau type d'artefact.
|
||||
|
||||
## Scope
|
||||
|
||||
REPLACE :
|
||||
|
||||
```text
|
||||
VERSION
|
||||
docs/rules/000-README.md
|
||||
docs/rules/210-WORKFLOW.md
|
||||
```
|
||||
|
||||
ADD :
|
||||
|
||||
```text
|
||||
deltas/0.0.5/alpha.2.md
|
||||
```
|
||||
|
||||
DELETE : aucun.
|
||||
|
||||
L'archive delta contient uniquement ces quatre fichiers complets avec leurs chemins relatifs. Elle ne contient pas `history/0.0.5/alpha.1.md`, livré séparément pour clôturer la tranche précédente, ni `history/0.0.5/alpha.2.md`, qui sera produit après la gate opérateur.
|
||||
|
||||
Le plan `docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md`, l'étude `docs/studies/001-KSP_GAMES_RECONCILIATION.md` et `docs/templates/003-NEW_SESSION_PROMPT.md` restent inchangés : cette tranche exécute leur trajectoire et préserve explicitement la séparation entre prompt versionné et message manuel de nouvelle session.
|
||||
|
||||
## Contrat matérialisé
|
||||
|
||||
`docs/rules/210-WORKFLOW.md` porte désormais un contrat réutilisable des prompts de démarrage versionnés couvrant :
|
||||
|
||||
- baseline autoritaire, cible et première tranche ;
|
||||
- ordre de lecture nécessaire à une reprise fiable ;
|
||||
- état déjà acquis et traçabilité des décisions conservées ;
|
||||
- mission et résultat attendu ;
|
||||
- scope et hors-scope ;
|
||||
- décisions gelées et questions ouvertes ;
|
||||
- première gate et travaux éventuellement interdits avant sa fermeture ;
|
||||
- trajectoire prévisionnelle explicitement non contraignante ;
|
||||
- validation et responsabilité de la preuve ;
|
||||
- comportement fail-closed lorsqu'une source externe requise manque.
|
||||
|
||||
Le contrat reste sémantique : il n'impose pas neuf titres littéraux ni une longueur uniforme. Les projets importants peuvent détailler leur ordre de lecture et leurs questions de cadrage ; les projets simples conservent une forme courte dès lors que les mêmes responsabilités sont couvertes.
|
||||
|
||||
Les règles locales de langage, plateforme, framework, architecture ou métier ne deviennent pas des règles PGR parce qu'elles apparaissent dans un prompt. Le prompt doit renvoyer vers les owners existants au lieu de les dupliquer.
|
||||
|
||||
`docs/templates/003-NEW_SESSION_PROMPT.md` conserve son rôle distinct : produire la courte phrase manuelle de reprise après une stable publiée. Il ne remplace pas le prompt versionné et n'est pas dupliqué par cette tranche.
|
||||
|
||||
## Validation opérateur
|
||||
|
||||
Après avoir appliqué `history/0.0.5/alpha.1.md`, committé `0.0.5-alpha.1`, puis appliqué le présent delta, depuis la racine du dépôt :
|
||||
|
||||
```bash
|
||||
test "$(cat VERSION)" = '0.0.5-alpha.2'
|
||||
test -f history/0.0.5/alpha.1.md
|
||||
test -f deltas/0.0.5/alpha.2.md
|
||||
test ! -e history/0.0.5/alpha.2.md
|
||||
|
||||
grep -Fx '<!-- version: 12 -->' docs/rules/000-README.md
|
||||
grep -Fx '<!-- version: 4 -->' docs/rules/210-WORKFLOW.md
|
||||
grep -F 'prompts versionnés' docs/rules/000-README.md
|
||||
|
||||
python3 -B -m unittest discover -s tests -v
|
||||
|
||||
python3 -B scripts/audit_markdown_headers.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_tables.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_links.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
|
||||
python3 -B - <<'PY'
|
||||
from pathlib import Path
|
||||
import re
|
||||
|
||||
history = Path('history/0.0.5/alpha.1.md').read_text(encoding='utf-8')
|
||||
assert re.search(r'## Statut\s+PASS\s', history)
|
||||
|
||||
workflow = Path('docs/rules/210-WORKFLOW.md').read_text(encoding='utf-8')
|
||||
required = (
|
||||
'## Prompt de démarrage versionné',
|
||||
'### Contrat minimal',
|
||||
'baseline autoritaire et cible',
|
||||
'ordre de lecture',
|
||||
'état déjà acquis',
|
||||
'mission et résultat attendu',
|
||||
'scope et hors-scope',
|
||||
'décisions gelées et questions ouvertes',
|
||||
'première gate',
|
||||
'trajectoire prévisionnelle',
|
||||
'validation et responsabilité',
|
||||
'### Sources externes et données manquantes',
|
||||
'### Décisions acquises et détails locaux',
|
||||
'### Création et clôture',
|
||||
'003-NEW_SESSION_PROMPT.md',
|
||||
)
|
||||
for phrase in required:
|
||||
assert phrase in workflow, phrase
|
||||
|
||||
for forbidden in (
|
||||
'prompts/036-V0_3_17_START_PROMPT.md',
|
||||
'prompts/007-V0_3_6_START_PROMPT.md',
|
||||
'tokio-postgres',
|
||||
'WebTransport',
|
||||
'Uroburas',
|
||||
):
|
||||
assert forbidden not in workflow, forbidden
|
||||
|
||||
assert 'MUST NOT les recopier exhaustivement' in workflow
|
||||
assert 'Le prompt n\'a pas à reproduire littéralement cette numérotation.' in workflow
|
||||
assert 'MUST NOT autoriser à reconstituer silencieusement' in workflow
|
||||
assert 'Les contraintes locales de langage, plateforme, framework, architecture ou métier restent chez leurs owners respectifs.' in workflow
|
||||
|
||||
manual = Path('docs/templates/003-NEW_SESSION_PROMPT.md').read_text(encoding='utf-8')
|
||||
assert '<!-- version: 1 -->' in manual
|
||||
assert 'une seule phrase' in manual
|
||||
|
||||
print('0.0.5 alpha.2 prompt contract audit: clean (versioned prompt strengthened, manual restart template unchanged)')
|
||||
PY
|
||||
|
||||
git diff --check
|
||||
git add VERSION docs/rules/000-README.md docs/rules/210-WORKFLOW.md \
|
||||
deltas/0.0.5/alpha.2.md
|
||||
git diff --cached --check
|
||||
git status --short
|
||||
```
|
||||
|
||||
Le scope indexé attendu avant ajout du history est :
|
||||
|
||||
```text
|
||||
M VERSION
|
||||
A deltas/0.0.5/alpha.2.md
|
||||
M docs/rules/000-README.md
|
||||
M docs/rules/210-WORKFLOW.md
|
||||
```
|
||||
|
||||
La revue opérateur doit en outre confirmer que :
|
||||
|
||||
- le nouveau contrat décrit des responsabilités de reprise et non une liste obligatoire de titres ;
|
||||
- la baseline et les sources manquantes restent fail-closed : aucun état externe n'est reconstruit depuis un souvenir ou un workspace non fourni ;
|
||||
- les décisions acquises sont résumées seulement lorsqu'elles empêchent une régression utile et restent traçables vers leur owner ;
|
||||
- les contraintes KSP/Games spécifiques ne sont pas aspirées dans la règle générale ;
|
||||
- le template `003-NEW_SESSION_PROMPT.md` reste la forme courte post-publication et n'est ni remplacé ni dupliqué.
|
||||
|
||||
## Transition
|
||||
|
||||
### PASS
|
||||
|
||||
Rédiger et livrer séparément `history/0.0.5/alpha.2.md` avec les résultats réellement observés ; l'appliquer et committer la tranche. Préparer seulement ensuite `0.0.5-alpha.3` pour le pattern facultatif de contrats de fichiers/familles.
|
||||
|
||||
### FAIL
|
||||
|
||||
Consigner le résultat réel dans le history de `alpha.2`, puis corriger le contrat dans `0.0.5-alpha.2.fix.1` ou produire un REPLAN motivé. Aucun contenu de `alpha.3` ne doit être absorbé silencieusement dans un fix.
|
||||
164
deltas/0.0.5/alpha.3.fix.1.md
Normal file
164
deltas/0.0.5/alpha.3.fix.1.md
Normal file
@@ -0,0 +1,164 @@
|
||||
<!-- file: deltas/0.0.5/alpha.3.fix.1.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Delta 0.0.5-alpha.3.fix.1 — couverture des tables dans les exemples Markdown fenced
|
||||
|
||||
## Baseline et version
|
||||
|
||||
Baseline attendue : commit opérateur de `0.0.5-alpha.3`, réalisé après application de `history/0.0.5/alpha.3.md` avec statut `FAIL`.
|
||||
|
||||
Le hash de ce commit n'est pas anticipé.
|
||||
|
||||
Version avant application :
|
||||
|
||||
```text
|
||||
0.0.5-alpha.3
|
||||
```
|
||||
|
||||
Version après application :
|
||||
|
||||
```text
|
||||
0.0.5-alpha.3.fix.1
|
||||
```
|
||||
|
||||
## Objet
|
||||
|
||||
Corriger le faux négatif découvert pendant la gate opérateur de `alpha.3` : `audit_markdown_tables.py` ignorait toutes les tables placées dans des blocs fenced, y compris les exemples explicitement `markdown` du template `004-FILE_FAMILY_CONTRACTS.md`.
|
||||
|
||||
Le fix étend uniquement le contrat de l'audit de tables. Il ne transforme pas l'audit en analyseur général des blocs de code et n'introduit aucun contenu de la tranche Rust `alpha.4`.
|
||||
|
||||
## Scope
|
||||
|
||||
REPLACE :
|
||||
|
||||
```text
|
||||
VERSION
|
||||
scripts/audit_markdown_tables.py
|
||||
docs/templates/004-FILE_FAMILY_CONTRACTS.md
|
||||
docs/validation/001-VALIDATION_MATRIX.md
|
||||
```
|
||||
|
||||
ADD :
|
||||
|
||||
```text
|
||||
tests/test_markdown_tables.py
|
||||
deltas/0.0.5/alpha.3.fix.1.md
|
||||
```
|
||||
|
||||
DELETE : aucun.
|
||||
|
||||
Le history `history/0.0.5/alpha.3.md` appartient au commit baseline du FAIL et n'est pas inclus dans l'archive du fix.
|
||||
|
||||
## Correction
|
||||
|
||||
`scripts/audit_markdown_tables.py` passe en révision interne `2`.
|
||||
|
||||
L'audit continue de contrôler les tables Markdown ordinaires. Dans un bloc fenced :
|
||||
|
||||
- une fence explicitement `markdown` est auditée ;
|
||||
- une fence explicitement `md` est auditée ;
|
||||
- une fence d'un autre langage ou sans langage reste ignorée.
|
||||
|
||||
Cette frontière évite les faux positifs sur les sorties terminal, extraits de code ou tableaux ASCII qui utilisent éventuellement des pipes sans être du Markdown à gouverner.
|
||||
|
||||
`tests/test_markdown_tables.py` verrouille quatre cas :
|
||||
|
||||
1. table ordinaire et table fenced Markdown valides toutes deux comptées ;
|
||||
2. table mal alignée dans une fence `markdown` rejetée ;
|
||||
3. alias `md` audité ;
|
||||
4. fence non Markdown conservée hors scope.
|
||||
|
||||
`docs/templates/004-FILE_FAMILY_CONTRACTS.md` passe en révision `2` et réaligne les deux tables fenced révélées par le nouvel audit.
|
||||
|
||||
`docs/validation/001-VALIDATION_MATRIX.md` passe en révision `10` et explicite la frontière de `PGR-MD-TABLE-001`.
|
||||
|
||||
## Validation opérateur
|
||||
|
||||
Après application du history `FAIL`, commit de `alpha.3`, puis application du présent delta :
|
||||
|
||||
```bash
|
||||
test "$(cat VERSION)" = '0.0.5-alpha.3.fix.1'
|
||||
test -f history/0.0.5/alpha.3.md
|
||||
test -f deltas/0.0.5/alpha.3.md
|
||||
test -f deltas/0.0.5/alpha.3.fix.1.md
|
||||
test -f tests/test_markdown_tables.py
|
||||
test ! -e history/0.0.5/alpha.3.fix.1.md
|
||||
|
||||
grep -A2 '^## Statut$' history/0.0.5/alpha.3.md | grep -Fx 'FAIL'
|
||||
grep -Fx '# version: 2' scripts/audit_markdown_tables.py
|
||||
grep -Fx '<!-- version: 2 -->' docs/templates/004-FILE_FAMILY_CONTRACTS.md
|
||||
grep -Fx '<!-- version: 10 -->' docs/validation/001-VALIDATION_MATRIX.md
|
||||
grep -Fx '# version: 1' tests/test_markdown_tables.py
|
||||
|
||||
python3 -B -m unittest discover -s tests -p 'test_markdown_tables.py' -v
|
||||
python3 -B -m unittest discover -s tests -v
|
||||
|
||||
python3 -B scripts/audit_markdown_headers.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_tables.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_links.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
|
||||
python3 -B scripts/audit_markdown_tables.py docs/templates/004-FILE_FAMILY_CONTRACTS.md
|
||||
|
||||
python3 -B - <<'PY'
|
||||
from pathlib import Path
|
||||
import re
|
||||
|
||||
history = Path('history/0.0.5/alpha.3.md').read_text(encoding='utf-8')
|
||||
assert re.search(r'## Statut\s+FAIL\s', history)
|
||||
|
||||
script = Path('scripts/audit_markdown_tables.py').read_text(encoding='utf-8')
|
||||
assert '_MARKDOWN_FENCE_LANGUAGES = frozenset({"markdown", "md"})' in script
|
||||
assert 'audit_fenced_markdown' in script
|
||||
|
||||
template = Path('docs/templates/004-FILE_FAMILY_CONTRACTS.md').read_text(encoding='utf-8')
|
||||
assert template.count('```markdown') == 2
|
||||
|
||||
matrix = Path('docs/validation/001-VALIDATION_MATRIX.md').read_text(encoding='utf-8')
|
||||
assert 'fences explicitement `markdown` ou `md`' in matrix
|
||||
assert 'sorties terminal' in matrix
|
||||
|
||||
print('0.0.5 alpha.3.fix.1 fenced Markdown table audit: clean (regression covered, two template examples governed)')
|
||||
PY
|
||||
|
||||
git diff --check
|
||||
|
||||
git add VERSION scripts/audit_markdown_tables.py tests/test_markdown_tables.py \
|
||||
docs/templates/004-FILE_FAMILY_CONTRACTS.md \
|
||||
docs/validation/001-VALIDATION_MATRIX.md \
|
||||
deltas/0.0.5/alpha.3.fix.1.md
|
||||
|
||||
git diff --cached --check
|
||||
git status --short
|
||||
```
|
||||
|
||||
La sortie Git attendue avant ajout du history du fix est exactement :
|
||||
|
||||
```text
|
||||
M VERSION
|
||||
A deltas/0.0.5/alpha.3.fix.1.md
|
||||
M docs/templates/004-FILE_FAMILY_CONTRACTS.md
|
||||
M docs/validation/001-VALIDATION_MATRIX.md
|
||||
M scripts/audit_markdown_tables.py
|
||||
A tests/test_markdown_tables.py
|
||||
```
|
||||
|
||||
Le contrôle ciblé du template doit désormais compter ses deux exemples :
|
||||
|
||||
```text
|
||||
Markdown table audit: clean (2 table(s), 1 file(s))
|
||||
```
|
||||
|
||||
La suite Python doit compter `19` tests si aucun autre test n'est ajouté localement avant exécution.
|
||||
|
||||
## Transition
|
||||
|
||||
### PASS
|
||||
|
||||
Créer et appliquer séparément `history/0.0.5/alpha.3.fix.1.md`, committer et pousser le fix, puis reprendre le plan `0.0.5` à `alpha.4`.
|
||||
|
||||
### FAIL
|
||||
|
||||
Rester dans `0.0.5-alpha.3.fix.M`. Le scope MUST rester limité au contrat de `PGR-MD-TABLE-001` et aux tables révélées par ce contrôle tant qu'aucun défaut plus large ne justifie un REPLAN.
|
||||
173
deltas/0.0.5/alpha.3.md
Normal file
173
deltas/0.0.5/alpha.3.md
Normal file
@@ -0,0 +1,173 @@
|
||||
<!-- file: deltas/0.0.5/alpha.3.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Delta 0.0.5-alpha.3 — pattern facultatif de contrats de fichiers ou familles
|
||||
|
||||
## Baseline et version
|
||||
|
||||
Baseline attendue : commit opérateur de `0.0.5-alpha.2`, réalisé après application de `history/0.0.5/alpha.2.md` avec statut `PASS`.
|
||||
|
||||
Le hash de ce commit n'est pas anticipé. Le history `alpha.2` et le présent delta peuvent être livrés dans le même échange, mais restent deux archives séparées et le delta `alpha.3` MUST NOT être appliqué avant le commit de `alpha.2`.
|
||||
|
||||
Version avant application :
|
||||
|
||||
```text
|
||||
0.0.5-alpha.2
|
||||
```
|
||||
|
||||
Version après application :
|
||||
|
||||
```text
|
||||
0.0.5-alpha.3
|
||||
```
|
||||
|
||||
## Objet
|
||||
|
||||
Exécuter la troisième tranche du plan `0.0.5` en généralisant un besoin observé indépendamment dans les deux corpus externes : expliciter, lorsque la complexité le justifie, la responsabilité et la règle de modification de certaines familles de fichiers locales.
|
||||
|
||||
La tranche normalise le pattern et non les catalogues KSP/Games. Elle n'impose ni le nom `FILE_CONTRACTS.md`, ni une table exhaustive, ni la reprise de leurs chemins, règles métier ou conventions de release.
|
||||
|
||||
## Scope
|
||||
|
||||
REPLACE :
|
||||
|
||||
```text
|
||||
VERSION
|
||||
docs/000-README.md
|
||||
docs/rules/300-DOCUMENTATION.md
|
||||
docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md
|
||||
```
|
||||
|
||||
ADD :
|
||||
|
||||
```text
|
||||
docs/templates/004-FILE_FAMILY_CONTRACTS.md
|
||||
deltas/0.0.5/alpha.3.md
|
||||
```
|
||||
|
||||
DELETE : aucun.
|
||||
|
||||
L'archive delta contient uniquement ces six fichiers complets avec leurs chemins relatifs. Elle ne contient pas `history/0.0.5/alpha.2.md`, livré séparément pour clôturer la tranche précédente, ni `history/0.0.5/alpha.3.md`, qui sera produit après la gate opérateur.
|
||||
|
||||
## Contrat matérialisé
|
||||
|
||||
`docs/rules/300-DOCUMENTATION.md` possède désormais le pattern générique :
|
||||
|
||||
- un registre local est facultatif et ne doit exister que pour lever une ambiguïté réelle ;
|
||||
- il décrit au minimum fichier/famille, responsabilité durable et règle de modification ;
|
||||
- source de vérité, statut généré/versionné, owner ou validation restent des champs optionnels ;
|
||||
- le registre ne doit ni recopier les owners existants ni devenir un miroir exhaustif de l'arborescence ;
|
||||
- son nom, son emplacement et sa forme appartiennent au projet destinataire ;
|
||||
- l'ajout d'un fichier déjà couvert par une famille ne force pas une entrée supplémentaire.
|
||||
|
||||
`docs/templates/004-FILE_FAMILY_CONTRACTS.md` fournit une forme d'adaptation courte avec critères d'usage, modèle minimal, règles d'instanciation et exemple abstrait.
|
||||
|
||||
La fondation `001-PROJECT_GOVERNANCE_FOUNDATION.md` référence ce pattern uniquement comme possibilité pour un projet dont plusieurs familles durables deviennent ambiguës. Elle confirme explicitement qu'un projet simple n'a rien à matérialiser.
|
||||
|
||||
## Validation opérateur
|
||||
|
||||
Après avoir appliqué `history/0.0.5/alpha.2.md`, committé `0.0.5-alpha.2`, puis appliqué le présent delta, depuis la racine du dépôt :
|
||||
|
||||
```bash
|
||||
test "$(cat VERSION)" = '0.0.5-alpha.3'
|
||||
test -f history/0.0.5/alpha.2.md
|
||||
test -f deltas/0.0.5/alpha.3.md
|
||||
test -f docs/templates/004-FILE_FAMILY_CONTRACTS.md
|
||||
test ! -e history/0.0.5/alpha.3.md
|
||||
|
||||
grep -Fx '<!-- version: 11 -->' docs/000-README.md
|
||||
grep -Fx '<!-- version: 3 -->' docs/rules/300-DOCUMENTATION.md
|
||||
grep -Fx '<!-- version: 2 -->' docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md
|
||||
grep -Fx '<!-- version: 1 -->' docs/templates/004-FILE_FAMILY_CONTRACTS.md
|
||||
|
||||
python3 -B -m unittest discover -s tests -v
|
||||
|
||||
python3 -B scripts/audit_markdown_headers.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_tables.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_links.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
|
||||
python3 -B - <<'PY'
|
||||
from pathlib import Path
|
||||
import re
|
||||
|
||||
history = Path('history/0.0.5/alpha.2.md').read_text(encoding='utf-8')
|
||||
assert re.search(r'## Statut\s+PASS\s', history)
|
||||
|
||||
doc = Path('docs/rules/300-DOCUMENTATION.md').read_text(encoding='utf-8')
|
||||
template = Path('docs/templates/004-FILE_FAMILY_CONTRACTS.md').read_text(encoding='utf-8')
|
||||
foundation = Path('docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md').read_text(encoding='utf-8')
|
||||
index = Path('docs/000-README.md').read_text(encoding='utf-8')
|
||||
|
||||
required_doc = (
|
||||
'## Registre local de contrats de fichiers ou familles',
|
||||
'outil de désambiguïsation, pas un inventaire exhaustif',
|
||||
'le fichier, motif de chemin ou famille concernée',
|
||||
'sa responsabilité durable',
|
||||
'la règle ou le déclencheur pertinent de modification',
|
||||
'PGR n\'impose ni `FILE_CONTRACTS.md`',
|
||||
'l\'ajout d\'un fichier conforme à une famille déjà décrite ne force pas une nouvelle entrée',
|
||||
)
|
||||
for phrase in required_doc:
|
||||
assert phrase in doc, phrase
|
||||
|
||||
required_template = (
|
||||
'# Pattern — contrats locaux de fichiers ou familles',
|
||||
'Quand l\'utiliser',
|
||||
'Forme minimale',
|
||||
'Règles d\'adaptation',
|
||||
'Critère de sortie',
|
||||
'`docs/rules/FILE_CONTRACTS.md` est un nom possible, pas une convention PGR obligatoire',
|
||||
)
|
||||
for phrase in required_template:
|
||||
assert phrase in template, phrase
|
||||
|
||||
assert '004-FILE_FAMILY_CONTRACTS.md' in foundation
|
||||
assert 'Ce registre reste facultatif' in foundation
|
||||
assert '004-FILE_FAMILY_CONTRACTS.md' in index
|
||||
|
||||
for text in (doc, template, foundation):
|
||||
for forbidden in ('tokio-postgres', 'WebTransport', 'Uroburas'):
|
||||
assert forbidden not in text, forbidden
|
||||
|
||||
print('0.0.5 alpha.3 file-family contract audit: clean (optional registry, short reusable pattern, no project-specific contract imported)')
|
||||
PY
|
||||
|
||||
git diff --check
|
||||
git add VERSION docs/000-README.md docs/rules/300-DOCUMENTATION.md \
|
||||
docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md \
|
||||
docs/templates/004-FILE_FAMILY_CONTRACTS.md deltas/0.0.5/alpha.3.md
|
||||
git diff --cached --check
|
||||
git status --short
|
||||
```
|
||||
|
||||
Le scope indexé attendu avant ajout du history est :
|
||||
|
||||
```text
|
||||
M VERSION
|
||||
A deltas/0.0.5/alpha.3.md
|
||||
M docs/000-README.md
|
||||
M docs/rules/300-DOCUMENTATION.md
|
||||
M docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md
|
||||
A docs/templates/004-FILE_FAMILY_CONTRACTS.md
|
||||
```
|
||||
|
||||
La revue opérateur doit en outre confirmer que :
|
||||
|
||||
- le pattern réduit une ambiguïté réelle au lieu d'imposer une nouvelle cérémonie ;
|
||||
- `FILE_CONTRACTS.md` reste un exemple de nom, jamais une obligation ;
|
||||
- le registre ne devient pas un catalogue exhaustif de chaque fichier du dépôt ;
|
||||
- une règle détaillée déjà possédée ailleurs est référencée plutôt que dupliquée ;
|
||||
- la fondation n'impose aucun nouveau document aux petits projets ou aux projets dont les responsabilités sont déjà claires.
|
||||
|
||||
## Transition
|
||||
|
||||
### PASS
|
||||
|
||||
Rédiger et livrer séparément `history/0.0.5/alpha.3.md` avec les résultats réellement observés ; l'appliquer et committer la tranche. Préparer seulement ensuite `0.0.5-alpha.4` pour l'audit Rust facultatif de façade/export completeness.
|
||||
|
||||
### FAIL
|
||||
|
||||
Consigner le résultat réel dans le history de `alpha.3`, puis corriger le pattern dans `0.0.5-alpha.3.fix.1` ou produire un REPLAN motivé. Aucun contenu de l'audit Rust `alpha.4` ne doit être absorbé silencieusement dans un fix.
|
||||
221
deltas/0.0.5/alpha.4.md
Normal file
221
deltas/0.0.5/alpha.4.md
Normal file
@@ -0,0 +1,221 @@
|
||||
<!-- file: deltas/0.0.5/alpha.4.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Delta 0.0.5-alpha.4 — REPLAN du lifecycle inter-release et de l'horizon
|
||||
|
||||
## Baseline et version
|
||||
|
||||
Baseline attendue : commit opérateur complet de `0.0.5-alpha.3.fix.1`, réalisé après application de `history/0.0.5/alpha.3.fix.1.md` avec statut `PASS`.
|
||||
|
||||
Le hash de ce futur commit n'est pas anticipé.
|
||||
|
||||
Version avant application :
|
||||
|
||||
```text
|
||||
0.0.5-alpha.3.fix.1
|
||||
```
|
||||
|
||||
Version après application :
|
||||
|
||||
```text
|
||||
0.0.5-alpha.4
|
||||
```
|
||||
|
||||
## Rôle de la tranche
|
||||
|
||||
`alpha.4` est un `REPLAN` déclenché après la gate réussie du fix précédent. Il traite un besoin de gouvernance général découvert en relisant le plan `0.0.5`, `ROADMAP.md` et les historiques de conception PGR `0.0.1` à `0.0.4` : les responsabilités de fermeture sont connues séparément mais ne sont pas encore reliées par un contrat explicite de plan, et l'horizon des versions futures ne possède pas de mécanisme de revue.
|
||||
|
||||
La tranche ne remet pas en cause `alpha.3.fix.1`, ne commence pas le chantier Rust de façade et ne matérialise aucun profil Tauri.
|
||||
|
||||
## Scope
|
||||
|
||||
REPLACE :
|
||||
|
||||
```text
|
||||
VERSION
|
||||
ROADMAP.md
|
||||
docs/000-README.md
|
||||
docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||
docs/rules/200-GOVERNANCE.md
|
||||
docs/rules/210-WORKFLOW.md
|
||||
docs/rules/300-DOCUMENTATION.md
|
||||
docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md
|
||||
docs/templates/003-NEW_SESSION_PROMPT.md
|
||||
```
|
||||
|
||||
ADD :
|
||||
|
||||
```text
|
||||
docs/templates/005-RELEASE_PLAN.md
|
||||
deltas/0.0.5/alpha.4.md
|
||||
```
|
||||
|
||||
DELETE : aucun.
|
||||
|
||||
Le history `alpha.3.fix.1` appartient au commit baseline et n'est pas inclus dans l'archive du présent delta.
|
||||
|
||||
## Décisions matérialisées
|
||||
|
||||
### Plan de release
|
||||
|
||||
Un plan complexe doit désormais expliciter sa **clôture et transition** : réconciliation documentaire, `CHANGELOG`, `ROADMAP`, prompt/handoff suivant, fermeture du plan, stable et publication.
|
||||
|
||||
Il doit aussi indiquer si une **revue d'horizon** est nécessaire. Une cible future inconnue reste inconnue : PGR interdit d'inventer une version ou une mission uniquement pour remplir le plan.
|
||||
|
||||
### Revue d'horizon
|
||||
|
||||
`ROADMAP.md` devient explicitement une trajectoire macro engagée à horizon fini. Une revue d'horizon est déclenchée lorsque la dernière release connue approche, qu'un jalon change la trajectoire ou que les ideas/studies/décisions accumulées justifient de rediscuter la suite.
|
||||
|
||||
La revue peut vivre dans une session stratégique séparée sans changement de `VERSION`.
|
||||
|
||||
Pour PGR, l'après-`0.1.0` reste volontairement ouvert. Le plan `0.1.0` devra programmer sa propre revue avant fermeture au lieu de spéculer dès `0.0.5`.
|
||||
|
||||
### Continuité et productivité
|
||||
|
||||
Lorsque la gate courante est `PASS` et que la suite est déjà déterminée, le générateur peut remettre `history` courant et `delta` suivant dans la même réponse. Les archives restent séparées et le delta suivant reste interdit d'application avant le commit de la tranche courante.
|
||||
|
||||
Le message manuel après publication devient spontané lorsque la prochaine cible est connue. S'il existe une preuve post-tag externe requise, la consigne finale indique explicitement qu'elle doit être fournie avec l'archive taggée.
|
||||
|
||||
### Pattern de plan
|
||||
|
||||
`docs/templates/005-RELEASE_PLAN.md` fournit une forme courte réutilisable pour KSP, Games et les futurs projets : mission, état acquis/ouvert, scope, validation, forecast, déclencheurs de REPLAN, clôture/transition et revue d'horizon.
|
||||
|
||||
Le pattern ne crée pas un journal de revisions obligatoire ; les deltas/histories restent la trace détaillée.
|
||||
|
||||
## Replan de 0.0.5
|
||||
|
||||
L'ancien forecast est décalé :
|
||||
|
||||
```text
|
||||
alpha.4 REPLAN lifecycle inter-release / horizon
|
||||
alpha.5 audit Rust façade/export completeness
|
||||
alpha.6 profil Tauri
|
||||
alpha.7 décision skeleton Tauri
|
||||
beta.1 réconciliation intégrée
|
||||
rc.1 candidate gelée / CHANGELOG / ROADMAP / prompt 006
|
||||
stable 0.0.5 + publish.001 séparé
|
||||
```
|
||||
|
||||
Aucun ancien objectif n'est abandonné par ce décalage.
|
||||
|
||||
## Validation opérateur
|
||||
|
||||
Après application du history `PASS` de `alpha.3.fix.1`, commit/push de ce fix, puis application du présent delta :
|
||||
|
||||
```bash
|
||||
test "$(cat VERSION)" = '0.0.5-alpha.4'
|
||||
test -f history/0.0.5/alpha.3.fix.1.md
|
||||
test -f deltas/0.0.5/alpha.4.md
|
||||
test -f docs/templates/005-RELEASE_PLAN.md
|
||||
test ! -e history/0.0.5/alpha.4.md
|
||||
|
||||
grep -A2 '^## Statut$' history/0.0.5/alpha.3.fix.1.md | grep -Fx 'PASS'
|
||||
grep -Fx '<!-- version: 2 -->' docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||
grep -Fx '<!-- version: 3 -->' docs/rules/200-GOVERNANCE.md
|
||||
grep -Fx '<!-- version: 5 -->' docs/rules/210-WORKFLOW.md
|
||||
grep -Fx '<!-- version: 4 -->' docs/rules/300-DOCUMENTATION.md
|
||||
grep -Fx '<!-- version: 6 -->' ROADMAP.md
|
||||
grep -Fx '<!-- version: 2 -->' docs/templates/003-NEW_SESSION_PROMPT.md
|
||||
grep -Fx '<!-- version: 1 -->' docs/templates/005-RELEASE_PLAN.md
|
||||
|
||||
python3 -B -m unittest discover -s tests -v
|
||||
|
||||
python3 -B scripts/audit_markdown_headers.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_tables.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_links.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
|
||||
python3 -B - <<'PY'
|
||||
from pathlib import Path
|
||||
import re
|
||||
|
||||
history = Path('history/0.0.5/alpha.3.fix.1.md').read_text(encoding='utf-8')
|
||||
assert re.search(r'## Statut\s+PASS\s', history)
|
||||
|
||||
plan = Path('docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md').read_text(encoding='utf-8')
|
||||
for phrase in (
|
||||
'## REPLAN alpha.4 — lifecycle inter-release et horizon',
|
||||
'## Clôture et transition',
|
||||
'## Revue d\'horizon',
|
||||
'### alpha.5 — audit Rust de façade/export completeness',
|
||||
'### alpha.6 — premier profil framework : Tauri',
|
||||
'### alpha.7 — décision de skeleton Tauri',
|
||||
):
|
||||
assert phrase in plan, phrase
|
||||
|
||||
workflow = Path('docs/rules/210-WORKFLOW.md').read_text(encoding='utf-8')
|
||||
for phrase in (
|
||||
'clôture et transition',
|
||||
'revue d\'horizon',
|
||||
'archive history de la tranche courante',
|
||||
'archive delta de la tranche suivante',
|
||||
'MUST remettre spontanément',
|
||||
'preuve future extérieure au tag',
|
||||
):
|
||||
assert phrase in workflow, phrase
|
||||
|
||||
doc = Path('docs/rules/300-DOCUMENTATION.md').read_text(encoding='utf-8')
|
||||
for phrase in (
|
||||
'### Revue d\'horizon',
|
||||
'Une roadmap à horizon fini est valide.',
|
||||
'roadmap ou plan lorsqu\'un engagement de réalisation existe',
|
||||
):
|
||||
assert phrase in doc, phrase
|
||||
|
||||
roadmap = Path('ROADMAP.md').read_text(encoding='utf-8')
|
||||
assert '## Horizon après `0.1.0`' in roadmap
|
||||
assert 'L\'horizon est volontairement ouvert.' in roadmap
|
||||
assert '0.2.0' in roadmap # cité uniquement comme version à ne pas réserver arbitrairement
|
||||
|
||||
template = Path('docs/templates/005-RELEASE_PLAN.md').read_text(encoding='utf-8')
|
||||
for phrase in ('## Contrat minimal', '## Clôture et transition', '## Revue d\'horizon', '## Critère de sortie'):
|
||||
assert phrase in template, phrase
|
||||
|
||||
manual = Path('docs/templates/003-NEW_SESSION_PROMPT.md').read_text(encoding='utf-8')
|
||||
assert 'doit être remis spontanément' in manual
|
||||
assert 'horizon reste ouvert' in manual
|
||||
|
||||
print('0.0.5 alpha.4 lifecycle audit: clean (closure assigned, horizon review explicit, deterministic handoff optimized)')
|
||||
PY
|
||||
|
||||
git diff --check
|
||||
|
||||
git add VERSION ROADMAP.md docs/000-README.md \
|
||||
docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md \
|
||||
docs/rules/200-GOVERNANCE.md docs/rules/210-WORKFLOW.md \
|
||||
docs/rules/300-DOCUMENTATION.md \
|
||||
docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md \
|
||||
docs/templates/003-NEW_SESSION_PROMPT.md docs/templates/005-RELEASE_PLAN.md \
|
||||
deltas/0.0.5/alpha.4.md
|
||||
|
||||
git diff --cached --check
|
||||
git status --short
|
||||
```
|
||||
|
||||
La sortie Git attendue avant ajout du history `alpha.4` est exactement :
|
||||
|
||||
```text
|
||||
M ROADMAP.md
|
||||
M VERSION
|
||||
A deltas/0.0.5/alpha.4.md
|
||||
M docs/000-README.md
|
||||
M docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||
M docs/rules/200-GOVERNANCE.md
|
||||
M docs/rules/210-WORKFLOW.md
|
||||
M docs/rules/300-DOCUMENTATION.md
|
||||
M docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md
|
||||
M docs/templates/003-NEW_SESSION_PROMPT.md
|
||||
A docs/templates/005-RELEASE_PLAN.md
|
||||
```
|
||||
|
||||
## Transition
|
||||
|
||||
### PASS
|
||||
|
||||
Créer/appliquer `history/0.0.5/alpha.4.md`, committer/pousser `0.0.5-alpha.4`, puis poursuivre le forecast révisé à `0.0.5-alpha.5` pour l'audit Rust de façade/export completeness.
|
||||
|
||||
### FAIL
|
||||
|
||||
Rester dans `0.0.5-alpha.4.fix.M` tant que le défaut concerne le lifecycle inter-release ou la documentation livrée par cette tranche. Si la revue révèle qu'un autre chantier substantiel doit être absorbé avant l'audit Rust, refaire explicitement le REPLAN plutôt que l'introduire dans un fix.
|
||||
217
deltas/0.0.5/alpha.5.fix.1.md
Normal file
217
deltas/0.0.5/alpha.5.fix.1.md
Normal file
@@ -0,0 +1,217 @@
|
||||
<!-- file: deltas/0.0.5/alpha.5.fix.1.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Delta 0.0.5-alpha.5.fix.1 — canonicalisation réelle des références crate-root
|
||||
|
||||
## Baseline et version
|
||||
|
||||
Baseline attendue : commit opérateur complet de `0.0.5-alpha.5`, réalisé après application de `history/0.0.5/alpha.5.md` avec statut `FAIL`.
|
||||
|
||||
Version avant application :
|
||||
|
||||
```text
|
||||
0.0.5-alpha.5
|
||||
```
|
||||
|
||||
Version après application :
|
||||
|
||||
```text
|
||||
0.0.5-alpha.5.fix.1
|
||||
```
|
||||
|
||||
## Cause du fix
|
||||
|
||||
La gate mécanique de `alpha.5` est passée, mais la revue fonctionnelle opérateur a identifié un blind spot dans `RUST-IMPORT-201` : la `version: 1` détecte `crate::module::Item` lorsque `crate::Item` existe, mais ne détecte pas un usage nu ou autrement non canonique de ce même item dans son module propriétaire ou un autre module.
|
||||
|
||||
Or le contrat recherché est bien :
|
||||
|
||||
```text
|
||||
item partagé pub/pub(crate)
|
||||
↓
|
||||
façade crate-root
|
||||
↓
|
||||
toutes les références intra-crate détectées utilisent crate::Item
|
||||
```
|
||||
|
||||
Le compilateur et Clippy ne possèdent pas cette convention. Une seule référence correcte à `crate::Item` peut rendre le réexport utilisé tout en laissant subsister d'autres `Item`, `self::Item`, `super::Item` ou chemins internes.
|
||||
|
||||
## Scope
|
||||
|
||||
REPLACE :
|
||||
|
||||
```text
|
||||
VERSION
|
||||
docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||
docs/rules/510-RUST_CARGO.md
|
||||
docs/studies/001-KSP_GAMES_RECONCILIATION.md
|
||||
docs/validation/003-RUST_EXPORT_COMPLETENESS.md
|
||||
scripts/audit_rust_export_completeness.py
|
||||
tests/test_rust_export_completeness.py
|
||||
```
|
||||
|
||||
ADD :
|
||||
|
||||
```text
|
||||
deltas/0.0.5/alpha.5.fix.1.md
|
||||
```
|
||||
|
||||
DELETE : aucun.
|
||||
|
||||
Le history `alpha.5` appartient au commit baseline et n'est pas inclus dans l'archive du présent delta.
|
||||
|
||||
## Décisions matérialisées
|
||||
|
||||
### RUST-IMPORT-201 couvre toute référence non canonique détectable
|
||||
|
||||
Pour un item possédant une identité crate-root, la seule forme intra-crate canonique est :
|
||||
|
||||
```text
|
||||
crate::Item
|
||||
```
|
||||
|
||||
Le diagnostic couvre désormais les formes suivantes lorsqu'elles désignent cet item partagé :
|
||||
|
||||
```text
|
||||
Item
|
||||
self::Item
|
||||
super::Item
|
||||
module::Item
|
||||
crate::module::Item
|
||||
```
|
||||
|
||||
La règle s'applique au module propriétaire lui-même : signatures, `impl`, constructeurs, appels et références de types doivent employer la façade crate-root lorsqu'ils portent l'item partagé.
|
||||
|
||||
Les déclarations qui créent l'item et les lignes de réexport qui construisent la façade sont exemptées. Les éléments strictement privés restent hors de cette règle ; leurs tests attachés peuvent utiliser `super::PrivateItem`.
|
||||
|
||||
### Targets Cargo distinctes
|
||||
|
||||
Le fix évite également de confondre bibliothèque et binaire d'un même package. `src/lib.rs`, `src/main.rs`, les bins standard et les targets explicites sont traités comme des crates compilées distinctes. Le graphe de modules de chaque target est suivi via `mod name;` et `#[path = "..."]`.
|
||||
|
||||
Cette correction est nécessaire pour ne pas qualifier à tort `owner_crate::Item` dans un binaire comme référence intra-crate de la bibliothèque du même package.
|
||||
|
||||
### Analyse lexicale bornée
|
||||
|
||||
L'audit reste read-only et standard library. Il ne prétend pas remplacer un parseur Rust :
|
||||
|
||||
- les commentaires et littéraux sont masqués ;
|
||||
- les chemins qualifiés par une crate externe ne sont pas assimilés à l'item local homonyme ;
|
||||
- un appel de méthode `.name()` n'est pas assimilé à une fonction libre locale de même nom ;
|
||||
- les fonctions libres sont contrôlées dans les contextes d'appel directs ; leur usage comme valeur de premier ordre peut nécessiter une revue humaine.
|
||||
|
||||
### Réconciliation corrigée
|
||||
|
||||
En `--report-only --summary-only`, la `version: 2` observe sur les baselines de `alpha.1` :
|
||||
|
||||
```text
|
||||
KSP 0.3.16
|
||||
22 package(s)
|
||||
1525 candidate(s)
|
||||
RUST-IMPORT-201: 1525
|
||||
|
||||
Games 0.3.5
|
||||
23 package(s)
|
||||
181 candidate(s)
|
||||
RUST-API-201: 2
|
||||
RUST-IMPORT-201: 179
|
||||
```
|
||||
|
||||
Ces nombres sont des lignes candidates à revoir, pas des déclarations distinctes. Ils ne constituent pas une non-conformité rétroactive : KSP et Games ne sont pas encore gouvernés par ce PGR. Ils montrent pourquoi une future adoption doit commencer par un inventaire `--report-only` et une migration proportionnée.
|
||||
|
||||
## Validation opérateur
|
||||
|
||||
Après application du history `FAIL` de `alpha.5`, commit/push de cette tranche, puis application du présent fix :
|
||||
|
||||
```bash
|
||||
test "$(cat VERSION)" = '0.0.5-alpha.5.fix.1'
|
||||
test -f history/0.0.5/alpha.5.md
|
||||
test -f deltas/0.0.5/alpha.5.fix.1.md
|
||||
test ! -e history/0.0.5/alpha.5.fix.1.md
|
||||
|
||||
grep -A2 '^## Statut$' history/0.0.5/alpha.5.md | grep -Fx 'FAIL'
|
||||
grep -Fx '# version: 2' scripts/audit_rust_export_completeness.py
|
||||
grep -Fx '# version: 2' tests/test_rust_export_completeness.py
|
||||
grep -Fx '<!-- version: 2 -->' docs/validation/003-RUST_EXPORT_COMPLETENESS.md
|
||||
grep -Fx '<!-- version: 4 -->' docs/rules/510-RUST_CARGO.md
|
||||
|
||||
python3 -B -m unittest discover -s tests -p 'test_rust_export_completeness.py' -v
|
||||
python3 -B -m unittest discover -s tests -v
|
||||
|
||||
python3 -B scripts/audit_markdown_headers.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_tables.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_links.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
|
||||
python3 -B - <<'PY'
|
||||
from pathlib import Path
|
||||
import re
|
||||
|
||||
history = Path('history/0.0.5/alpha.5.md').read_text(encoding='utf-8')
|
||||
assert re.search(r'## Statut\s+FAIL\s', history)
|
||||
|
||||
script = Path('scripts/audit_rust_export_completeness.py').read_text(encoding='utf-8')
|
||||
for phrase in (
|
||||
'def target_roots(',
|
||||
'def target_modules(',
|
||||
'def _canonical_reference_candidates(',
|
||||
'RUST-API-201',
|
||||
'RUST-IMPORT-201',
|
||||
'non-canonical same-crate reference',
|
||||
):
|
||||
assert phrase in script, phrase
|
||||
|
||||
validation = Path('docs/validation/003-RUST_EXPORT_COMPLETENESS.md').read_text(encoding='utf-8')
|
||||
for phrase in (
|
||||
'Item\nself::Item\nsuper::Item\nmodule::Item\ncrate::module::Item',
|
||||
'dans le module qui déclare l\'item',
|
||||
'1525 candidate(s)',
|
||||
'181 candidate(s)',
|
||||
'pas des déclarations distinctes',
|
||||
):
|
||||
assert phrase in validation, phrase
|
||||
|
||||
rules = Path('docs/rules/510-RUST_CARGO.md').read_text(encoding='utf-8')
|
||||
assert 'toute référence dans la même crate MUST utiliser `crate::Item`' in rules
|
||||
assert 'y compris depuis son module de déclaration' in rules
|
||||
|
||||
print('0.0.5 alpha.5.fix.1 canonical Rust path audit: clean (owner module, cross-module, attached tests, distinct Cargo targets)')
|
||||
PY
|
||||
|
||||
git diff --check
|
||||
|
||||
git add VERSION \
|
||||
docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md \
|
||||
docs/rules/510-RUST_CARGO.md \
|
||||
docs/studies/001-KSP_GAMES_RECONCILIATION.md \
|
||||
docs/validation/003-RUST_EXPORT_COMPLETENESS.md \
|
||||
scripts/audit_rust_export_completeness.py \
|
||||
tests/test_rust_export_completeness.py \
|
||||
deltas/0.0.5/alpha.5.fix.1.md
|
||||
|
||||
git diff --cached --check
|
||||
git status --short
|
||||
```
|
||||
|
||||
La sortie Git attendue avant ajout du history du fix est exactement :
|
||||
|
||||
```text
|
||||
M VERSION
|
||||
A deltas/0.0.5/alpha.5.fix.1.md
|
||||
M docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||
M docs/rules/510-RUST_CARGO.md
|
||||
M docs/studies/001-KSP_GAMES_RECONCILIATION.md
|
||||
M docs/validation/003-RUST_EXPORT_COMPLETENESS.md
|
||||
M scripts/audit_rust_export_completeness.py
|
||||
M tests/test_rust_export_completeness.py
|
||||
```
|
||||
|
||||
## Transition
|
||||
|
||||
### PASS
|
||||
|
||||
Créer/appliquer `history/0.0.5/alpha.5.fix.1.md`, committer/pousser `0.0.5-alpha.5.fix.1`, puis poursuivre à `0.0.5-alpha.6` pour le profil Tauri prévu par le plan.
|
||||
|
||||
### FAIL
|
||||
|
||||
Rester dans `0.0.5-alpha.5.fix.M`. Aucun travail Tauri ne doit être absorbé tant que le contrat de façade Rust n'est pas correctement fermé.
|
||||
205
deltas/0.0.5/alpha.5.md
Normal file
205
deltas/0.0.5/alpha.5.md
Normal file
@@ -0,0 +1,205 @@
|
||||
<!-- file: deltas/0.0.5/alpha.5.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Delta 0.0.5-alpha.5 — audit Rust de façade/export completeness
|
||||
|
||||
## Baseline et version
|
||||
|
||||
Baseline attendue : commit opérateur complet de `0.0.5-alpha.4`, réalisé après application de `history/0.0.5/alpha.4.md` avec statut `PASS`.
|
||||
|
||||
Le hash de ce futur commit n'est pas anticipé.
|
||||
|
||||
Version avant application :
|
||||
|
||||
```text
|
||||
0.0.5-alpha.4
|
||||
```
|
||||
|
||||
Version après application :
|
||||
|
||||
```text
|
||||
0.0.5-alpha.5
|
||||
```
|
||||
|
||||
## Rôle de la tranche
|
||||
|
||||
`alpha.5` extrait un audit Rust facultatif réellement réutilisable à partir du corpus KSP/Games, mais corrige avant généralisation une limite découverte dans le script historique : Games organise ses crates sous plusieurs niveaux et n'était pas réellement couvert par le glob `crates/*/Cargo.toml`.
|
||||
|
||||
La tranche reste limitée à la façade crate-root et aux chemins same-crate canoniques. Elle ne copie pas `audit_rust_general_rules.py`, ne commence pas Tauri et ne transforme pas PGR en workspace Rust.
|
||||
|
||||
## Scope
|
||||
|
||||
REPLACE :
|
||||
|
||||
```text
|
||||
VERSION
|
||||
docs/000-README.md
|
||||
docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||
docs/rules/510-RUST_CARGO.md
|
||||
docs/skeletons/002-RUST_CARGO_WORKSPACE.md
|
||||
docs/studies/001-KSP_GAMES_RECONCILIATION.md
|
||||
docs/validation/001-VALIDATION_MATRIX.md
|
||||
```
|
||||
|
||||
ADD :
|
||||
|
||||
```text
|
||||
docs/validation/003-RUST_EXPORT_COMPLETENESS.md
|
||||
scripts/audit_rust_export_completeness.py
|
||||
tests/test_rust_export_completeness.py
|
||||
deltas/0.0.5/alpha.5.md
|
||||
```
|
||||
|
||||
DELETE : aucun.
|
||||
|
||||
Le history `alpha.4` appartient au commit baseline et n'est pas inclus dans l'archive du présent delta.
|
||||
|
||||
## Décisions matérialisées
|
||||
|
||||
### Audit monotâche
|
||||
|
||||
Le nouveau script possède exactement deux responsabilités :
|
||||
|
||||
```text
|
||||
RUST-API-201
|
||||
façade crate-root absente pour un élément public, ou crate-public clairement partagé
|
||||
|
||||
RUST-IMPORT-201
|
||||
chemin `crate::module::Item` alors qu'un réexport explicite fournit déjà `crate::Item`
|
||||
```
|
||||
|
||||
Les conventions des tests unitaires séparés du script historique ne sont pas reprises. Le contrôle d'un symbole `crate::X` inexistant n'est pas repris non plus, car le compilateur Rust possède déjà la résolution de noms.
|
||||
|
||||
### Découverte des crates
|
||||
|
||||
La découverte des `Cargo.toml` devient récursive et accepte les crates imbriquées. Les arbres générés usuels (`target`, `build`, `builds`, `dist`, `node_modules`, etc.) restent ignorés.
|
||||
|
||||
Le module fichier `foo/mod.rs` est interprété comme `foo`, et les réexports crate-root simples, groupés ou aliasés couverts par les tests sont reconnus.
|
||||
|
||||
### Adoption facultative
|
||||
|
||||
Le contrat général Rust reste un `SHOULD`. Un projet existant peut commencer avec `--report-only`, traiter les écarts ou exceptions locales, puis rendre l'audit bloquant seulement après décision explicite.
|
||||
|
||||
L'audit est documenté dans `docs/validation/003-RUST_EXPORT_COMPLETENESS.md` et référencé par le skeleton Rust/Cargo sans devenir obligatoire.
|
||||
|
||||
### Mesure de réconciliation
|
||||
|
||||
La prévalidation générateur sur les baselines autoritaires de `alpha.1` observe :
|
||||
|
||||
```text
|
||||
KSP 0.3.16 22 crate(s) 0 candidate(s)
|
||||
Games 0.3.5 23 crate(s) 2 candidate(s)
|
||||
```
|
||||
|
||||
Le résultat Games antérieur `0 candidate(s)` provenait d'une découverte de crates incomplète. Les deux candidats actuels ne sont pas traités comme des défauts historiques, car Games n'est pas encore gouverné par PGR.
|
||||
|
||||
## Validation opérateur
|
||||
|
||||
Après application du history `PASS` de `alpha.4`, commit/push de cette tranche, puis application du présent delta :
|
||||
|
||||
```bash
|
||||
test "$(cat VERSION)" = '0.0.5-alpha.5'
|
||||
test -f history/0.0.5/alpha.4.md
|
||||
test -f deltas/0.0.5/alpha.5.md
|
||||
test -f scripts/audit_rust_export_completeness.py
|
||||
test -f tests/test_rust_export_completeness.py
|
||||
test -f docs/validation/003-RUST_EXPORT_COMPLETENESS.md
|
||||
test ! -e history/0.0.5/alpha.5.md
|
||||
|
||||
grep -A2 '^## Statut$' history/0.0.5/alpha.4.md | grep -Fx 'PASS'
|
||||
grep -Fx '# version: 1' scripts/audit_rust_export_completeness.py
|
||||
grep -Fx '# version: 1' tests/test_rust_export_completeness.py
|
||||
grep -Fx '<!-- version: 1 -->' docs/validation/003-RUST_EXPORT_COMPLETENESS.md
|
||||
grep -Fx '<!-- version: 3 -->' docs/rules/510-RUST_CARGO.md
|
||||
grep -Fx '<!-- version: 2 -->' docs/skeletons/002-RUST_CARGO_WORKSPACE.md
|
||||
grep -Fx '<!-- version: 11 -->' docs/validation/001-VALIDATION_MATRIX.md
|
||||
|
||||
python3 -B -m unittest discover -s tests -p 'test_rust_export_completeness.py' -v
|
||||
python3 -B -m unittest discover -s tests -v
|
||||
|
||||
python3 -B scripts/audit_markdown_headers.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_tables.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_links.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
|
||||
python3 -B - <<'PY'
|
||||
from pathlib import Path
|
||||
import re
|
||||
|
||||
history = Path('history/0.0.5/alpha.4.md').read_text(encoding='utf-8')
|
||||
assert re.search(r'## Statut\s+PASS\s', history)
|
||||
|
||||
script = Path('scripts/audit_rust_export_completeness.py').read_text(encoding='utf-8')
|
||||
for phrase in (
|
||||
'def crate_roots(',
|
||||
'root.rglob("Cargo.toml")',
|
||||
'RUST-API-201',
|
||||
'RUST-IMPORT-201',
|
||||
'--report-only',
|
||||
'--summary-only',
|
||||
):
|
||||
assert phrase in script, phrase
|
||||
for forbidden in ('RUST-IMPORT-202', 'RUST-IMPORT-203', 'RUST-IMPORT-204', 'RUST-IMPORT-205'):
|
||||
assert forbidden not in script, forbidden
|
||||
|
||||
validation = Path('docs/validation/003-RUST_EXPORT_COMPLETENESS.md').read_text(encoding='utf-8')
|
||||
for phrase in (
|
||||
'22` crates KSP',
|
||||
'23` crates Games',
|
||||
'0 candidate(s)',
|
||||
'2 candidate(s)',
|
||||
'ne sont pas qualifiés de défauts rétroactifs',
|
||||
):
|
||||
assert phrase in validation, phrase
|
||||
|
||||
plan = Path('docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md').read_text(encoding='utf-8')
|
||||
assert 'KSP = 0 candidate(s) / 22 crates' in plan
|
||||
assert 'Games = 2 candidate(s) / 23 crates' in plan
|
||||
|
||||
print('0.0.5 alpha.5 Rust façade audit: clean (recursive crate discovery, narrow ownership, regression coverage)')
|
||||
PY
|
||||
|
||||
git diff --check
|
||||
|
||||
git add VERSION docs/000-README.md \
|
||||
docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md \
|
||||
docs/rules/510-RUST_CARGO.md \
|
||||
docs/skeletons/002-RUST_CARGO_WORKSPACE.md \
|
||||
docs/studies/001-KSP_GAMES_RECONCILIATION.md \
|
||||
docs/validation/001-VALIDATION_MATRIX.md \
|
||||
docs/validation/003-RUST_EXPORT_COMPLETENESS.md \
|
||||
scripts/audit_rust_export_completeness.py \
|
||||
tests/test_rust_export_completeness.py \
|
||||
deltas/0.0.5/alpha.5.md
|
||||
|
||||
git diff --cached --check
|
||||
git status --short
|
||||
```
|
||||
|
||||
La sortie Git attendue avant ajout du history `alpha.5` est exactement :
|
||||
|
||||
```text
|
||||
M VERSION
|
||||
A deltas/0.0.5/alpha.5.md
|
||||
M docs/000-README.md
|
||||
M docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||
M docs/rules/510-RUST_CARGO.md
|
||||
M docs/skeletons/002-RUST_CARGO_WORKSPACE.md
|
||||
M docs/studies/001-KSP_GAMES_RECONCILIATION.md
|
||||
M docs/validation/001-VALIDATION_MATRIX.md
|
||||
A docs/validation/003-RUST_EXPORT_COMPLETENESS.md
|
||||
A scripts/audit_rust_export_completeness.py
|
||||
A tests/test_rust_export_completeness.py
|
||||
```
|
||||
|
||||
## Transition
|
||||
|
||||
### PASS
|
||||
|
||||
Créer/appliquer `history/0.0.5/alpha.5.md`, committer/pousser `0.0.5-alpha.5`, puis poursuivre à `0.0.5-alpha.6` pour le premier profil framework Tauri.
|
||||
|
||||
### FAIL
|
||||
|
||||
Rester dans `0.0.5-alpha.5.fix.M` si le défaut concerne l'audit, ses tests, sa documentation ou l'intégration Rust/Cargo. Ne pas absorber le profil Tauri dans un fix.
|
||||
178
deltas/0.0.5/alpha.6.fix.1.md
Normal file
178
deltas/0.0.5/alpha.6.fix.1.md
Normal file
@@ -0,0 +1,178 @@
|
||||
<!-- file: deltas/0.0.5/alpha.6.fix.1.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Delta 0.0.5-alpha.6.fix.1 — composition Tauri/Rust/frontend et gate corrigé
|
||||
|
||||
## Baseline et version
|
||||
|
||||
Baseline attendue : commit opérateur complet de `0.0.5-alpha.6`, réalisé après application de `history/0.0.5/alpha.6.md` avec statut `FAIL`.
|
||||
|
||||
Version avant application :
|
||||
|
||||
```text
|
||||
0.0.5-alpha.6
|
||||
```
|
||||
|
||||
Version après application :
|
||||
|
||||
```text
|
||||
0.0.5-alpha.6.fix.1
|
||||
```
|
||||
|
||||
## Cause du fix
|
||||
|
||||
Deux défauts appartiennent au scope exact de `alpha.6` :
|
||||
|
||||
1. le heredoc Python de la gate `alpha.6` contient une chaîne multilignes entre quotes simples et échoue avec `SyntaxError: unterminated string literal` ;
|
||||
2. le profil livré ne distingue pas encore assez explicitement le contrat Tauri universel des conventions de structure/stack retenues pour les projets Tauri que l'organisation contrôle.
|
||||
|
||||
La clarification opérateur confirme aussi un écart plus large dans le profil Rust strict PGR. Ce troisième sujet ne doit pas être absorbé par le présent fix : il est replanifié en `alpha.7`, puis la décision de skeleton Tauri passe à `alpha.8`.
|
||||
|
||||
## Scope
|
||||
|
||||
REPLACE :
|
||||
|
||||
```text
|
||||
VERSION
|
||||
docs/architecture/003-RULE_PROFILE_MODEL.md
|
||||
docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||
docs/rules/700-FRAMEWORKS.md
|
||||
docs/rules/710-TAURI.md
|
||||
docs/studies/001-KSP_GAMES_RECONCILIATION.md
|
||||
```
|
||||
|
||||
ADD :
|
||||
|
||||
```text
|
||||
deltas/0.0.5/alpha.6.fix.1.md
|
||||
```
|
||||
|
||||
DELETE : aucun.
|
||||
|
||||
## Décisions corrigées
|
||||
|
||||
Le fix précise que :
|
||||
|
||||
- un host Tauri est un projet Rust/Cargo et n'obtient aucune exception implicite aux règles Rust sélectionnées ;
|
||||
- un projet externe/imposé peut conserver des règles différentes via le niveau project-specific ou des overrides explicites ;
|
||||
- le profil Tauri universel ne possède pas le choix `frontend/`, Vite, TypeScript, Sass, Bootstrap ou du package manager ;
|
||||
- ces choix forment un candidat de skeleton pour les futurs projets contrôlés ;
|
||||
- WASM n'est pas une composante implicite de Tauri et reste normalement une unité séparée avec ses propres owners ;
|
||||
- `cargo tauri add` est une commodité, pas une obligation : l'ajout explicite des dépendances et de l'initialisation à partir de la documentation officielle des plugins est valide et peut être préféré pour garder le contrôle des manifests ;
|
||||
- un POC mobile non concluant pour Games ne permet pas de rejeter Tauri Android/iOS pour d'autres produits.
|
||||
|
||||
## REPLAN borné
|
||||
|
||||
La clarification révèle qu'une décision Rust déjà retenue historiquement n'est pas complètement matérialisée dans `510-RUST_CARGO.md`. `alpha.7` devient donc une tranche normale de complétude du profil Rust strict, puis l'ancienne décision de skeleton Tauri devient `alpha.8`.
|
||||
|
||||
Le présent fix ne modifie pas `510-RUST_CARGO.md` et n'ajoute aucun nouvel audit Rust : cela constituerait un nouveau scope fonctionnel.
|
||||
|
||||
## Validation opérateur
|
||||
|
||||
Après application du history `FAIL` de `alpha.6`, commit/push de cette tranche, puis application du présent fix :
|
||||
|
||||
```bash
|
||||
test "$(cat VERSION)" = '0.0.5-alpha.6.fix.1'
|
||||
test -f history/0.0.5/alpha.6.md
|
||||
test -f deltas/0.0.5/alpha.6.fix.1.md
|
||||
test ! -e history/0.0.5/alpha.6.fix.1.md
|
||||
|
||||
grep -A2 '^## Statut$' history/0.0.5/alpha.6.md | grep -Fx 'FAIL'
|
||||
grep -Fx '<!-- version: 2 -->' docs/rules/700-FRAMEWORKS.md
|
||||
grep -Fx '<!-- version: 2 -->' docs/rules/710-TAURI.md
|
||||
grep -Fx '<!-- version: 5 -->' docs/architecture/003-RULE_PROFILE_MODEL.md
|
||||
grep -Fx '<!-- version: 5 -->' docs/studies/001-KSP_GAMES_RECONCILIATION.md
|
||||
grep -Fx '<!-- version: 6 -->' docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||
|
||||
python3 -B -m unittest discover -s tests -v
|
||||
|
||||
python3 -B scripts/audit_markdown_headers.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_tables.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_links.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
|
||||
python3 -B - <<'PY'
|
||||
from pathlib import Path
|
||||
import re
|
||||
|
||||
history = Path('history/0.0.5/alpha.6.md').read_text(encoding='utf-8')
|
||||
assert re.search(r'## Statut\s+FAIL\s', history)
|
||||
|
||||
frameworks = Path('docs/rules/700-FRAMEWORKS.md').read_text(encoding='utf-8')
|
||||
for phrase in (
|
||||
"Il n'annule pas silencieusement les conventions des owners qu'il compose.",
|
||||
'Un projet existant ou imposé de l'extérieur MAY conserver des contraintes différentes.',
|
||||
'## Profil framework et convention d'instanciation',
|
||||
):
|
||||
assert phrase in frameworks, phrase
|
||||
|
||||
tauri = Path('docs/rules/710-TAURI.md').read_text(encoding='utf-8')
|
||||
for phrase in (
|
||||
'## Héritage Rust du host Tauri',
|
||||
'Tauri ne crée aucune exception implicite aux règles Rust sélectionnées par le projet.',
|
||||
'PGR MUST NOT imposer universellement Vite, TypeScript, Sass, Bootstrap, Tailwind CSS',
|
||||
'WASM n'est pas une composante implicite d'un projet Tauri.',
|
||||
'PGR ne définit aucun catalogue de plugins Tauri obligatoires et ne rend pas `cargo tauri add` obligatoire.',
|
||||
'Un POC Tauri mobile non concluant pour un produit particulier ne constitue pas une preuve',
|
||||
):
|
||||
assert phrase in tauri, phrase
|
||||
|
||||
version_chain = '\n'.join((
|
||||
'VERSION',
|
||||
'↓',
|
||||
'workspace.package.version',
|
||||
'↓',
|
||||
'package Cargo du host',
|
||||
'↓',
|
||||
'version applicative Tauri',
|
||||
))
|
||||
assert version_chain in tauri
|
||||
|
||||
study = Path('docs/studies/001-KSP_GAMES_RECONCILIATION.md').read_text(encoding='utf-8')
|
||||
assert 'candidat de skeleton pour projets contrôlés' in study
|
||||
assert 'WASM n'est pas une dépendance implicite de Tauri' in study
|
||||
assert 'écart antérieur dans le profil Rust PGR' in study
|
||||
|
||||
plan = Path('docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md').read_text(encoding='utf-8')
|
||||
assert '### alpha.7 — complétude du profil Rust strict' in plan
|
||||
assert '### alpha.8 — décision de skeleton Tauri pour projets contrôlés' in plan
|
||||
|
||||
print('0.0.5 alpha.6.fix.1 Tauri composition audit: clean (Rust inherited, frontend/skeleton separated, WASM independent, gate valid)')
|
||||
PY
|
||||
|
||||
git diff --check
|
||||
|
||||
git add VERSION \
|
||||
docs/architecture/003-RULE_PROFILE_MODEL.md \
|
||||
docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md \
|
||||
docs/rules/700-FRAMEWORKS.md docs/rules/710-TAURI.md \
|
||||
docs/studies/001-KSP_GAMES_RECONCILIATION.md \
|
||||
deltas/0.0.5/alpha.6.fix.1.md
|
||||
|
||||
git diff --cached --check
|
||||
git status --short
|
||||
```
|
||||
|
||||
La sortie Git attendue avant ajout du history est exactement :
|
||||
|
||||
```text
|
||||
M VERSION
|
||||
A deltas/0.0.5/alpha.6.fix.1.md
|
||||
M docs/architecture/003-RULE_PROFILE_MODEL.md
|
||||
M docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||
M docs/rules/700-FRAMEWORKS.md
|
||||
M docs/rules/710-TAURI.md
|
||||
M docs/studies/001-KSP_GAMES_RECONCILIATION.md
|
||||
```
|
||||
|
||||
## Transition
|
||||
|
||||
### PASS
|
||||
|
||||
Créer/appliquer `history/0.0.5/alpha.6.fix.1.md`, committer/pousser le fix, puis poursuivre à `0.0.5-alpha.7` pour réconcilier les conventions Rust strictes déjà décidées avant toute matérialisation d'un skeleton Tauri.
|
||||
|
||||
### FAIL
|
||||
|
||||
Rester dans `0.0.5-alpha.6.fix.M`. Aucun changement du profil Rust ni skeleton Tauri ne doit être absorbé tant que la frontière Tauri/Rust/frontend n'est pas correctement fermée.
|
||||
167
deltas/0.0.5/alpha.6.fix.2.md
Normal file
167
deltas/0.0.5/alpha.6.fix.2.md
Normal file
@@ -0,0 +1,167 @@
|
||||
<!-- file: deltas/0.0.5/alpha.6.fix.2.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Delta 0.0.5-alpha.6.fix.2 — convention Tauri contrôlée et gate robuste
|
||||
|
||||
## Baseline et version
|
||||
|
||||
Baseline attendue : commit opérateur complet de `0.0.5-alpha.6.fix.1`, réalisé après application de `history/0.0.5/alpha.6.fix.1.md` avec statut `FAIL`.
|
||||
|
||||
Version avant application :
|
||||
|
||||
```text
|
||||
0.0.5-alpha.6.fix.1
|
||||
```
|
||||
|
||||
Version après application :
|
||||
|
||||
```text
|
||||
0.0.5-alpha.6.fix.2
|
||||
```
|
||||
|
||||
## Cause du fix
|
||||
|
||||
`alpha.6.fix.1` conserve une gate Python invalide : une phrase contenant `l'extérieur` est placée dans une chaîne simple et son apostrophe provoque encore `SyntaxError: unterminated string literal`.
|
||||
|
||||
La revue opérateur demande en parallèle de confronter le profil non seulement aux configurations Tauri mais aux règles complètes KSP/Games. Cette seconde passe montre qu'une convention de projet contrôlé plus riche est déjà éprouvée et doit être distinguée du contrat Tauri universel.
|
||||
|
||||
## Scope
|
||||
|
||||
REPLACE :
|
||||
|
||||
```text
|
||||
VERSION
|
||||
docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||
docs/rules/710-TAURI.md
|
||||
docs/studies/001-KSP_GAMES_RECONCILIATION.md
|
||||
```
|
||||
|
||||
ADD :
|
||||
|
||||
```text
|
||||
deltas/0.0.5/alpha.6.fix.2.md
|
||||
```
|
||||
|
||||
DELETE : aucun.
|
||||
|
||||
## Décisions
|
||||
|
||||
Le fix établit pour les nouveaux projets Tauri contrôlés une convention forte mais adaptable :
|
||||
|
||||
- host Cargo direct, sans `src-tauri/` ajouté par réflexe ;
|
||||
- fichiers Tauri/frontend principaux à la racine de la crate et sources Rust sous `src/` ;
|
||||
- frontend versionné sous `frontend/` ;
|
||||
- `lib.rs` comme façade, `main.rs` comme launcher mince et `tauri.rs` comme owner de l'assemblage et des wrappers `#[tauri::command]` ;
|
||||
- modules cohérents par fenêtre/responsabilité et modules communs pour les helpers réellement partagés ;
|
||||
- TS-RS obligatoire dans le profil strict lorsque des DTO/enum/struct Rust possédés par le host sont partagés avec un frontend TypeScript, sauf incompatibilité documentée ;
|
||||
- bindings générés reconstruisibles et non modifiés manuellement ;
|
||||
- intégration explicite des plugins préférée à une commande de commodité opaque ;
|
||||
- WASM séparé du host Tauri par défaut.
|
||||
|
||||
Vite, TypeScript, Sass et Bootstrap restent le candidat de stack/skeleton pour les projets contrôlés ; ils ne deviennent pas des invariants universels du framework Tauri tant que leurs owners Web ne sont pas matérialisés.
|
||||
|
||||
## Replanification
|
||||
|
||||
La seconde lecture des règles KSP/Games montre que `alpha.7` serait trop large si elle mélangeait conventions sémantiques, nomenclature et tous les audits de formatage. Le forecast devient :
|
||||
|
||||
```text
|
||||
alpha.7 profil Rust strict + chemins + nomenclature des crates
|
||||
alpha.8 formatage Rust structurel + audits monotâches
|
||||
alpha.9 décision de skeleton Tauri pour projets contrôlés
|
||||
beta.1 réconciliation intégrée
|
||||
```
|
||||
|
||||
KSP est utilisé comme référence stricte ; Games sert à identifier ce qui doit rester `SHOULD`, sélectionnable ou project-specific.
|
||||
|
||||
## Validation opérateur
|
||||
|
||||
Après application du history `FAIL` de `alpha.6.fix.1`, commit/push de cette tranche, puis application du présent fix :
|
||||
|
||||
```bash
|
||||
test "$(cat VERSION)" = '0.0.5-alpha.6.fix.2'
|
||||
test -f history/0.0.5/alpha.6.fix.1.md
|
||||
test -f deltas/0.0.5/alpha.6.fix.2.md
|
||||
test ! -e history/0.0.5/alpha.6.fix.2.md
|
||||
|
||||
grep -A2 '^## Statut$' history/0.0.5/alpha.6.fix.1.md | grep -Fx 'FAIL'
|
||||
grep -Fx '<!-- version: 3 -->' docs/rules/710-TAURI.md
|
||||
grep -Fx '<!-- version: 6 -->' docs/studies/001-KSP_GAMES_RECONCILIATION.md
|
||||
grep -Fx '<!-- version: 7 -->' docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||
|
||||
python3 -B -m unittest discover -s tests -v
|
||||
|
||||
python3 -B scripts/audit_markdown_headers.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_tables.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_links.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
|
||||
python3 -B - <<'PY'
|
||||
from pathlib import Path
|
||||
import re
|
||||
|
||||
history = Path("history/0.0.5/alpha.6.fix.1.md").read_text(encoding="utf-8")
|
||||
assert re.search(r"## Statut\s+FAIL\s", history)
|
||||
|
||||
tauri = Path("docs/rules/710-TAURI.md").read_text(encoding="utf-8")
|
||||
for phrase in (
|
||||
"## Convention renforcée pour les projets contrôlés",
|
||||
"sans couche `src-tauri/` ajoutée uniquement pour reproduire `create-tauri-app`",
|
||||
"`src/tauri.rs` SHOULD posséder l'assemblage Tauri et les wrappers `#[tauri::command]`",
|
||||
"partagés avec le frontend MUST utiliser TS-RS comme source de génération",
|
||||
"WASM reste normalement une unité séparée de la crate Tauri",
|
||||
):
|
||||
assert phrase in tauri, phrase
|
||||
|
||||
study = Path("docs/studies/001-KSP_GAMES_RECONCILIATION.md").read_text(encoding="utf-8")
|
||||
for phrase in (
|
||||
"Commun aux `8` hosts Tauri observés",
|
||||
"aucun ne possède `src-tauri/`",
|
||||
"KSP plus strict mais réutilisable",
|
||||
"Nomenclature des crates",
|
||||
):
|
||||
assert phrase in study, phrase
|
||||
|
||||
plan = Path("docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md").read_text(encoding="utf-8")
|
||||
for phrase in (
|
||||
"### alpha.7 — profil Rust strict, chemins et nomenclature explicite",
|
||||
"### alpha.8 — formatage Rust structurel et audits monotâches",
|
||||
"### alpha.9 — décision de skeleton Tauri pour projets contrôlés",
|
||||
):
|
||||
assert phrase in plan, phrase
|
||||
|
||||
print("0.0.5 alpha.6.fix.2 Tauri convention audit: clean (8 hosts reconciled, strict controlled layout separated from universal framework)")
|
||||
PY
|
||||
|
||||
git diff --check
|
||||
|
||||
git add VERSION \
|
||||
docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md \
|
||||
docs/rules/710-TAURI.md \
|
||||
docs/studies/001-KSP_GAMES_RECONCILIATION.md \
|
||||
deltas/0.0.5/alpha.6.fix.2.md
|
||||
|
||||
git diff --cached --check
|
||||
git status --short
|
||||
```
|
||||
|
||||
La sortie Git attendue avant ajout du history est exactement :
|
||||
|
||||
```text
|
||||
M VERSION
|
||||
A deltas/0.0.5/alpha.6.fix.2.md
|
||||
M docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||
M docs/rules/710-TAURI.md
|
||||
M docs/studies/001-KSP_GAMES_RECONCILIATION.md
|
||||
```
|
||||
|
||||
## Transition
|
||||
|
||||
### PASS
|
||||
|
||||
Créer/appliquer `history/0.0.5/alpha.6.fix.2.md`, committer/pousser le fix, puis poursuivre avec `alpha.7`.
|
||||
|
||||
### FAIL
|
||||
|
||||
Rester dans `0.0.5-alpha.6.fix.M`. Ne pas commencer la réconciliation Rust tant que la convention Tauri et sa gate ne sont pas fermées proprement.
|
||||
140
deltas/0.0.5/alpha.6.fix.3.md
Normal file
140
deltas/0.0.5/alpha.6.fix.3.md
Normal file
@@ -0,0 +1,140 @@
|
||||
<!-- file: deltas/0.0.5/alpha.6.fix.3.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Delta 0.0.5-alpha.6.fix.3 — politique de versions Tauri/frontend
|
||||
|
||||
## Baseline et version
|
||||
|
||||
Baseline attendue : commit opérateur complet de `0.0.5-alpha.6.fix.2`, réalisé après application de `history/0.0.5/alpha.6.fix.2.md` avec statut `FAIL`.
|
||||
|
||||
Version après application :
|
||||
|
||||
```text
|
||||
0.0.5-alpha.6.fix.3
|
||||
```
|
||||
|
||||
## Motif
|
||||
|
||||
La gate mécanique de `alpha.6.fix.2` est propre, mais la revue fonctionnelle identifie une convention mal généralisée : KSP et Games ont tous deux utilisé l'omission de `tauri.conf.json > version` et une `package.json > version` rarement synchronisée comme moyen de réduire le churn des prereleases. PGR ne doit pas transformer cette solution historique en obligation.
|
||||
|
||||
L'objectif réel est de conserver `VERSION` comme identité exacte de travail tout en évitant de modifier les miroirs produit qui n'ont pas besoin de suivre chaque `alpha`, `.fix`, beta ou RC.
|
||||
|
||||
## Scope
|
||||
|
||||
REPLACE :
|
||||
|
||||
```text
|
||||
VERSION
|
||||
docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||
docs/rules/200-GOVERNANCE.md
|
||||
docs/rules/710-TAURI.md
|
||||
docs/studies/001-KSP_GAMES_RECONCILIATION.md
|
||||
```
|
||||
|
||||
ADD :
|
||||
|
||||
```text
|
||||
deltas/0.0.5/alpha.6.fix.3.md
|
||||
```
|
||||
|
||||
DELETE : aucun.
|
||||
|
||||
## Décisions
|
||||
|
||||
Le fix rétablit une classification explicite des valeurs de version :
|
||||
|
||||
- `CANONICAL` pour `VERSION` ;
|
||||
- `MIRROR-EXACT` pour les miroirs techniques qui doivent suivre chaque prerelease ;
|
||||
- `MIRROR-STABLE` pour les champs qui portent seulement la cible `X.Y.Z` ;
|
||||
- catégories indépendantes pour compteurs, schémas et révisions documentaires.
|
||||
|
||||
Pour une application Tauri contrôlée appartenant au même produit, `tauri.conf.json > version` et `package.json > version`, lorsqu'ils sont conservés, SHOULD être `MIRROR-STABLE` par défaut et porter `X.Y.Z` pendant tout le développement de cette cible. Ils ne sont pas modifiés uniquement pour passer de `alpha.N` à un autre alpha/fix/beta/RC.
|
||||
|
||||
Si des bundles prerelease sont réellement distribués et doivent être identifiables séparément, le projet MAY sélectionner `MIRROR-EXACT` ou une politique de jalons de packaging documentée. L'omission d'un champ reste possible lorsqu'il est réellement inutile, mais elle n'est plus la stratégie PGR recommandée uniquement pour éviter le churn.
|
||||
|
||||
La revue obligatoire déclenchée par `.fix.3` conclut `CONTINUE` : `alpha.6` reste bornée au profil Tauri ; `alpha.7`, `alpha.8` et `alpha.9` conservent leurs scopes distincts.
|
||||
|
||||
## Hors scope
|
||||
|
||||
Ce fix ne modifie ni les règles Rust strictes prévues en `alpha.7`, ni les audits de formatage de `alpha.8`, ni le skeleton Tauri de `alpha.9`. Il ne modifie pas non plus la politique Cargo existante de `510-RUST_CARGO.md`.
|
||||
|
||||
## Validation opérateur
|
||||
|
||||
Après application du history `FAIL` de `alpha.6.fix.2`, commit/push de cette tranche, puis application du présent fix :
|
||||
|
||||
```bash
|
||||
test "$(cat VERSION)" = '0.0.5-alpha.6.fix.3'
|
||||
test -f history/0.0.5/alpha.6.fix.2.md
|
||||
test -f deltas/0.0.5/alpha.6.fix.3.md
|
||||
test ! -e history/0.0.5/alpha.6.fix.3.md
|
||||
|
||||
grep -A2 '^## Statut$' history/0.0.5/alpha.6.fix.2.md | grep -Fx 'FAIL'
|
||||
grep -Fx '<!-- version: 4 -->' docs/rules/200-GOVERNANCE.md
|
||||
grep -Fx '<!-- version: 4 -->' docs/rules/710-TAURI.md
|
||||
grep -Fx '<!-- version: 7 -->' docs/studies/001-KSP_GAMES_RECONCILIATION.md
|
||||
grep -Fx '<!-- version: 8 -->' docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||
|
||||
python3 -B -m unittest discover -s tests -v
|
||||
|
||||
python3 -B scripts/audit_markdown_headers.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_tables.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_links.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
|
||||
python3 -B - <<'PY'
|
||||
from pathlib import Path
|
||||
import re
|
||||
|
||||
history = Path("history/0.0.5/alpha.6.fix.2.md").read_text(encoding="utf-8")
|
||||
assert re.search(r"## Statut\s+FAIL\s", history)
|
||||
|
||||
governance = Path("docs/rules/200-GOVERNANCE.md").read_text(encoding="utf-8")
|
||||
for phrase in (
|
||||
"MIRROR-EXACT",
|
||||
"MIRROR-STABLE",
|
||||
"Seul un `MIRROR-EXACT` est normalement modifié à chaque changement de `VERSION`.",
|
||||
"PGR MUST NOT imposer la suppression d'un champ utile uniquement pour éviter de le modifier à chaque prerelease",
|
||||
):
|
||||
assert phrase in governance, phrase
|
||||
|
||||
tauri = Path("docs/rules/710-TAURI.md").read_text(encoding="utf-8")
|
||||
for phrase in (
|
||||
"PGR MUST NOT imposer l'une de ces deux formes uniquement pour réduire le nombre de fichiers modifiés.",
|
||||
"la politique recommandée lorsque les prereleases ne sont pas distribuées comme produits installables distincts est `MIRROR-STABLE`",
|
||||
"tauri.conf.json version = X.Y.Z",
|
||||
"package.json version = X.Y.Z",
|
||||
"remplace explicitement les conventions historiques KSP/Games",
|
||||
):
|
||||
assert phrase in tauri, phrase
|
||||
|
||||
plan = Path("docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md").read_text(encoding="utf-8")
|
||||
assert "`alpha.6.fix.3` restaure la classification générale" in plan
|
||||
assert "résultat `CONTINUE`" in plan
|
||||
|
||||
print("0.0.5 alpha.6.fix.3 version policy audit: clean (canonical/exact/stable mirrors classified, Tauri/frontend churn bounded)")
|
||||
PY
|
||||
|
||||
git diff --check
|
||||
|
||||
git add VERSION \
|
||||
docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md \
|
||||
docs/rules/200-GOVERNANCE.md docs/rules/710-TAURI.md \
|
||||
docs/studies/001-KSP_GAMES_RECONCILIATION.md \
|
||||
deltas/0.0.5/alpha.6.fix.3.md
|
||||
|
||||
git diff --cached --check
|
||||
git status --short
|
||||
```
|
||||
|
||||
La sortie Git attendue avant ajout du history est exactement :
|
||||
|
||||
```text
|
||||
M VERSION
|
||||
A deltas/0.0.5/alpha.6.fix.3.md
|
||||
M docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||
M docs/rules/200-GOVERNANCE.md
|
||||
M docs/rules/710-TAURI.md
|
||||
M docs/studies/001-KSP_GAMES_RECONCILIATION.md
|
||||
```
|
||||
189
deltas/0.0.5/alpha.6.md
Normal file
189
deltas/0.0.5/alpha.6.md
Normal file
@@ -0,0 +1,189 @@
|
||||
<!-- file: deltas/0.0.5/alpha.6.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Delta 0.0.5-alpha.6 — premier profil framework : Tauri 2
|
||||
|
||||
## Baseline et version
|
||||
|
||||
Baseline attendue : commit opérateur complet de `0.0.5-alpha.5.fix.1`, réalisé après application de `history/0.0.5/alpha.5.fix.1.md` avec statut `PASS`.
|
||||
|
||||
Version avant application :
|
||||
|
||||
```text
|
||||
0.0.5-alpha.5.fix.1
|
||||
```
|
||||
|
||||
Version après application :
|
||||
|
||||
```text
|
||||
0.0.5-alpha.6
|
||||
```
|
||||
|
||||
## Scope
|
||||
|
||||
REPLACE :
|
||||
|
||||
```text
|
||||
VERSION
|
||||
RULES.md
|
||||
docs/000-README.md
|
||||
docs/architecture/003-RULE_PROFILE_MODEL.md
|
||||
docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||
docs/rules/000-README.md
|
||||
docs/studies/001-KSP_GAMES_RECONCILIATION.md
|
||||
```
|
||||
|
||||
ADD :
|
||||
|
||||
```text
|
||||
docs/rules/700-FRAMEWORKS.md
|
||||
docs/rules/710-TAURI.md
|
||||
deltas/0.0.5/alpha.6.md
|
||||
```
|
||||
|
||||
DELETE : aucun.
|
||||
|
||||
Le history `alpha.5.fix.1` appartient au commit baseline et n'est pas inclus dans l'archive du présent delta.
|
||||
|
||||
## Preuve de généralisation
|
||||
|
||||
Les baselines autoritaires étudiées en `alpha.1` contiennent :
|
||||
|
||||
```text
|
||||
KSP 0.3.16 6 applications Tauri
|
||||
Games 0.3.5 2 applications Tauri
|
||||
```
|
||||
|
||||
Les huit applications utilisent Tauri 2 avec un host Rust/Cargo, `tauri-build`, `tauri.conf.json`, des capability files, des hooks frontend et un `frontendDist`. Elles divergent en revanche sur fenêtres, ports, CSP, bundling, plugins, ressources et contenu réel des hooks.
|
||||
|
||||
Le profil normalise donc les responsabilités et l'orchestration communes, pas ces valeurs locales.
|
||||
|
||||
## Décisions matérialisées
|
||||
|
||||
### Famille `700 — frameworks`
|
||||
|
||||
`700-FRAMEWORKS.md` devient l'owner des règles communes aux frameworks : composition avec les owners langage/plateforme, ownership des commandes d'intégration, classification des artefacts générés, cohérence de version produit et validation proportionnée.
|
||||
|
||||
La famille interdit notamment de supposer qu'un framework absorbe automatiquement son frontend, sa plateforme ou son package manager.
|
||||
|
||||
### Profil `710 — Tauri 2`
|
||||
|
||||
Le profil Tauri :
|
||||
|
||||
- se compose au-dessus de Rust/Cargo et des plateformes réellement ciblées ;
|
||||
- ne rend pas Vite, WASM, TypeScript ou npm obligatoires ;
|
||||
- ne rend pas `src-tauri/` obligatoire lorsque la toolchain supporte clairement un autre layout ;
|
||||
- possède l'orchestration via le CLI Tauri lorsque les hooks/config/capabilities/bundles sont concernés ;
|
||||
- distingue un check Rust, un build frontend et une preuve d'intégration Tauri ;
|
||||
- préfère une chaîne de version unique `VERSION → workspace Cargo → package host → Tauri` lorsque l'application partage le release train et que la configuration Tauri peut omettre sa propre version ;
|
||||
- traite les capability files comme source de sécurité intentionnelle ;
|
||||
- ne généralise ni plugins, CSP, fenêtres, bundles, ports ni ressources des corpus ;
|
||||
- ne généralise pas l'ignorance de tout `gen/`, car un projet mobile généré peut recevoir des personnalisations intentionnelles ;
|
||||
- sélectionne `tauri dev/build` ou leur équivalent seulement lorsque la propriété à prouver le justifie.
|
||||
|
||||
### Pas de skeleton dans cette tranche
|
||||
|
||||
`alpha.6` ne crée aucun `tauri.conf.json`, package frontend, template Tauri ou skeleton. La décision de matérialiser une specialization Tauri appartient explicitement à `alpha.7`.
|
||||
|
||||
## Validation opérateur
|
||||
|
||||
Après application du history `PASS` de `alpha.5.fix.1`, commit/push de cette tranche, puis application du présent delta :
|
||||
|
||||
```bash
|
||||
test "$(cat VERSION)" = '0.0.5-alpha.6'
|
||||
test -f history/0.0.5/alpha.5.fix.1.md
|
||||
test -f deltas/0.0.5/alpha.6.md
|
||||
test -f docs/rules/700-FRAMEWORKS.md
|
||||
test -f docs/rules/710-TAURI.md
|
||||
test ! -e history/0.0.5/alpha.6.md
|
||||
|
||||
grep -A2 '^## Statut$' history/0.0.5/alpha.5.fix.1.md | grep -Fx 'PASS'
|
||||
grep -Fx '<!-- version: 11 -->' RULES.md
|
||||
grep -Fx '<!-- version: 13 -->' docs/rules/000-README.md
|
||||
grep -Fx '<!-- version: 4 -->' docs/architecture/003-RULE_PROFILE_MODEL.md
|
||||
grep -Fx '<!-- version: 1 -->' docs/rules/700-FRAMEWORKS.md
|
||||
grep -Fx '<!-- version: 1 -->' docs/rules/710-TAURI.md
|
||||
|
||||
python3 -B -m unittest discover -s tests -v
|
||||
|
||||
python3 -B scripts/audit_markdown_headers.py README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_tables.py README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_links.py README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
|
||||
python3 -B - <<'PY'
|
||||
from pathlib import Path
|
||||
import re
|
||||
|
||||
history = Path('history/0.0.5/alpha.5.fix.1.md').read_text(encoding='utf-8')
|
||||
assert re.search(r'## Statut\s+PASS\s', history)
|
||||
|
||||
frameworks = Path('docs/rules/700-FRAMEWORKS.md').read_text(encoding='utf-8')
|
||||
for phrase in (
|
||||
'# Règles de profils framework',
|
||||
"Ownership des commandes d'intégration",
|
||||
'PGR MUST NOT appliquer une règle globale « tout `gen/` est ignoré »',
|
||||
'Les profils spécifiques utilisent la plage `710` à `799`.',
|
||||
):
|
||||
assert phrase in frameworks, phrase
|
||||
|
||||
tauri = Path('docs/rules/710-TAURI.md').read_text(encoding='utf-8')
|
||||
for phrase in (
|
||||
'# Profil Tauri 2',
|
||||
'PGR MUST NOT imposer Vite, TypeScript, npm, pnpm, yarn, Bun, WASM',
|
||||
"le CLI Tauri est l'owner de l'orchestration",
|
||||
'VERSION
|
||||
↓
|
||||
workspace.package.version
|
||||
↓
|
||||
package Cargo du host
|
||||
↓
|
||||
version applicative Tauri',
|
||||
'PGR MUST NOT appliquer en revanche une exclusion universelle de tout répertoire `gen/`',
|
||||
'## Validation proportionnée',
|
||||
'de `tauri.conf.json` universel',
|
||||
):
|
||||
assert phrase in tauri, phrase
|
||||
|
||||
study = Path('docs/studies/001-KSP_GAMES_RECONCILIATION.md').read_text(encoding='utf-8')
|
||||
assert 'KSP contient `6` applications Desk Tauri et Games `2` hôtes Tauri' in study
|
||||
assert 'Décision `alpha.6` : classer Tauri `COMMON`' in study
|
||||
|
||||
plan = Path('docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md').read_text(encoding='utf-8')
|
||||
assert '`6` applications Tauri KSP et `2` applications Tauri Games' in plan
|
||||
assert 'La tranche active `700-FRAMEWORKS.md` et `710-TAURI.md`.' in plan
|
||||
|
||||
print('0.0.5 alpha.6 Tauri profile audit: clean (700 activated, Tauri 2 responsibilities bounded, no frontend/layout overreach)')
|
||||
PY
|
||||
|
||||
git diff --check
|
||||
|
||||
git add VERSION RULES.md docs/000-README.md docs/architecture/003-RULE_PROFILE_MODEL.md docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md docs/rules/000-README.md docs/rules/700-FRAMEWORKS.md docs/rules/710-TAURI.md docs/studies/001-KSP_GAMES_RECONCILIATION.md deltas/0.0.5/alpha.6.md
|
||||
|
||||
git diff --cached --check
|
||||
git status --short
|
||||
```
|
||||
|
||||
La sortie Git attendue avant ajout du history `alpha.6` est exactement :
|
||||
|
||||
```text
|
||||
M RULES.md
|
||||
M VERSION
|
||||
A deltas/0.0.5/alpha.6.md
|
||||
M docs/000-README.md
|
||||
M docs/architecture/003-RULE_PROFILE_MODEL.md
|
||||
M docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||
M docs/rules/000-README.md
|
||||
A docs/rules/700-FRAMEWORKS.md
|
||||
A docs/rules/710-TAURI.md
|
||||
M docs/studies/001-KSP_GAMES_RECONCILIATION.md
|
||||
```
|
||||
|
||||
## Transition
|
||||
|
||||
### PASS
|
||||
|
||||
Créer/appliquer `history/0.0.5/alpha.6.md`, committer/pousser `0.0.5-alpha.6`, puis poursuivre à `0.0.5-alpha.7` pour décider si une skeleton specification Tauri apporte réellement une valeur de composition au-dessus des profils existants.
|
||||
|
||||
### FAIL
|
||||
|
||||
Rester dans `0.0.5-alpha.6.fix.M` ou REPLAN si le profil exige encore une valeur applicative arbitraire. Aucun skeleton Tauri ne doit être créé tant que le profil framework n'est pas correctement fermé.
|
||||
186
deltas/0.0.5/alpha.7.fix.1.md
Normal file
186
deltas/0.0.5/alpha.7.fix.1.md
Normal file
@@ -0,0 +1,186 @@
|
||||
<!-- file: deltas/0.0.5/alpha.7.fix.1.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Delta 0.0.5-alpha.7.fix.1 — contrats de suffixes, packaging Rust et tracing
|
||||
|
||||
## Baseline et version
|
||||
|
||||
Baseline attendue : commit opérateur complet de `0.0.5-alpha.7`, réalisé après application de `history/0.0.5/alpha.7.md` avec statut `FAIL`.
|
||||
|
||||
Version après application :
|
||||
|
||||
```text
|
||||
0.0.5-alpha.7.fix.1
|
||||
```
|
||||
|
||||
## Motif
|
||||
|
||||
La gate mécanique de `alpha.7` est propre, mais la revue fonctionnelle opérateur révèle que la nomenclature livrée reste trop descriptive. Dans les projets contrôlés, les suffixes doivent également porter un contrat architectural : `-api` désigne une frontière de contrats réellement justifiée, `-lib` une implémentation/fonctionnalité réutilisable, tandis que les exécutables restent normalement des packages distincts et minces.
|
||||
|
||||
La relecture ciblée des corpus confirme plusieurs éléments réutilisables :
|
||||
|
||||
- KSP distingue explicitement `ksp-<domain>-api` et `ksp-<role>-lib`, interdit une crate `*-api` créée uniquement par symétrie et garde les APIs purement déclaratives sans logging runtime ;
|
||||
- Games sépare explicitement la crate lib de jeu et ses launchers ;
|
||||
- KSP et Games convergent sur `tracing`, la composition du subscriber et une crate transverse de logging ;
|
||||
- les six hosts Tauri KSP et les deux hosts Tauri Games observés utilisent tous un package mixte lib/bin avec des noms de targets distincts.
|
||||
|
||||
Une ancienne règle KSP préférait un package worker mixte lib/bin. Cette préférence n'est pas généralisée : la décision PGR actuelle est la séparation par défaut, Tauri restant l'exception framework explicitement reconnue.
|
||||
|
||||
## Scope
|
||||
|
||||
REPLACE :
|
||||
|
||||
```text
|
||||
VERSION
|
||||
docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||
docs/rules/510-RUST_CARGO.md
|
||||
docs/rules/710-TAURI.md
|
||||
docs/skeletons/002-RUST_CARGO_WORKSPACE.md
|
||||
docs/studies/001-KSP_GAMES_RECONCILIATION.md
|
||||
docs/templates/002-CARGO_MANIFESTS.md
|
||||
```
|
||||
|
||||
ADD :
|
||||
|
||||
```text
|
||||
deltas/0.0.5/alpha.7.fix.1.md
|
||||
```
|
||||
|
||||
DELETE : aucun.
|
||||
|
||||
## Décisions
|
||||
|
||||
Pour une nouvelle baseline Rust contrôlée :
|
||||
|
||||
- `-api` signifie contrat extensible/passif ; une crate `-api` n'est créée que si une séparation réelle est justifiée par extension, backend, lifecycle, implémentations multiples ou implémentation externe ;
|
||||
- une crate `-api` purement déclarative reste normalement sans logging/tracing runtime ;
|
||||
- lorsqu'une seule implémentation est utile et qu'aucune frontière séparée n'apporte de valeur, une seule crate `-lib` est préférée ;
|
||||
- `-lib` signifie implémentation ou fonctionnalité réutilisable et ne contient normalement pas de cible binaire ;
|
||||
- hors exception explicite de framework/plateforme, une bibliothèque réutilisable et son exécutable sont des packages Cargo distincts ;
|
||||
- l'exécutable porte un rôle lisible lorsqu'il existe (`cli`, `desk`, `worker`, `job`, `server`, etc.), dépend des libs nécessaires et conserve `main.rs` comme couche de bootstrap/composition mince ;
|
||||
- Tauri reste l'exception framework actuelle au package séparé lib/bin ; son profil impose alors des noms de targets réellement distincts, y compris après normalisation Cargo `-` -> `_`.
|
||||
|
||||
Pour les diagnostics :
|
||||
|
||||
- `tracing` est le mécanisme recommandé pour les nouveaux projets Rust contrôlés ;
|
||||
- `log` reste acceptable comme bridge de compatibilité mais n'est pas la façade par défaut sans contrainte externe ;
|
||||
- lorsqu'un workspace possède plusieurs runtimes partageant subscriber, filtres, sinks ou lifecycle, une crate transverse de logging/tracing SHOULD centraliser cette responsabilité ;
|
||||
- `tracing-subscriber` et `tracing-appender` appartiennent normalement à cet owner de composition ;
|
||||
- une bibliothèque métier/technique peut émettre des événements mais ne configure pas silencieusement le subscriber global.
|
||||
|
||||
## Hors scope
|
||||
|
||||
Ce correctif ne traite toujours pas l'ordre des blocs, le regroupement par visibilité, l'espacement interne, l'ordre alphabétique des items ou les audits de forme : ces sujets restent réservés à `alpha.8`.
|
||||
|
||||
Il ne crée aucun nouvel audit Python et ne transforme pas le profil Rust en catalogue exhaustif de suffixes. Les vocabulaires métier exacts restent locaux.
|
||||
|
||||
## Validation opérateur
|
||||
|
||||
Après application du history `FAIL` de `alpha.7`, commit/push de cette tranche, puis application du présent delta :
|
||||
|
||||
```bash
|
||||
test "$(cat VERSION)" = '0.0.5-alpha.7.fix.1'
|
||||
test -f history/0.0.5/alpha.7.md
|
||||
test -f deltas/0.0.5/alpha.7.fix.1.md
|
||||
test ! -e history/0.0.5/alpha.7.fix.1.md
|
||||
|
||||
grep -A2 '^## Statut$' history/0.0.5/alpha.7.md | grep -Fx 'FAIL'
|
||||
grep -Fx '<!-- version: 6 -->' docs/rules/510-RUST_CARGO.md
|
||||
grep -Fx '<!-- version: 5 -->' docs/rules/710-TAURI.md
|
||||
grep -Fx '<!-- version: 4 -->' docs/skeletons/002-RUST_CARGO_WORKSPACE.md
|
||||
grep -Fx '<!-- version: 3 -->' docs/templates/002-CARGO_MANIFESTS.md
|
||||
grep -Fx '<!-- version: 9 -->' docs/studies/001-KSP_GAMES_RECONCILIATION.md
|
||||
grep -Fx '<!-- version: 10 -->' docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||
|
||||
python3 -B -m unittest discover -s tests -v
|
||||
|
||||
python3 -B scripts/audit_markdown_headers.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_tables.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_links.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
|
||||
python3 -B - <<'PY'
|
||||
from pathlib import Path
|
||||
import re
|
||||
|
||||
history = Path("history/0.0.5/alpha.7.md").read_text(encoding="utf-8")
|
||||
assert re.search(r"## Statut\s+FAIL\s", history)
|
||||
|
||||
rules = Path("docs/rules/510-RUST_CARGO.md").read_text(encoding="utf-8")
|
||||
for phrase in (
|
||||
"### Les suffixes portent un contrat architectural",
|
||||
"Une crate `-api` MUST NOT être créée uniquement pour obtenir une paire de noms symétrique.",
|
||||
"Lorsqu'une seule implémentation est réellement prévue",
|
||||
"### Séparation bibliothèques / exécutables",
|
||||
"Tauri constitue l'exception framework actuellement reconnue par PGR",
|
||||
"## Diagnostics structurés et ownership du logging",
|
||||
"`tracing` est le mécanisme recommandé",
|
||||
"SHOULD NOT installer silencieusement un subscriber global",
|
||||
):
|
||||
assert phrase in rules, phrase
|
||||
|
||||
tauri = Path("docs/rules/710-TAURI.md").read_text(encoding="utf-8")
|
||||
for phrase in (
|
||||
"le package mixte `lib + bin` constitue l'exception framework explicite",
|
||||
"leurs noms MUST être distincts même après la normalisation Cargo usuelle des tirets en underscores",
|
||||
"project_feature_desk_lib",
|
||||
"Un plugin Tauri de tracing sert alors d'adapter",
|
||||
):
|
||||
assert phrase in tauri, phrase
|
||||
|
||||
skeleton = Path("docs/skeletons/002-RUST_CARGO_WORKSPACE.md").read_text(encoding="utf-8")
|
||||
for phrase in (
|
||||
"les frontières `-api` / `-lib` réellement justifiées",
|
||||
"Les exécutables sont des packages distincts des bibliothèques",
|
||||
"crate transverse de logging/tracing",
|
||||
):
|
||||
assert phrase in skeleton, phrase
|
||||
|
||||
template = Path("docs/templates/002-CARGO_MANIFESTS.md").read_text(encoding="utf-8")
|
||||
assert "une bibliothèque réutilisable et son exécutable sont normalement deux packages Cargo distincts" in template
|
||||
assert "Tauri est une exception framework" in template
|
||||
|
||||
study = Path("docs/studies/001-KSP_GAMES_RECONCILIATION.md").read_text(encoding="utf-8")
|
||||
for phrase in (
|
||||
"#### Correction `alpha.7.fix.1` — suffixes, packaging et tracing",
|
||||
"KSP-WORKER-014",
|
||||
"les `6` hosts Tauri KSP `0.3.16` et les `2` hosts Tauri Games `0.3.5`",
|
||||
"PGR retient donc `tracing` par défaut",
|
||||
):
|
||||
assert phrase in study, phrase
|
||||
|
||||
plan = Path("docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md").read_text(encoding="utf-8")
|
||||
assert "`alpha.7.fix.1` complète donc la tranche" in plan
|
||||
assert "### alpha.8 — formatage Rust structurel et audits monotâches" in plan
|
||||
|
||||
print("0.0.5 alpha.7.fix.1 crate contract audit: clean (api/lib semantics, binary split, tracing owner, Tauri exception)")
|
||||
PY
|
||||
|
||||
git diff --check
|
||||
|
||||
git add VERSION \
|
||||
docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md \
|
||||
docs/rules/510-RUST_CARGO.md docs/rules/710-TAURI.md \
|
||||
docs/skeletons/002-RUST_CARGO_WORKSPACE.md \
|
||||
docs/studies/001-KSP_GAMES_RECONCILIATION.md \
|
||||
docs/templates/002-CARGO_MANIFESTS.md \
|
||||
deltas/0.0.5/alpha.7.fix.1.md
|
||||
|
||||
git diff --cached --check
|
||||
git status --short
|
||||
```
|
||||
|
||||
La sortie Git attendue avant ajout du history est exactement :
|
||||
|
||||
```text
|
||||
M VERSION
|
||||
A deltas/0.0.5/alpha.7.fix.1.md
|
||||
M docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||
M docs/rules/510-RUST_CARGO.md
|
||||
M docs/rules/710-TAURI.md
|
||||
M docs/skeletons/002-RUST_CARGO_WORKSPACE.md
|
||||
M docs/studies/001-KSP_GAMES_RECONCILIATION.md
|
||||
M docs/templates/002-CARGO_MANIFESTS.md
|
||||
```
|
||||
175
deltas/0.0.5/alpha.7.md
Normal file
175
deltas/0.0.5/alpha.7.md
Normal file
@@ -0,0 +1,175 @@
|
||||
<!-- file: deltas/0.0.5/alpha.7.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Delta 0.0.5-alpha.7 — profil Rust strict, chemins et nomenclature explicite
|
||||
|
||||
## Baseline et version
|
||||
|
||||
Baseline attendue : commit opérateur complet de `0.0.5-alpha.6.fix.3`, réalisé après application de `history/0.0.5/alpha.6.fix.3.md` avec statut `PASS`.
|
||||
|
||||
Version après application :
|
||||
|
||||
```text
|
||||
0.0.5-alpha.7
|
||||
```
|
||||
|
||||
## Motif
|
||||
|
||||
La réconciliation Tauri a confirmé qu'un host contrôlé hérite du profil Rust au lieu de redéfinir ses conventions. La relecture des règles autoritaires KSP/Games révèle alors un écart PGR plus ancien : la conception initiale avait retenu un profil de forte explicité, mais `510-RUST_CARGO.md` matérialisé conservait encore une politique permissive sur les `use` non-traits et ne formalisait pas la nomenclature des crates.
|
||||
|
||||
KSP `RULES_RUST.md` version `10` fournit la référence stricte : Rust 2024, `use` réservé aux traits, chemins externes publics explicites et courts, réexports internes `self::`, façade crate-root, `crate::Item`, absence d'alias/globs et contrôle de flux explicite. Games `RULES_RUST.md` version `7` confirme le noyau Rust 2024/façade/erreurs mais reste plus léger sur certains imports et règles de forme. `alpha.7` retient donc le profil strict comme défaut des **nouvelles baselines contrôlées** tout en conservant des overrides explicites pour les projets externes ou historiques.
|
||||
|
||||
## Scope
|
||||
|
||||
REPLACE :
|
||||
|
||||
```text
|
||||
VERSION
|
||||
docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||
docs/rules/510-RUST_CARGO.md
|
||||
docs/skeletons/002-RUST_CARGO_WORKSPACE.md
|
||||
docs/studies/001-KSP_GAMES_RECONCILIATION.md
|
||||
docs/templates/002-CARGO_MANIFESTS.md
|
||||
```
|
||||
|
||||
ADD :
|
||||
|
||||
```text
|
||||
deltas/0.0.5/alpha.7.md
|
||||
```
|
||||
|
||||
DELETE : aucun.
|
||||
|
||||
## Décisions
|
||||
|
||||
Pour une nouvelle baseline Rust contrôlée :
|
||||
|
||||
- Rust 2024 devient la baseline normative actuelle ; une contrainte externe doit être documentée explicitement ;
|
||||
- `use` est réservé aux traits qui doivent réellement être mis en scope ; les autres symboles sont appelés par chemins explicites ;
|
||||
- un symbole externe utilise le chemin public le plus court exposé par sa crate ;
|
||||
- les réexports internes utilisent `self::`, restent explicites ligne par ligne et ne masquent pas les collisions par alias ;
|
||||
- les glob imports, regroupements par accolades de façade et imports non-traits de commodité sont interdits ;
|
||||
- les modules d'implémentation restent privés ; les items partagés passent par la façade crate-root et `crate::Item`, y compris dans leur module propriétaire ;
|
||||
- `pub(super)`/`pub(in ...)` ne remplacent pas cette façade dans une baseline contrôlée ;
|
||||
- tout `pub`/`pub(crate)` et tout réexport crate-root porte une rustdoc utile ;
|
||||
- `unwrap`, `expect` et `?` sont interdits en production dans le profil strict ; la propagation d'erreur et les retours restent explicites.
|
||||
|
||||
Le marqueur historique KSP `rust-rules: trait-import` n'est pas généralisé : il appartient à l'enforcement local, pas à la règle sémantique.
|
||||
|
||||
Pour la nomenclature des crates d'un nouveau projet contrôlé :
|
||||
|
||||
```text
|
||||
<project>-<responsibility>-<role-or-target>
|
||||
```
|
||||
|
||||
est la forme recommandée. Le préfixe projet/abréviation est obligatoire ; le classificateur (`lib`, `api`, `worker`, `job`, `cli`, `desk`, `desktop`, `tauri`, `wasm`, `server`, etc.) est utilisé lorsqu'il apporte une information réelle. Le vocabulaire exact reste local, aucun suffixe n'est ajouté par symétrie et aucun projet historique n'est renommé rétroactivement uniquement pour adopter cette grammaire.
|
||||
|
||||
Le skeleton Rust/Cargo et le guide des manifests adoptent ces choix pour les futures baselines contrôlées. L'audit de façade déjà livré devient une sélection recommandée du skeleton strict ; l'adoption d'un projet existant commence toujours en `--report-only`.
|
||||
|
||||
## Hors scope
|
||||
|
||||
Cette tranche ne modifie pas les règles de blocs homogènes, ordre alphabétique, espacement, regroupement par visibilité ou organisation structurelle des items : elles restent réservées à `alpha.8` avec leurs audits monotâches.
|
||||
|
||||
Elle n'importe pas `audit_rust_general_rules.py` depuis KSP/Games, ne crée aucun parser Rust général et ne modifie pas le skeleton Tauri prévu en `alpha.9`.
|
||||
|
||||
## Validation opérateur
|
||||
|
||||
Après application du history `PASS` de `alpha.6.fix.3`, commit/push de cette tranche, puis application du présent delta :
|
||||
|
||||
```bash
|
||||
test "$(cat VERSION)" = '0.0.5-alpha.7'
|
||||
test -f history/0.0.5/alpha.6.fix.3.md
|
||||
test -f deltas/0.0.5/alpha.7.md
|
||||
test ! -e history/0.0.5/alpha.7.md
|
||||
|
||||
grep -A2 '^## Statut$' history/0.0.5/alpha.6.fix.3.md | grep -Fx 'PASS'
|
||||
grep -Fx '<!-- version: 5 -->' docs/rules/510-RUST_CARGO.md
|
||||
grep -Fx '<!-- version: 3 -->' docs/skeletons/002-RUST_CARGO_WORKSPACE.md
|
||||
grep -Fx '<!-- version: 2 -->' docs/templates/002-CARGO_MANIFESTS.md
|
||||
grep -Fx '<!-- version: 8 -->' docs/studies/001-KSP_GAMES_RECONCILIATION.md
|
||||
grep -Fx '<!-- version: 9 -->' docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||
|
||||
python3 -B -m unittest discover -s tests -v
|
||||
|
||||
python3 -B scripts/audit_markdown_headers.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_tables.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_links.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
|
||||
python3 -B - <<'PY'
|
||||
from pathlib import Path
|
||||
import re
|
||||
|
||||
history = Path("history/0.0.5/alpha.6.fix.3.md").read_text(encoding="utf-8")
|
||||
assert re.search(r"## Statut\s+PASS\s", history)
|
||||
|
||||
rules = Path("docs/rules/510-RUST_CARGO.md").read_text(encoding="utf-8")
|
||||
for phrase in (
|
||||
"nouveau projet Rust contrôlé MUST utiliser l'édition Rust 2024",
|
||||
"### Nomenclature des crates dans un projet contrôlé",
|
||||
"<project>-<responsibility>-<role-or-target>",
|
||||
"### `use` réservé aux traits",
|
||||
"le code utilise directement le **chemin public le plus court**",
|
||||
"Les réexports d'éléments internes commencent par `self::`",
|
||||
"toute référence dans la même crate MUST utiliser `crate::Item`",
|
||||
"`unwrap()` et `expect()` MUST NOT être utilisés",
|
||||
"l'opérateur `?` MUST NOT être utilisé",
|
||||
):
|
||||
assert phrase in rules, phrase
|
||||
|
||||
for forbidden in (
|
||||
"PGR ne généralise pas l'interdiction KSP plus stricte de tous les `use` non-traits",
|
||||
"le profil de façade crate-root est seulement facultatif pour une nouvelle baseline contrôlée",
|
||||
):
|
||||
assert forbidden not in rules, forbidden
|
||||
|
||||
skeleton = Path("docs/skeletons/002-RUST_CARGO_WORKSPACE.md").read_text(encoding="utf-8")
|
||||
for phrase in (
|
||||
"nom court/abréviation canonique du projet",
|
||||
"édition Rust 2024",
|
||||
"façade crate-root et les chemins explicites sont sélectionnés par défaut",
|
||||
"audit_rust_export_completeness.py",
|
||||
):
|
||||
assert phrase in skeleton, phrase
|
||||
|
||||
study = Path("docs/studies/001-KSP_GAMES_RECONCILIATION.md").read_text(encoding="utf-8")
|
||||
assert "#### Décision `alpha.7` — profil Rust strict et nomenclature" in study
|
||||
assert "KSP `RULES_RUST.md` version `10`" in study
|
||||
assert "Games `RULES_RUST.md` version `7`" in study
|
||||
assert "Les règles de blocs homogènes" in study
|
||||
|
||||
plan = Path("docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md").read_text(encoding="utf-8")
|
||||
assert "La réconciliation des règles versionnées KSP/Games retient KSP comme référence stricte" in plan
|
||||
assert "### alpha.8 — formatage Rust structurel et audits monotâches" in plan
|
||||
assert "### alpha.9 — décision de skeleton Tauri pour projets contrôlés" in plan
|
||||
|
||||
print("0.0.5 alpha.7 strict Rust profile audit: clean (explicit paths, crate-root facade, controlled naming, alpha.8 formatting deferred)")
|
||||
PY
|
||||
|
||||
git diff --check
|
||||
|
||||
git add VERSION \
|
||||
docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md \
|
||||
docs/rules/510-RUST_CARGO.md \
|
||||
docs/skeletons/002-RUST_CARGO_WORKSPACE.md \
|
||||
docs/studies/001-KSP_GAMES_RECONCILIATION.md \
|
||||
docs/templates/002-CARGO_MANIFESTS.md \
|
||||
deltas/0.0.5/alpha.7.md
|
||||
|
||||
git diff --cached --check
|
||||
git status --short
|
||||
```
|
||||
|
||||
La sortie Git attendue avant ajout du history est exactement :
|
||||
|
||||
```text
|
||||
M VERSION
|
||||
A deltas/0.0.5/alpha.7.md
|
||||
M docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||
M docs/rules/510-RUST_CARGO.md
|
||||
M docs/skeletons/002-RUST_CARGO_WORKSPACE.md
|
||||
M docs/studies/001-KSP_GAMES_RECONCILIATION.md
|
||||
M docs/templates/002-CARGO_MANIFESTS.md
|
||||
```
|
||||
248
deltas/0.0.5/alpha.8.md
Normal file
248
deltas/0.0.5/alpha.8.md
Normal file
@@ -0,0 +1,248 @@
|
||||
<!-- file: deltas/0.0.5/alpha.8.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Delta 0.0.5-alpha.8 — formatage Rust structurel et audits monotâches
|
||||
|
||||
## Baseline et version
|
||||
|
||||
Baseline attendue : commit opérateur complet de `0.0.5-alpha.7.fix.1`, réalisé après application de `history/0.0.5/alpha.7.fix.1.md` avec statut `PASS`.
|
||||
|
||||
Version après application :
|
||||
|
||||
```text
|
||||
0.0.5-alpha.8
|
||||
```
|
||||
|
||||
## Mission
|
||||
|
||||
Fermer le chantier de réconciliation du formatage Rust structurel sans importer les anciens `audit_rust_general_rules.py` composites de KSP/Games.
|
||||
|
||||
La tranche attribue chaque propriété à un owner identifiable : Rustfmt lorsqu'il sait réellement réécrire la forme, audits PGR monotâches lorsqu'une structure stable n'est pas possédée par l'outil officiel, et revue humaine lorsque l'ordre peut être métier/protocolaire.
|
||||
|
||||
## Scope
|
||||
|
||||
REPLACE :
|
||||
|
||||
```text
|
||||
VERSION
|
||||
docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||
docs/rules/510-RUST_CARGO.md
|
||||
docs/skeletons/002-RUST_CARGO_WORKSPACE.md
|
||||
docs/studies/001-KSP_GAMES_RECONCILIATION.md
|
||||
docs/validation/001-VALIDATION_MATRIX.md
|
||||
docs/validation/002-RUST_STYLE_AUDITS.md
|
||||
tests/test_rust_audits.py
|
||||
```
|
||||
|
||||
ADD :
|
||||
|
||||
```text
|
||||
deltas/0.0.5/alpha.8.md
|
||||
scripts/audit_rust_item_spacing.py
|
||||
scripts/audit_rust_module_order.py
|
||||
scripts/audit_rust_reexport_blocks.py
|
||||
scripts/audit_rust_trait_import_blocks.py
|
||||
```
|
||||
|
||||
DELETE : aucun.
|
||||
|
||||
## Décisions de formatage
|
||||
|
||||
Pour une nouvelle baseline Rust contrôlée sélectionnant le profil strict :
|
||||
|
||||
- les lignes vides consécutives et les lignes vides dans fonctions/méthodes/`struct`/`enum` sont interdites ;
|
||||
- deux items Rust distincts voisins d'un même scope sont séparés par exactement une ligne vide lorsque rien d'intermédiaire ne possède lui-même l'espacement ;
|
||||
- les blocs compacts `const` restent sous un owner séparé et ne sont pas interprétés par l'audit d'espacement général ;
|
||||
- les modules de production précèdent les modules de tests et chaque groupe est alphabétique lorsque cet ordre est sans sémantique ;
|
||||
- les `use` non exportés autorisés par le profil strict restent dans un bloc module-level compact avant les déclarations métier ;
|
||||
- les `pub use` précèdent les `pub(crate) use`, sans ligne vide interne et avec exactement une ligne vide entre les deux visibilités lorsqu'elles coexistent ;
|
||||
- Rustfmt reste l'owner du tri intra-bloc des `use`, réexports et modules qu'il sait réécrire ; les audits PGR ne créent pas un tri concurrent.
|
||||
|
||||
PGR conserve comme fortes conventions de lisibilité le rapprochement d'un `struct` et de ses `impl`, ainsi que la préférence des éléments visibles avant les helpers privés lorsque cela clarifie le fichier. Aucun audit lexical n'impose cependant un ordre global `enum → struct → impl → fn` ou un tri visible/privé susceptible d'écraser une organisation métier.
|
||||
|
||||
## Audits ajoutés
|
||||
|
||||
Quatre contrôles read-only monotâches sont extraits :
|
||||
|
||||
```text
|
||||
audit_rust_item_spacing.py
|
||||
séparation exacte des items distincts voisins
|
||||
|
||||
audit_rust_module_order.py
|
||||
ordre production/tests et ordre alphabétique des modules
|
||||
|
||||
audit_rust_trait_import_blocks.py
|
||||
placement/contiguïté des use non exportés
|
||||
|
||||
audit_rust_reexport_blocks.py
|
||||
ordre de visibilité et espacement des blocs de réexports
|
||||
```
|
||||
|
||||
Ils utilisent `_rust_audit_common.py` pour la sélection et le masquage lexical. Ils ne tentent pas de remplacer un parser Rust ni de déterminer la nature sémantique d'un import.
|
||||
|
||||
Les audits déjà existants gardent leurs responsabilités :
|
||||
|
||||
```text
|
||||
audit_rust_blank_lines.py
|
||||
blancs consécutifs / blancs dans certains corps
|
||||
|
||||
audit_rust_const_blocks.py
|
||||
consts sélectionnées : visibilité, ordre, espacement
|
||||
|
||||
audit_rust_export_completeness.py
|
||||
façade crate-root et chemins canoniques
|
||||
```
|
||||
|
||||
## Mesure croisée
|
||||
|
||||
Les quatre nouveaux audits ont été exécutés pendant la préparation sur tous les fichiers Rust sous `crates/` des baselines autoritaires :
|
||||
|
||||
```text
|
||||
KSP 0.3.16 603 file(s) item/module/trait-import/reexport: clean
|
||||
Games 0.3.5 87 file(s) item/module/trait-import/reexport: clean
|
||||
```
|
||||
|
||||
`audit_rust_blank_lines.py` est également propre sur ces `603` et `87` fichiers.
|
||||
|
||||
En revanche, `audit_rust_const_blocks.py` exécuté aveuglément sur l'ensemble produit `18` signaux KSP et `0` Games. Certains signaux correspondent à des tables/schémas à ordre intentionnel. Il reste donc un audit à sélection explicite par fichier et ne devient pas une gate globale.
|
||||
|
||||
Ces mesures servent à qualifier la réutilisabilité des règles PGR ; elles ne constituent pas une validation opérateur de KSP/Games.
|
||||
|
||||
## Horizon documenté sans engagement
|
||||
|
||||
La revue d'horizon du plan conserve `0.1.0` comme seule prochaine release engagée, mais mémorise trois candidats sans numéro ni engagement :
|
||||
|
||||
1. profils techniques composables par langage/framework/target/plateforme et préoccupation transverse, notamment observability/logging ;
|
||||
2. profil documentaire/spécification, avec `saselang-bible` comme corpus pilote possible ;
|
||||
3. audit de généricité de PGR pour des projets hors développement logiciel.
|
||||
|
||||
Ces candidats ne deviennent ni `Study`, ni `ROADMAP`, ni release plan tant qu'une décision explicite ne les promeut pas.
|
||||
|
||||
## Hors scope
|
||||
|
||||
Cette tranche ne :
|
||||
|
||||
- crée pas de parser Rust général ;
|
||||
- réimporte pas `audit_rust_general_rules.py` ;
|
||||
- impose pas un ordre alphabétique à une séquence sémantique ;
|
||||
- crée pas d'audit dédié `static/type` uniquement pour la symétrie ;
|
||||
- modifie pas les contrats de suffixes/packaging/tracing fermés par `alpha.7.fix.1` ;
|
||||
- commence pas le skeleton Tauri réservé à `alpha.9` ;
|
||||
- transforme pas les candidats d'horizon en versions promises.
|
||||
|
||||
## Validation opérateur
|
||||
|
||||
Après application du history `PASS` de `alpha.7.fix.1`, commit/push de cette tranche, puis application du présent delta :
|
||||
|
||||
```bash
|
||||
test "$(cat VERSION)" = '0.0.5-alpha.8'
|
||||
test -f history/0.0.5/alpha.7.fix.1.md
|
||||
test -f deltas/0.0.5/alpha.8.md
|
||||
test -f scripts/audit_rust_item_spacing.py
|
||||
test -f scripts/audit_rust_module_order.py
|
||||
test -f scripts/audit_rust_reexport_blocks.py
|
||||
test -f scripts/audit_rust_trait_import_blocks.py
|
||||
test ! -e scripts/audit_rust_general_rules.py
|
||||
test ! -e history/0.0.5/alpha.8.md
|
||||
|
||||
grep -A2 '^## Statut$' history/0.0.5/alpha.7.fix.1.md | grep -Fx 'PASS'
|
||||
grep -Fx '<!-- version: 7 -->' docs/rules/510-RUST_CARGO.md
|
||||
grep -Fx '<!-- version: 5 -->' docs/skeletons/002-RUST_CARGO_WORKSPACE.md
|
||||
grep -Fx '<!-- version: 10 -->' docs/studies/001-KSP_GAMES_RECONCILIATION.md
|
||||
grep -Fx '<!-- version: 12 -->' docs/validation/001-VALIDATION_MATRIX.md
|
||||
grep -Fx '<!-- version: 2 -->' docs/validation/002-RUST_STYLE_AUDITS.md
|
||||
grep -Fx '<!-- version: 11 -->' docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||
grep -Fx '# version: 2' tests/test_rust_audits.py
|
||||
grep -Fx '# version: 1' scripts/audit_rust_item_spacing.py
|
||||
grep -Fx '# version: 1' scripts/audit_rust_module_order.py
|
||||
grep -Fx '# version: 1' scripts/audit_rust_reexport_blocks.py
|
||||
grep -Fx '# version: 1' scripts/audit_rust_trait_import_blocks.py
|
||||
|
||||
python3 -B -m unittest discover -s tests -p 'test_rust_audits.py' -v
|
||||
python3 -B -m unittest discover -s tests -v
|
||||
|
||||
python3 -B scripts/audit_markdown_headers.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_tables.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_links.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
|
||||
python3 -B - <<'PY'
|
||||
from pathlib import Path
|
||||
import re
|
||||
|
||||
history = Path("history/0.0.5/alpha.7.fix.1.md").read_text(encoding="utf-8")
|
||||
assert re.search(r"## Statut\s+PASS\s", history)
|
||||
|
||||
rules = Path("docs/rules/510-RUST_CARGO.md").read_text(encoding="utf-8")
|
||||
for phrase in (
|
||||
"Le profil structurel strict fait partie du défaut des nouvelles baselines Rust contrôlées.",
|
||||
"audit_rust_item_spacing.py",
|
||||
"audit_rust_module_order.py",
|
||||
"audit_rust_trait_import_blocks.py",
|
||||
"audit_rust_reexport_blocks.py",
|
||||
"PGR n'impose toutefois pas un ordre global automatique `enum → struct → impl → fn`",
|
||||
):
|
||||
assert phrase in rules, phrase
|
||||
|
||||
validation = Path("docs/validation/002-RUST_STYLE_AUDITS.md").read_text(encoding="utf-8")
|
||||
for phrase in (
|
||||
"603` fichiers KSP `0.3.16`",
|
||||
"87` fichiers Games `0.3.5`",
|
||||
"18` signaux KSP",
|
||||
"0` Games",
|
||||
"Rustfmt reste l'owner de l'ordre intra-bloc",
|
||||
):
|
||||
assert phrase in validation, phrase
|
||||
|
||||
plan = Path("docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md").read_text(encoding="utf-8")
|
||||
for phrase in (
|
||||
"quatre extractions monotâches complètent le profil",
|
||||
"maturation de profils techniques composables",
|
||||
"`saselang-bible` comme corpus pilote possible",
|
||||
"audit du noyau PGR hors développement logiciel",
|
||||
"### alpha.9 — décision de skeleton Tauri pour projets contrôlés",
|
||||
):
|
||||
assert phrase in plan, phrase
|
||||
|
||||
print("0.0.5 alpha.8 Rust structure audit: clean (owners split, four monotask audits, semantic order protected, horizon candidates recorded)")
|
||||
PY
|
||||
|
||||
git diff --check
|
||||
|
||||
git add VERSION \
|
||||
docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md \
|
||||
docs/rules/510-RUST_CARGO.md \
|
||||
docs/skeletons/002-RUST_CARGO_WORKSPACE.md \
|
||||
docs/studies/001-KSP_GAMES_RECONCILIATION.md \
|
||||
docs/validation/001-VALIDATION_MATRIX.md \
|
||||
docs/validation/002-RUST_STYLE_AUDITS.md \
|
||||
scripts/audit_rust_item_spacing.py \
|
||||
scripts/audit_rust_module_order.py \
|
||||
scripts/audit_rust_reexport_blocks.py \
|
||||
scripts/audit_rust_trait_import_blocks.py \
|
||||
tests/test_rust_audits.py \
|
||||
deltas/0.0.5/alpha.8.md
|
||||
|
||||
git diff --cached --check
|
||||
git status --short
|
||||
```
|
||||
|
||||
La sortie Git attendue avant ajout du history est exactement :
|
||||
|
||||
```text
|
||||
M VERSION
|
||||
A deltas/0.0.5/alpha.8.md
|
||||
M docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||
M docs/rules/510-RUST_CARGO.md
|
||||
M docs/skeletons/002-RUST_CARGO_WORKSPACE.md
|
||||
M docs/studies/001-KSP_GAMES_RECONCILIATION.md
|
||||
M docs/validation/001-VALIDATION_MATRIX.md
|
||||
M docs/validation/002-RUST_STYLE_AUDITS.md
|
||||
A scripts/audit_rust_item_spacing.py
|
||||
A scripts/audit_rust_module_order.py
|
||||
A scripts/audit_rust_reexport_blocks.py
|
||||
A scripts/audit_rust_trait_import_blocks.py
|
||||
M tests/test_rust_audits.py
|
||||
```
|
||||
178
deltas/0.0.5/alpha.9.md
Normal file
178
deltas/0.0.5/alpha.9.md
Normal file
@@ -0,0 +1,178 @@
|
||||
<!-- file: deltas/0.0.5/alpha.9.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Delta 0.0.5-alpha.9 — décision de skeleton Tauri contrôlé
|
||||
|
||||
## Baseline et version
|
||||
|
||||
Baseline attendue : commit opérateur complet de `0.0.5-alpha.8`, réalisé après application de `history/0.0.5/alpha.8.md` avec statut `PASS`.
|
||||
|
||||
Version après application :
|
||||
|
||||
```text
|
||||
0.0.5-alpha.9
|
||||
```
|
||||
|
||||
## Mission
|
||||
|
||||
Décider si les owners PGR réellement matérialisés permettent de créer un skeleton Tauri actionnable pour les projets contrôlés sans transformer ce skeleton en propriétaire implicite de règles Web encore absentes.
|
||||
|
||||
## Scope
|
||||
|
||||
REPLACE :
|
||||
|
||||
```text
|
||||
VERSION
|
||||
docs/000-README.md
|
||||
docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||
docs/skeletons/000-README.md
|
||||
docs/studies/000-README.md
|
||||
```
|
||||
|
||||
ADD :
|
||||
|
||||
```text
|
||||
deltas/0.0.5/alpha.9.md
|
||||
docs/studies/002-TAURI_SKELETON_DECISION.md
|
||||
```
|
||||
|
||||
DELETE : aucun.
|
||||
|
||||
Aucun fichier `docs/skeletons/003-TAURI*.md` n'est créé.
|
||||
|
||||
## Décision
|
||||
|
||||
Résultat :
|
||||
|
||||
```text
|
||||
DEFER
|
||||
```
|
||||
|
||||
Le host Tauri est suffisamment cadré par les owners existants : Rust/Cargo, Tauri, plateformes applicables et règles générales de skeleton. La partie frontend candidate ne l'est pas encore : PGR ne possède aucun profil Web/Vite/TypeScript/Sass.
|
||||
|
||||
Créer maintenant le skeleton obligerait donc sa specification à posséder de fait la structure et la validation Web, alors qu'un skeleton doit composer des owners et non compenser leur absence.
|
||||
|
||||
## Candidat conservé
|
||||
|
||||
La décision ne rejette pas le skeleton organisationnel. Elle conserve comme hypothèse à réévaluer lorsque les owners Web existeront :
|
||||
|
||||
```text
|
||||
host Cargo direct
|
||||
+ frontend/
|
||||
+ Vite
|
||||
+ TypeScript
|
||||
+ Sass
|
||||
+ Bootstrap lorsque pertinent
|
||||
+ TS-RS pour les DTO Rust partagés
|
||||
+ tauri.rs comme owner Tauri
|
||||
+ plugins/capabilities explicitement intégrés
|
||||
+ WASM séparé par défaut
|
||||
```
|
||||
|
||||
Aucune de ces lignes ne crée dans `0.0.5` un owner Web qui n'existe pas encore.
|
||||
|
||||
## Sources et vérification
|
||||
|
||||
La décision repose d'abord sur les baselines KSP `0.3.16` et Games `0.3.5` déjà autoritaires pour la réconciliation. La préparation a également vérifié la documentation Tauri 2 courante concernant la flexibilité du frontend, le scaffold `src-tauri/`, l'initialisation manuelle et l'installation explicite des plugins/capabilities.
|
||||
|
||||
L'étude détaillée est `docs/studies/002-TAURI_SKELETON_DECISION.md`.
|
||||
|
||||
## Hors scope
|
||||
|
||||
Cette tranche ne :
|
||||
|
||||
- crée pas un skeleton décoratif ;
|
||||
- matérialise pas les futurs profils Web ;
|
||||
- modifie pas `710-TAURI.md` ;
|
||||
- choisit pas un package manager universel ;
|
||||
- modifie pas les règles Rust fermées par `alpha.7/alpha.8` ;
|
||||
- réserve pas une release pour le futur skeleton.
|
||||
|
||||
## Validation opérateur
|
||||
|
||||
Après application du history `PASS` de `alpha.8`, commit/push de cette tranche, puis application du présent delta :
|
||||
|
||||
```bash
|
||||
test "$(cat VERSION)" = '0.0.5-alpha.9'
|
||||
test -f history/0.0.5/alpha.8.md
|
||||
test -f deltas/0.0.5/alpha.9.md
|
||||
test -f docs/studies/002-TAURI_SKELETON_DECISION.md
|
||||
test ! -e docs/skeletons/003-TAURI.md
|
||||
test ! -e docs/skeletons/003-TAURI_CONTROLLED_PROJECT.md
|
||||
test ! -e history/0.0.5/alpha.9.md
|
||||
|
||||
grep -A2 '^## Statut$' history/0.0.5/alpha.8.md | grep -Fx 'PASS'
|
||||
grep -Fx '<!-- version: 15 -->' docs/000-README.md
|
||||
grep -Fx '<!-- version: 12 -->' docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||
grep -Fx '<!-- version: 4 -->' docs/skeletons/000-README.md
|
||||
grep -Fx '<!-- version: 2 -->' docs/studies/000-README.md
|
||||
grep -Fx '<!-- version: 1 -->' docs/studies/002-TAURI_SKELETON_DECISION.md
|
||||
|
||||
python3 -B -m unittest discover -s tests -v
|
||||
|
||||
python3 -B scripts/audit_markdown_headers.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_tables.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_links.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
|
||||
python3 -B - <<'PY'
|
||||
from pathlib import Path
|
||||
import re
|
||||
|
||||
history = Path("history/0.0.5/alpha.8.md").read_text(encoding="utf-8")
|
||||
assert re.search(r"## Statut\s+PASS\s", history)
|
||||
|
||||
study = Path("docs/studies/002-TAURI_SKELETON_DECISION.md").read_text(encoding="utf-8")
|
||||
for phrase in (
|
||||
"Décision `alpha.9` :",
|
||||
"DEFER",
|
||||
"Aucun des `8` hosts n'utilise `src-tauri/`.",
|
||||
"PGR `0.0.5` **ne crée pas** de skeleton Tauri `003`.",
|
||||
"PGR `0.0.5` ne possède aucun profil Web dédié",
|
||||
"001-PROJECT_GOVERNANCE_FOUNDATION",
|
||||
"002-RUST_CARGO_WORKSPACE",
|
||||
"Bootstrap comme baseline de présentation lorsqu'un framework CSS généraliste est utile",
|
||||
):
|
||||
assert phrase in study, phrase
|
||||
|
||||
index = Path("docs/skeletons/000-README.md").read_text(encoding="utf-8")
|
||||
assert "Aucun `003-TAURI...` n'est donc créé dans `0.0.5`." in index
|
||||
assert "profils Web réellement matérialisés" in index
|
||||
|
||||
plan = Path("docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md").read_text(encoding="utf-8")
|
||||
assert "### alpha.9 — décision de skeleton Tauri pour projets contrôlés — DEFER" in plan
|
||||
assert "aucun skeleton Tauri `003` n'est créé dans `0.0.5`" in plan
|
||||
assert "### beta.1 — réconciliation intégrée" in plan
|
||||
|
||||
assert not any(Path("docs/skeletons").glob("003-TAURI*.md"))
|
||||
|
||||
print("0.0.5 alpha.9 Tauri skeleton decision: clean (host ready, Web owners missing, decorative skeleton rejected, exit conditions recorded)")
|
||||
PY
|
||||
|
||||
git diff --check
|
||||
|
||||
git add VERSION \
|
||||
docs/000-README.md \
|
||||
docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md \
|
||||
docs/skeletons/000-README.md \
|
||||
docs/studies/000-README.md \
|
||||
docs/studies/002-TAURI_SKELETON_DECISION.md \
|
||||
deltas/0.0.5/alpha.9.md
|
||||
|
||||
git diff --cached --check
|
||||
git status --short
|
||||
```
|
||||
|
||||
La sortie Git attendue avant ajout du history est exactement :
|
||||
|
||||
```text
|
||||
M VERSION
|
||||
A deltas/0.0.5/alpha.9.md
|
||||
M docs/000-README.md
|
||||
M docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||
M docs/skeletons/000-README.md
|
||||
M docs/studies/000-README.md
|
||||
A docs/studies/002-TAURI_SKELETON_DECISION.md
|
||||
```
|
||||
208
deltas/0.0.5/beta.1.md
Normal file
208
deltas/0.0.5/beta.1.md
Normal file
@@ -0,0 +1,208 @@
|
||||
<!-- file: deltas/0.0.5/beta.1.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Delta 0.0.5-beta.1 — réconciliation intégrée et transition vers 0.1.0
|
||||
|
||||
## Baseline
|
||||
|
||||
Version attendue avant application :
|
||||
|
||||
```text
|
||||
0.0.5-alpha.9
|
||||
```
|
||||
|
||||
Le history `history/0.0.5/alpha.9.md` avec statut `PASS` MUST avoir été appliqué, committé et poussé avant ce delta.
|
||||
|
||||
Version après application :
|
||||
|
||||
```text
|
||||
0.0.5-beta.1
|
||||
```
|
||||
|
||||
## Objet
|
||||
|
||||
Fermer la phase alpha de `0.0.5` par une réconciliation intégrée des décisions réellement matérialisées, puis préparer la transition vers la première baseline réutilisable `0.1.0` sans inventer d'owners, de skeletons ou de releases futures.
|
||||
|
||||
Cette tranche :
|
||||
|
||||
- rejoue la classification KSP/Games sur l'état PGR obtenu ;
|
||||
- vérifie que chaque responsabilité nouvelle possède un owner identifiable et que les conventions locales non généralisées restent hors du noyau ;
|
||||
- inscrit durablement le skeleton Tauri contrôlé comme trajectoire `DEFER` dans `ROADMAP.md`, sans numéro de release réservé ;
|
||||
- maintient les trois autres axes discutés pendant `alpha.8` au stade de candidats d'horizon, hors roadmap engagée ;
|
||||
- réconcilie les points d'entrée durables ;
|
||||
- prépare `prompts/006-V0_1_0_START_PROMPT.md` puisque la mission `0.1.0` est suffisamment connue.
|
||||
|
||||
## Décision de roadmap
|
||||
|
||||
La décision `alpha.9` a déjà établi qu'un skeleton Tauri complet ne peut pas être matérialisé proprement avant l'existence d'owners Web suffisants. Ce report est plus qu'une idée : il résulte d'une étude et possède des conditions de sortie explicites.
|
||||
|
||||
`ROADMAP.md` enregistre donc :
|
||||
|
||||
```text
|
||||
(d) skeleton Tauri pour projets contrôlés
|
||||
```
|
||||
|
||||
sans associer cette trajectoire à `0.1.1`, `0.2.0` ou une autre release hypothétique.
|
||||
|
||||
Les axes suivants restent en revanche hors roadmap tant qu'une revue d'horizon ne les engage pas :
|
||||
|
||||
- maturation plus large des profils techniques composables ;
|
||||
- projet documentaire/spécification avec `saselang-bible` comme corpus pilote possible ;
|
||||
- audit de généricité de PGR hors développement logiciel.
|
||||
|
||||
Cette distinction applique directement `300-DOCUMENTATION.md` : une décision de report réelle peut être conservée comme trajectoire différée, tandis qu'un candidat d'horizon ne devient pas automatiquement un engagement macro.
|
||||
|
||||
## Réconciliation intégrée
|
||||
|
||||
L'étude `001-KSP_GAMES_RECONCILIATION.md` reçoit une matrice de sortie `beta.1` qui confirme notamment :
|
||||
|
||||
```text
|
||||
prompt versionné OWNED
|
||||
contrats de fichiers/familles OWNED
|
||||
lifecycle inter-release / horizon OWNED
|
||||
profil Rust contrôlé OWNED
|
||||
audits Rust monotâches OWNED
|
||||
profil Tauri 2 OWNED
|
||||
skeleton Tauri complet DEFER
|
||||
Web/Vite/TypeScript/Sass DEFER
|
||||
Android/JNI spécifique LOCAL/DEFER
|
||||
architectures métier KSP/Games LOCAL
|
||||
```
|
||||
|
||||
La présence d'un owner PGR n'impose pas sa sélection à tous les projets. Applicabilité, composition et overrides restent gouvernés par le modèle de profils.
|
||||
|
||||
## Prompt 006
|
||||
|
||||
`prompts/006-V0_1_0_START_PROMPT.md` prépare la reprise après publication réelle de `v0.0.5`.
|
||||
|
||||
Il fixe uniquement ce qui est déjà décidé :
|
||||
|
||||
- baseline autoritaire `pgr-v0.0.5.zip` et rapport post-tag séparé lorsqu'il existe et est `PASS` ;
|
||||
- cible `0.1.0`, première tranche `0.1.0-alpha.1` ;
|
||||
- audit complet de la stable avant extension ;
|
||||
- mission de première baseline réellement réutilisable ;
|
||||
- nécessité de produire/consolider le plan `0.1.0` pendant `alpha.1` ;
|
||||
- revue d'horizon obligatoire avant fermeture ;
|
||||
- skeleton Tauri conservé `DEFER` tant que ses préconditions ne sont pas réellement satisfaites.
|
||||
|
||||
Le prompt MUST NOT être interprété comme un plan détaillé de `0.1.0` ni comme une promesse de matérialiser tous les candidats d'horizon.
|
||||
|
||||
## Documentation durable
|
||||
|
||||
`README.md` résume désormais les capacités réellement apportées par `0.0.5` sans recopier le plan de release.
|
||||
|
||||
`docs/000-README.md` expose les deux contrats de validation Rust et le prompt de reprise candidat `006`.
|
||||
|
||||
Le plan `005` enregistre le résultat de la réconciliation intégrée et conserve les responsabilités `rc.1`, stable et `publish.001` déjà attribuées.
|
||||
|
||||
## Hors scope
|
||||
|
||||
Cette tranche ne :
|
||||
|
||||
- crée pas de skeleton Tauri `003` ;
|
||||
- crée pas de profil Web placeholder ;
|
||||
- attribue pas de release au travail Tauri différé ;
|
||||
- ajoute pas les trois candidats d'horizon à la roadmap engagée ;
|
||||
- modifie pas `CHANGELOG.md`, réservé à la préparation RC puis à la stable ;
|
||||
- migre pas KSP ou Games ;
|
||||
- change pas les règles Rust/Tauri fermées pendant les alphas.
|
||||
|
||||
## Validation opérateur
|
||||
|
||||
Après application du history `PASS` de `alpha.9`, commit/push de cette tranche, puis application du présent delta :
|
||||
|
||||
```bash
|
||||
test "$(cat VERSION)" = '0.0.5-beta.1'
|
||||
test -f history/0.0.5/alpha.9.md
|
||||
test -f deltas/0.0.5/beta.1.md
|
||||
test -f prompts/006-V0_1_0_START_PROMPT.md
|
||||
test ! -e history/0.0.5/beta.1.md
|
||||
|
||||
grep -A2 '^## Statut$' history/0.0.5/alpha.9.md | grep -Fx 'PASS'
|
||||
grep -Fx '<!-- version: 13 -->' README.md
|
||||
grep -Fx '<!-- version: 7 -->' ROADMAP.md
|
||||
grep -Fx '<!-- version: 16 -->' docs/000-README.md
|
||||
grep -Fx '<!-- version: 13 -->' docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||
grep -Fx '<!-- version: 11 -->' docs/studies/001-KSP_GAMES_RECONCILIATION.md
|
||||
grep -Fx '<!-- version: 1 -->' prompts/006-V0_1_0_START_PROMPT.md
|
||||
|
||||
python3 -B -m unittest discover -s tests -v
|
||||
|
||||
python3 -B scripts/audit_markdown_headers.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_tables.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_links.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
|
||||
python3 -B - <<'PY'
|
||||
from pathlib import Path
|
||||
import re
|
||||
|
||||
history = Path("history/0.0.5/alpha.9.md").read_text(encoding="utf-8")
|
||||
assert re.search(r"## Statut\s+PASS\s", history)
|
||||
|
||||
roadmap = Path("ROADMAP.md").read_text(encoding="utf-8")
|
||||
assert "(d) skeleton Tauri pour projets contrôlés" in roadmap
|
||||
assert "Aucun numéro de release n'est réservé pour ce travail" in roadmap
|
||||
assert "saselang-bible" not in roadmap
|
||||
|
||||
study = Path("docs/studies/001-KSP_GAMES_RECONCILIATION.md").read_text(encoding="utf-8")
|
||||
for phrase in (
|
||||
"## Réconciliation intégrée `beta.1`",
|
||||
"skeleton Tauri contrôlé complet",
|
||||
"`DEFER`",
|
||||
"repris dans `ROADMAP.md` sans numéro de release",
|
||||
"Les trois axes plus larges identifiés pendant `alpha.8` restent des **candidats d'horizon**",
|
||||
):
|
||||
assert phrase in study, phrase
|
||||
|
||||
plan = Path("docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md").read_text(encoding="utf-8")
|
||||
for phrase in (
|
||||
"Le `DEFER` du skeleton Tauri contrôlé est suffisamment décidé",
|
||||
"`prompts/006-V0_1_0_START_PROMPT.md` est préparé",
|
||||
"il ne transforme pas le skeleton Tauri différé en obligation de `0.1.0`",
|
||||
):
|
||||
assert phrase in plan, phrase
|
||||
|
||||
prompt = Path("prompts/006-V0_1_0_START_PROMPT.md").read_text(encoding="utf-8")
|
||||
for phrase in (
|
||||
"# Prompt de démarrage 0.1.0 — première baseline réutilisable",
|
||||
"pgr-v0.0.5.zip",
|
||||
"pgr-0.0.5-publish.001-report.md",
|
||||
"Version cible : `0.1.0`. Première tranche attendue : `0.1.0-alpha.1`.",
|
||||
"Le skeleton Tauri contrôlé reste `DEFER`",
|
||||
"Le plan `0.1.0` MUST programmer une revue d'horizon avant la clôture stable.",
|
||||
):
|
||||
assert phrase in prompt, phrase
|
||||
|
||||
assert not any(Path("docs/skeletons").glob("003-TAURI*.md"))
|
||||
|
||||
print("0.0.5 beta.1 integrated reconciliation: clean (owners reconciled, Tauri defer roadmapped, horizon candidates remain uncommitted, prompt 006 prepared)")
|
||||
PY
|
||||
|
||||
git diff --check
|
||||
|
||||
git add VERSION README.md ROADMAP.md \
|
||||
docs/000-README.md \
|
||||
docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md \
|
||||
docs/studies/001-KSP_GAMES_RECONCILIATION.md \
|
||||
prompts/006-V0_1_0_START_PROMPT.md \
|
||||
deltas/0.0.5/beta.1.md
|
||||
|
||||
git diff --cached --check
|
||||
git status --short
|
||||
```
|
||||
|
||||
La sortie Git attendue avant ajout du history est exactement :
|
||||
|
||||
```text
|
||||
M README.md
|
||||
M ROADMAP.md
|
||||
M VERSION
|
||||
A deltas/0.0.5/beta.1.md
|
||||
M docs/000-README.md
|
||||
M docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||
M docs/studies/001-KSP_GAMES_RECONCILIATION.md
|
||||
A prompts/006-V0_1_0_START_PROMPT.md
|
||||
```
|
||||
190
deltas/0.0.5/rc.1.md
Normal file
190
deltas/0.0.5/rc.1.md
Normal file
@@ -0,0 +1,190 @@
|
||||
<!-- file: deltas/0.0.5/rc.1.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Delta 0.0.5-rc.1 — gel du scope et préparation de release
|
||||
|
||||
## Baseline et version
|
||||
|
||||
Baseline : `0.0.5-beta.1`, avec `history/0.0.5/beta.1.md` appliqué et committé. Ce delta MUST NOT être appliqué avant ce commit.
|
||||
|
||||
Le commit exact de cette baseline sera celui produit par l'opérateur après application du history beta ; il n'est pas anticipé dans cette livraison simultanée du history et du delta suivant.
|
||||
|
||||
Version avant application :
|
||||
|
||||
```text
|
||||
0.0.5-beta.1
|
||||
```
|
||||
|
||||
Version après application :
|
||||
|
||||
```text
|
||||
0.0.5-rc.1
|
||||
```
|
||||
|
||||
## Objet et gel
|
||||
|
||||
La réconciliation `beta.1` est `PASS`. La RC gèle le scope fonctionnel de `0.0.5` sur :
|
||||
|
||||
- les prompts versionnés, contrats documentaires facultatifs et responsabilités de lifecycle/revue d'horizon ;
|
||||
- le profil Rust strict des projets contrôlés, ses contrats de nomenclature/packaging/tracing et ses audits monotâches ;
|
||||
- l'audit de complétude de façade et l'usage canonique `crate::Item` ;
|
||||
- les profils framework et Tauri 2, leurs frontières Rust/frontend, TS-RS, plugins/capabilities, politique de versions produit et exception encadrée `lib + bin` ;
|
||||
- la décision explicite `DEFER` du skeleton Tauri contrôlé jusqu'à matérialisation d'owners Web suffisants ;
|
||||
- la réconciliation KSP/Games et le prompt candidat `006` vers `0.1.0`.
|
||||
|
||||
Le changelog reçoit une entrée candidate `0.0.5` orientée utilisateurs. `ROADMAP.md` est vérifié mais reste inchangé : `0.0.5` n'est marqué terminé qu'à la promotion stable ; `0.1.0` reste la prochaine release engagée ; le skeleton Tauri reste différé sans numéro réservé. Le prompt `006` est vérifié sans être réécrit si son contrat est déjà correct.
|
||||
|
||||
Aucun nouvel owner, profil Web, skeleton, template, audit, règle fonctionnelle ou version postérieure à `0.1.0` n'entre en RC.
|
||||
|
||||
## Scope
|
||||
|
||||
REPLACE :
|
||||
|
||||
```text
|
||||
VERSION
|
||||
CHANGELOG.md
|
||||
docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||
```
|
||||
|
||||
ADD :
|
||||
|
||||
```text
|
||||
deltas/0.0.5/rc.1.md
|
||||
```
|
||||
|
||||
DELETE : aucun.
|
||||
|
||||
L'archive contient exactement ces fichiers complets. Le history `beta.1` est livré séparément ; le history `rc.1` sera produit après la gate opérateur.
|
||||
|
||||
## Gate opérateur de release candidate
|
||||
|
||||
Après application du history `PASS` de `beta.1`, commit/push de cette tranche, puis application du présent delta :
|
||||
|
||||
```bash
|
||||
test "$(cat VERSION)" = '0.0.5-rc.1'
|
||||
git cat-file -e HEAD:history/0.0.5/beta.1.md
|
||||
test -f history/0.0.5/beta.1.md
|
||||
test -f deltas/0.0.5/rc.1.md
|
||||
test -f prompts/006-V0_1_0_START_PROMPT.md
|
||||
test ! -e history/0.0.5/rc.1.md
|
||||
|
||||
grep -A2 '^## Statut$' history/0.0.5/beta.1.md | grep -Fx 'PASS'
|
||||
grep -Fx '<!-- version: 8 -->' CHANGELOG.md
|
||||
grep -Fx '## 0.0.5 (candidate)' CHANGELOG.md
|
||||
grep -Fx '<!-- version: 14 -->' docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||
grep -Fx '<!-- version: 7 -->' ROADMAP.md
|
||||
grep -Fx '<!-- version: 1 -->' prompts/006-V0_1_0_START_PROMPT.md
|
||||
grep -F 'La gate opérateur de `beta.1` est `PASS`' docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||
grep -F '(d) skeleton Tauri pour projets contrôlés' ROADMAP.md
|
||||
grep -F 'Le skeleton Tauri contrôlé reste `DEFER`' prompts/006-V0_1_0_START_PROMPT.md
|
||||
|
||||
python3 -B -m unittest discover -s tests -v
|
||||
|
||||
python3 -B scripts/audit_markdown_headers.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_tables.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_links.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
|
||||
python3 -B - <<'PYGATE'
|
||||
from pathlib import Path
|
||||
import re
|
||||
|
||||
expected = {
|
||||
'alpha.1.md': 'PASS',
|
||||
'alpha.2.md': 'PASS',
|
||||
'alpha.3.md': 'FAIL',
|
||||
'alpha.3.fix.1.md': 'PASS',
|
||||
'alpha.4.md': 'PASS',
|
||||
'alpha.5.md': 'FAIL',
|
||||
'alpha.5.fix.1.md': 'PASS',
|
||||
'alpha.6.md': 'FAIL',
|
||||
'alpha.6.fix.1.md': 'FAIL',
|
||||
'alpha.6.fix.2.md': 'FAIL',
|
||||
'alpha.6.fix.3.md': 'PASS',
|
||||
'alpha.7.md': 'FAIL',
|
||||
'alpha.7.fix.1.md': 'PASS',
|
||||
'alpha.8.md': 'PASS',
|
||||
'alpha.9.md': 'PASS',
|
||||
'beta.1.md': 'PASS',
|
||||
}
|
||||
histories = {path.name for path in Path('history/0.0.5').glob('*.md')}
|
||||
assert histories == set(expected), histories
|
||||
for name, status in expected.items():
|
||||
text = Path('history/0.0.5', name).read_text(encoding='utf-8')
|
||||
assert re.search(rf'## Statut\s+{status}\s', text), (name, status)
|
||||
|
||||
deltas = {path.name for path in Path('deltas/0.0.5').glob('*.md')}
|
||||
assert deltas == set(expected) | {'rc.1.md'}, deltas
|
||||
|
||||
changelog = Path('CHANGELOG.md').read_text(encoding='utf-8')
|
||||
assert '## 0.0.5 (candidate)' in changelog
|
||||
for forbidden in ('alpha.6.fix.3', 'alpha.7.fix.1', 'beta.1'):
|
||||
assert forbidden not in changelog, forbidden
|
||||
|
||||
roadmap = Path('ROADMAP.md').read_text(encoding='utf-8')
|
||||
assert '- `( ) 0.0.5`' in roadmap
|
||||
assert '- `( ) 0.1.0`' in roadmap
|
||||
assert '(d) skeleton Tauri pour projets contrôlés' in roadmap
|
||||
assert 'saselang-bible' not in roadmap
|
||||
|
||||
prompt = Path('prompts/006-V0_1_0_START_PROMPT.md').read_text(encoding='utf-8')
|
||||
for value in (
|
||||
'pgr-v0.0.5.zip',
|
||||
'pgr-0.0.5-publish.001-report.md',
|
||||
'0.1.0-alpha.1',
|
||||
'Le skeleton Tauri contrôlé reste `DEFER`',
|
||||
"revue d'horizon avant la clôture stable",
|
||||
):
|
||||
assert value in prompt, value
|
||||
|
||||
for path in (
|
||||
'scripts/audit_rust_item_spacing.py',
|
||||
'scripts/audit_rust_module_order.py',
|
||||
'scripts/audit_rust_reexport_blocks.py',
|
||||
'scripts/audit_rust_trait_import_blocks.py',
|
||||
'scripts/audit_rust_export_completeness.py',
|
||||
):
|
||||
assert Path(path).is_file(), path
|
||||
|
||||
assert Path('docs/rules/710-TAURI.md').is_file()
|
||||
assert not any(Path('docs/skeletons').glob('003-TAURI*.md'))
|
||||
|
||||
print('0.0.5 rc.1 integration audit: clean (16 prior histories, frozen scope, candidate changelog, roadmap/prompt 006 verified)')
|
||||
PYGATE
|
||||
|
||||
git diff --check
|
||||
|
||||
git add VERSION CHANGELOG.md \
|
||||
docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md \
|
||||
deltas/0.0.5/rc.1.md
|
||||
|
||||
git diff --cached --check
|
||||
git status --short
|
||||
```
|
||||
|
||||
Le scope attendu avant ajout du history est exactement :
|
||||
|
||||
```text
|
||||
M CHANGELOG.md
|
||||
M VERSION
|
||||
A deltas/0.0.5/rc.1.md
|
||||
M docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||
```
|
||||
|
||||
## Revue opérateur complémentaire
|
||||
|
||||
Confirmer que le changelog décrit les capacités de la release plutôt que ses tranches internes, que le `DEFER` Tauri reste visible sans numéro de release, que les trois autres candidats d'horizon ne sont pas promus en roadmap, que le prompt `006` ne présume aucune publication post-tag et que la RC n'étend pas le périmètre fonctionnel.
|
||||
|
||||
Une gate RC `PASS` n'est ni la promotion stable, ni le tag `v0.0.5`, ni la vérification de l'archive publiée après le tag.
|
||||
|
||||
## Transition
|
||||
|
||||
### PASS
|
||||
|
||||
Produire séparément `history/0.0.5/rc.1.md`, l'appliquer puis committer/pousser la RC avant le delta stable `rel.001`.
|
||||
|
||||
### FAIL
|
||||
|
||||
Consigner l'échec réel dans `history/0.0.5/rc.1.md` et corriger uniquement le scope gelé dans `rc.1.fix.1`, sauf REPLAN explicite si la candidate révèle un défaut fonctionnel plus large.
|
||||
170
deltas/0.0.5/rel.001.fix.1.md
Normal file
170
deltas/0.0.5/rel.001.fix.1.md
Normal file
@@ -0,0 +1,170 @@
|
||||
<!-- file: deltas/0.0.5/rel.001.fix.1.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Delta 0.0.5 rel.001.fix.1 — correction de la gate stable pré-tag
|
||||
|
||||
## Baseline et version
|
||||
|
||||
Baseline : état stable `0.0.5` issu de `rel.001`, avec `history/0.0.5/rel.001.md` appliqué et committé en `FAIL`.
|
||||
|
||||
`VERSION` reste :
|
||||
|
||||
```text
|
||||
0.0.5
|
||||
```
|
||||
|
||||
Ce correctif est strictement documentaire et opérationnel. Il ne change ni la version produit, ni le scope fonctionnel validé par `rc.1`, ni les fichiers de présentation stable déjà promus par `rel.001`.
|
||||
|
||||
## Diagnostic corrigé
|
||||
|
||||
La gate `rel.001` devait confirmer la présence exacte du heading stable `## 0.0.5` dans `CHANGELOG.md`. Le delta livré a généré une chaîne Python simple contenant un retour à la ligne physique :
|
||||
|
||||
```python
|
||||
assert '## 0.0.5
|
||||
' in changelog
|
||||
```
|
||||
|
||||
Le heredoc est donc invalide et produit `SyntaxError: unterminated string literal` avant la preuve attendue.
|
||||
|
||||
`rel.001.fix.1` remplace cette forme fragile par une vérification ligne par ligne :
|
||||
|
||||
```python
|
||||
assert '## 0.0.5' in changelog.splitlines()
|
||||
```
|
||||
|
||||
Le delta historique `rel.001.md` reste immuable.
|
||||
|
||||
## Scope
|
||||
|
||||
REPLACE :
|
||||
|
||||
```text
|
||||
docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||
```
|
||||
|
||||
ADD :
|
||||
|
||||
```text
|
||||
deltas/0.0.5/rel.001.fix.1.md
|
||||
```
|
||||
|
||||
DELETE : aucun.
|
||||
|
||||
Aucun fichier `VERSION`, `README`, `ROADMAP`, `CHANGELOG`, règle, script, test, template ou skeleton n'est modifié par ce correctif.
|
||||
|
||||
## Validation opérateur pré-tag
|
||||
|
||||
Après application sur le commit qui contient le history `FAIL` de `rel.001` :
|
||||
|
||||
```bash
|
||||
test "$(cat VERSION)" = '0.0.5'
|
||||
git cat-file -e HEAD:history/0.0.5/rel.001.md
|
||||
test -f history/0.0.5/rel.001.md
|
||||
test -f deltas/0.0.5/rel.001.fix.1.md
|
||||
test -f prompts/006-V0_1_0_START_PROMPT.md
|
||||
test ! -e history/0.0.5/rel.001.fix.1.md
|
||||
|
||||
grep -A2 '^## Statut$' history/0.0.5/rel.001.md | grep -Fx 'FAIL'
|
||||
grep -Fx '<!-- version: 16 -->' docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||
grep -Fx '<!-- version: 14 -->' README.md
|
||||
grep -Fx '<!-- version: 8 -->' ROADMAP.md
|
||||
grep -Fx '<!-- version: 9 -->' CHANGELOG.md
|
||||
grep -Fx '## 0.0.5' CHANGELOG.md
|
||||
grep -F -- '- `(x) 0.0.5`' ROADMAP.md
|
||||
grep -F 'Le skeleton Tauri contrôlé reste `DEFER`' prompts/006-V0_1_0_START_PROMPT.md
|
||||
|
||||
python3 -B - <<'PYGATE'
|
||||
from pathlib import Path
|
||||
import re
|
||||
|
||||
expected = {
|
||||
'alpha.1.md': 'PASS',
|
||||
'alpha.2.md': 'PASS',
|
||||
'alpha.3.md': 'FAIL',
|
||||
'alpha.3.fix.1.md': 'PASS',
|
||||
'alpha.4.md': 'PASS',
|
||||
'alpha.5.md': 'FAIL',
|
||||
'alpha.5.fix.1.md': 'PASS',
|
||||
'alpha.6.md': 'FAIL',
|
||||
'alpha.6.fix.1.md': 'FAIL',
|
||||
'alpha.6.fix.2.md': 'FAIL',
|
||||
'alpha.6.fix.3.md': 'PASS',
|
||||
'alpha.7.md': 'FAIL',
|
||||
'alpha.7.fix.1.md': 'PASS',
|
||||
'alpha.8.md': 'PASS',
|
||||
'alpha.9.md': 'PASS',
|
||||
'beta.1.md': 'PASS',
|
||||
'rc.1.md': 'PASS',
|
||||
'rel.001.md': 'FAIL',
|
||||
}
|
||||
for name, status in expected.items():
|
||||
delta = Path('deltas/0.0.5', name)
|
||||
history = Path('history/0.0.5', name)
|
||||
assert delta.is_file(), name
|
||||
assert history.is_file(), name
|
||||
text = history.read_text(encoding='utf-8')
|
||||
assert re.search(rf'## Statut\s+{status}\s', text), (name, status)
|
||||
|
||||
pending = {p.name for p in Path('deltas/0.0.5').glob('*.md')} - \
|
||||
{p.name for p in Path('history/0.0.5').glob('*.md')}
|
||||
assert pending == {'rel.001.fix.1.md'}, pending
|
||||
|
||||
roadmap = Path('ROADMAP.md').read_text(encoding='utf-8')
|
||||
assert '- `(x) 0.0.5`' in roadmap
|
||||
assert '- `( ) 0.1.0`' in roadmap
|
||||
assert '(d) skeleton Tauri pour projets contrôlés' in roadmap
|
||||
assert 'saselang-bible' not in roadmap
|
||||
|
||||
changelog = Path('CHANGELOG.md').read_text(encoding='utf-8')
|
||||
assert '## 0.0.5' in changelog.splitlines()
|
||||
assert '## 0.0.5 (candidate)' not in changelog
|
||||
|
||||
prompt = Path('prompts/006-V0_1_0_START_PROMPT.md').read_text(encoding='utf-8')
|
||||
assert 'pgr-v0.0.5.zip' in prompt
|
||||
assert 'pgr-0.0.5-publish.001-report.md' in prompt
|
||||
assert '0.1.0-alpha.1' in prompt
|
||||
assert 'Le skeleton Tauri contrôlé reste `DEFER`' in prompt
|
||||
|
||||
plan = Path('docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md').read_text(encoding='utf-8')
|
||||
assert "La gate opérateur de `rel.001` est toutefois `FAIL`" in plan
|
||||
assert '`rel.001.fix.1` corrige uniquement cette preuve de clôture' in plan
|
||||
|
||||
print('0.0.5 rel.001.fix.1 stable history audit: clean (18 prior histories, failed rel preserved, corrected pre-tag proof)')
|
||||
PYGATE
|
||||
|
||||
python3 -B scripts/audit_markdown_headers.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_tables.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_links.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
|
||||
git diff --check
|
||||
|
||||
git add docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md \
|
||||
deltas/0.0.5/rel.001.fix.1.md
|
||||
|
||||
git diff --cached --check
|
||||
git status --short
|
||||
```
|
||||
|
||||
Le scope attendu avant ajout du history du fix est exactement :
|
||||
|
||||
```text
|
||||
A deltas/0.0.5/rel.001.fix.1.md
|
||||
M docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||
```
|
||||
|
||||
## Revue opérateur complémentaire
|
||||
|
||||
Confirmer que `VERSION` reste `0.0.5`, que la présentation stable de `rel.001` reste inchangée, que le `FAIL` de `rel.001` est conservé historiquement, que le fix ne modifie aucun owner fonctionnel et qu'aucun tag n'est créé avant le history PASS de ce correctif.
|
||||
|
||||
## Transition
|
||||
|
||||
### PASS
|
||||
|
||||
Produire séparément `history/0.0.5/rel.001.fix.1.md`, l'appliquer puis committer/pousser la clôture stable corrigée. Ensuite seulement créer et publier le tag canonique `v0.0.5`, télécharger son archive source depuis Gitea et exécuter la vérification externe `publish.001`.
|
||||
|
||||
### FAIL
|
||||
|
||||
Consigner le diagnostic réel dans `history/0.0.5/rel.001.fix.1.md`, ne pas tagger et poursuivre avec un nouveau `.fix.N` ou un REPLAN si le problème dépasse la gate de clôture.
|
||||
179
deltas/0.0.5/rel.001.md
Normal file
179
deltas/0.0.5/rel.001.md
Normal file
@@ -0,0 +1,179 @@
|
||||
<!-- file: deltas/0.0.5/rel.001.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Delta 0.0.5 rel.001 — promotion stable pré-tag
|
||||
|
||||
## Baseline et version
|
||||
|
||||
Baseline : `0.0.5-rc.1`, avec `history/0.0.5/rc.1.md` appliqué et committé. Ce delta MUST NOT être appliqué avant ce commit.
|
||||
|
||||
Le commit exact de cette baseline sera celui produit par l'opérateur après application du history RC ; il n'est pas anticipé dans cette livraison simultanée du history et du delta stable.
|
||||
|
||||
Version avant application :
|
||||
|
||||
```text
|
||||
0.0.5-rc.1
|
||||
```
|
||||
|
||||
Version après application :
|
||||
|
||||
```text
|
||||
0.0.5
|
||||
```
|
||||
|
||||
`rel.001` identifie la clôture opérationnelle ; il ne fait pas partie de la version SemVer du produit.
|
||||
|
||||
## Objet
|
||||
|
||||
Promouvoir la RC validée vers la stable `0.0.5`. La tranche finalise uniquement la présentation de la release : version stable, roadmap terminée, changelog sans marqueur candidate, index documentaires et plan historique.
|
||||
|
||||
Le scope fonctionnel reste celui validé en RC : lifecycle inter-release, prompts versionnés, contrats documentaires locaux, profil Rust strict et audits monotâches, contrats architecturaux des suffixes de crates, ownership du tracing, profil Tauri 2, classification des versions produit, réconciliation KSP/Games et décision `DEFER` du skeleton Tauri contrôlé jusqu'à matérialisation d'owners Web suffisants.
|
||||
|
||||
La validation de cette tranche est **pré-tag**. Ni le tag `v0.0.5`, ni l'archive `pgr-v0.0.5.zip` téléchargée depuis Gitea, ni un rapport `pgr-0.0.5-publish.001-report.md` ne sont déclarés existants par ce delta. Ils suivent le history PASS, le commit stable et la publication réelle du tag.
|
||||
|
||||
## Scope
|
||||
|
||||
REPLACE :
|
||||
|
||||
```text
|
||||
VERSION
|
||||
README.md
|
||||
ROADMAP.md
|
||||
CHANGELOG.md
|
||||
docs/000-README.md
|
||||
docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||
```
|
||||
|
||||
ADD :
|
||||
|
||||
```text
|
||||
deltas/0.0.5/rel.001.md
|
||||
```
|
||||
|
||||
DELETE : aucun.
|
||||
|
||||
L'archive contient uniquement ces fichiers complets. `history/0.0.5/rc.1.md` est livré séparément ; le history de `rel.001` sera produit après sa gate. Le rapport post-tag restera extérieur à l'archive source taggée.
|
||||
|
||||
## Validation opérateur pré-tag
|
||||
|
||||
Après application sur le commit `rc.1`, depuis la racine du dépôt :
|
||||
|
||||
```bash
|
||||
test "$(cat VERSION)" = '0.0.5'
|
||||
git cat-file -e HEAD:history/0.0.5/rc.1.md
|
||||
test -f history/0.0.5/rc.1.md
|
||||
test -f deltas/0.0.5/rel.001.md
|
||||
test -f prompts/006-V0_1_0_START_PROMPT.md
|
||||
test ! -e history/0.0.5/rel.001.md
|
||||
|
||||
grep -Fx '<!-- version: 14 -->' README.md
|
||||
grep -Fx '<!-- version: 8 -->' ROADMAP.md
|
||||
grep -Fx '<!-- version: 9 -->' CHANGELOG.md
|
||||
grep -Fx '<!-- version: 17 -->' docs/000-README.md
|
||||
grep -Fx '<!-- version: 15 -->' docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||
grep -F 'plan historique de réconciliation `0.0.5`' README.md
|
||||
grep -F -- '- `(x) 0.0.5`' ROADMAP.md
|
||||
grep -Fx '## 0.0.5' CHANGELOG.md
|
||||
grep -F 'périmètre et décisions de la release `0.0.5`' docs/000-README.md
|
||||
grep -F 'La gate opérateur de `rc.1` est `PASS`' docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||
grep -F 'pgr-0.0.5-publish.001-report.md' docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||
grep -F 'Le skeleton Tauri contrôlé reste `DEFER`' prompts/006-V0_1_0_START_PROMPT.md
|
||||
|
||||
python3 -B - <<'PYGATE'
|
||||
from pathlib import Path
|
||||
import re
|
||||
|
||||
expected = {
|
||||
'alpha.1.md': 'PASS',
|
||||
'alpha.2.md': 'PASS',
|
||||
'alpha.3.md': 'FAIL',
|
||||
'alpha.3.fix.1.md': 'PASS',
|
||||
'alpha.4.md': 'PASS',
|
||||
'alpha.5.md': 'FAIL',
|
||||
'alpha.5.fix.1.md': 'PASS',
|
||||
'alpha.6.md': 'FAIL',
|
||||
'alpha.6.fix.1.md': 'FAIL',
|
||||
'alpha.6.fix.2.md': 'FAIL',
|
||||
'alpha.6.fix.3.md': 'PASS',
|
||||
'alpha.7.md': 'FAIL',
|
||||
'alpha.7.fix.1.md': 'PASS',
|
||||
'alpha.8.md': 'PASS',
|
||||
'alpha.9.md': 'PASS',
|
||||
'beta.1.md': 'PASS',
|
||||
'rc.1.md': 'PASS',
|
||||
}
|
||||
for name, status in expected.items():
|
||||
delta = Path('deltas/0.0.5', name)
|
||||
history = Path('history/0.0.5', name)
|
||||
assert delta.is_file(), name
|
||||
assert history.is_file(), name
|
||||
text = history.read_text(encoding='utf-8')
|
||||
assert re.search(rf'## Statut\s+{status}\s', text), (name, status)
|
||||
|
||||
pending = {p.name for p in Path('deltas/0.0.5').glob('*.md')} - \
|
||||
{p.name for p in Path('history/0.0.5').glob('*.md')}
|
||||
assert pending == {'rel.001.md'}, pending
|
||||
|
||||
roadmap = Path('ROADMAP.md').read_text(encoding='utf-8')
|
||||
assert '- `(x) 0.0.5`' in roadmap
|
||||
assert '- `( ) 0.1.0`' in roadmap
|
||||
assert '(d) skeleton Tauri pour projets contrôlés' in roadmap
|
||||
assert 'saselang-bible' not in roadmap
|
||||
|
||||
changelog = Path('CHANGELOG.md').read_text(encoding='utf-8')
|
||||
assert '## 0.0.5
|
||||
' in changelog
|
||||
assert '## 0.0.5 (candidate)' not in changelog
|
||||
|
||||
prompt = Path('prompts/006-V0_1_0_START_PROMPT.md').read_text(encoding='utf-8')
|
||||
assert 'pgr-v0.0.5.zip' in prompt
|
||||
assert 'pgr-0.0.5-publish.001-report.md' in prompt
|
||||
assert '0.1.0-alpha.1' in prompt
|
||||
assert 'Le skeleton Tauri contrôlé reste `DEFER`' in prompt
|
||||
|
||||
print('0.0.5 stable history audit: clean (17 prior histories with expected statuses, rel.001 pending)')
|
||||
PYGATE
|
||||
|
||||
python3 -B scripts/audit_markdown_headers.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_tables.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_links.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
|
||||
git diff --check
|
||||
git add VERSION README.md ROADMAP.md CHANGELOG.md docs/000-README.md \
|
||||
docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md deltas/0.0.5/rel.001.md
|
||||
git diff --cached --check
|
||||
git status --short
|
||||
```
|
||||
|
||||
Le scope attendu avant ajout du history est exactement :
|
||||
|
||||
```text
|
||||
M CHANGELOG.md
|
||||
M README.md
|
||||
M ROADMAP.md
|
||||
M VERSION
|
||||
A deltas/0.0.5/rel.001.md
|
||||
M docs/000-README.md
|
||||
M docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||
```
|
||||
|
||||
Les `48` tests Python et les validations structurelles validés en RC restent des preuves applicables parce qu'aucun code, script, test, règle, template ou skeleton technique n'est modifié pendant `rel.001`. La gate stable se concentre donc sur l'intégrité de la chaîne historique, la présentation stable et les audits documentaires affectés.
|
||||
|
||||
## Revue opérateur complémentaire
|
||||
|
||||
Confirmer que le scope fonctionnel de la RC ne change pas, que README/roadmap/changelog/index/plan décrivent la même stable, que les `FAIL` historiques restent conservés avec leurs fixes `PASS`, que le skeleton Tauri reste différé sans release réservée, que le prompt `006` reste conditionnel à une vraie publication et qu'aucune preuve post-tag n'est anticipée.
|
||||
|
||||
## Transition
|
||||
|
||||
### PASS
|
||||
|
||||
Produire séparément `history/0.0.5/rel.001.md`, l'appliquer puis committer la stable. Ensuite seulement créer et publier le tag canonique `v0.0.5`, télécharger son archive source depuis Gitea, vérifier cette archive et conserver séparément la preuve post-tag `pgr-0.0.5-publish.001-report.md`.
|
||||
|
||||
Le message manuel de reprise de `prompts/006-V0_1_0_START_PROMPT.md` n'est remis à l'opérateur qu'après vérification effective de l'archive et d'un rapport post-tag PASS réel.
|
||||
|
||||
### FAIL
|
||||
|
||||
Consigner le diagnostic réel dans `history/0.0.5/rel.001.md`, ne pas tagger et corriger la clôture dans une tranche explicite avant publication.
|
||||
@@ -1,5 +1,5 @@
|
||||
<!-- file: docs/000-README.md -->
|
||||
<!-- version: 1 -->
|
||||
<!-- version: 17 -->
|
||||
|
||||
# Documentation PGR
|
||||
|
||||
@@ -10,9 +10,34 @@ Ce fichier est l'index d'entrée de la documentation structurée de Project Gove
|
||||
- [`objectives/`](objectives/) — mission, objectifs durables, non-objectifs et contraintes globales ;
|
||||
- [`architecture/`](architecture/) — état architectural courant de PGR et profils applicables ;
|
||||
- [`plans/`](plans/) — plans vivants des releases en cours, puis références historiques après fermeture ;
|
||||
- [`studies/`](studies/) — études bornées utilisées pour comparer des corpus, instruire une décision ou conserver une analyse avant normalisation ;
|
||||
- [`rules/`](rules/) — règles normatives détaillées, organisées progressivement par scope ;
|
||||
- [`skeletons/`](skeletons/) — spécifications Markdown de composition et d'initialisation de projets ;
|
||||
- [`templates/`](templates/) — instructions d'adaptation des templates techniques et spécification du message manuel de reprise ;
|
||||
- [`validation/`](validation/) — matrices de validation et contrats de preuve.
|
||||
|
||||
D'autres collections telles que `ideas/`, `studies/`, `reference/`, `formats/` ou `templates/` ne sont créées que lorsqu'un premier artefact réel les justifie.
|
||||
D'autres collections telles que `ideas/`, `studies/`, `reference/` ou `formats/` ne sont créées que lorsqu'un premier artefact réel les justifie.
|
||||
|
||||
Les répertoires workflow de racine (`deltas/`, `history/`, `handoffs/`, `manifests/`, `prompts/`, `scripts/`) restent séparés de `docs/` parce qu'ils portent le processus de développement et de livraison lui-même.
|
||||
Les templates techniques copiables sous `templates/` restent séparés des instructions documentaires sous `docs/templates/`. Les répertoires workflow de racine (`deltas/`, `history/`, `handoffs/`, `manifests/`, `prompts/`, `scripts/`) restent séparés de `docs/` parce qu'ils portent le processus de développement et de livraison lui-même.
|
||||
|
||||
## Points d'entrée de 0.0.5
|
||||
|
||||
- [`plans/005-V0_0_5_RECONCILIATION_PLAN.md`](plans/005-V0_0_5_RECONCILIATION_PLAN.md) — périmètre et décisions de la release `0.0.5` ;
|
||||
- [`studies/001-KSP_GAMES_RECONCILIATION.md`](studies/001-KSP_GAMES_RECONCILIATION.md) — inventaire comparatif des baselines KSP/Games et décisions de généralisation, maintien local ou différé.
|
||||
- [`studies/002-TAURI_SKELETON_DECISION.md`](studies/002-TAURI_SKELETON_DECISION.md) — décision `alpha.9` sur la maturité du skeleton Tauri contrôlé et ses prérequis Web encore manquants.
|
||||
- [`templates/004-FILE_FAMILY_CONTRACTS.md`](templates/004-FILE_FAMILY_CONTRACTS.md) — pattern facultatif pour expliciter les responsabilités et règles de modification de familles de fichiers locales lorsque la complexité le justifie.
|
||||
- [`templates/005-RELEASE_PLAN.md`](templates/005-RELEASE_PLAN.md) — pattern de plan de release avec clôture/transition explicites et revue d'horizon proportionnée.
|
||||
- [`validation/002-RUST_STYLE_AUDITS.md`](validation/002-RUST_STYLE_AUDITS.md) et [`validation/003-RUST_EXPORT_COMPLETENESS.md`](validation/003-RUST_EXPORT_COMPLETENESS.md) — contrats et limites des audits Rust monotâches réconciliés depuis les corpus réels.
|
||||
- [`rules/700-FRAMEWORKS.md`](rules/700-FRAMEWORKS.md) et [`rules/710-TAURI.md`](rules/710-TAURI.md) — activation de la famille framework et premier profil Tauri 2 issu de la réconciliation KSP/Games.
|
||||
- [`../prompts/006-V0_1_0_START_PROMPT.md`](../prompts/006-V0_1_0_START_PROMPT.md) — prompt de reprise préparé pour la première baseline réutilisable `0.1.0`, à utiliser seulement après publication et vérification post-tag de `0.0.5`.
|
||||
|
||||
## Points d'entrée de 0.0.4
|
||||
|
||||
- [`plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md`](plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md) — périmètre et décisions de la release `0.0.3` ;
|
||||
- [`plans/004-V0_0_4_SKELETONS_PLAN.md`](plans/004-V0_0_4_SKELETONS_PLAN.md) — périmètre et décisions de la release `0.0.4` ;
|
||||
- [`skeletons/000-README.md`](skeletons/000-README.md) — contrat de collection des skeleton specifications ;
|
||||
- [`skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md`](skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md) — fondation de gouvernance locale composable et sans spécialisation technologique ;
|
||||
- [`skeletons/002-RUST_CARGO_WORKSPACE.md`](skeletons/002-RUST_CARGO_WORKSPACE.md) — specialization Rust/Cargo workspace composable avec la fondation et les cinq templates existants ;
|
||||
- [`templates/001-RUST_CARGO_TOOLING.md`](templates/001-RUST_CARGO_TOOLING.md) et [`templates/002-CARGO_MANIFESTS.md`](templates/002-CARGO_MANIFESTS.md) — adaptation des cinq fichiers Rust/Cargo copiables ;
|
||||
- [`templates/003-NEW_SESSION_PROMPT.md`](templates/003-NEW_SESSION_PROMPT.md) — spécification du message manuel après une stable publiée ;
|
||||
- [`validation/001-VALIDATION_MATRIX.md`](validation/001-VALIDATION_MATRIX.md), [`validation/002-RUST_STYLE_AUDITS.md`](validation/002-RUST_STYLE_AUDITS.md) et [`validation/003-RUST_EXPORT_COMPLETENESS.md`](validation/003-RUST_EXPORT_COMPLETENESS.md) — gates PGR et limites des audits Rust facultatifs.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!-- file: docs/architecture/002-GOVERNANCE_ARCHITECTURE.md -->
|
||||
<!-- version: 2 -->
|
||||
<!-- version: 3 -->
|
||||
|
||||
# Architecture de gouvernance PGR
|
||||
|
||||
@@ -25,9 +25,9 @@ Après instanciation, le projet possède sa copie et ne dépend plus de PGR.
|
||||
|
||||
Un skeleton est une recette Markdown décrivant comment initialiser un type de projet ou composer plusieurs profils.
|
||||
|
||||
Il décrit notamment les profils applicables, la structure requise ou optionnelle, les templates à utiliser, les points de décision, la politique de version et la validation de base.
|
||||
Il décrit notamment les profils applicables, la structure requise ou optionnelle, les templates à utiliser, les points de décision, la politique de version et la validation de base. Le contrat transversal de sélection et de composition appartient à [`../rules/220-SKELETONS.md`](../rules/220-SKELETONS.md) ; les spécifications concrètes sont indexées sous [`../skeletons/`](../skeletons/000-README.md).
|
||||
|
||||
Un skeleton n'est pas un générateur et ne doit pas figer l'évolution future du projet.
|
||||
Un skeleton n'est pas un générateur et ne doit pas figer l'évolution future du projet. Il orchestre des owners normatifs et des artefacts existants sans devenir lui-même propriétaire d'une règle déjà possédée ailleurs.
|
||||
|
||||
### Audit
|
||||
|
||||
@@ -44,11 +44,11 @@ Le flux conceptuel est :
|
||||
```text
|
||||
PGR rules + templates + skeleton specifications
|
||||
↓
|
||||
sélection humaine / IA
|
||||
applicabilité + décisions du projet
|
||||
↓
|
||||
nouveau projet
|
||||
copie / adaptation contrôlée
|
||||
↓
|
||||
copies et règles locales
|
||||
validation de la baseline
|
||||
↓
|
||||
projet autonome et gouverné
|
||||
```
|
||||
|
||||
221
docs/architecture/003-RULE_PROFILE_MODEL.md
Normal file
221
docs/architecture/003-RULE_PROFILE_MODEL.md
Normal file
@@ -0,0 +1,221 @@
|
||||
<!-- file: docs/architecture/003-RULE_PROFILE_MODEL.md -->
|
||||
<!-- version: 5 -->
|
||||
|
||||
# Modèle de profils de règles PGR
|
||||
|
||||
## Rôle
|
||||
|
||||
Un profil PGR est un ensemble cohérent de règles réutilisables dont le scope est plus spécifique que les règles générales.
|
||||
|
||||
Un profil ne constitue ni un catalogue de dépendances, ni un template technique, ni un skeleton de projet. Il définit uniquement les règles durables réellement propres à un langage, un écosystème, une plateforme, un framework, un type de projet ou un sous-système.
|
||||
|
||||
Les règles générales restent héritées implicitement. Elles ne sont pas recopiées dans chaque profil.
|
||||
|
||||
## Axes de spécialisation
|
||||
|
||||
La composition normative suit l'ordre général :
|
||||
|
||||
```text
|
||||
GENERAL
|
||||
↓
|
||||
ecosystem / language
|
||||
↓
|
||||
platform
|
||||
↓
|
||||
framework
|
||||
↓
|
||||
project type / subsystem
|
||||
↓
|
||||
project-specific
|
||||
↓
|
||||
explicit exception
|
||||
```
|
||||
|
||||
Cet ordre exprime la spécificité des scopes. Il ne signifie pas qu'un projet doit posséder un profil à chaque niveau.
|
||||
|
||||
Un projet peut par exemple combiner uniquement :
|
||||
|
||||
```text
|
||||
GENERAL
|
||||
+ Rust / Cargo
|
||||
```
|
||||
|
||||
ou :
|
||||
|
||||
```text
|
||||
GENERAL
|
||||
+ Java
|
||||
+ Gradle
|
||||
+ Android
|
||||
```
|
||||
|
||||
Une technologie absente du projet ne rend aucun profil correspondant applicable.
|
||||
|
||||
## Propriétaire normatif
|
||||
|
||||
Toute règle durable doit posséder un seul propriétaire normatif canonique.
|
||||
|
||||
Lorsqu'une règle est déjà correctement possédée par un document général, un profil spécifique doit la référencer si nécessaire, mais ne doit pas la recopier sous une formulation équivalente.
|
||||
|
||||
Inversement, une contrainte réellement propre à un profil ne doit pas être remontée vers un owner général uniquement pour réduire le nombre de fichiers.
|
||||
|
||||
Le propriétaire est choisi selon le scope le plus général dans lequel la règle reste vraie sans exception implicite.
|
||||
|
||||
## Applicabilité
|
||||
|
||||
Un profil doit rendre son scope explicite : l'utilisateur ou le skeleton futur doit pouvoir déterminer à partir de faits du projet si le profil s'applique.
|
||||
|
||||
L'applicabilité doit reposer sur des propriétés concrètes, par exemple :
|
||||
|
||||
- langage ou écosystème réellement utilisé ;
|
||||
- build tool réellement utilisé ;
|
||||
- plateforme réellement ciblée ;
|
||||
- framework réellement présent ;
|
||||
- type de projet ou sous-système réellement concerné.
|
||||
|
||||
PGR ne doit pas appliquer un profil uniquement parce qu'il est fréquent, recommandé ailleurs ou présent dans un projet source historique.
|
||||
|
||||
## Composition et résolution
|
||||
|
||||
La résolution d'un ensemble de profils suit ces étapes :
|
||||
|
||||
1. appliquer les règles générales ;
|
||||
2. ajouter les profils langage/écosystème applicables ;
|
||||
3. ajouter les profils plateforme applicables ;
|
||||
4. ajouter les profils framework applicables ;
|
||||
5. ajouter les profils de type de projet ou sous-système applicables ;
|
||||
6. appliquer les règles propres au projet ;
|
||||
7. appliquer les exceptions explicites et bornées.
|
||||
|
||||
Une règle plus spécifique peut raffiner, renforcer ou remplacer une règle plus générale dans son scope.
|
||||
|
||||
Lorsqu'elle contredit volontairement une règle héritée, le profil spécifique doit identifier l'override, son scope et sa raison. L'ordre des fichiers dans un répertoire ne crée jamais une priorité normative.
|
||||
|
||||
Deux règles applicables de même niveau qui se contredisent sans relation explicite ne sont pas départagées arbitrairement : la situation constitue un défaut de conformité ou de modélisation à résoudre.
|
||||
|
||||
## Spécialisation interne à une famille
|
||||
|
||||
Une famille peut posséder plusieurs niveaux internes lorsque cela réduit la duplication.
|
||||
|
||||
Par exemple, un profil de langage peut être complété par un build tool particulier :
|
||||
|
||||
```text
|
||||
Java
|
||||
↓
|
||||
Maven
|
||||
```
|
||||
|
||||
ou :
|
||||
|
||||
```text
|
||||
Java
|
||||
↓
|
||||
Gradle
|
||||
```
|
||||
|
||||
Cette relation interne ne modifie pas la hiérarchie globale. Une contrainte de plateforme plus spécifique peut encore raffiner le résultat lorsqu'elle s'applique.
|
||||
|
||||
Lorsque langage et build tool sont pratiquement indissociables pour le scope visé, PGR peut les documenter dans un même profil si cette fusion évite une séparation artificielle. Le choix du découpage doit suivre les responsabilités réelles, pas une taxonomie rigide.
|
||||
|
||||
## Baseline contrôlée et projet imposé
|
||||
|
||||
La même combinaison de technologies peut être gouvernée avec des degrés de liberté différents.
|
||||
|
||||
Pour une baseline créée et contrôlée par le projet, les profils sélectionnés s'appliquent intégralement puis une skeleton specification MAY fixer des choix réutilisables supplémentaires : layout, stack frontend, conventions de manifests ou organisation des fichiers.
|
||||
|
||||
Pour un projet existant ou imposé par un tiers, PGR doit d'abord préserver les contraintes externes réellement obligatoires. Toute divergence avec le profil préféré devient une règle project-specific ou une exception explicite et bornée ; elle ne modifie pas automatiquement le profil général.
|
||||
|
||||
Cette distinction évite deux erreurs opposées : forcer le skeleton interne d'une organisation sur un dépôt qu'elle ne contrôle pas, ou affaiblir ses propres conventions sous prétexte qu'un framework accepte plusieurs formes.
|
||||
|
||||
## Profils composites
|
||||
|
||||
PGR ne crée pas automatiquement un profil composite pour chaque combinaison possible.
|
||||
|
||||
Un profil composite n'est justifié que lorsque l'intersection de plusieurs profils possède des règles propres qui ne peuvent être correctement possédées par chacun séparément.
|
||||
|
||||
Ainsi, la simple coexistence de Rust et Android ne suffit pas à créer un profil `Rust + Android`. Un tel profil devient pertinent seulement lorsqu'un contrat propre à leur interaction, par exemple une frontière FFI/JNI, doit être normé.
|
||||
|
||||
## Choix ouverts
|
||||
|
||||
Un choix encore indécis n'est pas une règle.
|
||||
|
||||
Lorsqu'un profil révèle plusieurs options légitimes sans critère permettant d'en retenir une, PGR doit conserver la question comme décision ouverte, étude ou point de planification approprié plutôt que d'inventer une valeur par défaut arbitraire.
|
||||
|
||||
Une contrainte issue d'un framework, d'une plateforme ou d'un outil externe peut devenir une règle spécifique lorsque son caractère obligatoire est établi.
|
||||
|
||||
## Non-duplication
|
||||
|
||||
Un profil doit contenir uniquement ce qui ajoute une information normative dans son scope.
|
||||
|
||||
Il ne doit pas recopier les règles générales relatives notamment à la gouvernance, aux documents, aux secrets, au lifecycle des releases ou à la validation lorsque ces règles s'appliquent déjà sans modification.
|
||||
|
||||
Une règle transversale découverte pendant la création de plusieurs profils doit être remontée vers un propriétaire commun uniquement si elle est réellement indépendante de ces profils.
|
||||
|
||||
## Croissance documentaire
|
||||
|
||||
PGR matérialise uniquement les familles et profils possédant un contenu normatif réel.
|
||||
|
||||
Pour `0.0.2`, les familles nécessaires sont :
|
||||
|
||||
```text
|
||||
500 — languages / ecosystems
|
||||
600 — platforms
|
||||
```
|
||||
|
||||
Les familles `700 — frameworks` et `800 — architecture` restent réservées tant qu'un premier profil réel ne justifie pas leur activation normative.
|
||||
|
||||
Le modèle architectural présent n'oblige pas à créer des fichiers placeholders pour les profils différés.
|
||||
|
||||
## Réconciliation des profils matérialisés en `0.0.2`
|
||||
|
||||
La première implémentation réelle du modèle comporte trois profils :
|
||||
|
||||
```text
|
||||
510 — Rust / Cargo
|
||||
520 — Java / Maven / Gradle
|
||||
610 — Android
|
||||
```
|
||||
|
||||
Leur composition observée confirme que la taxonomie n'a pas besoin d'un profil composite supplémentaire dans `0.0.2`.
|
||||
|
||||
Un projet Rust ordinaire peut appliquer :
|
||||
|
||||
```text
|
||||
GENERAL
|
||||
+ 500
|
||||
+ 510
|
||||
```
|
||||
|
||||
Un projet Java/Gradle Android peut appliquer :
|
||||
|
||||
```text
|
||||
GENERAL
|
||||
+ 500
|
||||
+ 520
|
||||
+ 600
|
||||
+ 610
|
||||
```
|
||||
|
||||
La forme condensée de cette composition est `GENERAL + 500 + 520 + 600 + 610`.
|
||||
|
||||
Le profil Android raffine localement les contraintes JDK/Gradle lorsque la matrice AGP/Gradle/JDK l'exige ; cette spécialisation ne modifie pas le profil Java/Gradle hors Android.
|
||||
|
||||
Aucune contradiction non résolue de même niveau n'a été identifiée entre les profils `510`, `520` et `610`.
|
||||
|
||||
La revue beta n'a pas justifié l'activation d'une famille `700 — frameworks` ou `800 — architecture`. Les règles réellement transversales rencontrées restent déjà possédées par `RULES.md`, les familles existantes ou le présent modèle architectural.
|
||||
|
||||
## Activation de la famille framework en `0.0.5`
|
||||
|
||||
La réconciliation indépendante de KSP et Games apporte le premier framework suffisamment répété pour activer la famille `700` : Tauri 2. Le profil `710-TAURI.md` se compose au-dessus de Rust/Cargo et, selon les targets, des profils plateforme applicables.
|
||||
|
||||
Cette activation ne change pas la hiérarchie : Tauri ne devient propriétaire ni des règles Rust générales, ni d'Android, ni du choix du frontend. Il possède uniquement l'orchestration Tauri, sa configuration/capabilities, ses hooks, sa version applicative et les gates d'intégration propres au framework.
|
||||
|
||||
La famille `800 — architecture` reste réservée : aucune règle nouvelle n'en justifie encore la matérialisation.
|
||||
|
||||
La réconciliation a également confirmé qu'une règle générale ne doit pas être recopiée comme si le profil spécifique en devenait propriétaire. Un profil peut rappeler une conséquence spécifique au contexte, mais doit référencer l'owner général lorsque le contrat lui-même n'est pas spécialisé.
|
||||
|
||||
## Instanciation par skeleton
|
||||
|
||||
Les skeleton specifications sélectionnent les profils applicables et identifient les règles à reprendre ou adapter dans la baseline locale du projet créé. Leur contrat transversal de composition appartient à [`../rules/220-SKELETONS.md`](../rules/220-SKELETONS.md) ; le présent document reste propriétaire de la hiérarchie et de la résolution des profils eux-mêmes.
|
||||
|
||||
Le projet instancié reste autonome : la composition de profils sert à construire sa baseline initiale, pas à créer une dépendance dynamique vers PGR.
|
||||
243
docs/plans/002-V0_0_2_RULE_PROFILES_PLAN.md
Normal file
243
docs/plans/002-V0_0_2_RULE_PROFILES_PLAN.md
Normal file
@@ -0,0 +1,243 @@
|
||||
<!-- file: docs/plans/002-V0_0_2_RULE_PROFILES_PLAN.md -->
|
||||
<!-- version: 6 -->
|
||||
|
||||
# Plan 0.0.2 — premiers profils de règles technologiques
|
||||
|
||||
## Statut
|
||||
|
||||
Plan clôturé par la promotion stable `0.0.2` après validation de `0.0.2-rc.1.fix.1`.
|
||||
|
||||
La baseline `v0.0.1` est cohérente pour démarrer `0.0.2`. L'absence de `.git` dans cette archive est normale et n'est pas une anomalie de baseline.
|
||||
|
||||
Le présent plan reste prévisionnel. Il peut être révisé lorsqu'un résultat réel invalide son dimensionnement ou son découpage, conformément aux règles de REPLAN.
|
||||
|
||||
## Mission
|
||||
|
||||
`0.0.2` introduit les premiers profils de règles technologiques réutilisables de PGR sans dupliquer les responsabilités déjà possédées par `RULES.md` et les familles `200`, `300` et `400`.
|
||||
|
||||
La release doit démontrer concrètement la composition :
|
||||
|
||||
```text
|
||||
GENERAL
|
||||
↓
|
||||
ecosystem / language
|
||||
↓
|
||||
platform
|
||||
↓
|
||||
framework
|
||||
↓
|
||||
project type / subsystem
|
||||
↓
|
||||
project-specific / explicit exception
|
||||
```
|
||||
|
||||
Un profil matérialisé doit posséder un contenu normatif réel, un scope explicite et un propriétaire documentaire identifiable. Il ne doit pas devenir un catalogue de dépendances ni répéter les règles générales sous une autre forme.
|
||||
|
||||
## Autorité des sources pendant la consolidation
|
||||
|
||||
Pour cette release :
|
||||
|
||||
- l'archive source issue du tag `v0.0.1` est la baseline autoritaire de l'état PGR ;
|
||||
- `prompts/002-V0_0_2_START_PROMPT.md` est le contrat opératoire de démarrage de `0.0.2` ;
|
||||
- les corpus de conception externes ou historiques peuvent servir de matière d'analyse, mais ne constituent pas l'état courant du dépôt ;
|
||||
- aucune règle, décision, version de fichier ou structure absente de la baseline et du prompt ne doit être supposée déjà acquise ;
|
||||
- chaque proposition réutilisée doit être requalifiée selon les règles PGR actuelles avant de devenir normative.
|
||||
|
||||
## Audit de la baseline `v0.0.1`
|
||||
|
||||
L'inspection de l'archive taggée a constaté :
|
||||
|
||||
- une racine unique `pgr/` ;
|
||||
- `44` fichiers et `13` répertoires dans l'archive, sans entrée dupliquée ;
|
||||
- aucune entrée absolue, traversée `..` ou symlink ;
|
||||
- aucune arborescence `.git`, conformément au contrat des archives de tag ;
|
||||
- `VERSION` égal exactement à `0.0.1` ;
|
||||
- aucun cache/build connu, `__pycache__`, `.pyc`, `node_modules`, `target`, `dist` ou secret local distribué ;
|
||||
- tous les fichiers Markdown avec headers `file/version` cohérents avec leur emplacement ;
|
||||
- aucun lien Markdown local cassé parmi les liens vérifiés ;
|
||||
- `12` deltas `0.0.1` et `12` histories correspondants, sans delta ou history orphelin ;
|
||||
- une chaîne de résultats cohérente : les `FAIL` de `alpha.1`, `alpha.1.fix.1`, `alpha.4` et `rc.1` restent historiques et sont suivis par leurs corrections validées avant progression ;
|
||||
- la promotion `rel.001` enregistrée `PASS`, le plan `0.0.1` clôturé et le prompt `0.0.2` présent ;
|
||||
- les compteurs internes `version:` des documents vivants cohérents avec les opérations `ADD`/`REPLACE` observées dans les deltas `0.0.1`.
|
||||
|
||||
Aucun défaut bloquant de gouvernance, de structure documentaire, de pairing delta/history ou de cohérence interne n'a été trouvé.
|
||||
|
||||
### Preuve post-tag `publish.001`
|
||||
|
||||
Le rapport post-tag `pgr-0.0.1-publish.001-report.md` a été retrouvé dans la bibliothèque de travail après la première revue de `alpha.1`.
|
||||
|
||||
Il enregistre `Status: PASS` pour `pgr-v0.0.1.zip` et confirme le SHA-256 déjà observé pour l'archive de baseline :
|
||||
|
||||
```text
|
||||
48bfed6acc50d2c5bdd69db764ae29fe8c5a06b64375943f5d4120c7bb8429ef
|
||||
```
|
||||
|
||||
Cette preuve est volontairement extérieure au tag `v0.0.1` parce qu'elle vérifie un artefact produit après le tag. Elle ne doit ni être injectée rétroactivement dans la stable ni remplacer l'audit d'intake de la session courante.
|
||||
|
||||
La revue a également identifié un besoin de maturité futur : un handoff/prompt de reprise doit finir par indiquer explicitement si une preuve post-publication telle que `publish.001` doit être fournie à la session suivante. Ce besoin de workflow reste hors scope fonctionnel de `0.0.2`.
|
||||
|
||||
## Inventaire des profils candidats
|
||||
|
||||
Le prompt demande d'examiner le corpus suivant. Après revue du sizing initial, `0.0.2-alpha.1.fix.1` réduit volontairement le nombre de profils matérialisés afin de conserver une version terminable et correctement validable dans une session.
|
||||
|
||||
| Domaine candidat | Décision `0.0.2` | Propriétaire prévisionnel | Motif |
|
||||
|------------------------------------------------|------------------|------------------------------------------------|------------------------------------------------------------------------------|
|
||||
| modèle de profil et composition des scopes | inclure | architecture PGR | nécessaire avant de créer plusieurs profils cohérents |
|
||||
| Rust / Cargo | inclure | famille `500 — languages / ecosystems` | premier profil langage/écosystème, corpus éprouvé |
|
||||
| Java / Maven / Gradle | inclure | famille `500 — languages / ecosystems` + build | permet de distinguer langage et build tool avant Android |
|
||||
| Android | inclure | famille `600 — platforms` | premier exemple de spécialisation plateforme sur des règles de langage/build |
|
||||
| Rust + Android / JNI | différer | future composition spécialisée | utile mais non nécessaire pour prouver le premier modèle |
|
||||
| Web / TypeScript / Vite / WASM / serveurs Rust | différer | future composition Web | scope autonome suffisamment large pour une release ultérieure |
|
||||
| Tauri desktop/mobile | différer | future famille `700 — frameworks` | dépend de profils Rust/Web/plateforme suffisamment stabilisés |
|
||||
| C / C++ / CMake | différer | future famille `500 — languages / ecosystems` | corpus utile mais non nécessaire au premier lot |
|
||||
| PHP / Composer | différer | future famille `500 — languages / ecosystems` | ne pas matérialiser un profil uniquement pour remplir la taxonomie |
|
||||
| Python 3 application/package | différer | future famille `500 — languages / ecosystems` | à introduire lorsqu'un besoin concret le justifie |
|
||||
| architecture/règles cross-cutting | conditionnel | famille `800 — architecture` ou owner existant | uniquement si plusieurs profils révèlent une règle commune sans propriétaire |
|
||||
|
||||
Les domaines différés restent des candidats légitimes. Leur absence de `0.0.2` ne vaut ni rejet ni interdiction future.
|
||||
|
||||
Le choix retenu cherche le plus petit ensemble qui exerce réellement plusieurs niveaux de composition : un modèle commun, un profil langage/écosystème, une distinction langage/build et une plateforme. Les compositions FFI, Web et framework restent séparées afin de ne pas transformer la première release de profils en catalogue.
|
||||
|
||||
## Règles de consolidation
|
||||
|
||||
Chaque tranche technologique doit :
|
||||
|
||||
1. repartir des règles générales actuellement applicables ;
|
||||
2. identifier ce qui est réellement spécifique au profil ;
|
||||
3. éviter les duplications de gouvernance, documentation et validation générales ;
|
||||
4. distinguer règle normative, exemple, choix de projet et point encore ouvert ;
|
||||
5. documenter explicitement les overrides/contraintes spécialisées et leur scope ;
|
||||
6. préférer les structures canoniques de l'écosystème lorsqu'elles apportent une vraie valeur ;
|
||||
7. ne pas fixer une version d'outil ou de dépendance sans raison de compatibilité, reproductibilité, support ou sécurité ;
|
||||
8. ne créer un audit que lorsqu'une propriété stable, objectivement automatisable et réellement utile a été démontrée ;
|
||||
9. conserver PGR lui-même indépendant des toolchains qu'il documente ;
|
||||
10. réviser le plan si une tranche devient sensiblement plus large que prévu au lieu d'absorber silencieusement le scope.
|
||||
|
||||
## Découpage prévisionnel
|
||||
|
||||
### alpha.1 — Baseline audit and profile sizing
|
||||
|
||||
Auditer intégralement `v0.0.1`, confronter le prompt à l'état réel, inventorier les profils candidats, fixer les domaines inclus/différés et créer le présent plan.
|
||||
|
||||
Aucune règle technologique détaillée n'est consolidée dans cette tranche.
|
||||
|
||||
### alpha.2 — Rule profile model
|
||||
|
||||
Formaliser le contrat d'un profil PGR : ownership, composition général → spécifique, navigation des familles nécessaires, règles de non-duplication et traitement des choix encore ouverts.
|
||||
|
||||
Cette tranche doit créer uniquement les propriétaires documentaires réellement nécessaires à `0.0.2`. Les familles `700` et `800` restent réservées tant qu'aucun contenu réel ne justifie leur matérialisation.
|
||||
|
||||
### alpha.3 — Rust / Cargo
|
||||
|
||||
Consolider le premier profil langage/écosystème Rust/Cargo, notamment structure de workspace/crates, manifests et toolchain, dépendances/features, API/imports, erreurs/safety, tests et validation spécialisée lorsque ces sujets ne sont pas déjà possédés par une règle générale.
|
||||
|
||||
Cette tranche sert aussi de mesure réelle du coût d'un profil. Si elle montre que le modèle documentaire est sensiblement plus lourd que prévu, un REPLAN doit intervenir avant d'enchaîner les autres profils.
|
||||
|
||||
### alpha.4 — Java / Maven / Gradle
|
||||
|
||||
Consolider le profil Java et ses spécialisations de build Maven/Gradle en maintenant une frontière nette entre règles Java, contraintes de build tool et choix propres à une plateforme ou un framework.
|
||||
|
||||
### alpha.5 — Android
|
||||
|
||||
Consolider le premier profil plateforme Android : structure canonique, toolchain compatible, SDK/targets, configuration locale/signing, modules, packaging, tests/smokes et règles de compatibilité de target.
|
||||
|
||||
Les règles Rust/JNI, Web et Tauri ne doivent pas être absorbées dans ce profil général. Elles restent différées jusqu'à une release où leurs compositions pourront être traitées sans surcharger `0.0.2`.
|
||||
|
||||
### beta.1 — Profile reconciliation
|
||||
|
||||
Réconcilier les profils créés, vérifier les scopes/overrides, éliminer les répétitions, vérifier la navigation et extraire vers un owner cross-cutting uniquement les règles réellement communes qui ne possèdent pas déjà de propriétaire normatif.
|
||||
|
||||
Aucun nouveau profil technologique majeur ne doit être introduit en beta sans REPLAN.
|
||||
|
||||
État observé à l'entrée de beta :
|
||||
|
||||
```text
|
||||
alpha.1 FAIL cadrage initial corrigé par fix.1
|
||||
alpha.1.fix.1 PASS sizing réduit + premier audit Markdown
|
||||
alpha.2 PASS modèle de profils et familles 500/600
|
||||
alpha.3 PASS Rust / Cargo
|
||||
alpha.4 FAIL incohérence locale entre texte et grep de gate
|
||||
alpha.4.fix.1 PASS cohérence de gate rétablie
|
||||
alpha.5 PASS Android
|
||||
beta.1 FAIL quoting Bash invalide dans une commande de gate
|
||||
beta.1.fix.1 PASS quoting de gate corrigé sans changement de scope
|
||||
```
|
||||
|
||||
Cette synthèse décrit uniquement la trajectoire du plan ; les preuves détaillées restent dans les histories immuables correspondants.
|
||||
|
||||
La réconciliation beta confirme comme owners technologiques de `0.0.2` :
|
||||
|
||||
```text
|
||||
510-RUST_CARGO.md
|
||||
520-JAVA_MAVEN_GRADLE.md
|
||||
610-ANDROID.md
|
||||
```
|
||||
|
||||
Aucune famille `700` ou `800` n'est activée. Aucun profil différé n'est ramené dans le scope.
|
||||
|
||||
### rc.1 — Rule profiles release candidate
|
||||
|
||||
Geler le scope, préparer l'entrée candidate `0.0.2` du changelog, finaliser le prompt `0.0.3` et exécuter la gate documentaire complète applicable.
|
||||
|
||||
Le scope RC est gelé sur les trois profils matérialisés (`510`, `520`, `610`) et les deux audits génériques monotâches (`tables`, `liens locaux`). Aucun nouveau profil, owner de famille ou audit technologique n'est admis sans correction strictement nécessaire ou REPLAN.
|
||||
|
||||
Le prompt `0.0.3` doit aussi fournir explicitement le texte manuel de nouvelle session et indiquer le rôle du futur rapport post-tag `publish.001`, afin que cette information ne dépende plus d'une demande ad hoc de l'opérateur.
|
||||
|
||||
### stable — 0.0.2
|
||||
|
||||
Promouvoir mécaniquement la RC validée, finaliser les métadonnées de release, enregistrer `rel.001`, commit/tag `v0.0.2`, puis vérifier séparément l'archive publiée issue du tag.
|
||||
|
||||
## Clôture
|
||||
|
||||
La release candidate `rc.1` a été enregistrée `FAIL` à cause d'un audit Python inline invalide dans sa gate. `rc.1.fix.1` a corrigé exclusivement cette commande et a ensuite été validée `PASS`, sans changement du scope fonctionnel ou normatif.
|
||||
|
||||
La promotion stable `rel.001` clôt le plan en mettant à jour uniquement les métadonnées vivantes de release et en préparant le tag `v0.0.2`.
|
||||
|
||||
Le contrôle post-tag `publish.001` reste une preuve séparée : il doit vérifier l'archive réellement produite depuis le tag et fournir `pgr-0.0.2-publish.001-report.md` à la future session `0.0.3` lorsqu'il est `PASS`.
|
||||
|
||||
## Dimensionnement et points de replan
|
||||
|
||||
Le premier forecast `alpha.2` à `alpha.8` a été jugé trop large pendant la revue opérateur de `alpha.1`. Le présent plan réduit donc la release avant tout développement technologique lourd.
|
||||
|
||||
Après `alpha.1.fix.1`, le chemin prévu est :
|
||||
|
||||
```text
|
||||
alpha.2 modèle de profil
|
||||
alpha.3 Rust / Cargo
|
||||
alpha.4 Java / Maven / Gradle
|
||||
alpha.5 Android
|
||||
beta.1 réconciliation
|
||||
rc.1 release candidate
|
||||
stable 0.0.2
|
||||
```
|
||||
|
||||
Ce découpage reste un forecast, pas une obligation de remplir tous les numéros coûte que coûte.
|
||||
|
||||
`alpha.3` est un point de mesure explicite. Si la construction du premier profil montre qu'un profil complet dépasse sensiblement le sizing envisagé, la release doit être REPLANifiée avant `alpha.4` au lieu de conserver mécaniquement le forecast.
|
||||
|
||||
Un nouveau besoin critique, plusieurs fixes consécutifs ou une évolution qui rend `0.0.2` non terminable dans la session doivent également déclencher un REPLAN. La qualité de la release prend le dessus sur la volonté de conserver artificiellement le nombre initial de profils.
|
||||
|
||||
## Hors périmètre
|
||||
|
||||
`0.0.2` ne doit pas :
|
||||
|
||||
- produire les templates techniques réservés à `0.0.3` ;
|
||||
- créer les skeleton specifications complètes réservées à `0.0.4` ;
|
||||
- créer un générateur ;
|
||||
- réécrire KSP ou `sasedev-games` ;
|
||||
- multiplier les audits spécialisés ; `0.0.2` ne matérialise que des audits génériques monotâches justifiés par un besoin réel (`tables` puis `liens locaux`), sans audit technologique artificiel ;
|
||||
- transformer les exemples de technologies en dépendances du dépôt PGR ;
|
||||
- modifier rétroactivement les deltas/histories `0.0.1` pour refléter des règles apparues après leur émission.
|
||||
|
||||
## Critères de fermeture
|
||||
|
||||
`0.0.2` peut atteindre RC lorsque :
|
||||
|
||||
- le modèle documentaire des profils est explicite et cohérent avec la hiérarchie PGR ;
|
||||
- les profils retenus dans le scope possèdent chacun un propriétaire normatif réel ;
|
||||
- les spécialisations de build et de plateforme retenues ne contaminent pas les règles générales ;
|
||||
- les choix encore ouverts restent identifiés comme tels ;
|
||||
- la navigation entre règles générales et profils spécifiques est claire ;
|
||||
- aucune duplication importante avec les familles `200`, `300` et `400` ne subsiste ;
|
||||
- les profils différés ne sont pas artificiellement matérialisés ;
|
||||
- les validations de la release restent documentaires et proportionnées au dépôt PGR lui-même.
|
||||
159
docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md
Normal file
159
docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md
Normal file
@@ -0,0 +1,159 @@
|
||||
<!-- file: docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md -->
|
||||
<!-- version: 9 -->
|
||||
|
||||
# Plan 0.0.3 — templates initiaux et audits réutilisables
|
||||
|
||||
## Statut et sources
|
||||
|
||||
Plan de cadrage créé dans `0.0.3-alpha.1` et corrigé dans `0.0.3-alpha.1.fix.1` après sa validation mécanique. `alpha.2` intègre la convention opérateur sur les fichiers d'outillage Rust et matérialise les premiers templates ; sa gate opérateur est PASS. Après cette gate, la demande de décomposer les audits de style Rust KSP/Games modifie le calendrier prévisionnel. Le résultat REPLAN de `alpha.3` est `SPLIT` : deux audits de style ciblés sont traités d'abord, les manifests Cargo puis les headers Markdown suivent dans des tranches distinctes. Les tranches suivantes restent une prévision, non un état validé.
|
||||
|
||||
La source autoritaire est l'archive Gitea fournie `pgr-v0.0.2.zip`, issue selon l'opérateur du tag `v0.0.2`. Son SHA-256 vérifié localement est :
|
||||
|
||||
```text
|
||||
8dc5c979a4d722b4ef6ec84b6227c8cbfffb3f865f4ea9063c03ecb1e365cdc4
|
||||
```
|
||||
|
||||
Le rapport séparé `pgr-0.0.2-publish.001-report.md` indique `PASS` et donne le même hash. Il atteste la publication post-tag sans appartenir au tag. L'archive sans `.git` ne peut prouver indépendamment le commit ni l'identité du tag ; ces éléments sont les déclarations et preuves de publication de l'opérateur.
|
||||
|
||||
Le contrat de démarrage est `prompts/003-V0_0_3_START_PROMPT.md`. Les règles applicables partent de `RULES.md`, puis des familles `200`, `210`, `300`, `400`, du modèle de profils `003` et des profils `500`/`510`, `520`, `600`/`610` selon leur scope. PGR reste un dépôt documentaire doté d'outils Python ; les toolchains Rust, Java et Android ne deviennent pas des prérequis du dépôt.
|
||||
|
||||
Deux corpus de comparaison supplémentaires, fournis après le gate initial de `alpha.1`, ont été inspectés pour ce fix documentaire :
|
||||
|
||||
```text
|
||||
khadhroony-solana-project-v0.3.16.zip SHA-256 db3cc1b3fc3fb07ee864b02e2a7346c673d4cf63b33e8e872aca6c6458856ca0
|
||||
games-v0.3.5.zip SHA-256 5f5fdee1a271386766d059657d6eaa831acdc263b3e722fed738808335c0a105
|
||||
```
|
||||
|
||||
Ce sont des sources de comparaison pour les décisions de templates et d'audits, non la baseline PGR et non des dépendances de build. Leur présence ne rend pas les conventions locales de KSP ou Games normatives pour tous les projets.
|
||||
|
||||
## Audit indépendant de la stable `v0.0.2`
|
||||
|
||||
L'inspection de l'archive, sa lecture et la comparaison des fichiers extraits avec les membres ZIP ont établi :
|
||||
|
||||
- ZIP lisible, `94` entrées : `78` fichiers et `16` répertoires, une seule racine `pgr/` ; aucun doublon, chemin absolu, traversée `..`, chemin Windows ambigu ou lien symbolique ;
|
||||
- exactement `78` fichiers extraits ; `VERSION` contient `0.0.2` avec un seul retour final à la ligne ; `.git` absent comme attendu ;
|
||||
- octets des fichiers distribués décodables en UTF-8, sans NUL, CR, espace de fin de ligne ou retour final manquant ;
|
||||
- `73` fichiers Markdown dont les deux premières lignes correspondent exactement au chemin relatif `file` et à une révision positive `version` ;
|
||||
- contrôle local des deux scripts existants : `Markdown table audit: clean (2 table(s), 73 file(s))` et `Markdown link audit: clean (50 local link(s), 73 file(s))` ;
|
||||
- aucun répertoire de build/cache ou fichier local sensible connu dans les chemins distribués ; seule la préférence Eclipse UTF-8 intentionnellement conservée est présente sous `.settings/`.
|
||||
|
||||
La vérification de structure et de gouvernance a constaté :
|
||||
|
||||
- `12` deltas et `12` histories appariés exactement dans chacune des séries `0.0.1` et `0.0.2`, y compris `rel.001` ; chaque history possède un statut explicite ;
|
||||
- les versions `avant`/`après` déclarées dans tous les deltas `0.0.2` forment une chaîne continue de `0.0.1` à `0.0.2` ; les deltas `0.0.1` au format homogène depuis `alpha.1.fix.2` forment également une chaîne continue jusqu'à la stable ;
|
||||
- dans `0.0.1`, les `FAIL` de `alpha.1`, `alpha.1.fix.1`, `alpha.4` et `rc.1` sont suivis d'une tranche corrective `PASS` ; dans `0.0.2`, même traitement pour `alpha.1`, `alpha.4`, `beta.1` et `rc.1` ; les deux `rel.001` sont `PASS` ;
|
||||
- `README.md`, `ROADMAP.md` et `CHANGELOG.md` présentent `0.0.2` comme terminé et `0.0.3` comme prévu ; les plans `001` et `002` restent historiques ; le prompt `003` nomme l'archive et la preuve post-tag fournies ;
|
||||
- séparation cohérente entre objectifs durables, architecture, règles normatives, validation, plans, deltas prospectifs, histories rétrospectifs et changelog stable ; les index pointent vers les familles et profils réellement présents ;
|
||||
- les profils réellement matérialisés sont `510` Rust/Cargo, `520` Java/Maven/Gradle et `610` Android ; les seuls scripts d'audit PGR sont ceux des tableaux et des liens Markdown locaux. Aucun skeleton, générateur ou profil différé n'est présent.
|
||||
|
||||
Aucun écart bloquant n'a été constaté dans ces contrôles. Les scripts Markdown ont chacun une portée volontairement limitée : le contrôle des liens vérifie l'existence des cibles inline locales, pas les ancres ; celui des tableaux vérifie leur structure source. Leur PASS n'atteste donc pas des propriétés hors de leur contrat.
|
||||
|
||||
## Comparaison réelle des corpus Rust
|
||||
|
||||
KSP `0.3.16` et Games `0.3.5` possèdent chacun un workspace Cargo virtuel avec `resolver = "3"` et centralisent réellement dans `[workspace.package]` `version`, `edition`, `license`, `repository`, `authors` et `publish`. Ils utilisent `[workspace.dependencies]` pour des dépendances tierces, mais avec respectivement `37` et `19` entrées propres à leur projet. Les deux racines déclarent les mêmes trois lints Rust de base (`missing_docs`, `unreachable_pub`, `unsafe_code`) et les mêmes `18` niveaux Clippy ; les éventuels `allow` doivent être revus un par un avant réemploi.
|
||||
|
||||
Les `22` crates KSP héritent des lints workspace par `[lints] workspace = true`. Parmi `23` crates Games, `22` utilisent ce même héritage ; l'entrée Android déclare des lints locaux pour ajuster `unsafe_code` à sa frontière FFI. La capacité d'exception locale est donc réelle et doit être expliquée sans rendre l'exception Android générale.
|
||||
|
||||
Les deux `rustfmt.toml` ont un contenu technique identique et seulement un numéro de révision de fichier différent. Les deux `clippy.toml` partagent leurs seuils principaux et divergent sur les identifiants courts autorisés et quelques entrées vides. L'opérateur confirme qu'il réutilise ces conventions comme baseline de départ, telles quelles ou avec de petites adaptations. Les deux `.cargo/config.toml` déplacent les artefacts de build vers `../builds/<projet>/target/` ; Games ajoute des flags Web propres à sa cible. La configuration générique de déplacement est donc retenue avec un nom de projet à remplacer.
|
||||
|
||||
## Sélection des templates
|
||||
|
||||
### Retenu : famille Rust/Cargo minimale
|
||||
|
||||
Le besoin concret n'est pas limité à `rustfmt.toml`. La première famille doit couvrir cinq responsabilités distinctes :
|
||||
|
||||
1. `rustfmt.toml` : options communes dont la valeur est justifiée ; alignement de `edition` avec le projet destinataire ; ne pas reprendre mécaniquement chaque préférence des deux sources ;
|
||||
2. configuration Clippy : niveaux de lint Rust/Clippy dans les sections Cargo `[workspace.lints.rust]` et `[workspace.lints.clippy]`, plus `clippy.toml` pour les seuils et réglages conservés dans le profil de départ éprouvé ; chaque projet peut adapter ces choix ;
|
||||
3. `.cargo/config.toml` : `target-dir` et `build-dir` vers un dossier frère `../builds/<projet>/target/`, après remplacement explicite du nom ; les flags Web et les autres particularités restent locaux ;
|
||||
4. `Cargo.toml` workspace : sections `[workspace]`, `[workspace.package]`, `[workspace.dependencies]` et `[workspace.lints.*]` avec les responsabilités et champs de décision explicités ; `VERSION` doit correspondre à `workspace.package.version` seulement pour une unité de release commune ;
|
||||
5. `Cargo.toml` d'une crate membre ordinaire : identité locale, héritage explicite des métadonnées communes et des lints, et dépendances/features limitées aux besoins de la crate. Une adaptation locale des lints doit être documentée comme exception ciblée ; elle ne devient pas un deuxième jeu de valeurs globales.
|
||||
|
||||
Ces fichiers ou extraits doivent être copiables et compréhensibles sans figer le nom de projet, la version, les dépendances, le layout de toutes les crates, la publication, la toolchain ni le minimum de plateforme. Lorsqu'un champ obligatoire ne peut pas avoir de valeur générique sûre, des instructions Markdown guident son remplacement avant l'usage ; un fichier TOML présenté comme prêt à l'emploi doit être valide. Les crates bibliothèque et application peuvent partager un tronc commun, leurs différences réelles restant documentées sans créer des dizaines de variantes.
|
||||
|
||||
Pour la validation, comparer les templates au profil `510`, parser les configs/manifests avec un parseur TOML et exercer sur un workspace d'essai les héritages et le cas d'une exception locale quand les toolchains sont disponibles. Tester `rustfmt` et Clippy pour les réglages réellement livrés dans un projet Rust concerné ; une compilation de KSP/Games n'est pas une gate de PGR.
|
||||
|
||||
### Retenu : spécification courte du prompt manuel de nouvelle session
|
||||
|
||||
Les prompts `002` et `003` répètent la transmission de la baseline taggée, de la cible et de la première tranche ; `003` ajoute le rapport post-tag et le texte manuel remis à l'opérateur. Après comparaison, `alpha.6` retient une courte spécification Markdown des champs et de la phrase de reprise. Elle facilite la prochaine clôture sans créer un générateur, un nouveau prompt versionné prématuré ou une copie du plan. Le rapport ne devient un champ rempli que s'il existe et que son résultat est réellement connu.
|
||||
|
||||
### Différés
|
||||
|
||||
Les fichiers Maven/Gradle complets, wrappers, Android `local.properties` ou signing, règles `.gitignore` universelles et versions de dépendances ne sont pas copiés par anticipation. Games fournit un exemple Android concret, mais sa matrice AGP/Gradle/JDK, son build natif et ses flags Cargo Web restent propres à ce projet. Les wrappers restent soumis aux outils officiels et à la décision du projet ; un `local.properties` entièrement régénéré ne justifie pas d'exemple.
|
||||
|
||||
Les spécifications complètes de skeleton restent réservées à `0.0.4` ; Rust/JNI, Web/WASM, Tauri et les autres profils différés n'entrent pas dans cette release par simple proximité technologique.
|
||||
|
||||
## Sélection des audits et patterns
|
||||
|
||||
Les trois audits Markdown (`headers`, `tables`, `liens locaux`) restent séparés : une propriété chacun, sélection explicite des chemins et lecture seule. L'audit des headers, livré en `alpha.5`, applique le contrat de `docs/rules/300-DOCUMENTATION.md` avec des cas positifs et négatifs ciblés ; il ne juge ni le rôle du document ni la pertinence de l'incrément de sa révision.
|
||||
|
||||
La comparaison des scripts Python KSP `0.3.16` et Games `0.3.5` montre que `audit_rust_general_rules.py` (~580 lignes dans chaque corpus) mélange headers et versions Rust, imports, rustdoc, structure des items, blancs, constantes et modules. `audit_rust_export_completeness.py` possède le contrat particulier des façades et réexports ; KSP ajoute `audit_ksp_workspace_rules.py` pour manifests/frontières/tracing, tandis que Games regroupe plusieurs intégrations Web/Android/Gradle dans `audit_distribution_layout.py`. `audit_rust_workspace_rules.py` est un orchestrateur ; il peut rester un lanceur sans devenir propriétaire de ces contrats.
|
||||
|
||||
| Propriété | Owner | Suite |
|
||||
|------------------------------------------|-------------------------|----------------------------------------|
|
||||
| Ordre interne des `use` et `mod` | Rustfmt | `cargo fmt --all -- --check` |
|
||||
| Diagnostics du langage et des lints | Rust/Clippy | Outils officiels du projet |
|
||||
| Espacement des lignes vides | Profil `510` facultatif | `audit_rust_blank_lines.py` |
|
||||
| Blocs de constantes racine | Profil `510` facultatif | `audit_rust_const_blocks.py` |
|
||||
| Headers, rustdoc, API, tests, plateforme | Profils locaux | Audits séparés uniquement si justifiés |
|
||||
|
||||
Le balayage préalable des vrais sources `crates/**/src/**/*.rs` donne `300` fichiers KSP et `59` Games. Le contrôle des blancs passe les deux corpus. Un tri naïf de toutes les constantes racine trouve `17` signaux dans KSP et zéro dans Games ; plusieurs listes KSP sont ordonnées par contrat de protocole ou de schéma. Cela interdit de déclarer le tri globalement obligatoire ou de corriger ces fichiers sans revue. Les scripts livrés sont des patrons facultatifs : le propriétaire d'un projet choisit le sous-ensemble de sources concerné, applique `cargo fmt` avant ces audits et conserve l'ordre sémantique là où il existe. Un petit helper lexical partagé masque commentaires et littéraux ; il n'est pas un troisième audit ni un parseur Rust exhaustif. Les limites et le mode d'emploi sont dans `docs/validation/002-RUST_STYLE_AUDITS.md`.
|
||||
|
||||
Les autres candidats demeurent conditionnels : miroir `VERSION`/`workspace.package.version` si une release unit est partagée, héritage explicite des lints dans les crates et façade publique seulement lorsqu'un projet possède ce contrat. Aucun audit spécialisé de ces domaines ni de layout Android/Web n'est justifié par le dépôt documentaire PGR lui-même.
|
||||
|
||||
## Trajectoire prévisionnelle
|
||||
|
||||
### alpha.1 — intake et dimensionnement
|
||||
|
||||
Enregistrer l'audit de la stable, confronter le prompt au dépôt réel, inventorier les candidats, fixer le scope et produire le présent plan ainsi que le delta. Aucune matérialisation technique importante. Attendre la validation opérateur, le history distinct et le commit avant tout delta suivant.
|
||||
|
||||
### alpha.1.fix.1 — correction documentaire du plan
|
||||
|
||||
Après le history et le commit de `alpha.1`, documenter la comparaison réelle de KSP/Games, élargir les templates Rust à Cargo et Clippy et redimensionner les tranches. Aucun template ou audit nouveau dans ce fix.
|
||||
|
||||
### alpha.2 — outillage Rust/Cargo partagé
|
||||
|
||||
Créer les templates `rustfmt.toml`, `clippy.toml` et `.cargo/config.toml` à partir du noyau éprouvé dans KSP et Games. Documenter les responsabilités distinctes : formatage, paramètres Clippy, sortie Cargo hors du dépôt. Le nom du projet, l'édition Rust et les seuils ajustables sont explicités au point de copie ; vérifier syntaxe et chemins relatifs. Les niveaux de lint dans `Cargo.toml` restent à `alpha.4` après le REPLAN, qui les reliera au profil Clippy retenu.
|
||||
|
||||
### alpha.3 — audits de style Rust découpés (REPLAN : SPLIT)
|
||||
|
||||
Suite à la demande post-gate `alpha.2`, isoler deux contrôles réutilisables des scripts composites KSP/Games : espacement des lignes vides et blocs de constantes racine sans ordre sémantique. Posséder leur convention facultative dans le profil `510`, documenter sélection/limites et exécuter des cas ciblés positifs et négatifs. Vérifier sur les corpus réels que les ordres contractuels ne deviennent pas de faux changements imposés. Les manifests initialement prévus ici passent à `alpha.4` : aucune validation anticipée n'est déduite du PASS de `alpha.2`.
|
||||
|
||||
### alpha.4 — manifests Cargo workspace et crate membre
|
||||
|
||||
Fournir des modèles minimaux de `Cargo.toml` racine et membre, incluant l'héritage des métadonnées et des lints et une explication des variations de scope. Vérifier les exemples sur un workspace d'essai lorsque la toolchain est disponible, sans recopier les listes de dépendances, versions et chemins de KSP/Games. Si les modèles exigent trop de décisions pour former des fichiers TOML valides, livrer des extraits complets avec procédure de substitution documentée, sans prétendre qu'un placeholder est prêt à compiler.
|
||||
|
||||
### alpha.5 — audit de headers Markdown
|
||||
|
||||
Extraire le contrôle récurrent en un script read-only monotâche, documenter sa portée dans la matrice et vérifier des cas positifs et négatifs utiles. Ne pas fusionner cet audit avec les deux audits Markdown existants.
|
||||
|
||||
### alpha.6 — décision sur le template de workflow
|
||||
|
||||
La comparaison des prompts `002` et `003` confirme une répétition utile à factoriser : baseline source, preuve post-tag éventuelle, prompt versionné et gate d'intake. Livrer une spécification courte de rédaction manuelle, détenue par `210-WORKFLOW.md`, sans générateur ni prompt de version suivante avant la clôture stable. Le template reste distinct des configurations Rust/Cargo et ne modifie pas les prompts historiques.
|
||||
|
||||
### beta.1 — réconciliation
|
||||
|
||||
Vérifier ownership, navigation, séparation règle/template/audit, absence de versions universelles arbitraires et proportion des contrôles. Aucun nouveau domaine majeur sans REPLAN.
|
||||
|
||||
La revue préparatoire de cette tranche a constaté que les sept deltas `0.0.3` de `alpha.1` à `alpha.6`, fix inclus, forment une chaîne de versions continue depuis `0.0.2` et possèdent chacun un history `PASS` fondé sur la gate opérateur. Les propriétaires restent distincts : profil `510` pour les conventions Rust facultatives, règles `210` et `300` pour workflow et headers, documents de `docs/templates/` pour l'adaptation, scripts monotâches pour les contrôles. Leurs validations ciblées avaient été acquises dans les tranches précédentes ; `beta.1` a vérifié leur intégration et la navigation sans exiger de nouveau build des projets sources.
|
||||
|
||||
Trois écarts documentaires justifiaient le delta : l'index de `docs/` présentait tous ses templates comme techniques alors que le troisième décrit la reprise de session ; le plan désignait toujours les headers Markdown comme candidat après leur livraison ; la matrice réservait l'audit de liens à `beta/RC/stable` alors que les gates `alpha` l'emploient également sur des changements de navigation. L'index racine ne pointait pas vers le plan actif. Ces renvois ont été corrigés dans les documents vivants sans modifier les snapshots ni les choix de version `0.1.0` et d'édition `2024` explicitement présentés comme exemples adaptables dans les manifests et instructions Rust/Cargo.
|
||||
|
||||
### rc.1 — gate de release candidate
|
||||
|
||||
Geler le scope, préparer le changelog et le prompt de la version suivante si la trajectoire est confirmée ; exécuter la gate documentaire et les vérifications ciblées des scripts réellement ajoutés.
|
||||
|
||||
La gate opérateur de `beta.1` est `PASS` : `15` tests ciblés, trois audits Markdown, chaîne des sept histories alpha et cinq TOML vérifiés. Son résultat détaillé appartient à `history/0.0.3/beta.1.md`. À l'entrée de `rc.1`, le scope est gelé sur les cinq fichiers Rust/Cargo avec leurs deux guides techniques, la spécification du message manuel, les deux audits de style Rust facultatifs et l'audit des headers Markdown. Les règles et scripts antérieurs restent en place ; aucun profil technologique nouveau, générateur ou skeleton complet n'entre dans cette release.
|
||||
|
||||
La RC a préparé une entrée candidate `0.0.3` dans le changelog et le prompt `004` de `0.0.4`. La gate opérateur de `rc.1` est `PASS` : `15` tests, trois audits Markdown, chaîne des huit histories précédents et cinq TOML vérifiés. Son résultat détaillé appartient à `history/0.0.3/rc.1.md`. La première tranche de `0.0.4` décidera des skeleton specifications réellement justifiées après audit de la stable publiée ; son rapport post-tag reste une preuve ultérieure distincte.
|
||||
|
||||
### stable — 0.0.3
|
||||
|
||||
Promouvoir la RC validée, produire le history de clôture pré-tag, committer et tagger, puis contrôler séparément l'archive du tag publiée.
|
||||
|
||||
Le delta `rel.001` prépare mécaniquement la version stable `0.0.3` : `VERSION`, statut de la roadmap, présentation du dépôt et des index, et conversion de l'entrée candidate du changelog en entrée stable. Ce plan devient une référence historique à la clôture, sans ajout de règle, profil, template ou audit. Le résultat réel de la gate pré-tag appartient à `history/0.0.3/rel.001.md`, fourni après exécution opérateur ; commit et tag `v0.0.3` suivent uniquement un PASS. La vérification de l'archive effectivement publiée depuis le tag constitue ensuite une preuve post-tag séparée, typiquement `publish.001`, et ne doit pas être présumée par le history pré-tag.
|
||||
|
||||
## Points de décision et validation
|
||||
|
||||
Le résultat `SPLIT` de `alpha.3` répond à la découverte post-gate de contrôles de style Rust utiles mais mêlés dans deux scripts de référence. Le plan doit encore être revu si les manifests Cargo exigent des choix de projet incompatibles avec un modèle minimal, si l'audit de headers ne peut rester fiable et monotâche, si le template de workflow duplique le plan, ou si un autre examen des corpus révèle des contraintes nouvelles. Un REPLAN explicite indique `CONTINUE`, `SPLIT`, `CONTINUE-NEXT-SESSION` ou `ABANDON` ; la durée d'une conversation ne crée pas une nouvelle version.
|
||||
|
||||
La validation `alpha.1` a porté sur l'identité de `VERSION`, la portée du delta, les headers et audits Markdown, l'absence de changement historique rétroactif et le contrôle Git du dépôt de l'opérateur. Ses résultats observés sont conservés dans `history/0.0.3/alpha.1.md`. Le fix documentaire décrit ci-dessus possède sa propre gate et son propre history : le PASS de `alpha.1` ne vaut pas validation anticipée de `alpha.1.fix.1`.
|
||||
158
docs/plans/004-V0_0_4_SKELETONS_PLAN.md
Normal file
158
docs/plans/004-V0_0_4_SKELETONS_PLAN.md
Normal file
@@ -0,0 +1,158 @@
|
||||
<!-- file: docs/plans/004-V0_0_4_SKELETONS_PLAN.md -->
|
||||
<!-- version: 3 -->
|
||||
|
||||
# Plan 0.0.4 — skeleton specifications et composition
|
||||
|
||||
## Statut et sources
|
||||
|
||||
Plan historique créé pendant `0.0.4-alpha.1` après audit indépendant de la stable publiée `v0.0.3` demandé par `prompts/004-V0_0_4_START_PROMPT.md`. Les tranches `alpha.1` à `alpha.3` sont `PASS`. `alpha.4` a enregistré `FAIL` sur sa gate d'instanciation, puis `alpha.4.fix.1` a corrigé cette gate et est `PASS`. `beta.1` a enregistré `FAIL` sur une erreur de syntaxe de sa gate de réconciliation, puis `beta.1.fix.1` a rejoué la réconciliation et est `PASS`. La gate opérateur de `rc.1` est `PASS` : intégration documentaire, prompt `005`, cinq TOML et instanciation temporaire Rust/Cargo avec `cargo metadata`, `fmt`, `check` et `clippy -D warnings` ont été validés. Le scope fonctionnel est gelé et `rel.001` ne réalise qu'une promotion stable pré-tag.
|
||||
|
||||
La baseline autoritaire est l'archive source fournie `pgr-v0.0.3.zip`, déclarée téléchargée depuis le tag Gitea `v0.0.3`. Son SHA-256 vérifié pendant le cadrage est :
|
||||
|
||||
```text
|
||||
517fb46ada098fdc221ae53a8ff4b409b81e0244ec5ce4d0e6fca0c3da61b866
|
||||
```
|
||||
|
||||
Le rapport externe `pgr-0.0.3-publish.001-report.md` est fourni séparément, conclut `PASS` et annonce le même hash. Il atteste une vérification post-tag distincte et ne fait pas partie de la stable. L'archive source ne contient pas `.git`, ce qui est conforme au contrat de reprise ; l'identité du commit et du tag décrite dans le rapport n'est pas déduite du contenu du ZIP.
|
||||
|
||||
Les règles applicables au cadrage sont `RULES.md`, les familles `200`, `210`, `300`, `400`, `500`, `510`, `520`, `600`, `610`, ainsi que `docs/architecture/003-RULE_PROFILE_MODEL.md`. Les guides `docs/templates/001` à `003`, les cinq modèles Rust/Cargo, les trois audits Markdown et les deux audits facultatifs de style Rust complètent l'inventaire réel de la stable.
|
||||
|
||||
## Audit indépendant de la stable `v0.0.3`
|
||||
|
||||
L'archive fournie est lisible et son contenu distribué est cohérent dans les contrôles effectués :
|
||||
|
||||
- SHA-256 égal au rapport post-tag ;
|
||||
- `140` entrées ZIP : `115` fichiers et `25` répertoires, avec une seule racine `pgr/` ;
|
||||
- test CRC propre, aucun doublon, aucune collision de casse, aucun chemin absolu ou avec traversée `..`, aucun chemin Windows ambigu et aucun lien symbolique ;
|
||||
- extraction propre de `115` fichiers ; `VERSION` contient exactement `0.0.3` suivi d'un retour à la ligne ; `.git` est absent comme attendu ;
|
||||
- les fichiers distribués sont UTF-8, sans octet NUL, retour CR, espace de fin de ligne ou retour final manquant ;
|
||||
- aucun chemin distribué de build/cache ou secret contrôlé n'est présent ; `.settings/org.eclipse.core.resources.prefs` reste l'exception Eclipse versionnée prévue ;
|
||||
- `99` fichiers Markdown possèdent des headers `file/version` mécaniquement conformes ;
|
||||
- les trois audits Markdown sont propres : `99` fichiers pour les headers, `3` tableaux et `79` liens locaux ;
|
||||
- les `15` tests Python ciblés réussissent ;
|
||||
- les cinq fichiers TOML sous `templates/rust-cargo/` se parsèrent correctement ;
|
||||
- les deux audits de style Rust facultatifs n'ont pas de corpus Rust produit à inspecter dans PGR ; leur comportement est couvert par `tests/test_rust_audits.py` et leur sélection doit rester explicite dans un projet destinataire.
|
||||
|
||||
La chaîne workflow est complète :
|
||||
|
||||
```text
|
||||
0.0.1 : 12 deltas / 12 histories
|
||||
0.0.2 : 12 deltas / 12 histories
|
||||
0.0.3 : 10 deltas / 10 histories
|
||||
```
|
||||
|
||||
Chaque delta possède son history homonyme. Les histories `0.0.3`, de `alpha.1` à `rel.001`, sont tous `PASS`. Les échecs historiques des séries antérieures sont conservés comme snapshots et sont suivis par leurs corrections explicites ; ils ne sont pas réécrits rétroactivement.
|
||||
|
||||
Les limites annoncées restent visibles et cohérentes : l'audit des liens ne valide pas les anchors, l'audit des headers ne juge pas la pertinence sémantique d'une révision, les audits Rust utilisent une analyse lexicale ciblée et l'archive source ne prouve pas elle-même une référence Git distante. Aucun de ces points ne constitue un défaut bloquant de la stable.
|
||||
|
||||
## Revue des règles, profils et propriétaires
|
||||
|
||||
La hiérarchie normative reste cohérente avec le modèle de profils : règles générales, langage/écosystème, plateforme, puis scopes plus spécifiques et exceptions explicites. Aucun profil n'est applicable par simple fréquence ou provenance historique.
|
||||
|
||||
Les responsabilités utiles à `0.0.4` sont distinctes :
|
||||
|
||||
- `200` possède le lifecycle et le rôle de `alpha.1` comme gate de cadrage ;
|
||||
- `210` possède plans, deltas, histories, prompts, baselines et séparation pré-tag/post-tag ;
|
||||
- `300` possède rôles documentaires, documents vivants, snapshots et headers ;
|
||||
- `400` possède la sélection proportionnelle des preuves et l'autorité du gate opérateur ;
|
||||
- `500` et `600` possèdent les contrats communs des profils langage et plateforme ;
|
||||
- `510`, `520` et `610` possèdent respectivement Rust/Cargo, Java/Maven/Gradle et Android ;
|
||||
- `docs/architecture/003-RULE_PROFILE_MODEL.md` possède le modèle de composition et interdit les profils composites sans contrat propre réel.
|
||||
|
||||
La séparation règle / template / skeleton / audit de `docs/architecture/002-GOVERNANCE_ARCHITECTURE.md` reste adaptée. `0.0.4` doit l'étendre par des artefacts concrets sans déplacer les propriétaires normatifs existants.
|
||||
|
||||
## Inventaire des capacités disponibles pour des skeletons
|
||||
|
||||
### Fondation gouvernée PGR — prête à être spécifiée
|
||||
|
||||
Une baseline de projet gouverné constitue une fondation composable, pas une architecture applicative. Les contrats nécessaires existent déjà : versioning, workflow, documentation, validation et modèle de profils. Le skeleton devra indiquer quels artefacts locaux créer ou copier, comment sélectionner les règles réellement applicables et quelles décisions restent propres au projet.
|
||||
|
||||
Il ne doit pas recopier l'historique de PGR, imposer toutes les familles de règles ni créer une dépendance dynamique vers le dépôt PGR.
|
||||
|
||||
### Rust/Cargo workspace — prêt à être spécifié
|
||||
|
||||
Le besoin est suffisamment couvert par des artefacts réels : profil `510`, deux guides d'adaptation, cinq templates Rust/Cargo et deux audits de style facultatifs documentés. Le skeleton pourra composer une fondation gouvernée avec `500 + 510` et sélectionner uniquement les templates nécessaires.
|
||||
|
||||
Les décisions destinataire restent explicites : nom du projet et des crates, version de release, édition/toolchain, métadonnées de publication, membres du workspace, dépendances et features, politique `Cargo.lock`, chemin des artefacts Cargo, seuils Clippy, politique de lints et sélection éventuelle des audits de style. Les valeurs d'exemple `0.1.0`, `2024`, `project-name`, `project-core-lib`, les seuils Clippy et les chemins de build ne deviennent jamais universels.
|
||||
|
||||
### Java / Maven / Gradle — différé
|
||||
|
||||
Le profil `520` définit des règles, mais PGR ne possède encore aucun template Maven/Gradle ou corpus technique éprouvé à instancier. Le choix Maven/Gradle, la politique de wrapper et les versions de toolchain doivent être déterminés dans un chantier justifié avant de produire un skeleton concret.
|
||||
|
||||
### Android — différé
|
||||
|
||||
Le profil `610` définit la structure de responsabilité et les décisions Android, mais aucun template AGP/Gradle, manifest applicatif, matrice SDK ou projet réel n'existe dans PGR. Un skeleton Android serait prématuré avant ces pièces et avant la sélection explicite de sa composition avec Java/Gradle ou un autre stack réel.
|
||||
|
||||
### Web, JNI, Tauri et autres familles absentes — différés
|
||||
|
||||
Ces domaines ne possèdent pas encore tous leurs propriétaires normatifs et templates nécessaires. `0.0.4` ne crée pas de profils ou skeletons placeholders pour eux.
|
||||
|
||||
## Contrat visé pour une skeleton specification
|
||||
|
||||
La tranche de composition devra fixer un contrat commun minimal. Chaque skeleton doit au moins permettre d'identifier :
|
||||
|
||||
```text
|
||||
applicabilité et objectif
|
||||
profils/règles sélectionnés
|
||||
fichiers à créer, copier ou adapter
|
||||
templates applicables et source de leurs choix
|
||||
décisions obligatoires propres au destinataire
|
||||
options et exceptions explicites
|
||||
ordre de composition
|
||||
validation initiale proportionnée
|
||||
éléments volontairement hors scope
|
||||
```
|
||||
|
||||
Un skeleton reste une procédure Markdown. Il ne génère pas le projet, ne télécharge pas de dépendances, ne remplace pas les toolchains et ne fige pas l'architecture future. Après instanciation, le projet possède ses copies locales et ses décisions.
|
||||
|
||||
Les règles communes de sélection et de composition doivent avoir un propriétaire normatif unique sous `docs/rules/`. Les spécifications concrètes vivront dans une collection documentaire dédiée créée seulement avec son premier contenu réel. Les fichiers techniques copiables restent sous `templates/` et leurs instructions d'adaptation sous `docs/templates/`.
|
||||
|
||||
## Découpage prévisionnel de `0.0.4`
|
||||
|
||||
### alpha.1 — audit de stable et cadrage
|
||||
|
||||
Vérifier indépendamment `v0.0.3`, le rapport post-tag, les règles `200` à `610`, les cinq templates Rust/Cargo, les trois audits Markdown, les deux audits Rust facultatifs et la chaîne de deltas/histories. Inventorier les skeletons réellement justifiés et fixer le présent plan avant toute matérialisation importante.
|
||||
|
||||
### alpha.2 — contrat de composition des skeletons
|
||||
|
||||
Créer le propriétaire normatif des règles de sélection et de composition des skeletons, puis la collection documentaire des skeleton specifications avec son index. Définir la frontière entre règles copiées/adaptées, templates techniques, décisions propres au projet, overrides et validation. Réconcilier les index et l'architecture sans créer encore de domaine technologique supplémentaire.
|
||||
|
||||
Le nom et le numéro exacts du document normatif seront choisis à l'application selon la responsabilité finale ; le plan ne transforme pas un chemin prévisionnel en règle déjà active.
|
||||
|
||||
### alpha.3 — fondation de projet gouverné
|
||||
|
||||
Matérialiser une première specification composable décrivant la baseline de gouvernance locale d'un projet utilisant PGR : version, règles sélectionnées, documentation minimale, workflow réellement retenu et validation initiale. Elle doit rester proportionnée et permettre d'omettre les collections ou artefacts sans contenu réel.
|
||||
|
||||
Cette fondation n'est ni un framework ni une architecture applicative et ne doit pas recopier les deltas, histories ou décisions propres au dépôt PGR.
|
||||
|
||||
### alpha.4 — skeleton Rust/Cargo workspace
|
||||
|
||||
Matérialiser la première specialization technologique en composant la fondation gouvernée avec `500 + 510`, les cinq templates Rust/Cargo et les guides d'adaptation existants. Documenter les décisions destinataire avant copie et les audits facultatifs explicitement sélectionnés.
|
||||
|
||||
La gate doit inclure une instanciation temporaire minimale ou une vérification équivalente lorsque la toolchain Rust est disponible, afin de distinguer la validité syntaxique des templates de leur adoption correcte. Cette preuve ne transforme pas PGR lui-même en workspace Rust.
|
||||
|
||||
### beta.1 — réconciliation interne
|
||||
|
||||
Vérifier ownership, liens, index, absence de duplication normative, non-universalisation des valeurs d'exemple, limites des audits et cohérence des deux premières specifications. Confirmer explicitement que Java/Android/Web/JNI/Tauri restent différés tant que leurs pièces requises manquent.
|
||||
|
||||
Aucun chantier de réconciliation complète avec KSP ou Games n'entre ici : la roadmap réserve cette mission à `0.0.5`.
|
||||
|
||||
La première gate `beta.1` a enregistré `FAIL` uniquement parce qu'une chaîne Python de contrôle contenait une apostrophe non échappée. `beta.1.fix.1` a corrigé la gate sans modifier de contenu vivant et a confirmé la réconciliation : owners distincts, trois documents skeletons seulement, valeurs Rust/Cargo adaptables, limites des audits explicites, cinq TOML valides et domaines différés toujours absents.
|
||||
|
||||
### rc.1 — gate de release candidate
|
||||
|
||||
Geler le scope, préparer l'entrée `0.0.4` du changelog et le prompt `005` de `0.0.5` si la trajectoire est confirmée. Rejouer les validations documentaires, tests et smokes réellement invalidés par la release.
|
||||
|
||||
Le scope gelé comprend le contrat transversal `220-SKELETONS.md`, l'index de collection, la fondation gouvernée `001`, la spécialisation Rust/Cargo `002` et l'utilisation des cinq templates Rust/Cargo déjà présents. Aucun nouveau domaine technologique, générateur, template, audit ou règle normative n'entre en RC. La trajectoire `0.0.5` reste celle de la roadmap : réconciliation réelle de PGR avec `khadhroony-solana-project` et `sasedev-games`, à partir de baselines explicites qui devront être fournies à cette future session plutôt que déduites d'un état local implicite.
|
||||
|
||||
### stable — 0.0.4
|
||||
|
||||
La gate opérateur de `rc.1` est `PASS`. Le delta `rel.001` prépare mécaniquement la stable `0.0.4` : `VERSION`, présentation du dépôt et des index, statut de la roadmap, conversion de l'entrée candidate du changelog et clôture du présent plan comme référence historique. Aucun nouveau skeleton, profil, template, audit ou domaine technologique n'est ajouté pendant cette promotion.
|
||||
|
||||
Le résultat réel de la gate pré-tag appartient à `history/0.0.4/rel.001.md`, produit après exécution opérateur. Le commit stable et le tag `v0.0.4` suivent uniquement un `PASS`. La vérification de l'archive effectivement publiée depuis Gitea et le rapport `pgr-0.0.4-publish.001-report.md` constituent ensuite une preuve post-tag séparée ; ils ne sont pas présumés par le delta ni par le history pré-tag.
|
||||
|
||||
## Points de décision et stratégie de validation
|
||||
|
||||
Un REPLAN devient nécessaire si la fondation gouvernée exige des templates génériques inexistants pour rester actionnable, si le contrat de composition duplique des règles existantes au lieu de les référencer, si le skeleton Rust impose une architecture plus étroite que le profil `510`, ou si l'instanciation minimale révèle qu'un template technique ne peut pas être adopté sans nouvelle décision normative.
|
||||
|
||||
Les tranches documentaires utilisent les trois audits Markdown et les contrôles Git applicables. Toute modification des scripts ou de leurs contrats rejoue leurs tests ciblés. Toute modification d'un template Rust/Cargo vérifie sa syntaxe et, lorsqu'elle prétend à une instanciation fonctionnelle, une gate Cargo proportionnée dans un environnement temporaire. Aucun build Java/Android n'est demandé tant qu'aucun artefact concret de ces écosystèmes n'entre dans le scope.
|
||||
222
docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
Normal file
222
docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
Normal file
@@ -0,0 +1,222 @@
|
||||
<!-- file: docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md -->
|
||||
<!-- version: 16 -->
|
||||
|
||||
# Plan 0.0.5 — réconciliation réelle avec KSP et sasedev-games
|
||||
|
||||
## Statut et sources
|
||||
|
||||
Plan historique créé pendant `0.0.5-alpha.1` conformément à `prompts/005-V0_0_5_START_PROMPT.md`. La release a confronté PGR à deux baselines autoritaires fournies sans présumer qu'elles avaient déjà adopté PGR.
|
||||
|
||||
Sources contrôlées :
|
||||
|
||||
```text
|
||||
pgr-v0.0.4.zip 7137bb084f017362323a2043d13ba71490be15b8786adc8d645981bf455b80ae
|
||||
khadhroony-solana-project-v0.3.16.zip db3cc1b3fc3fb07ee864b02e2a7346c673d4cf63b33e8e872aca6c6458856ca0
|
||||
games-v0.3.5.zip 5f5fdee1a271386766d059657d6eaa831acdc263b3e722fed738808335c0a105
|
||||
```
|
||||
|
||||
Le rapport externe `pgr-0.0.4-publish.001-report.md` est `PASS` et annonce le même hash pour la stable PGR. L'étude détaillée et les limites de l'environnement sont consignées dans [`../studies/001-KSP_GAMES_RECONCILIATION.md`](../studies/001-KSP_GAMES_RECONCILIATION.md).
|
||||
|
||||
## Mission et garde-fous
|
||||
|
||||
`0.0.5` doit améliorer PGR à partir des besoins réellement répétés dans KSP et Games sans transformer leurs conventions historiques en règles universelles.
|
||||
|
||||
Les deux projets ne sont pas encore gouvernés par PGR. Par conséquent :
|
||||
|
||||
- aucune divergence de leurs archives n'est qualifiée de défaut PGR par défaut ;
|
||||
- aucune migration de KSP ou Games n'appartient au scope de cette release ;
|
||||
- aucune ancienne tranche, nomenclature ou chaîne history n'est reconstruite rétroactivement ;
|
||||
- tout nouvel owner PGR doit correspondre à un besoin réutilisable et non à un simple copier-coller de projet ;
|
||||
- les règles métier, architecture, protocoles, distribution et infrastructure spécifiques restent locales.
|
||||
|
||||
## Résultat du cadrage alpha.1
|
||||
|
||||
L'audit classe la majorité des mécanismes de gouvernance, documentation, validation et Rust/Cargo comme déjà `OWNED` par PGR. Les améliorations candidates réellement communes sont bornées à quatre axes :
|
||||
|
||||
1. **prompt de démarrage de projet** : le contrat actuel de `210-WORKFLOW.md` est plus minimal que les prompts opératoires éprouvés dans les deux corpus ;
|
||||
2. **contrats documentaires locaux** : les deux projets utilisent un registre de responsabilités de fichiers/familles qui peut devenir un pattern facultatif de la fondation ;
|
||||
3. **façade Rust et export completeness** : les deux projets partagent pratiquement le même audit spécialisé, alors que PGR n'en fournit pas encore de version réutilisable ;
|
||||
4. **Tauri** : le framework est utilisé indépendamment et de manière répétée dans les deux corpus, ce qui fournit enfin une base réelle pour activer la famille framework `700` sans généraliser Vite/Web/JNI au-delà des preuves disponibles.
|
||||
|
||||
Les audits composites, le Web autonome, WASM, JNI, règles serveur, distribution Games et frontières métier KSP restent différés ou locaux.
|
||||
|
||||
## REPLAN alpha.4 — lifecycle inter-release et horizon
|
||||
|
||||
La gate `alpha.3.fix.1` a validé son correctif local. Une revue séparée du plan, de `ROADMAP.md` et des historiques de conception PGR `0.0.1` à `0.0.4` a ensuite confirmé un besoin général non couvert explicitement par le forecast initial : PGR sait piloter une release active, mais n'assigne pas encore assez strictement **où/quand sa fermeture et sa transition sont préparées**, ni **quand l'horizon des versions futures doit être rediscuté**.
|
||||
|
||||
Les historiques montrent que plusieurs briques avaient déjà été décidées séparément — moment du `CHANGELOG`, `ROADMAP`, prompt suivant, `REPLAN`, abandon/supersession, continuation inter-session, handoff et distinction `rel.001`/`publish.001`. Le problème n'est donc pas d'inventer un second workflow, mais de les relier dans le contrat du plan et d'éviter qu'elles restent implicites.
|
||||
|
||||
Ce constat déclenche le point de décision `REPLAN` prévu par `alpha.1`. Aucun travail antérieur n'est invalidé. Les anciennes tranches `alpha.4` à `alpha.6` sont décalées d'un numéro et restent dans le scope.
|
||||
|
||||
## Trajectoire prévisionnelle
|
||||
|
||||
### alpha.1 — audit indépendant, étude et plan
|
||||
|
||||
Vérifier la stable PGR, son rapport post-tag et les deux archives externes ; exécuter les audits statiques disponibles ; classifier les écarts ; créer l'étude et le présent plan. Aucun changement normatif, script réutilisable, profil framework ou skeleton nouveau dans cette tranche.
|
||||
|
||||
### alpha.2 — contrat générique des prompts de démarrage
|
||||
|
||||
Renforcer l'owner `210-WORKFLOW.md` pour les prompts versionnés sans recopier les règles locales KSP/Games. Fournir une spécification réutilisable couvrant au minimum : baseline autoritaire, ordre de lecture, état déjà validé, mission/résultat, scope/hors-scope, décisions gelées/ouvertes, première gate, trajectoire prévisionnelle et validations.
|
||||
|
||||
Le template manuel `003-NEW_SESSION_PROMPT.md` reste distinct : il sert au court message remis après publication, alors que cette tranche porte le prompt versionné du projet.
|
||||
|
||||
### alpha.3 — pattern de contrats de fichiers/familles
|
||||
|
||||
Étendre `300-DOCUMENTATION.md` et la fondation `001` uniquement si nécessaire pour décrire un registre local facultatif des fichiers ou familles dont le rôle et les règles de modification méritent d'être explicites. Fournir une spécification/template documentaire courte plutôt qu'un catalogue universel.
|
||||
|
||||
Le pattern ne doit pas imposer `FILE_CONTRACTS.md` à un petit projet, ni recopier les rôles déjà possédés par PGR. Le correctif `alpha.3.fix.1` a en outre renforcé l'audit des tables Markdown fenced sans modifier ce scope fonctionnel.
|
||||
|
||||
### alpha.4 — REPLAN : clôture, transition et revue d'horizon
|
||||
|
||||
Formaliser le lifecycle inter-release qui manquait au plan initial :
|
||||
|
||||
- imposer à un plan de release suffisamment complexe d'attribuer noir sur blanc les responsabilités de clôture/transition ;
|
||||
- définir la revue d'horizon sans imposer un nombre artificiel de versions futures ;
|
||||
- expliciter le passage `idea/study → décision durable → roadmap/plan` ;
|
||||
- confirmer qu'une discussion stratégique peut vivre dans une session séparée sans changer `VERSION` ;
|
||||
- rendre spontané le message manuel de reprise lorsque la prochaine cible est connue ;
|
||||
- permettre la livraison `history courant + delta suivant` dans une même réponse lorsque la suite est déterministe, tout en maintenant deux archives et l'ordre commit/apply ;
|
||||
- fournir un pattern réutilisable de plan de release pour l'adoption future dans KSP, Games et d'autres projets.
|
||||
|
||||
Cette tranche ne commence pas l'audit Rust ni le profil Tauri.
|
||||
|
||||
### alpha.5 — audit Rust de façade/export completeness
|
||||
|
||||
Extraire le noyau réellement commun de `audit_rust_export_completeness.py`, l'aligner avec `510-RUST_CARGO.md`, documenter son caractère facultatif et ses limites, et ajouter des tests positifs/négatifs.
|
||||
|
||||
La réconciliation a révélé que le script historique ne découvrait que `crates/*/Cargo.toml` : il couvrait les `22` packages KSP mais aucun des `23` packages Games imbriqués sous des sous-familles. La variante PGR corrige donc la découverte récursive et distingue aussi les cibles `lib`/`bin` d'un même package pour ne pas confondre plusieurs crates Rust compilées séparément.
|
||||
|
||||
La première livraison `alpha.5` a ensuite révélé un second défaut de scope pendant la revue opérateur : elle ne détectait que les chemins internes longs tels que `crate::module::Item`, alors que le contrat attendu impose `crate::Item` pour **toute référence intra-crate à un item partagé**, y compris un nom nu dans son module propriétaire. La gate mécanique était verte mais l'acceptation fonctionnelle est donc `FAIL`; `alpha.5.fix.1` corrige ce blind spot sans commencer Tauri.
|
||||
|
||||
Mesure `alpha.5.fix.1` en `--report-only --summary-only` : KSP `0.3.16` = `1525` lignes candidates `RUST-IMPORT-201` sur `22` packages ; Games `0.3.5` = `181` lignes candidates sur `23` packages (`2 RUST-API-201`, `179 RUST-IMPORT-201`). Ces nombres forment un inventaire d'adoption future, pas une non-conformité rétroactive des baselines.
|
||||
|
||||
Cette tranche ne réimporte pas `audit_rust_general_rules.py` en bloc et ne réintroduit pas le diagnostic historique de résolution `crate::X` déjà possédé par le compilateur. Toute autre règle déjà possédée par Rustfmt, Clippy, le compilateur ou les audits PGR existants reste chez son owner actuel.
|
||||
|
||||
### alpha.6 — premier profil framework : Tauri
|
||||
|
||||
La preuve commune est confirmée : `6` applications Tauri KSP et `2` applications Tauri Games partagent Tauri 2, un host Rust/Cargo, `tauri-build`, `tauri.conf.json`, des capability files, des hooks frontend et un `frontendDist`. Les valeurs applicatives divergent suffisamment pour exclure toute copie de ports, fenêtres, CSP, bundles, plugins ou commandes frontend particulières.
|
||||
|
||||
La première livraison active `700-FRAMEWORKS.md` et `710-TAURI.md`, mais la gate opérateur est `FAIL` pour deux raisons : le contrôle Python ciblé du delta contient une chaîne multilignes invalide et la revue fonctionnelle exige de mieux distinguer le profil Tauri universel des conventions d'instanciation des projets contrôlés. `alpha.6.fix.1` corrige donc le gate et explicite que le host Tauri hérite intégralement des règles Rust sélectionnées, que WASM reste normalement une unité séparée et que l'ajout manuel de plugins à partir de leur documentation officielle est une stratégie valide.
|
||||
|
||||
Les préférences récurrentes de l'organisation — frontend sous `frontend/`, Vite, TypeScript, Sass, Bootstrap et contrôle explicite des dépendances — sont consignées comme **candidat de skeleton**, pas comme invariants de `710-TAURI.md`. Un projet imposé de l'extérieur peut conserver une structure différente via ses règles project-specific.
|
||||
|
||||
La politique `gen/` n'est pas généralisée : les sorties purement reproductibles restent générées, mais les projets mobiles modifiés intentionnellement doivent être classifiés selon leur rôle réel. L'échec du POC Tauri mobile Games ne constitue pas un rejet général de Tauri Android/iOS pour les autres produits.
|
||||
|
||||
La gate `alpha.6.fix.1` révèle un second défaut de quoting Python (`l'extérieur` dans une chaîne simple) et la revue opérateur demande une seconde passe sur les règles réelles KSP/Games. `alpha.6.fix.2` corrige le gate et renforce la convention des projets contrôlés avec le layout direct sans `src-tauri/`, `lib.rs`/`main.rs`/`tauri.rs`, TS-RS lorsque le frontend TypeScript partage des DTO Rust, modules de fenêtres/responsabilités et préférence pour l'intégration explicite des plugins. Les règles Rust générales et la nomenclature des crates restent volontairement dans `alpha.7/alpha.8`.
|
||||
|
||||
La gate mécanique de `alpha.6.fix.2` est propre, mais la revue fonctionnelle révèle une troisième divergence : KSP et Games avaient tous deux converti la réduction du churn de version en préférence pour l'absence de `tauri.conf.json > version` et la stagnation de `package.json`. Cette solution ne doit pas devenir une règle PGR. `alpha.6.fix.3` restaure la classification générale `CANONICAL` / `MIRROR-EXACT` / `MIRROR-STABLE` et définit pour Tauri/frontend une synchronisation de jalon `X.Y.Z` par défaut, sans bump à chaque tranche.
|
||||
|
||||
Comme `fix.3` atteint le seuil de revue obligatoire des correctifs, le plan est réexaminé : résultat `CONTINUE`. Le scope Tauri reste cohérent et borné après cette correction ; les chantiers Rust `alpha.7`/`alpha.8` et la décision de skeleton `alpha.9` restent séparés et ne sont pas absorbés par le fix.
|
||||
|
||||
### alpha.7 — profil Rust strict, chemins et nomenclature explicite
|
||||
|
||||
La réconciliation des règles versionnées KSP/Games retient KSP comme référence stricte et Games comme contrôle de généralisation. Pour une nouvelle baseline contrôlée, `510-RUST_CARGO.md` impose désormais Rust 2024, réserve `use` aux traits réellement nécessaires, exige les chemins publics explicites les plus courts pour les autres symboles, les réexports internes `self::`, la façade crate-root et `crate::Item`, et conserve le contrôle de flux explicite sans `unwrap`, `expect` ni `?` en production.
|
||||
|
||||
La nomenclature des crates devient également explicite : préfixe projet/abréviation obligatoire ; responsabilité puis rôle/cible lisibles lorsque ce classificateur apporte une information réelle. La forme recommandée est `<project>-<responsibility>-<role-or-target>` sans figer les vocabulaires KSP/Games ni imposer de renommage rétroactif. Les projets externes ou historiquement contraints peuvent documenter un override borné.
|
||||
|
||||
Le skeleton Rust/Cargo et le guide de manifest reflètent ces choix. Aucun gros audit composite n'est importé ; le marqueur KSP spécifique des trait imports n'est pas généralisé et les contrôles déjà possédés par Clippy, rustc ou l'audit de façade restent chez leur owner.
|
||||
|
||||
La gate mécanique `alpha.7` est propre, mais la revue fonctionnelle post-gate montre que cette première matérialisation ne donnait pas encore de contrat architectural aux suffixes. `alpha.7.fix.1` complète donc la tranche sans la replanifier : `-api` devient un vrai contrat extensible/passif et n'est jamais créé par symétrie ; `-lib` identifie l'implémentation réutilisable ; les exécutables sont des packages distincts et minces par défaut ; `tracing` et un owner de logging commun sont fortement recommandés dans les workspaces multi-runtime. L'ancienne préférence KSP pour un worker mixte lib/bin n'est pas généralisée. Tauri reste l'exception framework actuelle et impose des noms de targets lib/bin réellement distincts.
|
||||
|
||||
### alpha.8 — formatage Rust structurel et audits monotâches
|
||||
|
||||
La réconciliation des anciens audits composites KSP/Games attribue désormais chaque propriété à un owner précis. Rustfmt reste propriétaire du formatage et du tri qu'il sait réellement réécrire dans un bloc contigu. Les audits PGR existants conservent `blank_lines` et `const_blocks`; quatre extractions monotâches complètent le profil : `item_spacing`, `module_order`, `trait_import_blocks` et `reexport_blocks`.
|
||||
|
||||
La mesure sur l'ensemble des sources `crates/**/*.rs` est propre pour les quatre nouveaux audits dans KSP `0.3.16` (`603` fichiers) et Games `0.3.5` (`87` fichiers). `blank_lines` est également propre sur ces corpus. `const_blocks` reste explicitement opt-in : son exécution globale remonte `18` signaux KSP, dont des tables/schémas à ordre intentionnel, contre `0` Games.
|
||||
|
||||
Le profil strict des nouvelles baselines contrôlées retient donc les règles mécaniques de lignes vides, séparation exacte des items distincts, modules production/tests, bloc de traits et blocs de réexports. PGR n'automatise pas un ordre global `enum → struct → impl → fn`, ni un tri visible/privé lorsque la structure métier peut être plus informative. Aucun parser Rust général ni audit composite n'est introduit.
|
||||
|
||||
### alpha.9 — décision de skeleton Tauri pour projets contrôlés — DEFER
|
||||
|
||||
La revue de readiness confirme que le host est suffisamment cadré : `510-RUST_CARGO.md` possède les règles Rust et le packaging, `710-TAURI.md` possède le layout contrôlé, l'exception `lib + bin`, `tauri.rs`, TS-RS à la frontière host/frontend, les plugins/capabilities, les versions produit et les gates d'orchestration Tauri. Les `8` hosts observés confirment également le layout direct sans `src-tauri/`, `frontend/`, Vite et TypeScript.
|
||||
|
||||
En revanche, PGR ne possède encore aucun profil Web/Vite/TypeScript/Sass. Le candidat organisationnel Vite + TypeScript + Sass + Bootstrap ne peut donc pas être instancié sans que le skeleton devienne de fait propriétaire de règles frontend, ce qui contredirait `220-SKELETONS.md` et le modèle de profils. La décision `alpha.9` est donc `DEFER` : aucun skeleton Tauri `003` n'est créé dans `0.0.5`.
|
||||
|
||||
Le futur skeleton reste un candidat explicite et devra au minimum composer la fondation de gouvernance, le skeleton Rust/Cargo, le profil Tauri et les owners Web alors disponibles. Il pourra ensuite sélectionner le layout direct, `frontend/`, Vite + TypeScript + Sass, Bootstrap comme baseline de présentation lorsque pertinente, TS-RS pour les DTO Rust partagés, intégration explicite des plugins/capabilities et séparation de WASM par défaut. Ces choix ne deviennent pas des règles Web dans la présente release.
|
||||
|
||||
La condition de sortie du `DEFER` est la matérialisation d'owners Web suffisants pour posséder la structure des sources frontend, la chaîne Vite/TypeScript, Sass/CSS, les artefacts de build et leur validation sans duplication normative dans le skeleton. La décision détaillée est enregistrée dans `docs/studies/002-TAURI_SKELETON_DECISION.md`.
|
||||
|
||||
### beta.1 — réconciliation intégrée
|
||||
|
||||
Rejouer la matrice de l'étude sur l'état PGR obtenu. Vérifier : owner unique, navigation, absence de règles KSP/Games aspirées par accident, caractère facultatif des patterns/audits concernés, cohérence des skeletons et domaines encore différés.
|
||||
|
||||
La réconciliation intégrée confirme que les owners créés ou renforcés par `0.0.5` restent bornés à leur responsabilité : prompt versionné, contrats documentaires facultatifs, lifecycle inter-release, profil/audits Rust stricts et profil Tauri. Les architectures métier KSP/Games, Android/JNI spécifique, Web autonome et distribution restent hors du noyau central tant qu'un owner réutilisable n'est pas justifié.
|
||||
|
||||
Le `DEFER` du skeleton Tauri contrôlé est suffisamment décidé pour devenir une trajectoire explicitement différée dans `ROADMAP.md`, sans numéro de release réservé. Les trois candidats plus larges de revue d'horizon restent volontairement hors de la roadmap engagée tant qu'une décision macro n'existe pas.
|
||||
|
||||
La mission `0.1.0` reste suffisamment connue : `prompts/006-V0_1_0_START_PROMPT.md` est préparé dans cette tranche comme prompt candidat de reprise. Il exige l'audit complet de la stable `0.0.5`, la consolidation d'un plan `0.1.0-alpha.1` proportionné et une revue d'horizon avant fermeture ; il ne transforme pas le skeleton Tauri différé en obligation de `0.1.0`.
|
||||
|
||||
Cette tranche réconcilie ainsi la documentation durable et confirme que le présent plan possède un contrat de fermeture exécutable avant `rc.1`.
|
||||
|
||||
La gate opérateur de `beta.1` est `PASS` : `48/48` tests Python, les trois audits Markdown, le contrôle d'intégration ciblé et les contrôles Git sont propres. La phase beta est donc fermée sans correctif.
|
||||
|
||||
### rc.1 — scope gelé et gate candidate
|
||||
|
||||
La RC gèle le scope fonctionnel de `0.0.5` sur les capacités déjà validées : contrats de reprise/lifecycle, profil Rust strict et ses audits monotâches, profil Tauri 2, réconciliation KSP/Games et décision `DEFER` du skeleton Tauri contrôlé. Aucun nouvel owner, skeleton, template, script d'audit ou domaine technique n'entre dans la candidate.
|
||||
|
||||
`CHANGELOG.md` reçoit l'entrée candidate `0.0.5` orientée utilisateurs. `ROADMAP.md` reste inchangé : `0.0.5` demeure en cours jusqu'à la promotion stable, `0.1.0` reste la prochaine release engagée et le skeleton Tauri reste `(d)` sans numéro de release. `prompts/006-V0_1_0_START_PROMPT.md` est vérifié comme prompt candidat de reprise et n'est pas modifié si son contrat est déjà correct.
|
||||
|
||||
La gate RC rejoue la suite Python complète, les audits Markdown et un contrôle d'intégrité historique de toutes les tranches `0.0.5`. Elle vérifie également la présence des owners/audits effectivement livrés et l'absence de skeleton Tauri `003`. Les validations lexicales déjà couvertes par la suite de tests ne sont pas dupliquées par un nouvel audit composite.
|
||||
|
||||
Aucune version postérieure à `0.1.0` n'est inventée à cette étape.
|
||||
|
||||
La gate opérateur de `rc.1` est `PASS` : `48/48` tests Python, les trois audits Markdown, le contrôle d'intégrité des `16` histories antérieurs et les contrôles Git sont propres. Le scope fonctionnel est donc gelé pour la promotion stable.
|
||||
|
||||
### stable — 0.0.5
|
||||
|
||||
Promouvoir mécaniquement la RC validée : synchroniser `VERSION`, README/index, `ROADMAP.md`, `CHANGELOG.md` et statut du présent plan sans ajouter de nouveau besoin commun. Après history PASS, commit et tag `v0.0.5`, vérifier séparément l'archive publiée.
|
||||
|
||||
La vérification post-tag doit produire, si le mécanisme reste retenu, `pgr-0.0.5-publish.001-report.md` extérieur au tag. Le message manuel final doit alors indiquer spontanément à l'opérateur de fournir l'archive taggée et ce rapport avec le prompt `006` lors de la session `0.1.0`.
|
||||
|
||||
La promotion `rel.001` clôt le présent plan sans modifier le scope fonctionnel : `VERSION = 0.0.5`, `ROADMAP.md` marque `0.0.5` terminé, le changelog perd son marqueur `candidate`, les index décrivent le plan comme historique et le prompt `006` reste conditionnel à la publication effective du tag et à son rapport post-tag PASS.
|
||||
|
||||
La gate opérateur de `rel.001` est toutefois `FAIL` pour un défaut strictement local à sa commande de validation : l'assertion Python qui cherchait le heading `## 0.0.5` a été livrée avec une chaîne simple coupée par un retour à la ligne et provoque `SyntaxError: unterminated string literal`. Les audits Markdown et les contrôles Git exécutés ensuite sont propres ; aucun défaut du contenu stable n'est établi. `rel.001.fix.1` corrige uniquement cette preuve de clôture, conserve `VERSION = 0.0.5` et ne rouvre pas le scope fonctionnel.
|
||||
|
||||
## Clôture et transition
|
||||
|
||||
Le présent plan attribue dès maintenant les responsabilités de fermeture :
|
||||
|
||||
- la documentation directement liée à chaque capacité évolue dans sa tranche ;
|
||||
- `beta.1` réalise la réconciliation durable globale et prépare le prompt suivant si sa mission est connue ;
|
||||
- `rc.1` porte le scope freeze, l'entrée `CHANGELOG` candidate, la vérification `ROADMAP` et le prompt suivant candidat ;
|
||||
- `rel.001`/stable finalise `CHANGELOG`, marque `0.0.5` terminée dans `ROADMAP`, ferme le présent plan et effectue le promotion gate pré-tag ;
|
||||
- `publish.001` vérifie l'archive réellement produite après le tag et fournit la preuve externe requise par la reprise suivante ;
|
||||
- aucune de ces opérations ne doit être repoussée implicitement à la session `0.1.0`.
|
||||
|
||||
## Revue d'horizon
|
||||
|
||||
Pour PGR, la prochaine release engagée est `0.1.0 — première baseline réutilisable`. La trajectoire au-delà n'est pas suffisamment décidée et reste volontairement ouverte ; ce n'est pas un défaut de roadmap.
|
||||
|
||||
`0.0.5` ne doit donc pas inventer `0.1.1`, `0.2.0` ou un catalogue de versions futures. Le plan de `0.1.0-alpha.1` devra en revanche identifier un moment de revue d'horizon avant sa fermeture, une fois la baseline réutilisable suffisamment concrète pour juger la suite. Cette revue pourra se tenir dans une session stratégique séparée sans modifier `VERSION`.
|
||||
|
||||
Ses sorties autorisées seront : étendre la roadmap avec des objectifs réellement décidés, maintenir l'horizon ouvert avec un prochain déclencheur, différer/mettre en pause la trajectoire ou constater qu'un objectif macro est accompli.
|
||||
|
||||
Trois **candidats d'horizon**, sans numéro de release réservé ni engagement de réalisation, sont maintenant identifiés pour cette revue :
|
||||
|
||||
1. maturation de profils techniques composables par langage, framework, target/plateforme et préoccupation transverse — par exemple observability/logging, Web/TypeScript/Vite/Sass, Android, WASM, networking ou persistence — toujours à partir de corpus réels avant normalisation ;
|
||||
2. profil de projet documentaire/spécification, avec `saselang-bible` comme corpus pilote possible pour tester gouvernance normative, terminologie, décisions, exemples, compatibilité et traduction lorsque la documentation est elle-même le produit ;
|
||||
3. audit du noyau PGR hors développement logiciel afin d'identifier ce qui est réellement universel et ce qui doit rester dans un profil `software`, sans inventer les règles métier de domaines spécialisés.
|
||||
|
||||
Ces sujets restent au stade `horizon candidat`. Ils ne deviennent `Study`, `ROADMAP` ou plan de release qu'après décision explicite selon `300-DOCUMENTATION.md`.
|
||||
|
||||
## Points de décision
|
||||
|
||||
Un REPLAN est requis si :
|
||||
|
||||
- le contrat de prompt devient une copie exhaustive des règles plutôt qu'un artefact de reprise ;
|
||||
- le pattern de contrats de fichiers ajoute plus de cérémonie qu'il n'en retire ;
|
||||
- le lifecycle de clôture impose des documents ou versions futures sans valeur opérationnelle ;
|
||||
- la revue d'horizon devient un quota de versions à prévoir plutôt qu'un mécanisme de décision ;
|
||||
- l'audit de façade Rust ne peut pas être séparé proprement des conventions strictes KSP/Games ;
|
||||
- le profil Tauri universel absorbe des choix de skeleton/frontend qui devraient rester project-specific ou appartenir à un owner Web ;
|
||||
- la réconciliation Rust stricte ne peut pas être séparée en owners fiables et audits monotâches ;
|
||||
- le skeleton Tauri n'apporte pas de décisions réutilisables au-delà du profil framework et des conventions explicites de projets contrôlés ;
|
||||
- une autre divergence des corpus apparaît comme un besoin commun critique non couvert par ce plan.
|
||||
|
||||
## Stratégie de validation
|
||||
|
||||
Les tranches documentaires rejouent les trois audits Markdown et la suite Python PGR. Toute modification d'un script ajoute ou adapte des tests ciblés avant la suite globale. Les templates/configurations structurées sont parsés ou exercés avec l'outil le plus fiable disponible.
|
||||
|
||||
PGR ne compile pas KSP ou Games comme gate de sa propre release : ces projets servent de corpus de pression. Une validation croisée MAY exécuter leurs audits statiques sur leurs archives fournies lorsque cela vérifie une propriété précise, mais ne remplace jamais leurs propres gates opérateur.
|
||||
|
||||
La toolchain Cargo n'étant pas disponible dans l'environnement de préparation de `alpha.1`, aucune preuve Cargo externe n'est revendiquée pour cette tranche. La gate PGR reste documentaire et structurelle.
|
||||
@@ -1,5 +1,5 @@
|
||||
<!-- file: docs/rules/000-README.md -->
|
||||
<!-- version: 6 -->
|
||||
<!-- version: 13 -->
|
||||
|
||||
# Index des règles PGR
|
||||
|
||||
@@ -12,9 +12,19 @@ Les règles générales actuellement nécessaires restent dans `RULES.md`. La fa
|
||||
## Familles actives
|
||||
|
||||
- [`200-GOVERNANCE.md`](200-GOVERNANCE.md) — versioning, lifecycle des releases, fixes, cadrage, replan et abandon/supersession.
|
||||
- [`210-WORKFLOW.md`](210-WORKFLOW.md) — contrats des artefacts workflow, ordre delta/history/commit, reprise et baselines de release.
|
||||
- [`210-WORKFLOW.md`](210-WORKFLOW.md) — contrats des artefacts workflow, ordre delta/history/commit, prompts versionnés, reprise et baselines de release.
|
||||
- [`220-SKELETONS.md`](220-SKELETONS.md) — contrat commun des skeleton specifications, sélection des profils/templates, décisions, overrides et validation.
|
||||
- [`300-DOCUMENTATION.md`](300-DOCUMENTATION.md) — rôles des documents, taxonomie, révisions internes, documents vivants et snapshots historiques.
|
||||
- [`400-VALIDATION.md`](400-VALIDATION.md) — matrice de validation, preuves proportionnelles, tests/audits/diagnostics, doubles de test et autorité du gate opérateur.
|
||||
- [`500-LANGUAGES.md`](500-LANGUAGES.md) — contrat commun des profils langage/écosystème et de leurs spécialisations de build.
|
||||
- [`510-RUST_CARGO.md`](510-RUST_CARGO.md) — profil Rust/Cargo et règles réutilisables propres à cet écosystème.
|
||||
- [`520-JAVA_MAVEN_GRADLE.md`](520-JAVA_MAVEN_GRADLE.md) — profil Java et spécialisations de build Maven/Gradle.
|
||||
- [`600-PLATFORMS.md`](600-PLATFORMS.md) — contrat commun des profils plateforme.
|
||||
- [`610-ANDROID.md`](610-ANDROID.md) — profil plateforme Android et règles réutilisables de compatibilité, packaging et validation.
|
||||
- [`700-FRAMEWORKS.md`](700-FRAMEWORKS.md) — contrat commun des profils framework et de leur composition avec les owners déjà applicables.
|
||||
- [`710-TAURI.md`](710-TAURI.md) — profil Tauri 2 et règles réutilisables d'orchestration native/frontend, sécurité et validation.
|
||||
|
||||
Le modèle transversal d'ownership, d'applicabilité et de composition est décrit dans [`../architecture/003-RULE_PROFILE_MODEL.md`](../architecture/003-RULE_PROFILE_MODEL.md).
|
||||
|
||||
## Organisation prévue
|
||||
|
||||
@@ -25,7 +35,7 @@ Les autres familles seront créées uniquement lorsqu'elles disposent d'un conte
|
||||
200 — governance
|
||||
300 — documentation
|
||||
400 — validation
|
||||
500 — languages
|
||||
500 — languages / ecosystems
|
||||
600 — platforms
|
||||
700 — frameworks
|
||||
800 — architecture
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!-- file: docs/rules/200-GOVERNANCE.md -->
|
||||
<!-- version: 2 -->
|
||||
<!-- version: 4 -->
|
||||
|
||||
# Governance rules
|
||||
|
||||
@@ -38,9 +38,20 @@ Lorsqu'un dépôt utilise le fichier racine `VERSION`, ce fichier :
|
||||
|
||||
Un manifeste technique MAY refléter exactement `VERSION` lorsque son propre contrat l'exige. Un autre mécanisme de versioning MAY rester indépendant lorsqu'il possède une sémantique différente, par exemple un `versionCode` Android, une révision de document ou une version de protocole.
|
||||
|
||||
PGR MUST NOT imposer une égalité globale entre tous les champs contenant un numéro de version.
|
||||
PGR MUST NOT imposer une égalité globale entre tous les champs contenant un numéro de version. Pour éviter à la fois les divergences silencieuses et le churn mécanique, chaque valeur de version durable SHOULD être classée selon son rôle réel. Les catégories réutilisables sont notamment :
|
||||
|
||||
Un champ de version qui n'est ni requis par l'écosystème ni utile au projet SHOULD être omis plutôt que maintenu comme duplication décorative.
|
||||
- `CANONICAL` — identité SemVer exacte de l'unité de release, normalement portée par `VERSION` ;
|
||||
- `MIRROR-EXACT` — miroir technique qui suit exactement `VERSION`, prereleases et fixes compris ;
|
||||
- `MIRROR-STABLE` — miroir du jalon produit `X.Y.Z` ciblé, stable pendant `X.Y.Z-alpha.*`, `beta.*`, `rc.*` et leurs fixes ;
|
||||
- `INDEPENDENT-COUNTER` — compteur technique monotone possédant sa propre sémantique ;
|
||||
- `INDEPENDENT-SCHEMA` — version de protocole, format ou schéma indépendante du produit ;
|
||||
- `DOCUMENT-REVISION` — révision interne d'un document ou artefact documentaire.
|
||||
|
||||
Seul un `MIRROR-EXACT` est normalement modifié à chaque changement de `VERSION`. Un `MIRROR-STABLE` SHOULD être fixé ou vérifié lorsque la cible `X.Y.Z` est ouverte, puis ne pas être réécrit uniquement parce qu'une tranche passe de `alpha.N` à `alpha.N+1`, à un `.fix.N`, à une beta ou à une RC. La promotion stable vérifie qu'il représente toujours la release publiée.
|
||||
|
||||
Lorsqu'une prerelease est réellement distribuée comme artefact installable distinct et que son écosystème exige une identité de package propre, le champ concerné peut devenir `MIRROR-EXACT` ou suivre des jalons explicitement définis. Cette décision appartient au plan de versioning/packaging du projet ; elle ne doit pas résulter d'une égalité globale implicite.
|
||||
|
||||
Un champ de version qui n'est ni requis par l'écosystème ni utile au projet SHOULD être omis plutôt que maintenu comme duplication décorative. Réciproquement, PGR MUST NOT imposer la suppression d'un champ utile uniquement pour éviter de le modifier à chaque prerelease : il faut d'abord lui attribuer la bonne classe de synchronisation.
|
||||
|
||||
## Schéma SemVer PGR
|
||||
|
||||
@@ -89,7 +100,9 @@ Cette convention pré-1.0 complète SemVer sans modifier sa syntaxe.
|
||||
- les études ou décisions encore ouvertes ;
|
||||
- les principaux risques et contraintes ;
|
||||
- la stratégie de validation et les smokes nécessaires ;
|
||||
- le dimensionnement des tranches.
|
||||
- le dimensionnement des tranches ;
|
||||
- lorsque la release possède un plan dédié, les responsabilités de clôture et de transition vers la suite ;
|
||||
- l'état de l'horizon de roadmap et, lorsqu'il devient court ou incertain, le moment prévu pour le réexaminer.
|
||||
|
||||
Une tranche cible généralement un volume de travail cohérent et vérifiable. Une durée de l'ordre de 15 à 30 minutes MAY servir d'heuristique de découpage, mais MUST NOT être traitée comme une deadline ou un quota.
|
||||
|
||||
@@ -145,6 +158,8 @@ ABANDON
|
||||
|
||||
Une interruption de conversation ou de session MUST NOT créer artificiellement une nouvelle version. Le même état de version et de tranche continue tant que le scope reste valable.
|
||||
|
||||
Une revue stratégique de versions futures MAY également se tenir dans une session séparée. Cette frontière de conversation n'est ni une release, ni une phase SemVer, ni une raison de modifier `VERSION`. Si la discussion produit une décision durable à matérialiser dans le dépôt, cette modification passe ensuite par une tranche gouvernée appropriée.
|
||||
|
||||
## Abandon et supersession
|
||||
|
||||
Une version ou prerelease commencée n'est pas forcée vers stable uniquement pour préserver une séquence esthétique.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!-- file: docs/rules/210-WORKFLOW.md -->
|
||||
<!-- version: 2 -->
|
||||
<!-- version: 5 -->
|
||||
|
||||
# Workflow artifact rules
|
||||
|
||||
@@ -49,13 +49,25 @@ docs/plans/
|
||||
|
||||
Un plan :
|
||||
|
||||
- SHOULD être créé pendant le cadrage lorsque plusieurs tranches ou décisions doivent être coordonnées ;
|
||||
- MAY évoluer lorsque le plan change réellement ;
|
||||
- SHOULD être créé ou consolidé pendant `alpha.1` lorsque plusieurs tranches ou décisions doivent être coordonnées ;
|
||||
- MAY évoluer lorsque la réalité invalide le forecast ;
|
||||
- SHOULD NOT être modifié à chaque tranche uniquement pour recopier l'avancement ;
|
||||
- MUST distinguer prévision et état réellement observé ;
|
||||
- MUST NOT remplacer ROADMAP, delta ou history.
|
||||
|
||||
Un changement substantiel du plan MAY être porté par une tranche REPLAN conformément aux règles de gouvernance.
|
||||
Lorsqu'un plan existe pour une release gouvernée par le workflow PGR, il MUST aussi rendre explicites, de manière proportionnée :
|
||||
|
||||
- la mission, le scope et le hors-scope actuellement applicables ;
|
||||
- la stratégie de validation et les gates qui conditionnent réellement la fermeture ;
|
||||
- la trajectoire prévisionnelle des responsabilités, sans transformer le forecast en promesse immuable ;
|
||||
- une section ou un bloc **clôture et transition** indiquant où seront traités la réconciliation documentaire durable, le `CHANGELOG`, la mise à jour de `ROADMAP`, le prompt ou handoff de reprise, la fermeture du plan et la promotion/publication ;
|
||||
- l'état de la **revue d'horizon** : soit elle n'est pas nécessaire parce que la roadmap possède déjà un horizon suffisant, soit son déclencheur et le moment où elle sera instruite sont identifiés.
|
||||
|
||||
Le plan MUST NOT inventer une version future uniquement pour remplir la rubrique de transition. Lorsque la cible suivante n'est pas suffisamment décidée, il l'indique explicitement et planifie une revue d'horizon ou un handoff approprié plutôt que de fabriquer un numéro, une mission ou un prompt.
|
||||
|
||||
Un changement substantiel du plan MAY être porté par une tranche REPLAN conformément aux règles de gouvernance. Le corps du plan reste l'état de pilotage actuellement applicable ; les deltas et histories conservent le détail historique des changements. PGR n'impose pas un journal `Revisions` alimenté à chaque tranche.
|
||||
|
||||
À la clôture `completed`, `abandoned` ou `superseded`, le plan devient principalement historique. Il ne doit plus être réécrit pour refléter silencieusement la connaissance acquise dans des releases ultérieures.
|
||||
|
||||
## Delta
|
||||
|
||||
@@ -137,6 +149,18 @@ L'archive history contient uniquement le ou les fichiers history à appliquer po
|
||||
|
||||
Delta et history MUST rester des livraisons séparées afin que la preuve observée ne soit pas confondue avec l'intention prospective.
|
||||
|
||||
Lorsque la gate courante est `PASS` et que la tranche suivante est déjà déterminée par le plan sans décision ouverte, le générateur SHOULD préparer et remettre dans la même réponse :
|
||||
|
||||
```text
|
||||
archive history de la tranche courante
|
||||
+
|
||||
archive delta de la tranche suivante
|
||||
```
|
||||
|
||||
Les deux archives restent séparées. Cette optimisation de flux n'autorise jamais l'application du delta suivant avant l'application du history courant et le commit complet de la tranche.
|
||||
|
||||
Le delta suivant SHOULD NOT être anticipé lorsqu'une décision opérateur, un REPLAN non résolu, un abandon/supersession, une preuve externe post-tag ou toute autre dépendance peut encore modifier sa baseline ou son scope.
|
||||
|
||||
## Commit de tranche
|
||||
|
||||
Le commit d'une tranche doit représenter l'état complet de cette tranche, y compris son history.
|
||||
@@ -173,9 +197,9 @@ S'il existe :
|
||||
|
||||
Un manifest ne doit pas exister vide uniquement pour satisfaire une structure théorique.
|
||||
|
||||
## Prompt de démarrage
|
||||
## Prompt de démarrage versionné
|
||||
|
||||
Un prompt de démarrage transmet la mission et le contexte nécessaires à une nouvelle version ou à une reprise explicitement prévue.
|
||||
Un prompt de démarrage versionné transmet le contrat de reprise nécessaire pour ouvrir une nouvelle version depuis une baseline autoritaire sans reconstruire implicitement l'état du projet depuis une conversation antérieure, un workspace non fourni ou une mémoire informelle.
|
||||
|
||||
Le chemin canonique est :
|
||||
|
||||
@@ -185,17 +209,55 @@ prompts/NNN-VX_Y_Z_START_PROMPT.md
|
||||
|
||||
`NNN` est monotone à l'échelle du dépôt.
|
||||
|
||||
Le prompt :
|
||||
Le prompt MUST rester un artefact de reprise et de cadrage. Il référence les règles, plans, histories, handoffs ou documents techniques qui possèdent déjà le détail ; il MUST NOT les recopier exhaustivement ni devenir une seconde source normative concurrente.
|
||||
|
||||
- doit transmettre la mission, la baseline et les règles de reprise utiles ;
|
||||
- MUST NOT devenir une copie exhaustive du plan ou de l'historique ;
|
||||
- SHOULD être finalisé à la clôture stable de la version précédente lorsqu'il prépare la version suivante.
|
||||
### Contrat minimal
|
||||
|
||||
Une interruption au milieu d'une version MUST NOT produire artificiellement le prompt de la version suivante.
|
||||
Le prompt MUST couvrir, sous des titres adaptés au projet plutôt que selon une forme imposée, les éléments suivants lorsqu'ils sont applicables :
|
||||
|
||||
1. **baseline autoritaire et cible** — identifier la source exacte depuis laquelle la version doit être ouverte, la version cible et la première tranche attendue ; préciser les limites matérielles de cette source, par exemple l'absence normale de `.git` dans une archive de tag ;
|
||||
2. **ordre de lecture** — nommer les points d'entrée normatifs, plans, histories, handoffs ou documents de subsystem qui doivent être lus avant de modifier le projet lorsqu'un ordre est nécessaire pour reconstruire correctement le contexte ;
|
||||
3. **état déjà acquis** — résumer uniquement les résultats stables nécessaires à la reprise et les décisions qui ne doivent pas être redébattues sans preuve nouvelle ; cet état MUST rester traçable à la baseline ou aux artefacts cités ;
|
||||
4. **mission et résultat attendu** — décrire ce que la version doit rendre vrai ou livrer, sans substituer un catalogue de tâches à l'objectif ;
|
||||
5. **scope et hors-scope** — borner les changements autorisés et les sujets explicitement différés afin d'éviter qu'une reprise étende silencieusement la release ;
|
||||
6. **décisions gelées et questions ouvertes** — distinguer les choix déjà établis des décisions que la première tranche doit encore instruire ; une valeur non prouvée MUST rester ouverte plutôt qu'être figée arbitrairement ;
|
||||
7. **première gate** — définir l'objectif de la première tranche, les lectures/audits ou preuves préalables attendus et, lorsque nécessaire, les travaux interdits avant fermeture de ce gate ;
|
||||
8. **trajectoire prévisionnelle** — fournir uniquement le forecast nécessaire pour dimensionner la release et ordonner les responsabilités ; il reste non contraignant et peut être scindé, fusionné ou replanifié selon les preuves ;
|
||||
9. **validation et responsabilité** — rappeler les familles de gates pertinentes, les validations déjà imposées par les règles applicables et toute séparation importante entre préparation, exécution opérateur et preuve observée, sans déclarer réussie une commande qui n'a pas été exécutée.
|
||||
|
||||
Un projet MAY regrouper plusieurs de ces éléments dans une même section lorsque le résultat reste explicite et non ambigu. Le prompt n'a pas à reproduire littéralement cette numérotation.
|
||||
|
||||
### Sources externes et données manquantes
|
||||
|
||||
Lorsqu'une release dépend de snapshots, corpus, rapports ou autres sources externes, le prompt MUST identifier celles qui sont réellement autoritaires pour la reprise et définir le comportement lorsque l'une d'elles manque.
|
||||
|
||||
L'absence d'une source attendue MUST être signalée. Le travail doit alors être borné à ce que les preuves disponibles permettent réellement de conclure ; le prompt MUST NOT autoriser à reconstituer silencieusement une version, un commit, un contenu ou un résultat depuis une conversation antérieure ou un workspace non fourni.
|
||||
|
||||
Une preuve externe complète la baseline seulement pour les propriétés qu'elle établit. Elle ne remplace pas l'audit de la source effectivement fournie à la nouvelle session.
|
||||
|
||||
### Décisions acquises et détails locaux
|
||||
|
||||
Le prompt SHOULD citer les décisions acquises qui empêchent une régression ou une réouverture inutile, mais il SHOULD pointer vers leur owner documentaire lorsque leur explication détaillée existe déjà.
|
||||
|
||||
Les contraintes locales de langage, plateforme, framework, architecture ou métier restent chez leurs owners respectifs. Leur présence dans un prompt de projet ne les élève pas au rang de règle générale PGR.
|
||||
|
||||
Le prompt MAY imposer un ordre de lecture détaillé ou une matrice de questions lorsque la taille du projet le justifie. Un petit projet SHOULD conserver une forme plus courte si elle couvre le même contrat de reprise.
|
||||
|
||||
### Création et clôture
|
||||
|
||||
Lorsque la version suivante est suffisamment connue, son prompt SHOULD être amorcé pendant la consolidation finale, vérifié pendant la RC et finalisé pendant la promotion stable. Il MUST être présent dans la stable taggée qui prépare cette reprise.
|
||||
|
||||
Lorsque la cible suivante n'est pas suffisamment connue, PGR MUST NOT fabriquer un prompt de version, un numéro ou une mission pour respecter une cérémonie. Le plan et la roadmap indiquent alors que l'horizon reste ouvert et un handoff `NEXT` ou une revue d'horizon porte la continuité nécessaire.
|
||||
|
||||
Une interruption au milieu d'une version MUST NOT produire artificiellement le prompt de la version suivante. La reprise de la tranche courante utilise son état committé et, si nécessaire, un handoff conforme au présent document.
|
||||
|
||||
Lorsqu'une stable publiée possède une cible suivante connue, le générateur MUST remettre spontanément à l'opérateur, après la vérification post-tag applicable, une courte consigne manuelle identifiant l'archive du tag, le rapport post-tag lorsqu'il existe réellement, le prompt versionné à lire et la première gate. [`../templates/003-NEW_SESSION_PROMPT.md`](../templates/003-NEW_SESSION_PROMPT.md) décrit cette forme courte ; elle reste distincte du prompt versionné et ne remplace ni son contrat détaillé ni la preuve de publication.
|
||||
|
||||
Si une preuve post-tag externe est requise pour la prochaine reprise, le prompt versionné MAY annoncer à l'avance son nom attendu mais MUST la décrire comme une preuve future extérieure au tag. La consigne manuelle finale ne la présente comme `PASS` qu'après sa production et sa vérification réelles.
|
||||
|
||||
## Handoff
|
||||
|
||||
Un handoff est un snapshot de continuité utilisé lorsqu'un travail doit être repris sans changer artificiellement de version ou de tranche.
|
||||
Un handoff est un snapshot de continuité utilisé lorsqu'un travail doit être repris à une frontière de session ou de responsabilité sans changer artificiellement de version ou de tranche. Un REPLAN traité entièrement dans la même session n'a pas besoin d'un handoff uniquement pour laisser une trace : delta, history et plan possèdent déjà cette trace.
|
||||
|
||||
Le chemin canonique est :
|
||||
|
||||
@@ -215,9 +277,21 @@ SUPERSEDE
|
||||
NEXT
|
||||
```
|
||||
|
||||
Le handoff SHOULD enregistrer uniquement les informations nécessaires à une reprise fiable : état de version/tranche, résultat déjà acquis, travail restant, risques ou décisions ouvertes et commandes pertinentes.
|
||||
Selon le besoin réel, un handoff SHOULD permettre de retrouver sans mémoire conversationnelle :
|
||||
|
||||
Une fois livré comme snapshot de reprise, il SHOULD être traité comme historique plutôt que réécrit continuellement.
|
||||
- son type, la version source et une cible éventuelle ;
|
||||
- la baseline autoritaire et le dernier état opérateur validé ;
|
||||
- le dernier delta validé et tout delta livré mais encore en attente ;
|
||||
- l'état du plan, le travail terminé et le travail restant ;
|
||||
- les décisions acquises, les questions ouvertes et les validations restantes ;
|
||||
- le prompt applicable lorsqu'il existe ;
|
||||
- l'instruction exacte de reprise et, lorsque cela aide l'opérateur, un court texte copiable vers la nouvelle session.
|
||||
|
||||
Un petit handoff n'a pas à répéter les champs sans valeur pour son cas. Il référence les owners existants plutôt que recopier leurs règles.
|
||||
|
||||
Un `NEXT` après stable peut transmettre une version suivante connue. Si l'horizon est volontairement ouvert, il peut au contraire transmettre explicitement le besoin de revue d'horizon sans inventer une release.
|
||||
|
||||
Une fois livré comme snapshot de reprise, un handoff SHOULD être traité comme historique plutôt que réécrit continuellement.
|
||||
|
||||
Un changement de conversation ou de session n'est jamais, à lui seul, une raison de changer `VERSION`.
|
||||
|
||||
@@ -255,6 +329,10 @@ post-tag verification
|
||||
|
||||
Un identifiant opérationnel tel que `rel.001` ou `publish.001` MAY être utilisé pour distinguer une clôture ou une vérification de publication sans devenir une nouvelle version SemVer produit.
|
||||
|
||||
`rel.001` prouve l'état stable avant création du tag. Une preuve `publish.001`, lorsqu'elle existe, porte sur l'artefact réellement publié après le tag et reste donc extérieure au tag qu'elle vérifie. Elle ne revalide pas fonctionnellement la release.
|
||||
|
||||
Lorsqu'un rapport `publish.001` est un prérequis de la session suivante, la clôture post-tag MUST indiquer explicitement à l'opérateur qu'il doit fournir ce rapport avec l'archive taggée. Le démarrage suivant effectue toujours son propre audit d'intake de la baseline ; il ne traite pas pour autant la stable précédente comme une release encore en attente de validation.
|
||||
|
||||
## Conservation et immutabilité
|
||||
|
||||
Deltas, histories, handoffs, plans historiques, études et autres preuves utiles SHOULD être conservés lorsqu'ils expliquent une décision ou permettent une reprise fiable.
|
||||
|
||||
123
docs/rules/220-SKELETONS.md
Normal file
123
docs/rules/220-SKELETONS.md
Normal file
@@ -0,0 +1,123 @@
|
||||
<!-- file: docs/rules/220-SKELETONS.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Skeleton specification rules
|
||||
|
||||
## Scope
|
||||
|
||||
Ce document définit le contrat transversal des skeleton specifications PGR : applicabilité, sélection des règles et profils, composition de skeletons, usage des templates, décisions propres au projet, overrides, instanciation et validation initiale.
|
||||
|
||||
Il ne définit pas les règles propres à une technologie. Les profils restent possédés par leurs documents normatifs, notamment le modèle de composition de [`../architecture/003-RULE_PROFILE_MODEL.md`](../architecture/003-RULE_PROFILE_MODEL.md). Les règles de validation restent possédées par [`400-VALIDATION.md`](400-VALIDATION.md) et le workflow delta/history par [`210-WORKFLOW.md`](210-WORKFLOW.md).
|
||||
|
||||
Les skeleton specifications concrètes vivent sous [`../skeletons/`](../skeletons/000-README.md).
|
||||
|
||||
## Nature d'un skeleton
|
||||
|
||||
Un skeleton PGR est une spécification Markdown procédurale permettant de construire une baseline locale cohérente à partir de règles, profils, templates et décisions explicites.
|
||||
|
||||
Un skeleton MUST NOT devenir :
|
||||
|
||||
- un générateur obligatoire de projet ;
|
||||
- une dépendance runtime ou build vers PGR ;
|
||||
- un nouveau propriétaire implicite de règles déjà possédées ailleurs ;
|
||||
- un moyen de figer une architecture au-delà du scope qu'il déclare ;
|
||||
- un catalogue de technologies ou de fichiers créés par anticipation.
|
||||
|
||||
Après instanciation, le projet destinataire possède ses fichiers, ses décisions et ses règles locales. Une évolution ultérieure de PGR ne modifie pas automatiquement ce projet.
|
||||
|
||||
## Applicabilité
|
||||
|
||||
Chaque skeleton MUST rendre explicites son objectif et les faits qui déterminent son applicabilité.
|
||||
|
||||
L'applicabilité MUST reposer sur le besoin réel du projet : type de baseline recherchée, langage ou écosystème utilisé, plateforme ciblée, framework réellement présent ou autre propriété concrète du scope.
|
||||
|
||||
Un skeleton MUST NOT être appliqué uniquement parce qu'il est fréquent, recommandé dans un autre projet ou disponible dans PGR.
|
||||
|
||||
Un skeleton spécialisé MAY déclarer un autre skeleton comme fondation. Cette relation doit être explicite et ne rend pas les spécialisations sœurs applicables entre elles.
|
||||
|
||||
## Contenu minimal d'une specification
|
||||
|
||||
Une skeleton specification MUST permettre d'identifier sans ambiguïté :
|
||||
|
||||
- son objectif et son applicabilité ;
|
||||
- les règles et profils sélectionnés ou requis ;
|
||||
- les autres skeletons dont elle dépend éventuellement pour sa composition ;
|
||||
- les fichiers à créer, copier, adapter ou omettre ;
|
||||
- les templates techniques utilisés et les décisions d'adaptation associées ;
|
||||
- les décisions obligatoires qui appartiennent au projet destinataire ;
|
||||
- les options, exceptions et overrides explicitement permis ;
|
||||
- l'ordre d'instanciation lorsque cet ordre est significatif ;
|
||||
- la validation initiale proportionnée ;
|
||||
- les éléments volontairement hors scope.
|
||||
|
||||
La structure Markdown exacte MAY varier si ces responsabilités restent clairement séparées. PGR MUST NOT imposer des sections vides uniquement pour respecter un format cérémoniel.
|
||||
|
||||
## Sélection des règles et profils
|
||||
|
||||
Un skeleton sélectionne les owners normatifs applicables ; il ne redéfinit pas leur contenu.
|
||||
|
||||
La sélection des profils MUST respecter l'applicabilité, la hiérarchie et la résolution définies dans [`../architecture/003-RULE_PROFILE_MODEL.md`](../architecture/003-RULE_PROFILE_MODEL.md).
|
||||
|
||||
Lorsqu'une règle générale est déjà applicable sans spécialisation, le skeleton SHOULD la référencer plutôt que la recopier comme si elle lui appartenait. Lors de l'instanciation, le projet destinataire doit néanmoins disposer localement des règles nécessaires à son fonctionnement autonome, sous la forme documentaire réellement adaptée à son propre référentiel.
|
||||
|
||||
Un skeleton MUST NOT sélectionner toute la bibliothèque PGR par défaut. Les profils ou familles sans rapport avec le projet restent absents.
|
||||
|
||||
## Templates et artefacts techniques
|
||||
|
||||
Un template reste un artefact technique copiable distinct du skeleton et de la règle qui justifie son usage.
|
||||
|
||||
Lorsqu'un skeleton utilise un template, il MUST identifier le template source et les valeurs qui doivent être revues ou adaptées avant adoption. Une valeur d'exemple, un placeholder, une version de toolchain, un nom de crate, un chemin de build ou un seuil de lint présent dans un template MUST NOT devenir une valeur universelle par simple copie.
|
||||
|
||||
Un skeleton MAY demander de copier un template tel quel seulement lorsque le contrat du template indique qu'aucune décision locale n'est requise pour le scope visé.
|
||||
|
||||
Un skeleton MUST NOT télécharger des dépendances, installer des toolchains ou exécuter implicitement des commandes externes à la place du projet destinataire. Ces opérations peuvent faire partie d'une validation explicitement demandée lorsque l'environnement et le scope les justifient.
|
||||
|
||||
## Décisions propres au projet
|
||||
|
||||
Toute décision qui ne découle pas d'une règle applicable ou d'une contrainte technique établie reste une décision du projet destinataire.
|
||||
|
||||
Le skeleton MUST distinguer une obligation normative d'une valeur d'exemple, d'un choix recommandé et d'une option libre lorsque cette distinction est nécessaire pour éviter une adoption accidentelle.
|
||||
|
||||
Les décisions nécessaires à une baseline fonctionnelle MUST être résolues ou laissées comme entrées explicites avant que l'instanciation soit présentée comme terminée. Un choix encore ouvert MUST NOT être converti silencieusement en règle ou valeur par défaut arbitraire.
|
||||
|
||||
Les décisions locales SHOULD être consignées dans les documents ou configurations qui les possèdent durablement dans le projet créé, et non uniquement dans une trace temporaire d'instanciation.
|
||||
|
||||
## Composition de plusieurs skeletons
|
||||
|
||||
La composition SHOULD partir de la fondation la plus générale explicitement requise, puis ajouter les spécialisations réellement applicables.
|
||||
|
||||
Un skeleton spécialisé SHOULD référencer les responsabilités déjà couvertes par sa fondation plutôt que les recopier. Il MAY ajouter des fichiers, décisions, templates ou validations propres à son scope.
|
||||
|
||||
L'ordre de composition ne crée aucune priorité normative implicite. Une règle plus spécifique ne remplace une règle plus générale que selon la hiérarchie normative, un profil applicable ou une exception explicitement documentée.
|
||||
|
||||
Si deux skeletons applicables exigent des choix incompatibles sans relation de spécialisation ou override défini, l'instanciation MUST s'arrêter sur cette décision au lieu de choisir arbitrairement le dernier appliqué.
|
||||
|
||||
PGR SHOULD NOT créer un skeleton composite pour chaque combinaison de technologies. Un skeleton composite n'est justifié que lorsqu'une interaction réelle possède des étapes, artefacts ou décisions qui ne peuvent pas être correctement possédés par les skeletons composants.
|
||||
|
||||
## Overrides et exceptions
|
||||
|
||||
Un override ou une exception MUST identifier la règle, le template, le choix ou l'étape concerné, son scope et sa raison.
|
||||
|
||||
Un skeleton MAY prévoir des points d'override lorsqu'ils correspondent à une variabilité légitime du projet. Il MUST NOT utiliser cette possibilité pour affaiblir silencieusement une règle applicable ou masquer une incompatibilité entre profils.
|
||||
|
||||
Une exception propre au projet est possédée par le projet destinataire après instanciation. Elle ne devient pas automatiquement une règle générale PGR.
|
||||
|
||||
## Validation de l'instanciation
|
||||
|
||||
Chaque skeleton MUST définir une validation initiale proportionnée à ce qu'il matérialise réellement.
|
||||
|
||||
La validation SHOULD utiliser le mécanisme le plus fiable disponible : parseur ou build tool officiel, linter, audit structurel read-only, test ciblé ou revue humaine selon la propriété à prouver.
|
||||
|
||||
Lorsqu'un skeleton prétend produire une baseline directement utilisable par une toolchain, une instanciation temporaire MAY être utilisée pour vérifier les fichiers copiés ou adaptés. Les ressources temporaires SHOULD être isolées et nettoyées après la gate.
|
||||
|
||||
La réussite d'un audit structurel ne remplace pas une validation de toolchain lorsque le contrat à prouver appartient à cette toolchain. Inversement, PGR SHOULD NOT imposer un build coûteux lorsqu'une propriété purement documentaire ou structurelle suffit à la tranche.
|
||||
|
||||
Une prévalidation réalisée lors de la préparation d'un delta ne remplace jamais la gate opérateur autoritaire définie par les règles de validation.
|
||||
|
||||
## Évolution
|
||||
|
||||
Une skeleton specification est un document vivant tant qu'elle reste la specification courante de son type de projet. Sa révision interne suit les règles documentaires PGR.
|
||||
|
||||
Modifier un skeleton PGR n'altère pas rétroactivement les projets déjà instanciés. Une migration depuis une ancienne baseline est une décision explicite du projet concerné.
|
||||
|
||||
PGR matérialise un nouveau skeleton uniquement lorsqu'un besoin réel, des owners normatifs suffisants et les artefacts nécessaires existent. Une technologie encore insuffisamment cadrée reste différée plutôt que représentée par un skeleton placeholder.
|
||||
@@ -1,5 +1,5 @@
|
||||
<!-- file: docs/rules/300-DOCUMENTATION.md -->
|
||||
<!-- version: 1 -->
|
||||
<!-- version: 4 -->
|
||||
|
||||
# Documentation rules
|
||||
|
||||
@@ -47,9 +47,9 @@ Il SHOULD NOT devenir un fichier monolithique contenant toutes les règles spéc
|
||||
|
||||
### `ROADMAP.md`
|
||||
|
||||
`ROADMAP.md` décrit la trajectoire macro du projet : objectifs de versions, grandes étapes et ordre fonctionnel attendu.
|
||||
`ROADMAP.md` décrit la trajectoire macro **engagée** du projet : objectifs de versions, grandes étapes et ordre fonctionnel attendu. Elle n'est ni un catalogue de toutes les possibilités futures, ni une obligation de prévoir arbitrairement plusieurs versions à l'avance.
|
||||
|
||||
Il MUST NOT devenir un journal des prereleases ou recopier les histories de tranche.
|
||||
Il MUST NOT devenir un journal des prereleases ou recopier les histories de tranche. Une idée, une étude ou une possibilité encore spéculative reste chez son owner tant qu'une décision suffisante ne justifie pas son entrée dans la trajectoire engagée.
|
||||
|
||||
Lorsqu'un projet utilise des statuts de roadmap, la convention PGR est :
|
||||
|
||||
@@ -62,6 +62,30 @@ Lorsqu'un projet utilise des statuts de roadmap, la convention PGR est :
|
||||
|
||||
Une autre convention MAY être adoptée par un projet si elle est explicitement définie et cohérente.
|
||||
|
||||
Une roadmap à horizon fini est valide. Le projet MUST NOT inventer un numéro de version, un objectif ou un engagement uniquement pour éviter que la roadmap se termine.
|
||||
|
||||
### Revue d'horizon
|
||||
|
||||
Une revue d'horizon est une activité de gouvernance qui décide si la trajectoire macro connue doit être étendue, maintenue volontairement ouverte, mise en pause ou considérée accomplie. Elle n'est pas une nouvelle phase SemVer.
|
||||
|
||||
Une revue SHOULD être planifiée lorsque l'un des signaux suivants devient pertinent :
|
||||
|
||||
- la release courante ou la suivante est la dernière entrée engagée de la roadmap alors que le projet doit continuer ;
|
||||
- un jalon important change ce qu'il est raisonnable de planifier ensuite ;
|
||||
- plusieurs ideas/studies ou décisions récentes peuvent modifier la trajectoire ;
|
||||
- les hypothèses qui fondaient les versions futures ont été invalidées par le travail réel.
|
||||
|
||||
La revue MAY avoir lieu dans une tranche de la release courante ou dans une session stratégique séparée. Une session séparée ne change pas `VERSION` par elle-même.
|
||||
|
||||
Une revue d'horizon produit l'un des résultats utiles suivants :
|
||||
|
||||
- **étendre** `ROADMAP.md` avec des objectifs suffisamment décidés ;
|
||||
- **laisser l'horizon ouvert** et enregistrer le déclencheur ou le moment de la prochaine revue ;
|
||||
- **différer/mettre en pause** une trajectoire sans fabriquer de remplaçant ;
|
||||
- **constater l'accomplissement** de l'objectif macro si aucune suite n'est nécessaire.
|
||||
|
||||
Le plan actif SHOULD indiquer si une telle revue est nécessaire avant sa fermeture et où elle aura lieu.
|
||||
|
||||
### `CHANGELOG.md`
|
||||
|
||||
`CHANGELOG.md` décrit les changements utiles aux utilisateurs ou intégrateurs d'une release.
|
||||
@@ -76,6 +100,26 @@ Un document sous `docs/objectives/` décrit la mission durable, les objectifs, c
|
||||
|
||||
Il MUST NOT être remplacé par `ROADMAP.md` : les objectifs expliquent pourquoi le projet existe et ce qu'il cherche à garantir ; la roadmap décrit comment sa trajectoire est découpée.
|
||||
|
||||
## Registre local de contrats de fichiers ou familles
|
||||
|
||||
Un projet MAY maintenir un registre local lorsque plusieurs fichiers ou familles durables ont des responsabilités, sources de vérité ou règles de modification qui ne sont pas suffisamment évidentes depuis leur nom, leur écosystème ou leurs owners existants.
|
||||
|
||||
Ce registre est un outil de désambiguïsation, pas un inventaire exhaustif de l'arborescence. Il MUST NOT être créé uniquement pour recopier les rôles déjà définis par PGR, un manifeste, une toolchain ou une documentation locale plus appropriée. Un petit projet dont les responsabilités sont déjà claires SHOULD ne pas créer ce document.
|
||||
|
||||
Chaque entrée utile SHOULD identifier au minimum :
|
||||
|
||||
- le fichier, motif de chemin ou famille concernée ;
|
||||
- sa responsabilité durable ;
|
||||
- la règle ou le déclencheur pertinent de modification.
|
||||
|
||||
Selon le besoin, une entrée MAY aussi préciser une source de vérité, le caractère généré/versionné, un owner local ou une validation associée. Ces champs supplémentaires ne doivent être ajoutés que s'ils réduisent réellement une ambiguïté.
|
||||
|
||||
Le nom, l'emplacement et la forme du registre appartiennent au projet destinataire. PGR n'impose ni `FILE_CONTRACTS.md`, ni une table Markdown, ni un catalogue de chaque fichier. Une liste courte, une table ou une autre forme lisible sont équivalentes si le contrat reste explicite.
|
||||
|
||||
Lorsqu'un owner existant possède déjà la règle détaillée, le registre SHOULD le référencer plutôt que dupliquer son contenu. Il est mis à jour lorsque le contrat d'une famille change réellement ; l'ajout d'un fichier conforme à une famille déjà décrite ne force pas une nouvelle entrée.
|
||||
|
||||
[`../templates/004-FILE_FAMILY_CONTRACTS.md`](../templates/004-FILE_FAMILY_CONTRACTS.md) fournit un pattern documentaire court pour les projets qui choisissent d'adopter ce registre.
|
||||
|
||||
## Taxonomie documentaire
|
||||
|
||||
La taxonomie doit rester sémantique et proportionnée. Les familles communes comprennent notamment :
|
||||
@@ -111,6 +155,22 @@ Si une décision est déjà imposée par une contrainte explicite et qu'aucune a
|
||||
|
||||
Les décisions durables doivent ensuite être reflétées dans l'architecture, les règles, objectifs ou autres documents vivants qui possèdent réellement ce contrat.
|
||||
|
||||
La maturation typique MAY suivre :
|
||||
|
||||
```text
|
||||
idea
|
||||
↓
|
||||
study
|
||||
↓
|
||||
decision durable / architecture / règle
|
||||
↓
|
||||
roadmap ou plan lorsqu'un engagement de réalisation existe
|
||||
↓
|
||||
implementation
|
||||
```
|
||||
|
||||
Toutes les possibilités n'ont pas à parcourir cette chaîne. Une idée ou une étude MAY être rejetée, différée, superseded ou rester inconclusive. Une conclusion `retained` ne crée pas automatiquement une promesse de roadmap : le passage vers `ROADMAP.md` exige encore une décision d'engagement macro explicite.
|
||||
|
||||
## Documents vivants et snapshots historiques
|
||||
|
||||
PGR distingue :
|
||||
@@ -165,6 +225,8 @@ La syntaxe de commentaire dépend du format. Pour Markdown :
|
||||
<!-- version: 1 -->
|
||||
```
|
||||
|
||||
Dans le dépôt PGR, `README.md`, `RULES.md`, `ROADMAP.md`, `CHANGELOG.md` et les fichiers Markdown gouvernés sous `docs/`, `deltas/`, `history/` et `prompts/` MUST placer ces deux commentaires sur leurs deux premières lignes. Le `file` MUST être le chemin relatif depuis la racine du dépôt et `version` MUST être un entier positif sans zéro initial. `scripts/audit_markdown_headers.py` contrôle mécaniquement ces deux champs pour les chemins explicitement sélectionnés. Ce contrôle ne juge ni le contenu du document, ni si le numéro de révision a réellement été incrémenté lors d'un changement.
|
||||
|
||||
`file` identifie le chemin relatif canonique du fichier.
|
||||
|
||||
`version` est une révision interne du fichier. Elle est indépendante de `VERSION`, de SemVer produit, des versions de protocole, de schema ou de package.
|
||||
|
||||
76
docs/rules/500-LANGUAGES.md
Normal file
76
docs/rules/500-LANGUAGES.md
Normal file
@@ -0,0 +1,76 @@
|
||||
<!-- file: docs/rules/500-LANGUAGES.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Règles de profils langage et écosystème
|
||||
|
||||
## Scope
|
||||
|
||||
Cette famille définit le contrat commun des profils liés à un langage, son écosystème et, lorsque pertinent, ses build tools ou package managers.
|
||||
|
||||
Les règles propres à Rust/Cargo, Java, Maven, Gradle ou à d'autres technologies sont ajoutées dans des documents plus spécifiques uniquement lorsqu'un contenu normatif réel existe.
|
||||
|
||||
## Responsabilités de la famille
|
||||
|
||||
Un profil langage/écosystème MAY posséder les règles spécifiques concernant notamment :
|
||||
|
||||
- l'organisation canonique des sources, packages, modules, crates ou workspaces ;
|
||||
- les manifests et fichiers de configuration propres à l'écosystème ;
|
||||
- la toolchain de compilation ou d'exécution lorsqu'elle appartient au langage ;
|
||||
- les build tools et package managers liés à cet écosystème ;
|
||||
- les dépendances, features, scopes ou configurations propres au gestionnaire utilisé ;
|
||||
- le formatter, le linter et les commandes officielles de vérification ;
|
||||
- les conventions d'API, d'import, d'erreur ou de safety réellement propres au langage ;
|
||||
- l'organisation des tests lorsque l'écosystème lui donne une structure spécifique ;
|
||||
- les artefacts générés ou lockfiles lorsque leur traitement dépend réellement de l'écosystème.
|
||||
|
||||
Un profil langage/écosystème MUST NOT absorber des règles dont le propriétaire naturel est une plateforme, un framework, un domaine métier ou le projet particulier.
|
||||
|
||||
## Héritage
|
||||
|
||||
Les profils de cette famille héritent des règles générales PGR et ne doivent pas recopier les contrats déjà possédés par les familles de gouvernance, documentation ou validation.
|
||||
|
||||
Une règle générale comme l'interdiction de versionner des secrets reste applicable sans être répétée dans chaque profil langage.
|
||||
|
||||
Lorsqu'un langage ou un build tool impose une exception réelle à une règle générale, le profil spécifique doit déclarer l'override et sa justification.
|
||||
|
||||
## Langage et build tool
|
||||
|
||||
PGR ne force pas un découpage identique pour tous les écosystèmes.
|
||||
|
||||
Un langage et son build tool MAY partager un profil lorsque leurs responsabilités sont suffisamment liées et que les séparer ne produirait que des renvois artificiels.
|
||||
|
||||
Ils SHOULD être séparés lorsque plusieurs build tools interchangeables possèdent chacun des règles propres significatives.
|
||||
|
||||
Dans ce second cas, la composition est explicite :
|
||||
|
||||
```text
|
||||
language profile
|
||||
↓
|
||||
build-tool specialization
|
||||
```
|
||||
|
||||
Une spécialisation de build tool ne devient pas une règle du langage entier.
|
||||
|
||||
## Versions d'outils et dépendances
|
||||
|
||||
Un profil MUST NOT figer une version exacte d'outil ou de dépendance uniquement parce qu'une version apparaît dans un projet source historique.
|
||||
|
||||
Une contrainte de version appartient au profil lorsqu'elle répond à une nécessité démontrée de compatibilité, reproductibilité, support, sécurité ou matrice imposée par un outil plus spécifique.
|
||||
|
||||
Une contrainte introduite par une plateforme ou un framework reste possédée par ce scope plus spécifique et ne se propage pas au langage entier.
|
||||
|
||||
## Validation spécialisée
|
||||
|
||||
Un profil langage/écosystème peut ajouter des commandes de formatage, lint, check ou test propres à sa toolchain.
|
||||
|
||||
Ces commandes complètent la gouvernance de validation générale ; elles ne redéfinissent ni l'autorité du gate opérateur, ni les statuts de preuve, ni le principe de proportionnalité.
|
||||
|
||||
Un audit Python PGR ne doit pas réimplémenter une propriété déjà contrôlée de façon fiable par le compilateur, le formatter, le linter ou le build tool officiel sans besoin distinct démontré.
|
||||
|
||||
## Nomenclature documentaire
|
||||
|
||||
Le document `500-LANGUAGES.md` possède le contrat commun de la famille.
|
||||
|
||||
Les profils spécifiques utilisent la plage `510` à `599`. Leur numéro identifie la navigation documentaire et ne représente ni une priorité normative implicite ni une version technologique.
|
||||
|
||||
L'applicabilité et les relations de spécialisation sont déterminées par le contenu du profil conformément à [`../architecture/003-RULE_PROFILE_MODEL.md`](../architecture/003-RULE_PROFILE_MODEL.md), jamais par l'ordre lexical des fichiers.
|
||||
301
docs/rules/510-RUST_CARGO.md
Normal file
301
docs/rules/510-RUST_CARGO.md
Normal file
@@ -0,0 +1,301 @@
|
||||
<!-- file: docs/rules/510-RUST_CARGO.md -->
|
||||
<!-- version: 7 -->
|
||||
|
||||
# Profil Rust / Cargo
|
||||
|
||||
## Scope
|
||||
|
||||
Ce profil s'applique aux projets qui utilisent Rust avec Cargo.
|
||||
|
||||
Il spécialise [`500-LANGUAGES.md`](500-LANGUAGES.md) pour les responsabilités propres à Rust et Cargo. Il ne possède pas les contraintes particulières d'une plateforme, d'un framework, d'une FFI, d'un protocole ou d'un domaine métier.
|
||||
|
||||
Une règle plus spécifique, par exemple Android, WASM, Tauri ou une frontière FFI, MAY raffiner ce profil dans son scope sans modifier la politique Rust générale.
|
||||
|
||||
Pour un **nouveau projet contrôlé** par l'organisation, PGR sélectionne par défaut le profil strict décrit ci-dessous : provenance des symboles visible, façade crate-root explicite, contrôle de flux explicite et noms de crates lisibles. Un projet existant ou imposé par un tiers MAY conserver des contraintes différentes via des règles project-specific ou des exceptions bornées ; cette adaptation ne rend pas le profil strict moins canonique pour les nouvelles baselines contrôlées.
|
||||
|
||||
## Toolchain et édition
|
||||
|
||||
Un nouveau projet Rust contrôlé MUST utiliser l'édition Rust 2024 avec une toolchain stable compatible avec ses dépendances et ses cibles, sauf contrainte externe explicitement documentée. Une toolchain nightly, beta ou autre prerelease nécessite une justification explicite.
|
||||
|
||||
`2024` est la baseline normative actuelle des projets contrôlés ; PGR ne bascule pas automatiquement vers une future édition au seul motif qu'elle existe. Une évolution de cette baseline demande une décision PGR explicite et une validation de compatibilité.
|
||||
|
||||
PGR MUST NOT imposer un pin exact de toolchain uniquement parce qu'un projet source historique utilisait cette version. Un fichier `rust-toolchain.toml` ou équivalent SHOULD être ajouté uniquement lorsqu'un besoin réel de reproductibilité, de composant ou de compatibilité l'exige.
|
||||
|
||||
Lorsqu'un workspace partage une politique d'édition unique, l'édition Rust SHOULD être déclarée une seule fois sous `[workspace.package]` et héritée par les membres. Une évolution d'édition est une décision de compatibilité/toolchain et non une modification opportuniste.
|
||||
|
||||
## Workspace et unités de release
|
||||
|
||||
Un projet Rust composé de plusieurs packages SHOULD utiliser un workspace Cargo lorsque les packages partagent réellement gouvernance, validation ou dépendances.
|
||||
|
||||
Pour un workspace à train de release unique :
|
||||
|
||||
- le fichier PGR `VERSION` reste la version canonique de l'unité de release ;
|
||||
- `[workspace.package].version` MUST refléter cette version lorsque Cargo exige une version de package ;
|
||||
- les crates membres SHOULD hériter de la version workspace plutôt que recopier la même valeur ;
|
||||
- les métadonnées réellement communes comme `edition`, `license`, `repository` ou `authors` SHOULD être centralisées puis héritées lorsqu'elles ont le même propriétaire.
|
||||
|
||||
Un monorepo contenant plusieurs unités de release indépendantes MUST NOT fabriquer une fausse version Cargo globale uniquement pour appliquer ce modèle. Chaque unité conserve alors son propriétaire de version conformément aux règles générales PGR.
|
||||
|
||||
Le répertoire `crates/` est le placement PGR recommandé pour les packages Rust d'un workspace structuré, sauf layout imposé par un framework, une plateforme ou un projet existant.
|
||||
|
||||
|
||||
### Nomenclature des crates dans un projet contrôlé
|
||||
|
||||
Une crate appartenant à un projet contrôlé MUST commencer par le nom court canonique du projet ou une abréviation documentée et stable. Le reste du nom SHOULD rendre immédiatement lisibles sa responsabilité principale puis, lorsqu'il apporte une information réelle, son rôle ou sa cible.
|
||||
|
||||
La forme recommandée est :
|
||||
|
||||
```text
|
||||
<project>-<responsibility>-<role-or-target>
|
||||
```
|
||||
|
||||
Exemples de classificateurs utiles selon le projet :
|
||||
|
||||
```text
|
||||
lib
|
||||
api
|
||||
worker
|
||||
job
|
||||
cli
|
||||
desk
|
||||
desktop
|
||||
tauri
|
||||
wasm
|
||||
server
|
||||
```
|
||||
|
||||
Cette liste n'est ni exhaustive ni un vocabulaire imposé. Un suffixe ou classificateur ne doit pas être ajouté par symétrie : `api` suppose un vrai contrat/extensibility boundary, `worker` un service continu identifiable, `cli` une interface ligne de commande, etc. À l'inverse, un rôle important ne doit pas être masqué dans un nom générique comme `common`, `core` ou `utils` sans responsabilité suffisamment précise.
|
||||
|
||||
Un projet historique MAY conserver un ordre local déjà stable, par exemple un rôle placé avant la responsabilité, si sa nomenclature est documentée et cohérente. PGR n'impose aucune campagne de renommage rétroactive uniquement pour adopter la grammaire recommandée.
|
||||
|
||||
### Les suffixes portent un contrat architectural
|
||||
|
||||
Dans un projet contrôlé, les classificateurs de nom ne sont pas décoratifs. Lorsqu'ils sont utilisés, ils décrivent une responsabilité que l'architecture et le graphe de dépendances doivent respecter.
|
||||
|
||||
Une crate terminée par `-api` porte principalement des contrats réutilisables : traits, types, DTOs, identifiants et primitives nécessaires à des implémentations séparées. Elle SHOULD rester passive et sans runtime. Une crate `-api` purement déclarative MUST NOT dépendre d'une crate de logging/tracing uniquement pour satisfaire une convention transversale. Une instrumentation n'y est ajoutée que si la crate possède un comportement réel à observer.
|
||||
|
||||
Une crate `-api` MUST NOT être créée uniquement pour obtenir une paire de noms symétrique. Elle est justifiée lorsqu'au moins une frontière réelle existe : implémentations multiples ou remplaçables, implémentation externe, backend injectable, lifecycle partagé ou contrat public dont l'implémentation doit pouvoir vivre dans une autre crate. Lorsqu'une seule implémentation est réellement prévue et qu'aucune frontière de contrat séparée n'apporte de valeur, une seule crate `-lib` est préférée.
|
||||
|
||||
Une crate terminée par `-lib` porte une implémentation ou fonctionnalité réutilisable. Par défaut, elle est une crate bibliothèque sans cible binaire. Des familles comme `worker`, `job`, `store`, `transport` ou `scenario` MAY apparaître dans la responsabilité avant le suffixe `-lib` lorsqu'elles décrivent ce que la bibliothèque implémente ; le suffixe terminal `-lib` continue alors d'indiquer qu'il s'agit d'une unité réutilisable et non d'un launcher.
|
||||
|
||||
### Séparation bibliothèques / exécutables
|
||||
|
||||
Hors exception de framework ou plateforme explicitement documentée, un package contrôlé MUST NOT combiner une bibliothèque réutilisable et une cible binaire uniquement par commodité. La logique réutilisable appartient à une ou plusieurs crates `-lib`; l'exécutable appartient à un package distinct qui les consomme.
|
||||
|
||||
Le nom d'un package exécutable SHOULD rendre visible son rôle de processus ou d'interface, par exemple `-cli`, `-desk`, `-worker`, `-job` ou `-server` lorsque ces termes décrivent réellement le launcher. Le binaire SHOULD rester une couche de composition mince : initialisation du processus, verrou/single-instance lorsque nécessaire, arguments CLI, wiring des bibliothèques, lifecycle et arrêt. La logique métier ou technique réutilisable ne doit pas être dupliquée dans `main.rs`.
|
||||
|
||||
Tauri constitue l'exception framework actuellement reconnue par PGR à cette séparation par défaut : son profil peut demander un package mixte bibliothèque + binaire pour servir simultanément les entrées desktop/mobile. Cette exception est possédée par [`710-TAURI.md`](710-TAURI.md) et ne justifie pas de généraliser les packages mixtes aux workers, jobs ou autres exécutables. Toute autre exception mixte demande une règle locale et une raison technique identifiable.
|
||||
|
||||
## Diagnostics structurés et ownership du logging
|
||||
|
||||
Pour les nouveaux projets Rust contrôlés, `tracing` est le mécanisme recommandé de diagnostics structurés. La façade `log` MAY être conservée comme bridge de compatibilité lorsqu'une dépendance l'impose, mais elle SHOULD NOT devenir le mécanisme principal d'un nouveau projet lorsqu'aucune contrainte externe ne le requiert.
|
||||
|
||||
Lorsqu'un workspace possède plusieurs crates runtime partageant les mêmes règles de diagnostics, il SHOULD centraliser la configuration de logging/tracing dans une crate transverse dédiée, typiquement `<project>-logging-lib` ou un nom équivalent conforme à la nomenclature locale. Dès que plusieurs exécutables ou bibliothèques ont besoin du même subscriber, des mêmes filtres/sinks ou du même lifecycle de guard, cet owner commun SHOULD remplacer les initialisations dupliquées. Un petit projet à exécutable unique n'est pas obligé de créer une crate dédiée sans valeur de réutilisation.
|
||||
|
||||
Cette crate commune possède normalement la composition de `tracing-subscriber`, l'usage de `tracing-appender` lorsque nécessaire, les filtres/sinks/formats partagés et le lifecycle d'initialisation. Une bibliothèque métier ou technique MAY émettre des événements structurés, mais SHOULD NOT installer silencieusement un subscriber global. Les crates `-api` purement déclaratives restent normalement sans dépendance de logging.
|
||||
|
||||
## Manifests et dépendances Cargo
|
||||
|
||||
Dans un workspace, une dépendance tierce réellement partagée par plusieurs crates SHOULD posséder sa contrainte de version canonique sous `[workspace.dependencies]`.
|
||||
|
||||
Une crate membre SHOULD consommer cette dépendance avec `workspace = true` et activer localement uniquement les features nécessaires à son propre code. Une feature de plateforme ou de test MUST NOT être activée globalement par commodité lorsqu'un scope plus étroit suffit.
|
||||
|
||||
Une dépendance utilisée uniquement par les tests, benchmarks ou exemples SHOULD rester dans la section de dépendances de développement appropriée.
|
||||
|
||||
Les contraintes de version SHOULD exprimer l'intention de compatibilité réellement souhaitée. Un pin exact ou une version volontairement ancienne MUST avoir une raison identifiable : compatibilité, reproductibilité, sécurité, bug connu ou matrice imposée par un scope plus spécifique.
|
||||
|
||||
`cargo update` MUST NOT être exécuté opportunistement dans une tranche sans rapport avec les dépendances. Une mise à jour de résolution ou de dépendance appartient au scope courant uniquement lorsqu'elle est nécessaire et explicitement vérifiée.
|
||||
|
||||
## Politique de `Cargo.lock`
|
||||
|
||||
PGR ne généralise pas automatiquement la politique de lockfile d'un projet source à tous les projets Rust.
|
||||
|
||||
La décision de versionner ou non `Cargo.lock` MUST être explicite et cohérente avec le type de produit, le mode de publication et le besoin de reproductibilité du projet. Un profil plus spécifique MAY imposer une politique particulière.
|
||||
|
||||
Dans tous les cas, un lockfile ne remplace jamais les contraintes de version et décisions de compatibilité appartenant aux manifests et à la documentation normative.
|
||||
|
||||
## Lints communs
|
||||
|
||||
Un workspace structuré SHOULD déclarer les lints communs au niveau racine et les crates membres SHOULD les hériter plutôt que maintenir plusieurs copies divergentes.
|
||||
|
||||
Le profil strict PGR recommandé pour un nouveau workspace Rust comprend au minimum :
|
||||
|
||||
```toml
|
||||
[workspace.lints.rust]
|
||||
missing_docs = "warn"
|
||||
unreachable_pub = "deny"
|
||||
unsafe_code = "forbid"
|
||||
|
||||
[workspace.lints.clippy]
|
||||
unwrap_used = "deny"
|
||||
expect_used = "deny"
|
||||
implicit_return = "deny"
|
||||
question_mark = "deny"
|
||||
question_mark_used = "deny"
|
||||
```
|
||||
|
||||
Des `allow` nécessaires pour éviter qu'un lint de suggestion contredise intentionnellement le style retenu MAY être déclarés au workspace, mais la liste doit rester minimale et justifiée par une règle réelle.
|
||||
|
||||
## Safety et FFI
|
||||
|
||||
Le code `unsafe` est interdit par défaut dans un projet suivant le profil strict PGR.
|
||||
|
||||
Lorsqu'une FFI ou une plateforme impose réellement une opération `unsafe`, l'exception MUST appartenir au scope le plus étroit possible : crate, module, symbole ou attribut concerné. Elle MUST être documentée et ne doit pas affaiblir silencieusement le reste du workspace.
|
||||
|
||||
Une exception FFI locale n'autorise donc pas à remplacer globalement `unsafe_code = "forbid"` par une politique permissive pour toutes les crates.
|
||||
|
||||
## API, visibilité, imports et chemins
|
||||
|
||||
Dans le profil strict d'un projet contrôlé, tout élément `pub` ou `pub(crate)` MUST posséder une rustdoc utile au point de déclaration. Toute réexportation `pub use` ou `pub(crate) use` visible au crate-root MUST également porter une rustdoc adjacente utile. Une rustdoc qui répète seulement le nom du symbole ne satisfait pas ce contrat.
|
||||
|
||||
Les modules d'implémentation restent privés. `pub mod` MUST NOT être utilisé pour exposer paresseusement une arborescence interne ; `pub(super)` et `pub(in ...)` MUST NOT remplacer une façade crate-root explicite dans une baseline contrôlée.
|
||||
|
||||
Un élément `pub` d'un module fichier MUST être réexporté explicitement au crate-root. Un élément `pub(crate)` consommé hors de son module MUST de même posséder un réexport `pub(crate)` au crate-root. Un helper réellement local SHOULD rester privé plutôt qu'élargir artificiellement sa visibilité.
|
||||
|
||||
Les réexports d'éléments internes commencent par `self::` :
|
||||
|
||||
```rust
|
||||
pub use self::foo::Foo;
|
||||
pub(crate) use self::bar::InternalBar;
|
||||
```
|
||||
|
||||
Un réexport de crate externe utilise son chemin public canonique. Les réexports groupés par accolades, les glob imports et les alias `as` servant à raccourcir ou masquer un nom MUST NOT être utilisés. Une collision durable se résout en donnant au symbole son nom canonique dans son module propriétaire.
|
||||
|
||||
### `use` réservé aux traits
|
||||
|
||||
Dans le profil strict, `use` MUST NOT importer une constante, fonction, structure, énumération, union, alias de type, module ou macro uniquement pour raccourcir son chemin. Les déclarations `use` sont réservées aux traits lorsqu'une résolution de méthode ou une contrainte du langage exige réellement leur mise en scope.
|
||||
|
||||
Un import de trait reste au niveau du module et ne mélange pas de symboles non-traits. Un projet MAY ajouter un marqueur de commentaire spécifique à son audit local, mais PGR n'impose pas un commentaire tel que `rust-rules: trait-import` : ce marqueur est un mécanisme d'enforcement, pas la règle sémantique elle-même.
|
||||
|
||||
Pour un élément fourni par une crate externe, le code utilise directement le **chemin public le plus court** exposé par cette crate, par exemple :
|
||||
|
||||
```rust
|
||||
std::path::Path
|
||||
serde_json::Value
|
||||
other_crate::Item
|
||||
```
|
||||
|
||||
et non un `use` non-trait destiné à raccourcir ce chemin. Un chemin interne plus long n'est pas préféré lorsque la crate externe expose déjà une façade publique plus courte.
|
||||
|
||||
### Façade crate-root et références intra-crate
|
||||
|
||||
Dès qu'un item partagé possède une identité crate-root, toute référence dans la même crate MUST utiliser `crate::Item`, y compris depuis son module de déclaration et depuis ses tests unitaires attachés. Les formes `Item`, `self::Item`, `super::Item`, `module::Item` et `crate::module::Item` ne sont pas des chemins de consommation canoniques pour cet item partagé.
|
||||
|
||||
Un élément strictement privé reste local au module et n'est pas réexporté. Dans un fichier de tests unitaires rattaché au module parent, un élément privé du parent peut être référencé via `super::PrivateItem`; un élément `pub` ou `pub(crate)` partagé continue d'être référencé via `crate::Item`.
|
||||
|
||||
Les autres crates consomment l'API publique du crate propriétaire via `owner_crate::Item`, jamais via ses modules internes. La visibilité d'un item MUST NOT être élargie uniquement pour permettre son test.
|
||||
|
||||
Ces conventions sont plus strictes que le Rust idiomatique minimal, mais elles sont retenues pour les projets contrôlés afin de rendre immédiatement visibles l'ownership et la provenance des symboles. Un projet externe contraint peut définir un override explicite ; l'exception ne devient pas la nouvelle règle PGR.
|
||||
|
||||
## Contrôle de flux et erreurs
|
||||
|
||||
Dans le code de production du profil strict PGR :
|
||||
|
||||
- `unwrap()` et `expect()` MUST NOT être utilisés ;
|
||||
- `panic!` MUST NOT représenter une erreur métier récupérable ;
|
||||
- les retours explicites sont obligatoires lorsque la fonction possède une valeur de retour ;
|
||||
- l'opérateur `?` MUST NOT être utilisé ; les chemins `Ok`/`Err` et conversions d'erreur restent explicites.
|
||||
|
||||
Une règle plus spécifique MAY définir une politique d'erreur différente lorsqu'elle possède une justification architecturale explicite. PGR ne généralise pas l'interdiction d'une bibliothèque d'erreur particulière à partir d'un seul projet source.
|
||||
|
||||
## Formatage
|
||||
|
||||
`rustfmt.toml` à la racine SHOULD être le propriétaire canonique du formatage Rust d'un workspace.
|
||||
|
||||
Le profil PGR issu des corpus actuellement éprouvés utilise notamment :
|
||||
|
||||
```toml
|
||||
edition = "2024"
|
||||
newline_style = "Unix"
|
||||
hard_tabs = false
|
||||
tab_spaces = 4
|
||||
max_width = 160
|
||||
reorder_imports = true
|
||||
reorder_modules = true
|
||||
use_try_shorthand = false
|
||||
force_explicit_abi = true
|
||||
```
|
||||
|
||||
L'édition de ce fichier MUST rester cohérente avec l'édition réellement utilisée par le workspace ; l'exemple `2024` décrit la baseline actuelle et ne constitue pas un pin éternel pour les futures éditions Rust.
|
||||
|
||||
Après une modification Rust, `cargo fmt --all` applique le formatage canonique puis `cargo fmt --all -- --check` vérifie l'état livré. Une modification produite uniquement par le formatter officiel ne crée pas artificiellement une nouvelle révision documentaire d'un fichier si aucun contenu réel n'a changé.
|
||||
|
||||
Le profil structurel strict fait partie du défaut des nouvelles baselines Rust contrôlées. Un projet externe, historique ou imposé peut documenter un override borné ; cet override ne réduit pas le profil canonique des nouveaux projets. L'owner reste partagé entre `rustfmt` pour ce qu'il sait réécrire de manière fiable et des audits read-only monotâches pour les propriétés de structure qu'il ne possède pas.
|
||||
|
||||
Les lignes vides consécutives MUST être supprimées. 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`. `scripts/audit_rust_blank_lines.py` contrôle ces deux propriétés sur les fichiers Rust sélectionnés.
|
||||
|
||||
Deux items Rust distincts et voisins d'un même scope — fonctions/méthodes, `struct`, `enum`, `union`, `trait`, blocs `impl` ou changements de catégorie/visibilité — MUST être séparés par exactement une ligne vide lorsqu'aucune syntaxe intermédiaire ne possède elle-même l'espacement. `scripts/audit_rust_item_spacing.py` contrôle cette séparation sans tenter d'interpréter les macros ou de posséder les blocs compacts `const`/`static`/`type`.
|
||||
|
||||
Les déclarations compactes d'un même type et d'une même visibilité SHOULD former un bloc sans ligne vide lorsque l'ordre n'a pas de signification sémantique. Pour les constantes de module sélectionnées, l'ordre canonique est `pub`, `pub(crate)`, privé, puis le nom dans chaque visibilité ; exactement une ligne vide sépare deux niveaux de visibilité. `scripts/audit_rust_const_blocks.py` possède uniquement ce contrat `const` au niveau racine. Il MUST NOT être appliqué aveuglément à une table de protocole, une séquence de migrations, un schéma, une table de dispatch ou toute autre série dont l'ordre est contractuel. Les blocs `static`/`type` peuvent suivre la même présentation par convention locale, mais PGR ne leur ajoute pas encore un audit dédié uniquement pour atteindre une symétrie théorique.
|
||||
|
||||
Les déclarations `mod` de production d'un même fichier MUST précéder les modules de tests conditionnels ; les deux groupes sont ordonnés alphabétiquement lorsque l'ordre ne porte aucune sémantique locale. `scripts/audit_rust_module_order.py` contrôle cette propriété. `rustfmt` reste propriétaire de l'ordre qu'il réécrit déjà à l'intérieur d'un bloc contigu.
|
||||
|
||||
Les `use` non exportés autorisés par le profil strict — donc normalement des imports de traits — restent au niveau du module, avant les déclarations Rust métier et dans un bloc contigu sans ligne vide interne. `scripts/audit_rust_trait_import_blocks.py` contrôle uniquement cette disposition ; il ne prétend pas déterminer lexicalement si le symbole importé est effectivement un trait. L'ordre intra-bloc reste celui de `cargo fmt --all`.
|
||||
|
||||
Au crate-root, les réexports `pub use` constituent un bloc avant les `pub(crate) use`. Aucune ligne vide n'est admise à l'intérieur d'un bloc de même visibilité et exactement une ligne vide sépare les deux niveaux lorsqu'ils existent tous deux. `scripts/audit_rust_reexport_blocks.py` contrôle cette structure sans imposer un second tri : l'ordre intra-bloc reste celui produit par Rustfmt. Les rustdocs adjacentes restent possédées par les règles d'API, pas par cet audit de forme.
|
||||
|
||||
Lorsqu'un `struct` et ses `impl` forment une unité locale, les `impl` SHOULD suivre la structure ; de même, les éléments visibles SHOULD généralement précéder les helpers privés lorsque cela rend l'API plus lisible. PGR n'impose toutefois pas un ordre global automatique `enum → struct → impl → fn` : un ordre métier, protocolaire ou pédagogique peut être plus important. Cette propriété reste une revue tant qu'un audit fiable ne peut pas distinguer la structure informative d'un ordre sémantique.
|
||||
|
||||
Les scripts PGR restent des analyseurs lexicaux ciblés, pas un parser Rust général. Une macro complexe, un item généré ou une syntaxe nouvelle peut nécessiter une revue humaine ou l'owner Rust officiel. Une règle déjà possédée par `rustfmt`, rustc ou Clippy MUST NOT être réimplémentée uniquement pour multiplier les gates.
|
||||
## Configuration Cargo et artefacts générés
|
||||
|
||||
`.cargo/config.toml` est le propriétaire naturel d'une configuration Cargo partagée par le projet lorsqu'une telle configuration est nécessaire.
|
||||
|
||||
Si un projet choisit de placer les artefacts Cargo hors de l'arborescence source, `target-dir` et les autres paramètres correspondants SHOULD être définis dans cette configuration plutôt que répétés dans chaque commande. Le chemin exact reste une décision de projet ou de skeleton et n'est pas figé par ce profil.
|
||||
|
||||
Les sorties `target/`, caches et artefacts de compilation MUST rester hors des livraisons source sauf contrat de packaging explicite.
|
||||
|
||||
## Tests Rust
|
||||
|
||||
Les tests MUST NOT élargir artificiellement la visibilité de l'API de production.
|
||||
|
||||
Les tests d'intégration Cargo résident sous `tests/` de la crate concernée et consomment son API publique.
|
||||
|
||||
Les tests unitaires restent sous la responsabilité de la crate ou du module testé. Un workspace MAY adopter une arborescence `unit_tests/` séparée et miroir de `src/` lorsqu'elle améliore la lisibilité ; cette convention doit alors être appliquée de manière cohérente sans transformer `tests/` en tests internes.
|
||||
|
||||
Une dépendance ou feature exclusivement nécessaire aux tests SHOULD rester dans le scope de développement/test approprié.
|
||||
|
||||
## Validation Rust / Cargo
|
||||
|
||||
Les catégories, l'autorité du gate et la proportionnalité restent possédées par [`400-VALIDATION.md`](400-VALIDATION.md). Ce profil ajoute seulement les commandes propres à Rust/Cargo.
|
||||
|
||||
Lorsqu'un delta modifie du code Rust, un manifeste Cargo, une feature ou une dépendance Rust, la séquence normale SHOULD inclure :
|
||||
|
||||
```bash
|
||||
cargo fmt --all
|
||||
cargo fmt --all -- --check
|
||||
cargo check --workspace
|
||||
cargo clippy --workspace --all-targets --all-features -- -D warnings
|
||||
```
|
||||
|
||||
Les audits structurels read-only réellement applicables s'insèrent après le formatage et avant ou autour des contrôles Cargo selon leur responsabilité.
|
||||
|
||||
Les tests ciblés constituent la stratégie normale d'une tranche :
|
||||
|
||||
```bash
|
||||
cargo test -p <crate> --all-targets --all-features
|
||||
```
|
||||
|
||||
`cargo test --workspace --all-targets --all-features` est une gate plus large réservée aux changements transverses ou aux phases où une validation globale apporte une preuve supplémentaire réelle.
|
||||
|
||||
`cargo build` SHOULD être exécuté lorsqu'un artefact est nécessaire ; il ne doit pas être ajouté systématiquement à `cargo check` sans besoin de build ou packaging.
|
||||
|
||||
`cargo tree` et ses variantes SHOULD être utilisés lors d'une modification de dépendances/features ou d'un diagnostic de graphe, pas comme cérémonie de chaque delta.
|
||||
|
||||
`cargo clean` est une opération de maintenance et MUST NOT être exécuté automatiquement à chaque tranche.
|
||||
|
||||
La validation Cargo finale appartient à l'environnement autoritaire du projet. Une prévalidation par générateur ou CI supplémentaire ne remplace pas le gate opérateur défini par le projet.
|
||||
|
||||
## Audits PGR pour Rust
|
||||
|
||||
Les audits Rust historiques de projets sources peuvent combiner de nombreuses responsabilités. PGR ne doit pas recopier cette complexité comme point de départ.
|
||||
|
||||
Lorsqu'une règle Rust devient objectivement automatisable dans un projet ou skeleton concret, PGR SHOULD préférer plusieurs audits monotâches et lisibles, par exemple un contrôle de manifests/workspace distinct d'un contrôle de headers ou de façade publique.
|
||||
|
||||
Un éventuel wrapper d'orchestration MAY appeler plusieurs audits, mais chaque audit propriétaire doit conserver une responsabilité identifiable et rester read-only.
|
||||
|
||||
Les deux audits de style disponibles sont documentés dans [`../validation/002-RUST_STYLE_AUDITS.md`](../validation/002-RUST_STYLE_AUDITS.md). Ils restent optionnels et prennent un corpus Rust explicitement sélectionné.
|
||||
|
||||
[`../validation/003-RUST_EXPORT_COMPLETENESS.md`](../validation/003-RUST_EXPORT_COMPLETENESS.md) documente séparément l'audit facultatif qui matérialise ce contrat strict. `RUST-API-201` vérifie la présence de la façade pour les items partagés ; `RUST-IMPORT-201` vérifie que les références intra-crate détectées passent réellement par `crate::Item`, y compris dans le module propriétaire, et pas seulement qu'un chemin interne long a été évité.
|
||||
|
||||
Cet audit ne rend pas le contrat strict obligatoire pour tous les projets Rust et ne remplace pas le compilateur. Il contrôle au contraire une convention architecturale que `rustc` et Clippy ne possèdent pas. Le dépôt PGR lui-même ne contient pas de workspace Rust sur lequel une telle gate fournirait une preuve runtime ou Cargo réelle.
|
||||
316
docs/rules/520-JAVA_MAVEN_GRADLE.md
Normal file
316
docs/rules/520-JAVA_MAVEN_GRADLE.md
Normal file
@@ -0,0 +1,316 @@
|
||||
<!-- file: docs/rules/520-JAVA_MAVEN_GRADLE.md -->
|
||||
<!-- version: 2 -->
|
||||
|
||||
# Profil Java / Maven / Gradle
|
||||
|
||||
## Rôle
|
||||
|
||||
Ce document possède les règles réutilisables propres au langage Java et à ses deux spécialisations de build principales retenues ici : Maven et Gradle.
|
||||
|
||||
Il complète [`500-LANGUAGES.md`](500-LANGUAGES.md). Les règles de gouvernance, documentation et validation restent possédées par leurs familles générales.
|
||||
|
||||
Android n'est pas défini ici. Une contrainte AGP, SDK Android, `minSdk`, `targetSdk`, `versionCode`, signing ou packaging APK/AAB appartient au profil plateforme Android et peut surcharger localement les règles Gradle ou JDK de ce document.
|
||||
|
||||
## Politique JDK et compatibilité Java
|
||||
|
||||
Pour un projet Java général suivant le profil PGR :
|
||||
|
||||
- le JDK de développement SHOULD être une version LTS ;
|
||||
- la dernière LTS compatible disponible dans l'environnement SHOULD être utilisée par défaut ;
|
||||
- une LTS plus ancienne MAY être sélectionnée lorsqu'un outil, framework, serveur, CI ou environnement d'exécution l'exige ;
|
||||
- une version Java non-LTS SHOULD NOT être introduite sans besoin technique explicite.
|
||||
|
||||
PGR MUST distinguer :
|
||||
|
||||
```text
|
||||
JDK utilisé pour construire
|
||||
≠
|
||||
niveau Java du code source
|
||||
≠
|
||||
niveau de bytecode/runtime minimal supporté
|
||||
```
|
||||
|
||||
Le niveau Java ciblé MUST être déclaré explicitement par le build lorsqu'il affecte la compatibilité. Il ne doit pas dépendre implicitement du JDK actif sur la machine.
|
||||
|
||||
Une hausse de la version Java minimale supportée constitue un changement de compatibilité et MUST être justifiée comme telle.
|
||||
|
||||
PGR MUST NOT imposer une version exacte de JDK uniquement parce qu'un corpus historique ou un autre projet utilise cette version.
|
||||
|
||||
## Structure source Java
|
||||
|
||||
Un module Java classique SHOULD conserver la structure reconnue par l'écosystème :
|
||||
|
||||
```text
|
||||
src/
|
||||
├── main/
|
||||
│ ├── java/
|
||||
│ └── resources/
|
||||
└── test/
|
||||
├── java/
|
||||
└── resources/
|
||||
```
|
||||
|
||||
PGR SHOULD NOT remplacer cette convention par une arborescence propriétaire telle que `sources/`, `java-code/` ou `tests-java/` sans contrainte réelle.
|
||||
|
||||
Les chemins canoniques correspondants sont donc notamment `src/main/java/`, `src/main/resources/`, `src/test/java/` et `src/test/resources/`.
|
||||
|
||||
Lorsqu'un projet distingue des tests d'intégration, environnementaux ou live, il SHOULD utiliser un source set ou un module explicitement déclaré par le build plutôt que détourner `src/test/`.
|
||||
|
||||
## Packages et ownership
|
||||
|
||||
Un package Java représente une responsabilité architecturale, pas seulement un dossier.
|
||||
|
||||
La racine de package SHOULD être stable et appartenir au projet ou à l'organisation. Les sous-packages SHOULD refléter des responsabilités telles que `config`, `transport`, `store`, `logging` ou `protocol`.
|
||||
|
||||
Les packages génériques tels que `misc`, `stuff`, `helpers`, `common` ou `util` SHOULD NOT devenir des dépotoirs. Lorsqu'un élément est partagé, son propriétaire architectural doit d'abord être identifié.
|
||||
|
||||
Un package utilitaire petit et cohérent MAY exister lorsque sa responsabilité est claire.
|
||||
|
||||
## Nommage des modules
|
||||
|
||||
Lorsqu'un dépôt multi-langage ou multi-module utilise déjà une nomenclature de rôles commune, les modules Java SHOULD conserver les mêmes suffixes conceptuels afin de rester lisibles à l'échelle du dépôt.
|
||||
|
||||
Exemples usuels :
|
||||
|
||||
```text
|
||||
foo-api
|
||||
foo-lib
|
||||
foo-app
|
||||
foo-cli
|
||||
foo-server
|
||||
foo-service
|
||||
foo-worker
|
||||
foo-tool
|
||||
foo-demo
|
||||
foo-smoke
|
||||
foo-poc
|
||||
```
|
||||
|
||||
Ce vocabulaire est une convention de rôle et non une obligation de créer artificiellement des modules séparés.
|
||||
|
||||
## Imports
|
||||
|
||||
Les imports wildcard SHOULD NOT être utilisés :
|
||||
|
||||
```java
|
||||
import foo.*;
|
||||
import static foo.Bar.*;
|
||||
```
|
||||
|
||||
Les imports explicites sont préférés afin de conserver l'origine des symboles visible.
|
||||
|
||||
Les imports statiques SHOULD être évités par défaut dans le code produit lorsqu'une forme qualifiée reste lisible. Une règle de test ou de framework plus spécifique MAY autoriser une convention différente lorsqu'elle est réellement idiomatique et bornée.
|
||||
|
||||
## Visibilité et API
|
||||
|
||||
La visibilité minimale appropriée est la règle par défaut :
|
||||
|
||||
```text
|
||||
private
|
||||
→ package-private
|
||||
→ protected
|
||||
→ public
|
||||
```
|
||||
|
||||
Une méthode ou un type MUST NOT devenir `public` uniquement pour faciliter un test.
|
||||
|
||||
Une interface Java SHOULD exister lorsqu'elle représente une vraie frontière : plusieurs implémentations, contrat consommé indépendamment, adaptation de plateforme, API publique ou autre séparation architecturale réelle.
|
||||
|
||||
PGR SHOULD NOT généraliser le pattern `Foo` / `FooImpl` lorsqu'une seule implémentation existe sans frontière utile.
|
||||
|
||||
## Annotations et génération implicite
|
||||
|
||||
PGR n'interdit pas les annotations en tant que mécanisme Java.
|
||||
|
||||
Les annotations fonctionnelles faisant partie du contrat officiel d'un framework ou d'une API sont légitimes, par exemple pour la persistance, la validation, l'injection, le routage ou d'autres mécanismes officiellement documentés.
|
||||
|
||||
En revanche, Lombok et les outils équivalents de convenience/codegen implicite SHOULD NOT être utilisés par défaut lorsqu'ils servent principalement à masquer du boilerplate, générer des constructeurs/getters/setters ou modifier implicitement l'API visible dans la source.
|
||||
|
||||
Une exception exige une justification explicite et reste attachée au projet ou framework concerné.
|
||||
|
||||
## Nullabilité
|
||||
|
||||
`null` SHOULD apparaître uniquement lorsqu'il appartient explicitement au contrat.
|
||||
|
||||
Une API ne devrait pas laisser le caller deviner si l'absence est possible. Selon le cas, le contrat peut employer :
|
||||
|
||||
- `Optional<T>` ;
|
||||
- une collection vide ;
|
||||
- une exception appropriée ;
|
||||
- un type résultat plus explicite ;
|
||||
- une annotation de nullabilité reconnue par le projet.
|
||||
|
||||
PGR MUST NOT imposer `Optional` partout. L'objectif est l'explicitation du contrat, pas une cérémonie syntaxique.
|
||||
|
||||
## Exceptions
|
||||
|
||||
Java possède un mécanisme natif d'exceptions ; PGR ne recrée pas automatiquement un modèle `Result` autour de toutes les opérations.
|
||||
|
||||
La distinction checked/unchecked appartient au contrat de la couche concernée.
|
||||
|
||||
Un `catch` SHOULD exister uniquement lorsque la couche sait réellement traiter, traduire ou enrichir l'erreur. Les captures silencieuses de `Exception` ou `Throwable` sont interdites hors mécanisme de frontière explicitement spécialisé.
|
||||
|
||||
Lorsqu'une erreur est traduite, sa cause SHOULD être préservée lorsque cette information reste pertinente.
|
||||
|
||||
Une couche SHOULD exposer ses propres erreurs de contrat plutôt que propager sans contrôle les détails techniques d'une dépendance interne.
|
||||
|
||||
## Tests Java
|
||||
|
||||
Les tests comportementaux et structurels gardent des responsabilités distinctes.
|
||||
|
||||
Les tests unitaires résident normalement sous `src/test/java/`. Les tests d'intégration, environnementaux ou live SHOULD être séparés par source set, module ou tâche lorsque leur exécution possède des préconditions différentes.
|
||||
|
||||
Les tests MUST NOT :
|
||||
|
||||
- rendre publique une API uniquement pour l'atteindre ;
|
||||
- rechercher des chaînes dans les sources pour simuler un audit d'architecture ;
|
||||
- vérifier une prerelease en codant en dur la version courante ;
|
||||
- ouvrir `VERSION`, `pom.xml` ou `build.gradle` uniquement pour confirmer leur synchronisation.
|
||||
|
||||
Les contraintes structurelles appartiennent au build system, au compilateur, à un linter adapté ou à un audit read-only.
|
||||
|
||||
## Maven — ownership du build
|
||||
|
||||
Dans un projet Maven multi-module, le POM parent/root SHOULD centraliser ce qui est réellement commun :
|
||||
|
||||
- version du projet lorsqu'elle doit être reflétée par Maven ;
|
||||
- niveau Java cible ;
|
||||
- `dependencyManagement` ;
|
||||
- `pluginManagement` ;
|
||||
- configuration commune de compilation et de tests.
|
||||
|
||||
Les modules SHOULD hériter de cette politique lorsque Maven le permet et ne pas recopier les mêmes versions/configurations sans nécessité.
|
||||
|
||||
Le fichier PGR `VERSION` reste la version canonique de l'unité de release. Le `pom.xml` racine porte un miroir technique lorsque Maven exige cette valeur. Les enfants SHOULD hériter de la version parent afin d'éviter les modifications mécaniques répétées de nombreux POM.
|
||||
|
||||
`dependencyManagement` centralise les contraintes de version communes ; il ne signifie pas qu'une dépendance doit être effectivement ajoutée à tous les modules. Chaque module déclare uniquement ce qu'il utilise.
|
||||
|
||||
## Maven Wrapper
|
||||
|
||||
Deux politiques sont légitimes :
|
||||
|
||||
```text
|
||||
Maven système
|
||||
→ environnement contrôlé
|
||||
→ contrainte de version documentée
|
||||
|
||||
Maven Wrapper
|
||||
→ distribution / CI / onboarding reproductible
|
||||
→ wrapper versionné
|
||||
```
|
||||
|
||||
PGR MUST NOT ajouter un Maven Wrapper uniquement par cérémonie.
|
||||
|
||||
Lorsqu'un wrapper est retenu, ses fichiers requis sont versionnés et constituent une exception explicite à la politique générale qui ignore les outputs générés.
|
||||
|
||||
## Validation Maven
|
||||
|
||||
Le développement SHOULD privilégier les gates ciblées avant le reactor complet.
|
||||
|
||||
Exemple avec wrapper :
|
||||
|
||||
```bash
|
||||
./mvnw -pl <module> -am test
|
||||
```
|
||||
|
||||
Exemple avec Maven système :
|
||||
|
||||
```bash
|
||||
mvn -pl <module> -am test
|
||||
```
|
||||
|
||||
Les gates globales telles que le reactor complet, `verify` ou le packaging de tous les modules SHOULD être réservées aux changements transverses et aux phases où elles fournissent une preuve supplémentaire réelle.
|
||||
|
||||
`clean` est une opération de maintenance et MUST NOT précéder automatiquement chaque validation.
|
||||
|
||||
## Gradle — ownership du build
|
||||
|
||||
Un projet Gradle SHOULD centraliser la configuration commune au niveau root lorsqu'elle est réellement partagée.
|
||||
|
||||
Selon le DSL retenu, les propriétaires typiques sont :
|
||||
|
||||
```text
|
||||
settings.gradle / settings.gradle.kts
|
||||
build.gradle / build.gradle.kts
|
||||
gradle.properties
|
||||
```
|
||||
|
||||
Les sous-projets SHOULD NOT recopier sans nécessité :
|
||||
|
||||
- la compatibilité Java ;
|
||||
- les repositories ;
|
||||
- les versions de plugins ;
|
||||
- les contraintes de dépendances ;
|
||||
- les configurations de tests communes.
|
||||
|
||||
Un version catalog tel que `gradle/libs.versions.toml` MAY être utilisé lorsque la taille du projet le justifie. PGR MUST NOT l'imposer pour un projet qui n'en tire aucun bénéfice réel.
|
||||
|
||||
## Gradle Wrapper et version de Gradle
|
||||
|
||||
La contrainte Gradle doit refléter la matrice réellement supportée par le projet :
|
||||
|
||||
```text
|
||||
minimum seulement
|
||||
range min..max
|
||||
version exacte/pinnée
|
||||
latest compatible
|
||||
```
|
||||
|
||||
Le projet MUST choisir la forme la moins restrictive qui prouve réellement sa compatibilité.
|
||||
|
||||
Un Gradle Wrapper SHOULD être versionné lorsqu'il apporte une reproductibilité utile pour la distribution, la CI ou l'onboarding. Un projet contrôlé MAY utiliser un Gradle système si sa contrainte de compatibilité est explicitement vérifiée.
|
||||
|
||||
Une plateforme ou un framework plus spécifique MAY imposer une contrainte plus étroite. Cette contrainte ne se propage jamais implicitement aux autres projets Gradle.
|
||||
|
||||
## DSL Gradle
|
||||
|
||||
PGR ne transforme pas une préférence de langage applicatif en interdiction du DSL de build.
|
||||
|
||||
Groovy DSL et Kotlin DSL sont tous deux reconnus. Un projet SHOULD retenir un DSL canonique et éviter de les mélanger arbitrairement.
|
||||
|
||||
Le code applicatif Java reste Java par défaut lorsque rien n'impose Kotlin/Groovy. Les scripts Gradle SHOULD rester aussi déclaratifs et courts que raisonnablement possible.
|
||||
|
||||
Une logique de build devenue importante SHOULD être déplacée vers une abstraction ou un plugin clairement possédé plutôt que grossir indéfiniment les scripts root.
|
||||
|
||||
## Validation Gradle
|
||||
|
||||
Les tâches ciblées sont préférées pendant le développement :
|
||||
|
||||
```bash
|
||||
./gradlew :<module>:test
|
||||
```
|
||||
|
||||
ou, lorsqu'un Gradle système est explicitement retenu :
|
||||
|
||||
```bash
|
||||
gradle :<module>:test
|
||||
```
|
||||
|
||||
Les tâches globales `check`, `build`, `assemble` ou de packaging complet SHOULD être sélectionnées lorsqu'elles correspondent réellement au scope, typiquement lors d'un changement transverse ou dans les phases de stabilisation/release.
|
||||
|
||||
`gradle clean` est une opération de maintenance et MUST NOT être utilisé comme précondition automatique à chaque build.
|
||||
|
||||
## Outputs, état local et Git
|
||||
|
||||
Les sorties de build et caches usuels ne sont pas versionnés :
|
||||
|
||||
```text
|
||||
Maven: target/
|
||||
Gradle: .gradle/, build/
|
||||
```
|
||||
|
||||
Les métadonnées IDE spécifiques à une machine restent ignorées sauf exception explicitement partagée selon les règles générales du projet.
|
||||
|
||||
Les wrappers retenus sont une exception volontaire : ils peuvent être générés par l'outil, mais leurs fichiers nécessaires au bootstrap reproductible sont versionnés.
|
||||
|
||||
Les fichiers de configuration locale contenant chemins machine, credentials ou overrides développeur restent hors Git. Un template est ajouté uniquement lorsqu'un utilisateur doit réellement préparer une valeur non régénérée automatiquement.
|
||||
|
||||
## Validation et futurs audits PGR
|
||||
|
||||
Les catégories et l'autorité du gate restent possédées par [`400-VALIDATION.md`](400-VALIDATION.md).
|
||||
|
||||
Ce profil définit des commandes et politiques Java/Maven/Gradle, mais PGR lui-même ne possède actuellement aucun projet Java, Maven ou Gradle à compiler. Aucune commande Maven/Gradle n'est donc ajoutée à la gate documentaire de cette tranche.
|
||||
|
||||
De même, aucun audit Java/Maven/Gradle n'est créé uniquement pour matérialiser un outil.
|
||||
|
||||
Lorsqu'un skeleton ou projet réel fournira un sujet stable, des audits monotâches MAY vérifier séparément des propriétés objectivement structurelles, par exemple la cohérence `VERSION`/POM, l'héritage d'une politique Maven ou la contrainte Gradle déclarée. Ils resteront read-only et ne lanceront jamais Maven ou Gradle à la place de leurs gates propres.
|
||||
65
docs/rules/600-PLATFORMS.md
Normal file
65
docs/rules/600-PLATFORMS.md
Normal file
@@ -0,0 +1,65 @@
|
||||
<!-- file: docs/rules/600-PLATFORMS.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Règles de profils plateforme
|
||||
|
||||
## Scope
|
||||
|
||||
Cette famille définit le contrat commun des profils liés à une plateforme de build, d'exécution ou de distribution telle qu'Android, iOS, Desktop, Web ou une cible embarquée lorsqu'un profil réel le justifie.
|
||||
|
||||
Les règles propres à une plateforme sont ajoutées dans des documents plus spécifiques uniquement lorsqu'elles possèdent un contenu normatif réel.
|
||||
|
||||
## Responsabilités de la famille
|
||||
|
||||
Un profil plateforme MAY posséder les règles spécifiques concernant notamment :
|
||||
|
||||
- la structure de projet imposée ou conventionnelle sur cette plateforme ;
|
||||
- les SDKs, targets, runtimes et niveaux minimums supportés ;
|
||||
- les contraintes de toolchain réellement imposées par la plateforme ;
|
||||
- les permissions, manifests, capabilities ou métadonnées de plateforme ;
|
||||
- le packaging, la signature et les artefacts de distribution ;
|
||||
- les émulateurs, simulateurs, appareils ou environnements nécessaires aux smokes ;
|
||||
- les adaptations de lifecycle, input ou services réellement propres à la plateforme ;
|
||||
- les contraintes de compatibilité utilisateur liées à une version minimale de target/runtime.
|
||||
|
||||
Un profil plateforme MUST NOT recopier les règles du langage ou du build tool lorsque celles-ci restent valides sans spécialisation.
|
||||
|
||||
## Composition avec les langages et build tools
|
||||
|
||||
Une plateforme peut être utilisée avec plusieurs langages ou toolchains. Son profil ne doit donc pas supposer implicitement une combinaison unique lorsque la plateforme elle-même ne l'impose pas.
|
||||
|
||||
Lorsqu'une plateforme impose une contrainte plus précise à un langage ou build tool déjà applicable, la règle plateforme peut la raffiner ou la remplacer dans son scope à condition d'identifier clairement la contrainte et sa raison.
|
||||
|
||||
Cette contrainte MUST NOT se propager aux projets utilisant le même langage hors de cette plateforme.
|
||||
|
||||
## Toolchain de build et compatibilité de target
|
||||
|
||||
La modernité de la toolchain de build et la version minimale du runtime ou de la target sont deux décisions distinctes.
|
||||
|
||||
L'utilisation d'un SDK, compilateur ou build tool récent ne justifie pas à elle seule l'augmentation de la version minimale supportée par les utilisateurs.
|
||||
|
||||
Une hausse d'un minimum de target/runtime constitue un changement de compatibilité et doit être justifiée par une contrainte ou un bénéfice réel du projet.
|
||||
|
||||
Inversement, un minimum ancien ne doit pas être conservé artificiellement lorsqu'il empêche une capacité nécessaire, une maintenance raisonnable ou une chaîne de build supportée.
|
||||
|
||||
## Packaging, secrets et configuration locale
|
||||
|
||||
Les règles de packaging ou de signature spécifiques à une plateforme peuvent appartenir à son profil, mais les secrets eux-mêmes restent soumis aux règles générales PGR et ne sont jamais versionnés.
|
||||
|
||||
Une plateforme peut nécessiter des fichiers locaux ou générés particuliers ; leur politique Git doit être documentée dans le profil spécifique seulement lorsqu'elle diffère réellement du contrat général.
|
||||
|
||||
## Validation spécialisée
|
||||
|
||||
Un profil plateforme peut définir les builds, packages et smokes réellement nécessaires pour prouver le support annoncé.
|
||||
|
||||
La présence d'une plateforme dans un projet ne rend pas automatiquement tous ses smokes obligatoires à chaque tranche. La sélection reste proportionnée au scope modifié et aux preuves invalidées.
|
||||
|
||||
Les validations nécessitant un appareil, un simulateur, un service externe ou une chaîne de packaging réelle doivent être distinguées des contrôles documentaires ou unitaires qui ne prouvent pas ces comportements.
|
||||
|
||||
## Nomenclature documentaire
|
||||
|
||||
Le document `600-PLATFORMS.md` possède le contrat commun de la famille.
|
||||
|
||||
Les profils spécifiques utilisent la plage `610` à `699`. Leur numéro sert à la navigation et ne détermine pas une priorité normative implicite.
|
||||
|
||||
La résolution entre profils suit [`../architecture/003-RULE_PROFILE_MODEL.md`](../architecture/003-RULE_PROFILE_MODEL.md).
|
||||
316
docs/rules/610-ANDROID.md
Normal file
316
docs/rules/610-ANDROID.md
Normal file
@@ -0,0 +1,316 @@
|
||||
<!-- file: docs/rules/610-ANDROID.md -->
|
||||
<!-- version: 2 -->
|
||||
|
||||
# Profil Android
|
||||
|
||||
## Rôle
|
||||
|
||||
Ce document possède les règles réutilisables propres à la plateforme Android.
|
||||
|
||||
Il complète [`600-PLATFORMS.md`](600-PLATFORMS.md) et, lorsqu'un projet Android utilise Java/Gradle, [`520-JAVA_MAVEN_GRADLE.md`](520-JAVA_MAVEN_GRADLE.md).
|
||||
|
||||
Une contrainte Android plus spécifique MAY raffiner les règles générales Java ou Gradle dans le seul scope Android lorsqu'une matrice AGP/Gradle/JDK, un SDK ou une contrainte de distribution l'impose.
|
||||
|
||||
Les profils Rust/JNI et Tauri ne sont pas définis ici. Ils constituent des compositions plus spécialisées et MUST NOT contaminer le profil Android général.
|
||||
|
||||
## Structure du projet
|
||||
|
||||
Pour un dépôt exclusivement Android, les conventions Android normales restent prioritaires et la racine du dépôt MAY être directement le projet Gradle.
|
||||
|
||||
Dans un dépôt multi-plateforme où une zone Android distincte est nécessaire, PGR SHOULD utiliser la racine :
|
||||
|
||||
```text
|
||||
Android/
|
||||
```
|
||||
|
||||
Cette racine est alors un chemin de plateforme stable. Elle ne doit pas être renommée arbitrairement en `android/`, `mobile/` ou autre uniquement par préférence locale.
|
||||
|
||||
Une structure multi-plateforme peut par exemple contenir :
|
||||
|
||||
```text
|
||||
project/
|
||||
├── VERSION
|
||||
├── crates/
|
||||
├── Web/
|
||||
└── Android/
|
||||
├── settings.gradle
|
||||
├── build.gradle
|
||||
├── gradle.properties
|
||||
├── gradlew
|
||||
├── gradlew.bat
|
||||
└── gradle/
|
||||
```
|
||||
|
||||
Les noms et fichiers exacts restent soumis au projet Android réellement utilisé ; PGR ne crée pas de niveau `Android/` artificiel dans un dépôt qui est déjà exclusivement Android.
|
||||
|
||||
## Langage applicatif et logique de build
|
||||
|
||||
Java est le langage applicatif Android par défaut du profil PGR lorsqu'aucune API, framework ou contrainte réelle n'impose un autre choix.
|
||||
|
||||
Kotlin MAY être utilisé lorsqu'une API, un framework ou une intégration l'exige réellement.
|
||||
|
||||
Groovy DSL ou Kotlin DSL MAY être utilisés par Gradle comme langage de configuration. Leur présence dans le build ne transforme pas Kotlin ou Groovy en langage applicatif du projet.
|
||||
|
||||
Les fichiers Gradle SHOULD rester aussi déclaratifs et courts que raisonnablement possible. Une logique de build importante SHOULD être possédée par une abstraction ou un plugin identifiable plutôt que devenir du code produit caché dans un script Gradle.
|
||||
|
||||
Les annotations fonctionnelles Android ou de frameworks restent autorisées lorsqu'elles constituent le mécanisme officiel de l'API concernée.
|
||||
|
||||
## Matrice AGP / Gradle / JDK
|
||||
|
||||
Un projet Android MUST exprimer une chaîne de build compatible.
|
||||
|
||||
La matrice conceptuelle est :
|
||||
|
||||
```text
|
||||
Android Gradle Plugin
|
||||
↕
|
||||
Gradle
|
||||
↕
|
||||
JDK LTS
|
||||
```
|
||||
|
||||
PGR MUST NOT imposer globalement une version Gradle, AGP ou JDK uniquement parce qu'elle est utilisée par un autre projet Android.
|
||||
|
||||
La contrainte applicable peut être :
|
||||
|
||||
```text
|
||||
minimum
|
||||
range min..max
|
||||
version exacte / pin
|
||||
latest compatible
|
||||
```
|
||||
|
||||
Le projet choisit la forme la moins restrictive qui reste réellement compatible avec sa stack.
|
||||
|
||||
Le JDK suit le profil Java : dernière LTS compatible par défaut, LTS plus ancienne lorsqu'une contrainte Android ou de framework l'impose, non-LTS uniquement par exception justifiée.
|
||||
|
||||
Lorsque le Gradle Wrapper est retenu, ses fichiers requis sont versionnés et sa version doit satisfaire la matrice réelle AGP/Gradle/JDK.
|
||||
|
||||
## `compileSdk`, `targetSdk` et `minSdk`
|
||||
|
||||
Ces trois valeurs représentent des contrats différents.
|
||||
|
||||
`compileSdk` définit l'API Android utilisée pour compiler. Il MAY être récent afin de permettre l'usage des APIs et outils actuels.
|
||||
|
||||
`targetSdk` déclare le niveau de comportement Android pour lequel l'application a été adaptée. Il MUST respecter les exigences applicables au canal de distribution réellement visé.
|
||||
|
||||
`minSdk` définit la plus ancienne version Android que le produit promet de pouvoir installer et exécuter.
|
||||
|
||||
PGR MUST NOT déduire une hausse de `minSdk` d'une hausse de `compileSdk` ou `targetSdk`.
|
||||
|
||||
`minSdk` SHOULD rester aussi bas que raisonnablement supportable tant que cela ne compromet pas une capacité nécessaire, une dépendance imposée, la sécurité ou une maintenance raisonnable.
|
||||
|
||||
Une hausse de `minSdk` est un changement de compatibilité utilisateur et MUST être explicitement justifiée.
|
||||
|
||||
## `VERSION`, `versionName` et `versionCode`
|
||||
|
||||
Lorsqu'une application Android appartient au même release train que le projet, le fichier PGR `VERSION` reste la version SemVer canonique de cette unité de release.
|
||||
|
||||
`versionName` est un miroir technique de cette version lorsqu'elle doit représenter la même release à l'utilisateur ou au canal de distribution.
|
||||
|
||||
`versionCode` est un compteur Android monotone distinct du SemVer.
|
||||
|
||||
PGR MUST NOT confondre `versionCode` avec `VERSION` ou `versionName`.
|
||||
|
||||
Pour une application publiée, `versionCode` MUST NOT diminuer. Lorsqu'un dépôt publie plusieurs applications indépendantes, chaque application MAY posséder son propre compteur versionné.
|
||||
|
||||
Le projet MAY stocker ce compteur dans un fichier explicite tel que :
|
||||
|
||||
```text
|
||||
Android/app/VERSION_CODE
|
||||
```
|
||||
|
||||
si cela correspond à son architecture.
|
||||
|
||||
PGR SHOULD NOT imposer une formule dérivant automatiquement `versionCode` du SemVer sans décision explicite du projet.
|
||||
|
||||
Un futur audit read-only MAY vérifier séparément :
|
||||
|
||||
```text
|
||||
VERSION ↔ versionName
|
||||
VERSION_CODE ↔ configuration Android
|
||||
```
|
||||
|
||||
lorsqu'un projet ou skeleton réel fournit des fichiers à contrôler. Cet audit ne doit jamais modifier les versions.
|
||||
|
||||
## Configuration locale
|
||||
|
||||
`local.properties` est un fichier local Android typique et SHOULD rester hors Git lorsqu'il contient des chemins machine tels que l'emplacement du SDK.
|
||||
|
||||
PGR MUST NOT utiliser `local.properties` comme source normative de configuration partagée du projet.
|
||||
|
||||
Si l'outil ou l'IDE régénère intégralement ce fichier, aucun fichier exemple n'est nécessaire.
|
||||
|
||||
Lorsqu'une propriété locale obligatoire n'est pas automatiquement reproductible, un template MAY être fourni conformément aux règles générales PGR.
|
||||
|
||||
La même politique s'applique aux fichiers locaux analogues tels que `keystore.properties`, `user.properties` ou des variantes `*.local.properties` lorsqu'ils contiennent des valeurs propres à la machine ou à l'utilisateur.
|
||||
|
||||
## Signing et secrets
|
||||
|
||||
L'interdiction générale de versionner ou distribuer des secrets reste possédée par `RULES.md`. Le profil Android ajoute uniquement les conséquences propres au signing de cette plateforme.
|
||||
|
||||
Dans le scope Android, les éléments suivants sont notamment des secrets ou artefacts privés soumis à cette interdiction :
|
||||
|
||||
```text
|
||||
release keystore
|
||||
private signing key
|
||||
passwords
|
||||
credentials
|
||||
service account secret
|
||||
```
|
||||
|
||||
Une configuration versionnée MAY référencer des variables ou propriétés telles que :
|
||||
|
||||
```text
|
||||
RELEASE_KEYSTORE
|
||||
RELEASE_KEY_ALIAS
|
||||
```
|
||||
|
||||
mais MUST NOT contenir leurs valeurs privées.
|
||||
|
||||
Le debug keystore généré automatiquement est local.
|
||||
|
||||
Le signing de release ne doit pas être requis pour une validation ordinaire de développement sauf lorsque la tranche valide précisément la distribution ou la signature finale.
|
||||
|
||||
## Modules Android
|
||||
|
||||
Les modules Android SHOULD être nommés par responsabilité.
|
||||
|
||||
Des noms tels que :
|
||||
|
||||
```text
|
||||
app
|
||||
common
|
||||
game-reflex
|
||||
game-snake
|
||||
```
|
||||
|
||||
peuvent être légitimes lorsque ces responsabilités existent réellement.
|
||||
|
||||
Des noms opaques tels que `module1`, `module2`, `misc` ou `utils2` SHOULD NOT servir de structure durable.
|
||||
|
||||
Un module partagé doit posséder une responsabilité commune réelle ; il ne doit pas devenir un dépôt générique de code sans owner.
|
||||
|
||||
## Dépendances Android
|
||||
|
||||
Les dépendances Android doivent rester minimales et explicites.
|
||||
|
||||
Une dépendance officielle et étroite SHOULD être préférée à un framework beaucoup plus large lorsqu'une petite capability suffit.
|
||||
|
||||
À l'inverse, PGR SHOULD NOT réimplémenter une API de plateforme, un protocole standard ou une primitive de sécurité uniquement pour éviter une dépendance officielle appropriée.
|
||||
|
||||
Une BOM ou un mécanisme officiel de gestion de versions MAY être utilisé lorsqu'il réduit réellement les incompatibilités. Il ne doit pas entraîner l'ajout automatique de toute une famille de dépendances non utilisées.
|
||||
|
||||
La politique d'un lockfile Android/Gradle, lorsqu'un projet en utilise un, doit être décidée selon le besoin réel de cet écosystème et du projet. Elle n'est pas déduite automatiquement d'un autre profil.
|
||||
|
||||
## ABI et code natif
|
||||
|
||||
Un projet Android purement Java peut ne posséder aucune règle ABI spécifique.
|
||||
|
||||
Dès qu'un projet contient du code natif via NDK, C/C++, Rust ou une autre frontière native, les ABI réellement supportées MUST être déclarées explicitement.
|
||||
|
||||
Exemples possibles :
|
||||
|
||||
```text
|
||||
arm64-v8a
|
||||
armeabi-v7a
|
||||
x86_64
|
||||
```
|
||||
|
||||
PGR ne fixe pas une liste universelle d'ABI.
|
||||
|
||||
Une ABI annoncée comme supportée doit disposer d'une preuve adaptée. Une cross-compilation native seule ne prouve pas l'intégration dans l'APK, le lifecycle Android ni l'exécution sur device/AVD.
|
||||
|
||||
Les règles JNI elles-mêmes appartiennent à un profil spécialisé et restent hors de ce document.
|
||||
|
||||
## Niveaux de tests Android
|
||||
|
||||
PGR distingue au moins trois niveaux de preuve Android lorsqu'ils sont applicables :
|
||||
|
||||
```text
|
||||
JVM unit
|
||||
→ logique ne nécessitant pas le runtime Android
|
||||
|
||||
instrumented / integration
|
||||
→ comportement nécessitant le framework Android
|
||||
|
||||
smoke device / AVD
|
||||
→ application ou package réel dans un environnement Android
|
||||
```
|
||||
|
||||
Un test JVM MUST NOT être enregistré comme preuve d'un comportement réel d'`Activity`, de lifecycle ou de device.
|
||||
|
||||
Un test instrumenté ne remplace pas automatiquement un smoke du package final.
|
||||
|
||||
Un appareil physique n'est pas obligatoire pour chaque release. Il devient nécessaire lorsqu'une propriété annoncée dépend d'un matériel ou comportement qui ne peut pas être suffisamment prouvé par AVD.
|
||||
|
||||
## Ordre de validation Android
|
||||
|
||||
Une validation Android ordinaire SHOULD progresser du ciblé vers le plus coûteux :
|
||||
|
||||
```text
|
||||
format applicable
|
||||
↓
|
||||
audits read-only applicables
|
||||
↓
|
||||
compilation module ciblé
|
||||
↓
|
||||
lint Android ciblé
|
||||
↓
|
||||
unit tests ciblés
|
||||
↓
|
||||
assemble/package lorsque nécessaire
|
||||
↓
|
||||
install
|
||||
↓
|
||||
smoke
|
||||
```
|
||||
|
||||
Les tests globaux, l'instrumentation large, les bundles de release, les matrices multi-ABI et les smokes multi-device sont sélectionnés lorsque le scope ou la phase de release l'exige réellement.
|
||||
|
||||
Les commandes exactes appartiennent à la matrice du projet ou du skeleton qui possède un Android build réel.
|
||||
|
||||
`clean` reste une opération de maintenance et ne doit pas précéder automatiquement chaque gate.
|
||||
|
||||
## Manifest et ressources
|
||||
|
||||
`AndroidManifest.xml` MUST déclarer uniquement les permissions et capabilities réellement nécessaires.
|
||||
|
||||
Une permission sensible ne doit pas être ajoutée « au cas où ». Son introduction constitue un changement significatif qui doit être visible dans le delta et, lorsque pertinent, dans la documentation de release.
|
||||
|
||||
`src/main/res/` reste la source canonique des ressources Android d'un module standard.
|
||||
|
||||
Dans un projet multi-plateforme, des assets réellement partagés MAY vivre dans un owner commun hors d'Android si leur consommation est définie clairement.
|
||||
|
||||
PGR SHOULD NOT maintenir manuellement plusieurs copies divergentes du même asset source dans des arborescences de plateforme différentes.
|
||||
|
||||
## APK, AAB et artefacts de distribution
|
||||
|
||||
PGR distingue les rôles des principaux artefacts :
|
||||
|
||||
```text
|
||||
APK debug
|
||||
→ développement et smokes ordinaires
|
||||
|
||||
APK release
|
||||
→ validation d'un package release installable lorsque nécessaire
|
||||
|
||||
AAB
|
||||
→ artefact de distribution lorsque le canal cible l'exige
|
||||
```
|
||||
|
||||
La phase de release et le scope modifié déterminent l'artefact nécessaire.
|
||||
|
||||
Une alpha documentaire n'a pas besoin d'un package Android réel si aucun projet Android n'est concerné. Une release d'une application Android peut au contraire nécessiter un package ou smoke réel lorsque `versionName`, `versionCode`, signing ou packaging sont modifiés.
|
||||
|
||||
La promotion stable ne doit pas provoquer mécaniquement un full rebuild sans preuve invalidée ; elle doit toutefois revalider le packaging ciblé lorsque les métadonnées qui entrent dans l'artefact ont changé.
|
||||
|
||||
## Validation et futurs audits PGR
|
||||
|
||||
Les catégories générales et l'autorité du gate restent possédées par [`400-VALIDATION.md`](400-VALIDATION.md).
|
||||
|
||||
PGR lui-même ne contient actuellement aucun projet Android à compiler, installer ou exécuter. Cette tranche ne prétend donc pas valider AGP, Gradle, SDK, AVD, APK ou AAB réels.
|
||||
|
||||
Aucun audit Android spécialisé n'est créé uniquement pour remplir le profil.
|
||||
|
||||
Lorsqu'un skeleton ou projet concret fournira les fichiers nécessaires, des audits monotâches MAY vérifier des propriétés structurelles stables telles que la cohérence de version, la présence d'une configuration locale ignorée ou une matrice de compatibilité explicitement déclarée. Ces audits restent read-only et ne remplacent jamais Gradle, Android Lint, l'installation ou les smokes.
|
||||
125
docs/rules/700-FRAMEWORKS.md
Normal file
125
docs/rules/700-FRAMEWORKS.md
Normal file
@@ -0,0 +1,125 @@
|
||||
<!-- file: docs/rules/700-FRAMEWORKS.md -->
|
||||
<!-- version: 2 -->
|
||||
|
||||
# Règles de profils framework
|
||||
|
||||
## Scope
|
||||
|
||||
Cette famille définit le contrat commun des profils liés à un framework réellement utilisé par le projet.
|
||||
|
||||
Un framework peut combiner plusieurs owners déjà applicables — langage/écosystème, plateforme, frontend, packaging ou runtime — sans devenir propriétaire de leurs règles générales. Son profil possède uniquement les contraintes et l'orchestration ajoutées par le framework lui-même.
|
||||
|
||||
## Responsabilités de la famille
|
||||
|
||||
Un profil framework MAY posséder les règles spécifiques concernant notamment :
|
||||
|
||||
- les fichiers de configuration réellement possédés par le framework ;
|
||||
- la relation entre plusieurs toolchains que le framework orchestre ;
|
||||
- les commandes de développement, build, packaging ou génération qui passent par son CLI ;
|
||||
- les hooks exécutés par ce CLI et leur ordre de responsabilité ;
|
||||
- les permissions, capabilities, manifests ou métadonnées propres au framework ;
|
||||
- les artefacts générés par le framework et leur classification source/généré ;
|
||||
- la cohérence de version lorsque le framework possède une version applicative distincte ou dérivée ;
|
||||
- les gates d'intégration que les outils sous-jacents ne prouvent pas isolément.
|
||||
|
||||
Un profil framework MUST NOT recopier les règles d'un langage, d'une plateforme ou d'un build tool lorsqu'elles restent valides sans spécialisation.
|
||||
|
||||
## Composition
|
||||
|
||||
Un framework s'ajoute aux profils réellement applicables au projet. Il n'annule pas silencieusement les conventions des owners qu'il compose.
|
||||
|
||||
Par exemple :
|
||||
|
||||
```text
|
||||
GENERAL
|
||||
+ Rust / Cargo
|
||||
+ Tauri
|
||||
```
|
||||
|
||||
ou, pour une cible Android :
|
||||
|
||||
```text
|
||||
GENERAL
|
||||
+ Rust / Cargo
|
||||
+ Android
|
||||
+ Tauri
|
||||
```
|
||||
|
||||
Lorsque PGR gouverne la baseline du projet, les règles des profils hérités restent applicables dans leur scope complet tant qu'un override plus spécifique n'est pas documenté. Un framework ne constitue pas à lui seul une justification pour affaiblir une convention de langage, de plateforme ou de sécurité.
|
||||
|
||||
Un projet existant ou imposé de l'extérieur MAY conserver des contraintes différentes. Ces écarts appartiennent alors au niveau project-specific ou à une exception explicite et bornée ; ils ne doivent pas être remontés comme nouvelle règle générale du framework.
|
||||
|
||||
La présence d'un frontend WebView n'active pas automatiquement un futur profil Web/Vite/WASM. Ces technologies restent sélectionnées selon les faits du projet et leurs propres owners.
|
||||
|
||||
## Profil framework et convention d'instanciation
|
||||
|
||||
Le profil framework décrit ce qui reste vrai pour toute adoption conforme du framework. Une skeleton specification ou une baseline locale MAY choisir en plus un layout, un bundler, un langage frontend, un package manager ou des bibliothèques préférées pour les projets que l'organisation contrôle.
|
||||
|
||||
Ces valeurs d'instanciation ne deviennent pas des invariants du framework :
|
||||
|
||||
```text
|
||||
profil framework
|
||||
→ responsabilités et contraintes propres au framework
|
||||
|
||||
skeleton / projet local
|
||||
→ choix réutilisables de structure et de stack
|
||||
```
|
||||
|
||||
Cette séparation permet d'appliquer PGR à un projet imposé sans lui forcer le skeleton préféré des nouveaux projets.
|
||||
|
||||
## Ownership des commandes d'intégration
|
||||
|
||||
Lorsqu'un framework possède un CLI qui orchestre plusieurs étapes, la validation de l'intégration SHOULD utiliser ce CLI plutôt que rejouer manuellement ses sous-commandes comme si elles prouvaient le même contrat.
|
||||
|
||||
Une commande sous-jacente reste utile pour une preuve ciblée : compiler le backend ne prouve pas les hooks frontend ; construire le frontend seul ne prouve pas l'intégration native ; un build framework complet n'est pas requis pour une modification purement documentaire qui n'invalide aucune de ces propriétés.
|
||||
|
||||
La gate sélectionnée reste proportionnée au scope et à la maturité conformément à [`400-VALIDATION.md`](400-VALIDATION.md).
|
||||
|
||||
## Sources, générés et configuration locale
|
||||
|
||||
Un framework MAY produire des répertoires générés, projets de plateforme, schémas, bindings ou artefacts de build. Leur simple origine framework ne suffit pas à décider leur politique Git.
|
||||
|
||||
Le profil spécifique doit distinguer :
|
||||
|
||||
```text
|
||||
source intentionnelle
|
||||
configuration durable
|
||||
artefact reproductible
|
||||
généré modifié intentionnellement
|
||||
généré purement transitoire
|
||||
secret / configuration locale
|
||||
```
|
||||
|
||||
PGR MUST NOT appliquer une règle globale « tout `gen/` est ignoré » ou « tout généré est versionné » sans examiner le rôle réel de l'artefact.
|
||||
|
||||
Les secrets et valeurs locales restent possédés par les règles générales et les profils plateforme applicables.
|
||||
|
||||
## Version du framework et version produit
|
||||
|
||||
La version du framework/de ses dépendances et la version du produit sont deux contrats distincts.
|
||||
|
||||
Un projet MAY utiliser une plage compatible, un pin ou une politique de mise à jour adaptée au framework ; PGR ne copie pas une version observée dans un projet source comme règle générale.
|
||||
|
||||
Lorsqu'un framework expose une version applicative qui représente la même unité de release que `VERSION`, le profil spécifique doit définir une source de vérité ou une synchronisation explicite afin d'éviter plusieurs valeurs indépendantes.
|
||||
|
||||
## Validation spécialisée
|
||||
|
||||
Un profil framework doit expliquer ce que prouvent ses commandes propres et ce qu'elles ne prouvent pas.
|
||||
|
||||
Selon le scope, la preuve peut être :
|
||||
|
||||
- un check du langage/backend ;
|
||||
- un build/test frontend ;
|
||||
- un lancement framework avec smoke ciblé ;
|
||||
- un build/package framework ;
|
||||
- une validation de plateforme réelle lorsque le framework cible Android, iOS ou une autre plateforme.
|
||||
|
||||
Aucune de ces catégories n'est obligatoire à chaque tranche par simple présence du framework.
|
||||
|
||||
## Nomenclature documentaire
|
||||
|
||||
Le document `700-FRAMEWORKS.md` possède le contrat commun de la famille.
|
||||
|
||||
Les profils spécifiques utilisent la plage `710` à `799`. Leur numéro sert à la navigation et ne représente ni priorité normative, ni version du framework.
|
||||
|
||||
La résolution avec les autres profils suit [`../architecture/003-RULE_PROFILE_MODEL.md`](../architecture/003-RULE_PROFILE_MODEL.md).
|
||||
213
docs/rules/710-TAURI.md
Normal file
213
docs/rules/710-TAURI.md
Normal file
@@ -0,0 +1,213 @@
|
||||
<!-- file: docs/rules/710-TAURI.md -->
|
||||
<!-- version: 5 -->
|
||||
|
||||
# Profil Tauri 2
|
||||
|
||||
## Rôle et applicabilité
|
||||
|
||||
Ce document possède les règles réutilisables propres à une application utilisant Tauri 2 comme host natif et orchestrateur d'intégration entre un host Rust et un frontend WebView.
|
||||
|
||||
Il complète [`700-FRAMEWORKS.md`](700-FRAMEWORKS.md) et [`510-RUST_CARGO.md`](510-RUST_CARGO.md). Les profils plateforme réellement ciblés, par exemple [`610-ANDROID.md`](610-ANDROID.md), restent applicables et possèdent leurs contraintes de SDK, packaging et smoke de plateforme.
|
||||
|
||||
Le profil est volontairement borné à Tauri 2. Une future génération incompatible du framework doit être réévaluée avant d'hériter automatiquement de ces règles.
|
||||
|
||||
## Héritage Rust du host Tauri
|
||||
|
||||
Un host Tauri est un projet Rust/Cargo. Tauri ne crée aucune exception implicite aux règles Rust sélectionnées par le projet.
|
||||
|
||||
Pour un projet dont PGR gouverne la baseline, le host Tauri MUST appliquer le profil Rust/Cargo et les conventions Rust locales retenues exactement comme une autre crate ou application Rust du même projet : édition, lints, safety, erreurs, formatage, façade, chemins canoniques, imports, organisation des sources et audits applicables restent possédés par leur owner Rust.
|
||||
|
||||
Un exemple généré par `create-tauri-app`, une documentation de plugin ou une macro Tauri MAY employer un style différent ; il doit être adapté aux règles Rust du projet lorsqu'il est intégré. La présence de Tauri ne justifie donc pas à elle seule `unwrap`, `expect`, `?`, un `use` non autorisé, un chemin interne non canonique ou un affaiblissement des lints si le profil Rust sélectionné les interdit.
|
||||
|
||||
Un projet Tauri existant ou imposé de l'extérieur MAY conserver d'autres conventions Rust. Ces différences doivent être traitées comme règles project-specific ou overrides explicites, pas comme un relâchement du profil Tauri général.
|
||||
|
||||
## Composition avec le frontend
|
||||
|
||||
Tauri ne détermine pas à lui seul le framework frontend, le bundler, le langage de style ou le package manager du projet.
|
||||
|
||||
PGR MUST NOT imposer universellement Vite, TypeScript, Sass, Bootstrap, Tailwind CSS, npm, pnpm, yarn, Bun, WASM ou une arborescence frontend particulière uniquement parce que Tauri est utilisé.
|
||||
|
||||
Le frontend possède ses propres règles et peut être sélectionné par une skeleton specification ou par la baseline locale du projet. Le profil Tauri possède seulement le contrat d'intégration entre ce frontend et le host natif.
|
||||
|
||||
Pour les projets que l'organisation contrôle entièrement, une skeleton MAY choisir une stack frontend par défaut et un layout stable. Cette décision appartient au skeleton et aux futurs profils Web applicables, pas au présent owner Tauri.
|
||||
|
||||
## WASM
|
||||
|
||||
WASM n'est pas une composante implicite d'un projet Tauri. Un package ou projet WASM SHOULD être traité comme une unité distincte appliquant ses propres profils Rust/Web/WASM, même s'il partage le même dépôt ou certaines crates avec une application Tauri.
|
||||
|
||||
Une application Tauri MAY consommer explicitement un artefact WASM lorsqu'un besoin architectural réel le justifie. Cette composition doit alors être documentée comme telle ; elle ne transforme pas les règles WASM en règles Tauri et ne justifie pas de placer systématiquement une chaîne WASM dans les hooks Tauri.
|
||||
|
||||
## Layout et fichiers possédés par Tauri
|
||||
|
||||
PGR MUST NOT imposer universellement un répertoire `src-tauri/` ni recopier le layout de `create-tauri-app`. Le projet peut utiliser le layout standard de Tauri ou une intégration différente lorsque la toolchain la supporte clairement.
|
||||
|
||||
Les éléments suivants appartiennent néanmoins au scope Tauri lorsqu'ils existent :
|
||||
|
||||
- le manifeste Cargo du host natif ;
|
||||
- l'intégration build-time Tauri, généralement via `tauri-build` ;
|
||||
- la configuration Tauri supportée par la version du framework, par exemple `tauri.conf.json` ;
|
||||
- les capability files et permissions Tauri ;
|
||||
- les icônes, ressources ou métadonnées de bundle référencées par la configuration ;
|
||||
- les projets ou fichiers de plateforme produits/consommés par la toolchain Tauri.
|
||||
|
||||
Leur emplacement exact reste une décision du projet ou du skeleton retenu tant qu'il est supporté par la toolchain.
|
||||
|
||||
## Convention renforcée pour les projets contrôlés
|
||||
|
||||
Le contrat universel ci-dessus reste compatible avec des projets Tauri imposés de l'extérieur. Pour un **nouveau projet Tauri contrôlé par l'organisation** qui sélectionne le profil strict PGR, les conventions suivantes forment en revanche la baseline recommandée et ne doivent pas être abandonnées sans raison documentée.
|
||||
|
||||
Le host SHOULD être une crate Cargo mixte directement lisible, sans couche `src-tauri/` ajoutée uniquement pour reproduire `create-tauri-app`. Le layout recommandé est :
|
||||
|
||||
```text
|
||||
<tauri-crate>/
|
||||
├── Cargo.toml
|
||||
├── build.rs
|
||||
├── package.json
|
||||
├── tsconfig.json
|
||||
├── tauri.conf.json
|
||||
├── capabilities/
|
||||
├── src/
|
||||
└── frontend/
|
||||
```
|
||||
|
||||
Un fichier comme `vite.config.ts` appartient également à la racine lorsque Vite est le bundler sélectionné. Un projet externe MAY conserver `src-tauri/` ou une autre organisation lorsque cette structure est imposée ou qu'une migration n'apporte pas de valeur suffisante.
|
||||
|
||||
Dans le host Rust, le package mixte `lib + bin` constitue l'exception framework explicite à la séparation générale définie par `510-RUST_CARGO.md`. Pour une nouvelle baseline Tauri contrôlée :
|
||||
|
||||
- le package SHOULD déclarer explicitement une cible bibliothèque et une cible binaire ;
|
||||
- leurs noms MUST être distincts même après la normalisation Cargo usuelle des tirets en underscores ; un modèle valide est package/bin `project-feature-desk` et lib `project_feature_desk_lib` ;
|
||||
- `src/lib.rs` SHOULD rester une façade de modules/réexports et porter l'accès à la fonctionnalité applicative réutilisable ;
|
||||
- `src/main.rs` SHOULD rester un launcher mince vers une fonction publique de la bibliothèque applicative ; il MAY posséder le verrou/single-instance, les arguments strictement process et le bootstrap exécutable qui ne peut pas appartenir à la bibliothèque ;
|
||||
- `src/tauri.rs` SHOULD posséder l'assemblage Tauri et les wrappers `#[tauri::command]`, qui délèguent aux modules propriétaires plutôt que porter la logique métier ;
|
||||
- une fenêtre ou responsabilité UI non triviale SHOULD posséder un module cohérent, avec sous-modules si nécessaire ; les helpers réellement partagés entre plusieurs fenêtres/responsabilités SHOULD être déplacés dans des modules communs dédiés ;
|
||||
- un préfixe local comme `tw_` MAY être utilisé pour identifier les modules de fenêtres, mais PGR n'impose pas ce préfixe à tous les projets.
|
||||
|
||||
Lorsque le workspace possède une crate de logging/tracing commune, le host Tauri l'utilise pour initialiser le runtime de diagnostics. Un plugin Tauri de tracing sert alors d'adapter à la frontière desktop/mobile ; il ne remplace pas l'owner Rust de `tracing-subscriber`, des sinks ou du lifecycle de logging.
|
||||
|
||||
Lorsque le frontend sélectionné est TypeScript, les structures, énumérations et DTO Rust **possédés par le host** et partagés avec le frontend MUST utiliser TS-RS comme source de génération dans le profil strict, sauf incompatibilité technique explicitement documentée. Le contrat Rust reste la source de vérité ; les bindings générés ne sont pas modifiés manuellement et SHOULD rester hors Git lorsqu'ils sont entièrement reproductibles. Le skeleton MAY normaliser leur sortie sous `frontend/ts/bindings/`.
|
||||
|
||||
Pour les projets contrôlés, `frontend/` est le répertoire recommandé pour les sources Web versionnées. Vite + TypeScript + Sass constitue la stack candidate par défaut et Bootstrap est la baseline de présentation privilégiée lorsque le projet a besoin d'un framework CSS généraliste. Tailwind CSS n'est pas interdit par le profil Tauri, mais il n'est pas le choix PGR par défaut et son adoption demande une décision explicite du projet. Ces choix restent possédés par le futur skeleton et les profils Web correspondants.
|
||||
|
||||
L'intégration d'un plugin SHOULD préférer les étapes explicites décrites par sa documentation — dépendance Cargo, initialisation Rust, package frontend et capabilities nécessaires — afin que chaque modification reste visible et revue. `cargo tauri add` MAY être utilisé lorsque ce raccourci apporte une vraie valeur, mais il n'est pas la voie canonique imposée aux projets contrôlés.
|
||||
|
||||
WASM reste normalement une unité séparée de la crate Tauri. Une adaptation WASM réutilisable SHOULD donc posséder sa propre crate/package et ses propres profils ; elle n'est intégrée au host Tauri que lorsqu'une composition architecturale explicite l'exige.
|
||||
|
||||
## Ownership du build et hooks frontend
|
||||
|
||||
Lorsqu'une validation concerne l'intégration Tauri complète, le CLI Tauri est l'owner de l'orchestration.
|
||||
|
||||
Si `beforeDevCommand`, `beforeBuildCommand` ou un hook Tauri équivalent est configuré, la gate d'intégration SHOULD invoquer le CLI Tauri afin que ce hook soit exécuté dans le contexte prévu.
|
||||
|
||||
Ainsi :
|
||||
|
||||
```text
|
||||
cargo check / cargo clippy
|
||||
→ preuve Rust ciblée
|
||||
|
||||
frontend build/test direct
|
||||
→ preuve frontend ciblée
|
||||
|
||||
Tauri CLI dev/build
|
||||
→ preuve d'orchestration Tauri + hooks correspondants
|
||||
```
|
||||
|
||||
Un projet MUST NOT considérer `npm run build`, `cargo build` ou une autre sous-commande isolée comme équivalente à un build Tauri lorsque la propriété à valider dépend des hooks, de `frontendDist`, des capabilities, du contexte Tauri ou du bundling.
|
||||
|
||||
Le CLI MAY être invoqué via `cargo tauri`, un script du package manager frontend ou une autre forme officiellement supportée. PGR n'impose pas le package manager qui sert de lanceur.
|
||||
|
||||
## `devUrl`, `frontendDist` et sorties frontend
|
||||
|
||||
`devUrl` et `frontendDist` doivent pointer vers les entrées/sorties réellement possédées par la chaîne frontend du projet.
|
||||
|
||||
PGR ne fixe ni port, ni nom de répertoire de distribution, ni profondeur relative universelle.
|
||||
|
||||
Le répertoire produit par le frontend est un artefact de build lorsqu'il est reproductible ; il SHOULD rester hors du source control sauf besoin explicite contraire. La configuration Tauri qui le référence reste, elle, source durable.
|
||||
|
||||
## Version produit
|
||||
|
||||
Lorsque l'application Tauri appartient au même release train que le projet, `VERSION` reste la version canonique exacte de cette unité de release. Les champs de version de Tauri et du frontend ne sont toutefois pas obligés de suivre chaque prerelease ou fix : ils sont classés selon [`200-GOVERNANCE.md`](200-GOVERNANCE.md).
|
||||
|
||||
Tauri 2 accepte une `version` applicative explicite dans `tauri.conf.json` et l'utilise pour les métadonnées/bundles. Si ce champ est absent, Tauri peut utiliser la version du package Cargo du host. PGR MUST NOT imposer l'une de ces deux formes uniquement pour réduire le nombre de fichiers modifiés.
|
||||
|
||||
Pour un projet contrôlé qui conserve une `version` explicite dans `tauri.conf.json`, la politique recommandée lorsque les prereleases ne sont pas distribuées comme produits installables distincts est `MIRROR-STABLE` : le champ porte la cible `X.Y.Z` de la version en cours de développement, est fixé ou vérifié à l'ouverture de cette cible et reste stable pendant ses `alpha.*`, `beta.*`, `rc.*` et fixes. La promotion stable vérifie la cohérence sans provoquer de réécriture cérémonielle si la valeur est déjà correcte.
|
||||
|
||||
Si le projet distribue réellement des bundles prerelease qui doivent être identifiables séparément, `tauri.conf.json > version` MAY devenir `MIRROR-EXACT` ou suivre des jalons de packaging explicitement documentés. Le choix dépend du contrat de distribution, pas d'une préférence PGR pour l'omission du champ.
|
||||
|
||||
Pour un `package.json` frontend privé appartenant à la même application, une propriété `version` conservée SHOULD de même être classée `MIRROR-STABLE` par défaut : elle peut porter `X.Y.Z` pendant tout le développement de cette release sans suivre chaque tranche. Si le package frontend est publié ou versionné indépendamment, il possède alors sa propre unité/version et cette règle ne s'applique plus.
|
||||
|
||||
La chaîne de version d'un projet contrôlé peut donc être, par exemple :
|
||||
|
||||
```text
|
||||
VERSION = X.Y.Z-alpha.N.fix.M # CANONICAL
|
||||
workspace.package.version = X.Y.Z-alpha.N.fix.M # MIRROR-EXACT si le workspace l'a choisi
|
||||
tauri.conf.json version = X.Y.Z # MIRROR-STABLE
|
||||
package.json version = X.Y.Z # MIRROR-STABLE si conservée
|
||||
```
|
||||
|
||||
Cette classification évite de réécrire `package.json` et `tauri.conf.json` à chaque delta tout en conservant des champs de version utiles et lisibles. Elle remplace explicitement les conventions historiques KSP/Games qui préféraient omettre la version Tauri comme solution générale au churn.
|
||||
|
||||
Les numéros propres aux plateformes, par exemple Android `versionCode`, restent possédés par le profil plateforme concerné et ne sont pas assimilés au SemVer produit.
|
||||
|
||||
## Capabilities, permissions et frontière WebView/native
|
||||
|
||||
Les capability files et permissions Tauri sont du source de sécurité et SHOULD être versionnés lorsqu'ils définissent intentionnellement la surface exposée au frontend.
|
||||
|
||||
Le projet SHOULD accorder uniquement les permissions nécessaires aux fenêtres/webviews concernées. Ajouter un plugin ou une commande native ne justifie pas automatiquement une capability globale plus large.
|
||||
|
||||
Les schémas générés référencés par les capability files servent à l'outillage et à la validation de configuration ; ils ne deviennent pas pour autant la source normative de la politique de permissions.
|
||||
|
||||
Toute permission distante, origine distante ou extension de scope sensible doit être explicitement justifiée et validée comme frontière de sécurité.
|
||||
|
||||
## Plugins
|
||||
|
||||
PGR ne définit aucun catalogue de plugins Tauri obligatoires et ne rend pas `cargo tauri add` obligatoire.
|
||||
|
||||
Les pages officielles des plugins peuvent décrire à la fois une commande d'ajout automatique et les étapes explicites correspondantes côté Cargo, initialisation Rust et bindings frontend. Un projet MAY préférer appliquer manuellement ces étapes afin que les modifications de `Cargo.toml`, du manifeste frontend et du code d'initialisation restent directement contrôlées et revues.
|
||||
|
||||
Si une commande de commodité telle que `tauri add` est utilisée, les fichiers qu'elle modifie MUST être relus comme toute autre génération avant validation. Le projet ne doit installer que les côtés réellement nécessaires du plugin : dépendance Rust, bindings frontend, capabilities/permissions ou configuration associée selon le cas.
|
||||
|
||||
## CSP, fenêtres et bundles
|
||||
|
||||
CSP, nombre de fenêtres, labels, tailles, ports, `bundle.active`, targets de bundle, icônes et ressources restent des décisions du produit ou de la plateforme tant qu'aucun invariant plus général ne les impose.
|
||||
|
||||
Une règle locale MAY renforcer ces choix. Elle ne doit pas être remontée dans le profil Tauri uniquement parce qu'elle apparaît dans plusieurs applications d'un même projet.
|
||||
|
||||
## Artefacts générés et projets mobiles
|
||||
|
||||
Les dépendances frontend téléchargées et sorties de build reproductibles, telles que `node_modules/` ou le `frontendDist`, SHOULD rester hors Git.
|
||||
|
||||
PGR MUST NOT appliquer en revanche une exclusion universelle de tout répertoire `gen/`. Tauri peut générer des projets de plateforme qui deviennent ensuite le lieu de personnalisations Android/iOS intentionnelles. Le projet doit classifier chaque sous-arbre : reproductible/transitoire, configuration durable ou généré modifié volontairement.
|
||||
|
||||
Un POC Tauri mobile non concluant pour un produit particulier ne constitue pas une preuve que Tauri Android/iOS est inadapté à tous les autres projets. Le support mobile doit être jugé selon le besoin, les ABI, plugins, intégrations natives et gates plateforme du projet concerné.
|
||||
|
||||
Les secrets de signature, keystores, credentials et fichiers locaux restent hors Git conformément aux règles générales et aux profils plateforme applicables.
|
||||
|
||||
## Validation proportionnée
|
||||
|
||||
| Scope modifié | Preuve Tauri normalement pertinente | Ce que cette preuve ne remplace pas |
|
||||
|-------------------------------------------------|------------------------------------------------------------------------|------------------------------------------------------|
|
||||
| backend Rust uniquement | gates Rust/Cargo sélectionnées | frontend, hooks, WebView ou packaging |
|
||||
| frontend uniquement | build/tests/smoke du frontend selon son owner | host natif ou packaging Tauri |
|
||||
| hooks, config, capabilities, IPC ou intégration | `tauri dev` ou équivalent + smoke ciblé | package release de plateforme |
|
||||
| bundling, ressources ou version packagée | `tauri build` ou équivalent + inspection/smoke de l'artefact | exigences d'un store ou d'une plateforme non exercée |
|
||||
| Android/iOS | commande mobile Tauri applicable + gates du profil plateforme concerné | autres plateformes |
|
||||
|
||||
La syntaxe exacte de la commande dépend du lanceur choisi (`cargo`, npm, pnpm, etc.) et de la plateforme. Le delta/plan du projet doit fournir la commande concrète.
|
||||
|
||||
Un `cargo check` direct MAY rester utile pour une modification Rust ciblée, mais il ne constitue pas un smoke Tauri complet. Inversement, un full `tauri build` n'est pas requis lorsqu'aucune propriété d'intégration ou de packaging n'a été invalidée.
|
||||
|
||||
## Ce que le profil n'impose pas
|
||||
|
||||
Ce profil ne crée pas :
|
||||
|
||||
- de `tauri.conf.json` universel ;
|
||||
- de port de développement par défaut PGR ;
|
||||
- de frontend Vite/TypeScript/Sass/Bootstrap obligatoire ;
|
||||
- de frontend WASM implicite ;
|
||||
- de plugin obligatoire ;
|
||||
- de nombre ou taille de fenêtres ;
|
||||
- de politique de bundle unique ;
|
||||
- de layout universel imposé aux projets externes ; la convention stricte des projets contrôlés est définie séparément ci-dessus ;
|
||||
- de version exacte de Tauri, `tauri-build` ou du CLI.
|
||||
|
||||
Ces décisions appartiennent au projet, à un profil plus spécifique ou à une skeleton specification seulement lorsqu'une valeur réutilisable est réellement démontrée.
|
||||
29
docs/skeletons/000-README.md
Normal file
29
docs/skeletons/000-README.md
Normal file
@@ -0,0 +1,29 @@
|
||||
<!-- file: docs/skeletons/000-README.md -->
|
||||
<!-- version: 4 -->
|
||||
|
||||
# Index des skeleton specifications PGR
|
||||
|
||||
Cette collection contient les recettes Markdown utilisées pour initialiser des baselines de projet ou composer plusieurs profils PGR sans transformer PGR en générateur.
|
||||
|
||||
Le contrat normatif commun des skeletons appartient à [`../rules/220-SKELETONS.md`](../rules/220-SKELETONS.md). Le modèle de composition des profils reste défini par [`../architecture/003-RULE_PROFILE_MODEL.md`](../architecture/003-RULE_PROFILE_MODEL.md).
|
||||
|
||||
## Rôle de la collection
|
||||
|
||||
Chaque specification concrète doit décrire un besoin réel et actionnable. Elle sélectionne les owners normatifs et templates nécessaires, rend visibles les décisions propres au projet, définit l'ordre de composition utile et fournit une validation initiale proportionnée.
|
||||
|
||||
Les fichiers techniques copiables ne vivent pas ici : ils restent sous `templates/`. Leurs guides d'adaptation restent sous `docs/templates/`. Les règles restent sous `docs/rules/`.
|
||||
|
||||
Une specification peut se composer avec une fondation plus générale, mais la collection ne duplique pas artificiellement une recette pour chaque combinaison possible de technologies.
|
||||
|
||||
## Specifications actives
|
||||
|
||||
- [`001-PROJECT_GOVERNANCE_FOUNDATION.md`](001-PROJECT_GOVERNANCE_FOUNDATION.md) — fondation composable pour établir la gouvernance locale, la version, la documentation minimale, le workflow retenu et sa validation initiale sans imposer d'architecture applicative.
|
||||
- [`002-RUST_CARGO_WORKSPACE.md`](002-RUST_CARGO_WORKSPACE.md) — specialization composable d'un workspace Rust/Cargo fondée sur `001`, les profils `500 + 510`, les cinq templates Rust/Cargo et une validation réelle de la toolchain.
|
||||
|
||||
Les familles Java/Android, Web, JNI et autres domaines sans pièces suffisantes restent différées tant que leurs owners normatifs et artefacts d'instanciation ne permettent pas une baseline réellement actionnable.
|
||||
|
||||
Le skeleton Tauri a fait l'objet d'une décision explicite en `0.0.5-alpha.9` : le host Rust/Tauri est suffisamment cadré par `510` et `710`, mais PGR ne possède pas encore les owners Web/Vite/TypeScript/Sass nécessaires pour matérialiser proprement la stack frontend candidate des projets contrôlés. Aucun `003-TAURI...` n'est donc créé dans `0.0.5`. La décision et ses conditions de sortie sont enregistrées dans [`../studies/002-TAURI_SKELETON_DECISION.md`](../studies/002-TAURI_SKELETON_DECISION.md).
|
||||
|
||||
Un futur skeleton Tauri devra composer les owners existants avec les profils Web réellement matérialisés ; il ne devra pas faire du skeleton lui-même le propriétaire des règles Vite, TypeScript, Sass, Bootstrap ou du package manager.
|
||||
|
||||
Aucun fichier placeholder ne doit être ajouté pour réserver un skeleton futur.
|
||||
158
docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md
Normal file
158
docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md
Normal file
@@ -0,0 +1,158 @@
|
||||
<!-- file: docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md -->
|
||||
<!-- version: 3 -->
|
||||
|
||||
# Skeleton — Project governance foundation
|
||||
|
||||
## Objectif
|
||||
|
||||
Cette specification décrit une fondation composable pour un projet qui choisit d'adopter la gouvernance PGR sans sélectionner encore de langage, plateforme, framework ou architecture applicative.
|
||||
|
||||
Elle permet d'établir une baseline locale cohérente : identité de version, point d'entrée normatif, documentation réellement utile, workflow de changement effectivement retenu et validation initiale proportionnée.
|
||||
|
||||
Le contrat commun des skeletons appartient à [`../rules/220-SKELETONS.md`](../rules/220-SKELETONS.md). La présente specification sélectionne et adapte les owners généraux utiles ; elle n'en devient pas propriétaire.
|
||||
|
||||
## Applicabilité
|
||||
|
||||
Appliquer cette fondation lorsqu'un dépôt ou release unit veut utiliser PGR comme source de gouvernance locale et qu'aucune specialization technologique n'est nécessaire pour définir cette base commune.
|
||||
|
||||
Elle MAY servir de fondation à un skeleton spécialisé, qui ajoute ensuite uniquement les profils, templates, décisions et validations propres à son scope.
|
||||
|
||||
Ne pas l'appliquer comme cérémonie à un dépôt qui ne souhaite pas adopter le lifecycle ou les règles PGR. Elle ne transforme pas PGR en dépendance du projet destinataire.
|
||||
|
||||
## Owners sélectionnés
|
||||
|
||||
La fondation s'appuie sur les responsabilités PGR suivantes :
|
||||
|
||||
```text
|
||||
docs/rules/200-GOVERNANCE.md
|
||||
versioning, phases et discipline de changement
|
||||
|
||||
docs/rules/210-WORKFLOW.md
|
||||
plans, deltas, histories, commits de tranche et artefacts à la demande
|
||||
|
||||
docs/rules/300-DOCUMENTATION.md
|
||||
rôles documentaires, taxonomie, révisions et snapshots
|
||||
|
||||
docs/rules/400-VALIDATION.md
|
||||
preuves proportionnées, statuts de gate et autorité opérateur
|
||||
```
|
||||
|
||||
`docs/rules/220-SKELETONS.md` gouverne l'instanciation elle-même. Il n'est pas automatiquement une règle à recopier dans le projet destinataire si ce projet ne maintient pas sa propre collection de skeletons.
|
||||
|
||||
Aucun profil `500+` ou `600+` n'est sélectionné par cette fondation. Un skeleton spécialisé les ajoute seulement lorsqu'ils sont réellement applicables.
|
||||
|
||||
## Décisions destinataire avant matérialisation
|
||||
|
||||
Avant de considérer la fondation comme instanciée, résoudre explicitement les décisions suivantes :
|
||||
|
||||
1. identifier le release unit gouverné et sa version SemVer courante ;
|
||||
2. décider si le projet utilise le fichier racine `VERSION` comme repère canonique simple ;
|
||||
3. identifier les règles PGR réellement reprises et les adaptations locales nécessaires ;
|
||||
4. déterminer quels documents vivants ont une responsabilité réelle dès la baseline ;
|
||||
5. déterminer quels artefacts du workflow PGR sont effectivement utilisés et à partir de quel état gouverné ;
|
||||
6. sélectionner les validations disponibles qui prouvent réellement cette baseline ;
|
||||
7. consigner toute exception ou divergence intentionnelle dans le propriétaire local approprié.
|
||||
|
||||
Une décision non résolue MUST rester visible comme décision à prendre. Elle ne doit pas être remplacée par une valeur arbitraire provenant de PGR ou d'un autre projet.
|
||||
|
||||
## Baseline locale à matérialiser
|
||||
|
||||
### Point d'entrée normatif
|
||||
|
||||
Le projet destinataire MUST disposer d'un point d'entrée normatif local clairement identifiable. Lorsqu'il adopte la convention PGR, ce point d'entrée est `RULES.md`.
|
||||
|
||||
Ce document doit au minimum :
|
||||
|
||||
- déclarer le scope qu'il gouverne ;
|
||||
- identifier les owners généraux ou spécialisés réellement applicables ;
|
||||
- expliquer la priorité ou la spécialisation locale lorsqu'une adaptation existe ;
|
||||
- renvoyer vers les documents détaillés au lieu de recopier leur contenu sans nécessité.
|
||||
|
||||
Le projet doit rester autonome : ses règles nécessaires vivent dans son dépôt ou dans un mécanisme de dépendance documentaire explicitement choisi par lui. Une URL vers PGR ne remplace pas à elle seule une baseline locale exploitable.
|
||||
|
||||
### Version
|
||||
|
||||
Le release unit MUST posséder une version SemVer courante explicite conformément au contrat local retenu.
|
||||
|
||||
Si le fichier racine `VERSION` est choisi, l'instanciation doit le créer ou l'adapter selon [`../rules/200-GOVERNANCE.md`](../rules/200-GOVERNANCE.md). Si l'écosystème possède un autre owner canonique, la relation avec `VERSION` doit être décidée explicitement plutôt que dupliquée par défaut.
|
||||
|
||||
La valeur de version initiale appartient au projet destinataire. Cette specification ne fournit pas de numéro universel.
|
||||
|
||||
### Documentation minimale
|
||||
|
||||
`README.md` SHOULD fournir l'onboarding et les points d'entrée de premier niveau du projet.
|
||||
|
||||
Créer `docs/000-README.md` uniquement si une documentation structurée sous `docs/` existe réellement. Créer ensuite uniquement les collections possédant un premier contenu utile. Une collection vide ou un document placeholder n'est pas requis par cette fondation.
|
||||
|
||||
Selon la réalité du projet :
|
||||
|
||||
- `ROADMAP.md` est utile lorsqu'une trajectoire macro doit être rendue explicite ;
|
||||
- `CHANGELOG.md` est utile lorsque des changements de release doivent être communiqués aux utilisateurs ou intégrateurs ;
|
||||
- `docs/objectives/` est utile lorsqu'une mission durable, des contraintes ou non-objectifs méritent un owner distinct ;
|
||||
- `docs/architecture/` est utile lorsqu'un état architectural ou un profil local doit être possédé durablement ;
|
||||
- `docs/validation/` est utile lorsqu'une matrice ou un contrat de preuve mérite un document séparé.
|
||||
|
||||
Pour un projet où plusieurs fichiers ou familles durables ont des responsabilités ou règles de modification difficiles à déduire, la fondation MAY aussi instancier un registre local selon [`../templates/004-FILE_FAMILY_CONTRACTS.md`](../templates/004-FILE_FAMILY_CONTRACTS.md). Ce registre reste facultatif : un projet simple ou déjà explicite n'a rien à matérialiser.
|
||||
|
||||
Lorsqu'une release possède plusieurs tranches ou responsabilités de fermeture, le projet SHOULD utiliser un plan explicite conforme à [`../templates/005-RELEASE_PLAN.md`](../templates/005-RELEASE_PLAN.md) ou une forme locale équivalente. Le plan doit notamment attribuer la clôture/transition et éviter qu'une roadmap arrivée à son horizon soit étendue par spéculation.
|
||||
|
||||
Ne pas créer ces fichiers uniquement pour reproduire l'arborescence du dépôt PGR.
|
||||
|
||||
### Workflow retenu
|
||||
|
||||
Si le projet adopte le workflow de tranches PGR, il doit préserver la séquence définie par [`../rules/210-WORKFLOW.md`](../rules/210-WORKFLOW.md) : intention prospective dans le delta, gate réelle, preuve rétrospective dans le history, puis commit de tranche avant application du delta suivant.
|
||||
|
||||
Les répertoires `deltas/`, `history/`, `prompts/`, `handoffs/` et `manifests/` sont créés à la demande lorsqu'un artefact réel les justifie. Ils ne constituent pas un layout obligatoire à précréer.
|
||||
|
||||
Un projet qui n'adopte qu'une partie du workflow PGR doit l'indiquer dans ses règles locales et ne pas présenter les artefacts omis comme s'ils étaient encore obligatoires.
|
||||
|
||||
### Validation initiale
|
||||
|
||||
La validation de la fondation doit prouver seulement les propriétés réellement matérialisées. Elle SHOULD combiner selon le scope :
|
||||
|
||||
```text
|
||||
CHECK version courante conforme au mécanisme choisi
|
||||
CHECK git diff --check ou équivalent du VCS retenu
|
||||
AUDIT chemins et rôles documentaires réellement créés
|
||||
AUDIT liens locaux principaux si la navigation Markdown a été modifiée
|
||||
AUDIT owners sélectionnés et exceptions locales explicites
|
||||
REVIEW absence de collections, profils ou placeholders non justifiés
|
||||
```
|
||||
|
||||
Si le projet possède déjà des audits fiables pour ses headers, liens, structure ou règles, ils MAY être ajoutés. Cette fondation n'impose pas de copier les scripts du dépôt PGR sans décision explicite de réutilisation.
|
||||
|
||||
La prévalidation qui accompagne une instanciation ou un delta ne remplace pas la gate opérateur autoritaire du projet destinataire.
|
||||
|
||||
## Ordre de composition
|
||||
|
||||
Cette fondation SHOULD être appliquée avant une specialization qui la déclare comme base.
|
||||
|
||||
Une specialization technologique peut ensuite :
|
||||
|
||||
- sélectionner ses familles et profils applicables ;
|
||||
- copier ou adapter les templates techniques correspondants ;
|
||||
- ajouter ses décisions spécifiques ;
|
||||
- étendre la validation initiale avec la toolchain réellement concernée.
|
||||
|
||||
Elle MUST NOT redéfinir les responsabilités générales déjà possédées par la fondation sauf specialization ou override explicitement justifié.
|
||||
|
||||
## Overrides et exceptions
|
||||
|
||||
Un projet MAY adapter la structure documentaire, le mécanisme de version, le VCS, le workflow ou une convention PGR lorsqu'une contrainte réelle le justifie et que l'owner local reste clair.
|
||||
|
||||
Une exception doit identifier son scope et sa raison. Elle ne devient pas une règle générale PGR et ne doit pas être masquée par la simple copie d'un fichier provenant de PGR.
|
||||
|
||||
## Hors scope
|
||||
|
||||
Cette fondation ne définit pas :
|
||||
|
||||
- l'architecture applicative ou les crates/modules/packages du produit ;
|
||||
- un langage, une plateforme, un framework ou une toolchain ;
|
||||
- des noms de package, versions de dépendances ou chemins de build ;
|
||||
- des templates techniques génériques inexistants ;
|
||||
- un CI/CD universel ;
|
||||
- une politique de branching universelle ;
|
||||
- une obligation de recopier la structure complète du dépôt PGR ;
|
||||
- la migration rétroactive des anciennes releases ou anciens commits du projet destinataire.
|
||||
|
||||
Les spécialisations futures doivent rester indépendantes et composables au-dessus de cette fondation.
|
||||
217
docs/skeletons/002-RUST_CARGO_WORKSPACE.md
Normal file
217
docs/skeletons/002-RUST_CARGO_WORKSPACE.md
Normal file
@@ -0,0 +1,217 @@
|
||||
<!-- file: docs/skeletons/002-RUST_CARGO_WORKSPACE.md -->
|
||||
<!-- version: 5 -->
|
||||
|
||||
# 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) et [`../validation/003-RUST_EXPORT_COMPLETENESS.md`](../validation/003-RUST_EXPORT_COMPLETENESS.md) sont seulement des options supplémentaires. Les scripts Rust PGR ne sont copiés que si le projet choisit explicitement les conventions correspondantes. Le helper `_rust_audit_common.py` peut être partagé entre ces audits.
|
||||
|
||||
## 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. le nom court/abréviation canonique du projet, la liste réelle des packages membres, leurs responsabilités, rôles et chemins, puis la conformité de leurs noms au contrat de `510-RUST_CARGO.md` ;
|
||||
3. l'édition Rust 2024, le resolver Cargo et la toolchain stable compatible, ou l'exception externe explicitement documentée ;
|
||||
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 frontières `-api` / `-lib` réellement justifiées, les packages exécutables distincts de leurs bibliothèques et toute exception framework à cette séparation ;
|
||||
11. l'ownership du logging/tracing : simple exécutable local ou crate transverse commune lorsque plusieurs runtimes partagent subscriber, sinks ou policy ;
|
||||
12. les exceptions éventuelles au profil Rust strict ; pour une nouvelle baseline contrôlée, la façade crate-root, les chemins explicites et les conventions structurelles sans ordre métier sont sélectionnés par défaut ;
|
||||
13. les fichiers pour lesquels un ordre mécanique des blocs `const` est réellement applicable, sans englober les tables/protocoles/schémas ordonnés ;
|
||||
14. 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é. Dans une nouvelle baseline contrôlée, remplacer `project` par le nom court/abréviation du projet et choisir une responsabilité puis un rôle/cible lisibles conformément à `510-RUST_CARGO.md`. Une crate bibliothèque, binaire ou spécialisée doit conserver le layout et les héritages qui correspondent à son rôle réel ; un suffixe n'est pas ajouté uniquement pour obtenir une symétrie artificielle.
|
||||
|
||||
Avant de créer une paire `*-api` / `*-lib`, démontrer la frontière contractuelle qui justifie deux packages. Une implémentation unique sans extension/backend/lifecycle séparé reste normalement une seule crate `-lib`. À l'inverse, une vraie crate `-api` reste principalement déclarative et ne reçoit pas le runtime de logging du projet par automatisme.
|
||||
|
||||
Les exécutables sont des packages distincts des bibliothèques qu'ils composent, sauf exception de framework sélectionnée. Leur `main.rs` reste mince. Si plusieurs crates runtime partagent la même configuration de diagnostics, prévoir une crate transverse de logging/tracing ; ne pas répliquer l'initialisation du subscriber dans chaque binaire ou bibliothèque.
|
||||
|
||||
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 Rust ciblés
|
||||
|
||||
Pour une nouvelle baseline contrôlée qui adopte le profil strict, [`../validation/002-RUST_STYLE_AUDITS.md`](../validation/002-RUST_STYLE_AUDITS.md) fournit des contrôles monotâches pour les propriétés structurelles que Rustfmt ne possède pas complètement : lignes vides, séparation des items, ordre des modules, bloc d'imports de traits et blocs de réexports. Copier seulement les scripts réellement retenus et adapter leurs headers aux chemins locaux.
|
||||
|
||||
L'audit `audit_rust_const_blocks.py` reste à sélection explicite par fichier : il ne doit jamais réordonner une table de protocole, une séquence de migrations, un schéma ou toute structure dont l'ordre possède une sémantique propre. Les blocs `static`/`type` peuvent reprendre localement la même présentation sans qu'un audit supplémentaire soit créé par symétrie.
|
||||
|
||||
Le contrat de façade décrit dans [`../validation/003-RUST_EXPORT_COMPLETENESS.md`](../validation/003-RUST_EXPORT_COMPLETENESS.md) appartient également au profil strict ; `audit_rust_export_completeness.py` avec `_rust_audit_common.py` SHOULD être adopté afin de contrôler les propriétés que `rustc` et Clippy ne possèdent pas. Une adoption d'un projet existant SHOULD commencer en `--report-only`, résoudre les écarts ou exceptions locales, puis seulement rendre l'audit bloquant.
|
||||
|
||||
Aucun script n'est copié uniquement parce qu'il existe dans PGR. Si un autre owner fiable possède déjà la propriété ou si l'ordre est sémantique, la revue ou l'outil officiel reste préférable.
|
||||
|
||||
## 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 des audits Rust facultatifs ont été sélectionnés, exécuter les audits de style après formatage sur les seuls chemins concernés et l'audit de façade sur la racine du projet une fois son contrat explicitement adopté.
|
||||
|
||||
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, préfixés et nommés selon leur responsabilité/rôle
|
||||
CHECK édition Rust 2024 ou exception externe explicitement documentée
|
||||
CHECK profil strict de chemins/façade appliqué ou override borné documenté
|
||||
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.
|
||||
13
docs/studies/000-README.md
Normal file
13
docs/studies/000-README.md
Normal file
@@ -0,0 +1,13 @@
|
||||
<!-- file: docs/studies/000-README.md -->
|
||||
<!-- version: 2 -->
|
||||
|
||||
# Index des études PGR
|
||||
|
||||
Les études PGR enregistrent une analyse bornée nécessaire à une décision, une réconciliation ou une future normalisation sans transformer prématurément leurs conclusions en règles.
|
||||
|
||||
Une étude peut comparer des projets sources, des technologies ou plusieurs options. Elle doit distinguer les faits observés, les conclusions déjà suffisamment étayées, les décisions encore ouvertes et les éléments qui doivent rester spécifiques à leur contexte.
|
||||
|
||||
## Études actives
|
||||
|
||||
- [`001-KSP_GAMES_RECONCILIATION.md`](001-KSP_GAMES_RECONCILIATION.md) — première réconciliation explicite de PGR avec les baselines autoritaires fournies de `khadhroony-solana-project` et `sasedev-games`.
|
||||
- [`002-TAURI_SKELETON_DECISION.md`](002-TAURI_SKELETON_DECISION.md) — étude de readiness `alpha.9` déterminant si les owners existants suffisent à matérialiser un skeleton Tauri contrôlé sans transférer au skeleton la propriété normative du frontend.
|
||||
317
docs/studies/001-KSP_GAMES_RECONCILIATION.md
Normal file
317
docs/studies/001-KSP_GAMES_RECONCILIATION.md
Normal file
@@ -0,0 +1,317 @@
|
||||
<!-- file: docs/studies/001-KSP_GAMES_RECONCILIATION.md -->
|
||||
<!-- version: 11 -->
|
||||
|
||||
# Étude de réconciliation PGR / KSP / sasedev-games
|
||||
|
||||
## Objet et statut des corpus
|
||||
|
||||
Cette étude exécute l'inventaire demandé par `prompts/005-V0_0_5_START_PROMPT.md` avant toute modification normative importante de `0.0.5`.
|
||||
|
||||
`khadhroony-solana-project` et `sasedev-games` sont ici des **corpus de conception et de réconciliation**. Ils n'ont pas encore adopté PGR comme référentiel de gouvernance. Une divergence observée dans leurs baselines ne constitue donc pas une non-conformité PGR et ne doit pas être « corrigée » rétroactivement dans ces projets pendant cette release.
|
||||
|
||||
La question utile est différente : quelles responsabilités déjà éprouvées doivent rester locales, lesquelles sont déjà correctement possédées par PGR, et lesquelles révèlent un besoin générique suffisamment réutilisable pour améliorer PGR avant une future adoption ?
|
||||
|
||||
## Sources autoritaires contrôlées
|
||||
|
||||
### PGR
|
||||
|
||||
Baseline : archive source `pgr-v0.0.4.zip`, annoncée comme téléchargement du tag Gitea `v0.0.4`, accompagnée du rapport externe `pgr-0.0.4-publish.001-report.md` avec statut `PASS`.
|
||||
|
||||
```text
|
||||
SHA-256 7137bb084f017362323a2043d13ba71490be15b8786adc8d645981bf455b80ae
|
||||
entrées 167
|
||||
fichiers 139
|
||||
répertoires 28
|
||||
racine pgr/
|
||||
CRC clean
|
||||
.git absent
|
||||
```
|
||||
|
||||
Aucun doublon ZIP, collision de casse, chemin dangereux ou lien symbolique n'a été détecté. Les `15` tests Python PGR passent ; les audits Markdown affichent `123` fichiers contrôlés, `3` tableaux propres et `116` liens locaux propres. Les cinq fichiers TOML du template Rust/Cargo se parsèrent correctement.
|
||||
|
||||
Le rapport post-tag donne le même hash et sépare explicitement la preuve de publication de l'état contenu dans l'archive.
|
||||
|
||||
### khadhroony-solana-project
|
||||
|
||||
Baseline autoritaire fournie : `khadhroony-solana-project-v0.3.16.zip`.
|
||||
|
||||
```text
|
||||
SHA-256 db3cc1b3fc3fb07ee864b02e2a7346c673d4cf63b33e8e872aca6c6458856ca0
|
||||
entrées 2229
|
||||
fichiers 2017
|
||||
répertoires 212
|
||||
racine khadhroony-solana-project/
|
||||
CRC clean
|
||||
.git absent
|
||||
```
|
||||
|
||||
Aucun doublon ZIP, collision de casse, chemin dangereux ou lien symbolique n'a été détecté. Les audits Python fournis par la baseline passent :
|
||||
|
||||
```text
|
||||
General Rust rule audit: clean
|
||||
Rust export completeness audit: 0 candidate(s)
|
||||
KSP workspace Rust rule audit: clean
|
||||
Markdown table audit: clean (352 table(s), 962 file(s))
|
||||
```
|
||||
|
||||
### sasedev-games
|
||||
|
||||
Baseline autoritaire fournie : `games-v0.3.5.zip`.
|
||||
|
||||
```text
|
||||
SHA-256 5f5fdee1a271386766d059657d6eaa831acdc263b3e722fed738808335c0a105
|
||||
entrées 664
|
||||
fichiers 508
|
||||
répertoires 156
|
||||
racine games/
|
||||
CRC clean
|
||||
.git absent
|
||||
```
|
||||
|
||||
Aucun doublon ZIP, collision de casse, chemin dangereux ou lien symbolique n'a été détecté. Les audits Python fournis par la baseline passent :
|
||||
|
||||
```text
|
||||
General Rust rule audit: clean
|
||||
Rust export completeness audit: 0 candidate(s)
|
||||
games.sasedev workspace audit: clean
|
||||
Markdown table audit: clean (5 table(s), 304 file(s))
|
||||
Distribution layout audit: clean (66 required path(s), 8 forbidden path(s) absent)
|
||||
```
|
||||
|
||||
La toolchain `cargo` n'est pas disponible dans l'environnement utilisé pour cette étude ; aucun `cargo metadata`, build, test ou Clippy externe n'est donc présenté comme exécuté ici. Cette limite n'empêche pas l'inventaire documentaire et statique demandé à `alpha.1` et ne transforme pas les audits Python en preuve de compilation.
|
||||
|
||||
## Méthode de classification
|
||||
|
||||
Chaque propriété observée est classée selon l'un des états suivants :
|
||||
|
||||
```text
|
||||
OWNED déjà correctement possédée par PGR ; l'usage local ne crée pas de nouvelle règle
|
||||
COMMON besoin générique réel insuffisamment matérialisé dans PGR ; candidat de 0.0.5
|
||||
LOCAL besoin spécifique au projet, à son architecture, son domaine ou sa plateforme
|
||||
LEGACY divergence historique ou duplication locale à considérer lors d'une future adoption, pas à corriger ici
|
||||
DEFER preuve insuffisante pour créer maintenant un owner PGR durable
|
||||
```
|
||||
|
||||
La classification porte sur les responsabilités et contrats, pas sur la simple ressemblance des noms de fichiers.
|
||||
|
||||
## Réconciliation de la gouvernance et de la documentation
|
||||
|
||||
| Sujet observé | KSP / Games | Classification | Décision PGR |
|
||||
|-----------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------|----------------|--------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| hiérarchie normative et exceptions bornées | présente dans les deux corpus | `OWNED` | `RULES.md` et le modèle de profils possèdent déjà ce contrat ; ne pas recopier les règles locales |
|
||||
| langue code/chemins anglais, documentation interne française | commune | `OWNED` | déjà possédée par `RULES.md` et `300-DOCUMENTATION.md` |
|
||||
| rôles de `README`, `RULES`, `ROADMAP`, `CHANGELOG`, plans et documents durables | largement communs | `OWNED` | `300-DOCUMENTATION.md` couvre déjà les rôles génériques |
|
||||
| headers internes `file` / `version` | communs | `OWNED` | déjà possédés et audités par PGR ; les règles locales plus strictes restent locales tant qu'elles ajoutent une sémantique propre |
|
||||
| `FILE_CONTRACTS.md` local décrivant responsabilité et règle de modification des familles importantes | présent dans les deux corpus | `COMMON` | fournir un pattern/template documentaire facultatif et l'intégrer à la fondation seulement lorsque la complexité du projet le justifie |
|
||||
| prompt de démarrage autonome avec baseline, ordre de lecture, état validé, mission, hors-scope, première gate et validation | présent dans les deux corpus | `COMMON` | renforcer le contrat générique des prompts PGR et fournir une spécification réutilisable ; ne pas copier les commandes KSP/Games |
|
||||
| règle « une version complète par session » | explicitement forte dans Games, structurante dans certaines pratiques locales | `LOCAL` | PGR conserve sa règle actuelle : une session ne force pas artificiellement une version ; un projet peut ajouter une contrainte locale plus forte |
|
||||
| couloirs exacts de fermeture et numérotation de prereleases | plus détaillés dans KSP/Games | `DEFER` | conserver le principe PGR de consolidation/RC/stable ; ne pas généraliser des numéros ou un nombre fixe de tranches |
|
||||
| absence de `history/` dans KSP `v0.3.16` et historique partiel dans Games | divergence de workflow antérieure à l'adoption de PGR | `LEGACY` | ne pas créer de dette rétroactive ; une future adoption décide son point de départ et ne réécrit pas l'historique |
|
||||
|
||||
## Réconciliation de la validation
|
||||
|
||||
PGR possède déjà le besoin générique le plus important : sélectionner les preuves à partir du scope, des risques invalidés et de la maturité, avec une matrice canonique facultative pour les projets suffisamment structurés.
|
||||
|
||||
Les matrices et documents de validation de Games et KSP confirment plusieurs pratiques déjà couvertes : tests ciblés pendant le développement, gates plus larges aux frontières de maturité, contrôles de dépendances seulement lorsqu'ils apportent une preuve, et distinction entre audit statique, build, smoke et diagnostic. Ces éléments restent `OWNED`.
|
||||
|
||||
Les audits spécialisés restent locaux :
|
||||
|
||||
- `audit_ksp_workspace_rules.py` contrôle des frontières, dépendances et conventions propres à KSP ;
|
||||
- `audit_distribution_layout.py` contrôle le layout et plusieurs intégrations Web/Android/Gradle propres à Games ;
|
||||
- ces scripts ne doivent pas être copiés dans PGR ni transformés en audits universels.
|
||||
|
||||
## Réconciliation Rust/Cargo
|
||||
|
||||
Les travaux `0.0.3` et `0.0.4` ont déjà absorbé les parties génériques évidentes des deux corpus : workspace Cargo, héritage des métadonnées et lints, templates `rustfmt.toml`/`clippy.toml`/`.cargo/config.toml`, manifests, safety/FFI bornée et audits de style ciblés. Ces propriétés restent `OWNED`.
|
||||
|
||||
Un besoin commun reste cependant suffisamment net pour être repris : les deux projets contiennent `audit_rust_export_completeness.py` avec le même contrat et le même corps fonctionnel à l'exception de la révision de fichier. Il contrôle la complétude de façade crate-root et les chemins canoniques associés, propriété que Rustfmt et Clippy ne possèdent pas. Le profil `510` décrit déjà cette architecture comme convention recommandée.
|
||||
|
||||
Décision : classer ce contrôle `COMMON`, mais ne pas copier le script tel quel en `alpha.1`. Une tranche dédiée doit d'abord :
|
||||
|
||||
1. séparer ce qui dépend du profil Rust général de ce qui dépend d'un style KSP/Games plus strict ;
|
||||
2. conserver l'audit facultatif tant que la façade crate-root n'est qu'un `SHOULD` du profil ;
|
||||
3. fournir des tests positifs/négatifs ciblés et documenter les limites du parsing lexical ;
|
||||
4. éviter de réintroduire les règles déjà possédées par Rustfmt, Clippy ou les deux audits de style PGR existants.
|
||||
|
||||
#### Mesure alpha.5
|
||||
|
||||
La relecture du script historique révèle une limite importante : sa découverte `crates/*/Cargo.toml` couvre les `22` crates KSP placées directement sous `crates/`, mais aucune des `23` crates Games imbriquées sous `crates/apps`, `crates/common`, `crates/engines`, etc. Le code des deux scripts est bien commun, mais le résultat historique Games `0 candidate(s)` n'était pas une preuve d'audit des crates réelles.
|
||||
|
||||
La variante PGR corrige d'abord la découverte récursive. La revue opérateur de `alpha.5` montre ensuite que limiter la canonicalisation à `crate::module::Item` est insuffisant : les corpus contiennent de nombreuses références nues à des items pourtant réexportés, notamment dans leur module propriétaire, et ni `rustc` ni Clippy ne possèdent la convention « référence partagée = `crate::Item` partout dans la crate ». `alpha.5` est donc conservé `FAIL` et `alpha.5.fix.1` étend `RUST-IMPORT-201` à ce contrat réel.
|
||||
|
||||
La mesure corrigée, avec découverte récursive et séparation des cibles Cargo, donne `1525` lignes candidates `RUST-IMPORT-201` dans KSP sur `22` packages et `181` lignes candidates dans Games sur `23` packages (`2 RUST-API-201`, `179 RUST-IMPORT-201`). Ces volumes ne sont pas interprétés comme des défauts rétroactifs : ils montrent précisément pourquoi une adoption PGR d'un projet existant doit commencer en `--report-only`, puis migrer progressivement la convention avant d'en faire une gate bloquante.
|
||||
|
||||
Le grand `audit_rust_general_rules.py` des deux corpus reste `DEFER` comme source d'extraction, pas comme script à importer. Il mélange plusieurs responsabilités : headers, rustdoc, imports, structure de façade, blancs, constantes et règles locales ; Games y ajoute une exception FFI Android étroite. PGR doit continuer à extraire des audits monotâches seulement lorsqu'une propriété commune apporte une preuve non redondante.
|
||||
|
||||
L'orchestrateur `audit_rust_workspace_rules.py` est un pattern d'ergonomie utile mais ne possède aucune règle. PGR peut documenter comment composer des audits sélectionnés dans un projet destinataire sans fournir un lanceur universel qui supposerait les mêmes scripts partout.
|
||||
|
||||
## Réconciliation des frameworks et plateformes
|
||||
|
||||
### Tauri
|
||||
|
||||
Tauri est réellement présent dans les deux corpus et n'est plus un exemple isolé : KSP contient `6` applications Desk Tauri et Games `2` hôtes Tauri. Les `8` applications observées utilisent Tauri 2, un package Rust avec `tauri-build`, une configuration `tauri.conf.json`, des capability files, des hooks frontend et un `frontendDist` dédié.
|
||||
|
||||
Les différences sont tout aussi importantes que les points communs : KSP possède deux fenêtres par Desk, active le bundling et utilise des hooks npm simples ; Games utilise une fenêtre, désactive le bundling dans les POC observés et l'un de ses hooks construit d'abord un frontend WASM via un script Python. Les CSP, ports, identifiants, ressources et plugins ne sont pas uniformes.
|
||||
|
||||
Toutes les configurations observées omettent une version Tauri explicite tandis que leur package Cargo hérite de la version workspace. La relecture des règles montre que ce n'est pas un simple accident : KSP `VER-ID-015/016` et Games `VER-TAURI-001..004` ont tous deux utilisé l'omission de `tauri.conf.json > version` et la non-synchronisation systématique de `package.json` pour réduire le churn. La clarification opérateur de `alpha.6.fix.2` rejette toutefois la généralisation de cette solution : l'objectif durable est de **classifier la fréquence de synchronisation**, pas de supprimer les champs. PGR conserve donc la possibilité d'une version Tauri/frontend explicite et privilégie `MIRROR-STABLE` lorsque ces valeurs doivent seulement porter le jalon `X.Y.Z` cible.
|
||||
|
||||
Les deux corpus versionnent leurs capability files et ignorent les dépendances/sorties frontend reproductibles. Ils ignorent également `gen/`, mais ce dernier point n'est pas généralisé : les projets mobiles Tauri peuvent contenir sous leur projet généré des personnalisations de plateforme intentionnelles qui doivent être classifiées avant toute politique Git.
|
||||
|
||||
Décision `alpha.6` : classer Tauri `COMMON`, activer `700-FRAMEWORKS.md` et créer `710-TAURI.md`. Le profil possède l'orchestration Tauri : host Rust, configuration/capabilities, hooks frontend, version produit et gates d'intégration. Il ne possède pas à lui seul Vite, TypeScript, Sass, Bootstrap, WASM, le package manager, les ports, fenêtres, CSP, bundles ou plugins particuliers.
|
||||
|
||||
La revue opérateur de `alpha.6` apporte deux clarifications importantes. Premièrement, dans les projets Tauri que l'organisation contrôle, le host est traité comme n'importe quel projet Rust du même ensemble et doit donc hériter sans exception implicite du profil Rust sélectionné ; un projet imposé de l'extérieur peut conserver d'autres conventions via des overrides project-specific. Deuxièmement, les choix récurrents `frontend/`, Vite, TypeScript, Sass, Bootstrap et ajout explicite des dépendances de plugins décrivent un **candidat de skeleton pour projets contrôlés**, pas le contrat universel de Tauri.
|
||||
|
||||
Le POC Tauri mobile de Games n'a pas été concluant pour les besoins Games observés, notamment l'objectif Android/ABI et les contraintes de monétisation envisagées. Cette expérience ne permet pas de rejeter Tauri mobile pour d'autres produits : la capacité reste à évaluer par projet avec les profils plateforme applicables.
|
||||
|
||||
La règle de validation commune reste confirmée : lorsqu'une propriété dépend de `beforeDevCommand`, `beforeBuildCommand`, `frontendDist`, des capabilities ou du bundling, une sous-commande directe telle que `npm run build` ou `cargo build` ne prouve pas l'intégration Tauri complète. La gate doit passer par le CLI Tauri ou une forme officiellement équivalente ; les sous-commandes restent pertinentes pour leurs preuves ciblées.
|
||||
|
||||
Le CLI Tauri fournit une commande `add`, mais les documentations officielles des plugins détaillent également l'ajout explicite de la dépendance Cargo, l'initialisation Rust et, lorsqu'ils existent, les bindings frontend. PGR ne doit donc pas imposer la commande de commodité : un projet qui privilégie le contrôle manuel des manifests peut suivre explicitement ces étapes et revoir chaque modification.
|
||||
|
||||
#### Seconde passe de réconciliation des conventions Tauri/Rust
|
||||
|
||||
La clarification opérateur de `alpha.6.fix.1` déclenche une seconde lecture des règles versionnées plutôt qu'une simple extrapolation depuis les fichiers de configuration. Cette passe confirme plusieurs niveaux de preuve.
|
||||
|
||||
**Commun aux `8` hosts Tauri observés** : les `6` Desk KSP et les `2` hosts Games placent directement à la racine de leur crate `Cargo.toml`, `build.rs`, `package.json`, `tsconfig.json` et `tauri.conf.json`; tous possèdent `src/lib.rs`, `src/main.rs`, `src/tauri.rs` et `frontend/`; aucun ne possède `src-tauri/`. Cette convergence justifie une forte recommandation PGR pour les nouveaux projets contrôlés sans imposer une migration mécanique aux projets externes.
|
||||
|
||||
**Commun et déjà normatif dans les corpus** : KSP `KSP-APP-010..013` et Games `GAME-PLATFORM-010` convergent vers une bibliothèque applicative avec façade `lib.rs`, un launcher `main.rs` mince et un `tauri.rs` qui assemble Tauri et expose les wrappers de commandes. Games `GAME-PLATFORM-009` confirme aussi que l'adaptation WASM réutilisable reste distincte de la crate Tauri.
|
||||
|
||||
**KSP plus strict mais réutilisable** : `KSP-APP-023` place les sources Web sous `frontend/`, TypeScript sous `frontend/ts/`, Sass sous `frontend/sass/` et les bindings TS-RS sous `frontend/ts/bindings/`, les DTO Rust restant la source de vérité. La baseline KSP `0.3.16` contient `41` fichiers Rust applicatifs utilisant TS-RS dans les apps Desk. Games n'a pas encore ce contrat TS-RS : PGR le classe donc comme convention stricte des projets contrôlés, pas comme invariant universel de Tauri.
|
||||
|
||||
**Fortement recommandé mais pas universel** : le préfixe KSP `tw_`, le splashscreen commun, les paires de ports fixes, le plugin tracing précis et les détails de shell sont locaux. En revanche, un module cohérent par fenêtre/responsabilité, des helpers communs séparés et l'ajout explicite/revu des plugins sont des patterns réutilisables.
|
||||
|
||||
**Rust au-delà de Tauri** : `RULES_RUST.md` KSP contient un profil beaucoup plus complet que Games : `use` non-traits interdits, chemins externes explicites les plus courts, réexports `self::`, alias interdits, blocs de visibilité/ordre, contrôle de flux explicite et façade stricte. Games confirme le noyau façade/chemins/erreurs mais pas toutes les contraintes de style. Ces écarts doivent être traités en tranches Rust dédiées, avec KSP comme référence stricte et Games comme pression pour classifier correctement `MUST`/`SHOULD`/override.
|
||||
|
||||
**Nomenclature des crates** : KSP encode explicitement le rôle (`ksp-<role>-lib`, `ksp-<domain>-api`, `ksp-app-<role>-<interface>`, workers/jobs), tandis que Games conserve lui aussi des noms révélant rôle et cible (`game-logging-lib`, `*-desktop`, `*-tauri`, `*-wasm`, `engine-v1-*`). PGR doit donc étudier une convention générale « préfixe projet + responsabilité + suffixe de rôle/cible » sans figer les vocabulaires propres à KSP ou Games.
|
||||
|
||||
|
||||
#### Décision `alpha.7` — profil Rust strict et nomenclature
|
||||
|
||||
La seconde passe sur les règles autoritaires confirme que KSP `RULES_RUST.md` version `10` matérialise le profil d'explicité le plus complet : Rust 2024, `use` réservé aux traits réellement nécessaires, chemins externes publics les plus courts, réexports internes `self::`, absence de glob/groupement/alias, façade crate-root, `crate::Item` intra-crate et contrôle de flux explicite. Games `RULES_RUST.md` version `7` confirme Rust 2024, façade crate-root, `crate::Item`, interdiction des globs, erreurs explicites et lints communs, tout en étant moins strict sur les imports non-traits et certaines formes de visibilité.
|
||||
|
||||
La décision PGR est de retenir ce niveau strict comme **défaut des nouvelles baselines Rust contrôlées**. Un projet externe ou historiquement contraint peut conserver une convention différente via un override project-specific borné ; cette exception ne réduit pas le profil canonique des nouveaux projets.
|
||||
|
||||
Les règles sémantiques retenues dans `alpha.7` sont :
|
||||
|
||||
- édition Rust 2024 comme baseline actuelle des projets contrôlés ;
|
||||
- `use` réservé aux traits qui doivent réellement être mis en scope ;
|
||||
- chemins explicites pour les autres symboles, avec le chemin public externe le plus court ;
|
||||
- réexports internes explicites via `self::`, sans glob, regroupement par accolades ni alias de commodité ;
|
||||
- façade crate-root pour les items partagés et `crate::Item` dans la crate, y compris dans le module propriétaire ;
|
||||
- pas de visibilité élargie uniquement pour les tests ;
|
||||
- `unwrap`, `expect` et `?` interdits en production dans le profil strict, avec retours et propagation d'erreurs explicites.
|
||||
|
||||
Le marqueur KSP `rust-rules: trait-import` n'est pas généralisé : il sert l'audit historique KSP et n'est pas la règle sémantique. De même, `alpha.7` n'importe aucun script composite KSP/Games ; l'enforcement complémentaire reste découpé entre les owners PGR existants et la tranche `alpha.8`.
|
||||
|
||||
La nomenclature converge sur une propriété utile sans imposer les vocabulaires locaux : KSP préfixe toutes ses crates avec `ksp-` et encode explicitement bibliothèque/API/application/worker/job ; Games emploie également des noms où responsabilité et cible restent visibles (`game-logging-lib`, `*-desktop`, `*-tauri`, `*-wasm`, familles `engine-v1-*`). PGR retient donc pour les nouveaux projets contrôlés un préfixe projet/abréviation obligatoire et recommande la forme `<project>-<responsibility>-<role-or-target>` lorsque le classificateur apporte une information réelle. Les ordres historiques déjà cohérents ne sont pas renommés rétroactivement.
|
||||
|
||||
Les règles de blocs homogènes, visibilité, espacement et ordre alphabétique restent volontairement hors de cette décision et appartiennent à `alpha.8`.
|
||||
|
||||
#### Correction `alpha.7.fix.1` — suffixes, packaging et tracing
|
||||
|
||||
La gate mécanique de `alpha.7` passe, mais la revue fonctionnelle opérateur révèle que la première matérialisation traitait encore les suffixes comme de simples indications de lisibilité. Le corpus KSP contient pourtant un contrat plus fort : `KSP-NAME-001..003` distingue implémentation réutilisable `-lib` et contrat extensible `-api`, `KSP-API-007` interdit de créer une API par symétrie, et `002-LAYERS_AND_DEPENDENCIES.md` réserve le logging aux crates ayant réellement du comportement.
|
||||
|
||||
La règle PGR devient donc sémantique : `-api` signifie frontière de contrat réellement justifiée et principalement passive ; `-lib` signifie implémentation/fonctionnalité réutilisable. Une implémentation unique sans besoin d'extension/backend/lifecycle ne crée pas artificiellement une paire `-api` / `-lib`. Les rôles `worker`, `job`, `store`, etc. peuvent faire partie du nom d'une bibliothèque, mais `-lib` continue d'indiquer qu'elle n'est pas le launcher.
|
||||
|
||||
Sur le packaging, les deux corpus ne doivent pas être fusionnés mécaniquement. Games `GAME-WS-007` sépare explicitement la lib de jeu et son runner Desktop. KSP contient encore `KSP-WORKER-014`, qui préférait à terme un package worker mixte bibliothèque + binaire. Cette dernière préférence n'est **pas généralisée** : la clarification opérateur retient désormais la séparation package bibliothèque / package exécutable par défaut, les exécutables restant des couches de composition minces. Tauri est l'exception framework actuelle.
|
||||
|
||||
Cette exception est elle-même fortement observée : les `6` hosts Tauri KSP `0.3.16` et les `2` hosts Tauri Games `0.3.5` déclarent une cible `lib` et une cible `bin` distinctes ; les libs utilisent un nom terminé par `_lib` tandis que le binaire conserve le nom applicatif. PGR exige donc, dans une nouvelle baseline Tauri contrôlée, des noms de targets distincts même après normalisation `-` → `_`. Le motif cross-platform exact à l'origine de cette convention n'est pas utilisé comme preuve normative ici ; le contrat observable et reproductible suffit.
|
||||
|
||||
Le logging converge également fortement. KSP possède `ksp-logging-lib` comme façade/runtime commun et garde ses `*-api` déclaratives sans logging ; Games définit `tracing` comme mécanisme canonique, `tracing-subscriber` comme owner de composition, `tracing-appender` lorsque nécessaire et `game-logging-lib` comme crate transverse. PGR retient donc `tracing` par défaut et recommande une crate commune de logging dès que plusieurs runtimes partagent subscriber, sinks, filtres ou lifecycle ; la façade `log` reste seulement une compatibilité possible, pas le default d'une nouvelle baseline contrôlée.
|
||||
|
||||
#### Politique de version Tauri/frontend réconciliée
|
||||
|
||||
La baseline KSP `0.3.16` illustre le défaut de l'ancienne convention : les six `tauri.conf.json` n'ont pas de champ `version`, tandis que leurs `package.json` portent des versions historiques différentes (`0.2.6`, `0.2.12-pre.9`, `0.3.7`, `0.3.8` ou `0.3.15`) sans représenter uniformément la release courante. Games `0.3.5` suit la même famille de règles. Cette situation réduit les modifications mécaniques mais affaiblit la lisibilité des manifests.
|
||||
|
||||
La décision PGR est donc :
|
||||
|
||||
- `VERSION` = `CANONICAL` exact de la tranche ;
|
||||
- version Cargo = `MIRROR-EXACT` lorsque le profil Rust du projet la synchronise ;
|
||||
- `tauri.conf.json > version` et `package.json > version`, lorsqu'ils sont conservés pour le même produit, SHOULD normalement être `MIRROR-STABLE` et porter la cible `X.Y.Z` pendant tout le développement ;
|
||||
- une distribution réelle de prereleases peut sélectionner une politique plus fine (`MIRROR-EXACT` ou jalons de packaging) ;
|
||||
- l'absence du champ reste autorisée lorsque le projet n'en tire aucune valeur, mais n'est plus la recommandation PGR destinée à éviter le churn.
|
||||
|
||||
Cette décision est cohérente avec le principe PGR historique qui distingue déjà version canonique, miroirs techniques, compteurs et versions de schéma au lieu d'exiger `tous les champs == VERSION`.
|
||||
|
||||
#### Décision `alpha.8` — formatage structurel et audits monotâches
|
||||
|
||||
La comparaison des `audit_rust_general_rules.py` KSP/Games confirme que leur grand script mélangeait plusieurs owners qui peuvent être séparés proprement. PGR possédait déjà `blank_lines` et `const_blocks`; la tranche extrait quatre propriétés supplémentaires sans copier les contrôles de headers, FFI, rustdoc, façade ou imports déjà possédés ailleurs.
|
||||
|
||||
Les nouveaux audits ciblés sont :
|
||||
|
||||
- `item_spacing` : exactement une ligne vide entre items distincts voisins d'un même scope ; les blocs compacts `const/static/type` homogènes sont délégués afin d'éviter les faux positifs sémantiques ;
|
||||
- `module_order` : modules de production avant les modules de tests, ordre alphabétique de chaque groupe ;
|
||||
- `trait_import_blocks` : `use` non exportés au niveau module, avant les déclarations et sans ligne vide interne ; la nature réelle du trait n'est pas inférée lexicalement ;
|
||||
- `reexport_blocks` : bloc `pub use` avant `pub(crate) use`, aucun blanc interne et exactement un blanc entre niveaux ; Rustfmt reste owner du tri intra-bloc.
|
||||
|
||||
La mesure croisée sur tous les fichiers `crates/**/*.rs` donne `603` fichiers KSP et `87` Games. Les quatre nouveaux audits sont propres sur les deux corpus, de même que `blank_lines`. L'audit `const_blocks` produit en revanche `18` signaux KSP lorsqu'il est appliqué aveuglément et `0` Games ; certains signaux KSP correspondent à des tables ou schémas dont l'ordre est intentionnel. Cette différence confirme que `const_blocks` doit rester opt-in sur des fichiers explicitement sélectionnés.
|
||||
|
||||
PGR ne reprend pas automatiquement `RUST-FMT-110` du script KSP (item après `return` comme suspicion d'accolade déplacée), ni un ordre global `enum → struct → impl → fn`, ni l'idée que tous les éléments visibles doivent mécaniquement précéder les privés. Ces propriétés peuvent dépendre de la structure métier ; un audit lexical général créerait plus de faux positifs qu'il n'apporterait de preuve. La convention `struct` suivi de ses `impl` reste une forte préférence de lisibilité, pas un tri universel automatisé.
|
||||
|
||||
Cette extraction ferme le besoin identifié pour `alpha.8` sans créer de parser Rust général.
|
||||
|
||||
### Web / Vite / WASM
|
||||
|
||||
Les corpus et la clarification opérateur permettent désormais de séparer trois choses :
|
||||
|
||||
- le frontend Tauri est un owner distinct du host Rust et du framework Tauri ;
|
||||
- Vite + TypeScript + Sass + Bootstrap constitue un candidat de stack par défaut pour les futurs skeletons de projets contrôlés, mais manque encore de profils Web dédiés dans PGR ;
|
||||
- WASM n'est pas une dépendance implicite de Tauri et doit généralement rester un projet/package séparé appliquant ses propres profils, sauf composition architecturale explicitement voulue.
|
||||
|
||||
La création de profils Web/Vite/TypeScript/Sass reste `DEFER` pour `0.0.5` : cette release peut cadrer la future composition sans matérialiser précipitamment toute la famille Web.
|
||||
|
||||
La même clarification révèle un écart antérieur dans le profil Rust PGR : la conception initiale avait retenu le profil strict sans `use` non-trait, chemins explicites et conventions d'organisation, alors que le `510-RUST_CARGO.md` matérialisé conserve encore une formulation plus permissive. Ce sujet ne doit pas être absorbé par un fix Tauri ; il devient une tranche Rust normale dédiée avant toute décision de skeleton Tauri.
|
||||
|
||||
### Android / JNI
|
||||
|
||||
Android possède déjà un owner PGR `610`. Le JNI/Rust natif réellement observé est surtout propre à Games dans les baselines présentes. Les exceptions `unsafe`, ABI, exports JNI et génération Gradle doivent rester locales ou différées jusqu'à une étude composite Rust + Android/JNI suffisante. Classification : `DEFER`.
|
||||
|
||||
## Éléments qui doivent rester spécifiques
|
||||
|
||||
Les responsabilités suivantes sont utiles dans leurs projets mais ne fournissent pas un owner PGR générique :
|
||||
|
||||
- firewall de dépendances, protocoles Solana, transports, Store, workers/jobs, tracing targets et materialization de KSP ;
|
||||
- générations de moteur, assets de jeux, Uroburas, serveurs temps réel, distribution Android/Web et politiques de hosting de Games ;
|
||||
- noms métier exacts des crates, répertoires de config, schémas, routes, plugins et ressources propres à chaque application ; la convention générique de noms exprimant préfixe projet, responsabilité et rôle reste à réconcilier en `alpha.7` ;
|
||||
- seuils Clippy, identifiants courts autorisés, ports de développement et paramètres de fenêtres lorsqu'ils n'expriment aucun invariant réutilisable.
|
||||
|
||||
Ces éléments servent à tester que PGR permet des règles locales spécifiques ; ils ne doivent pas être aspirés dans le référentiel central.
|
||||
|
||||
## Conséquences pour une future adoption de PGR
|
||||
|
||||
La future application de PGR à KSP et Games doit être une migration explicitement planifiée dans chacun des projets, après stabilisation de la release PGR retenue. Elle ne doit pas reconstruire artificiellement leurs anciens deltas/histories ni renommer rétroactivement toutes les conventions historiques.
|
||||
|
||||
Le point de départ attendu sera plutôt :
|
||||
|
||||
```text
|
||||
prendre la stable réelle du projet
|
||||
+ sélectionner les owners PGR applicables
|
||||
+ comparer les règles locales actuelles
|
||||
+ conserver les contraintes projet spécifiques
|
||||
+ remplacer seulement les duplications devenues inutiles
|
||||
+ introduire les nouveaux audits/templates de manière proportionnée
|
||||
+ valider la migration comme une release du projet lui-même
|
||||
```
|
||||
|
||||
`0.0.5` améliore donc le référentiel et ses points d'adoption ; il ne migre ni KSP ni Games.
|
||||
|
||||
## Réconciliation intégrée `beta.1`
|
||||
|
||||
Après les tranches `alpha.1` à `alpha.9`, la classification initiale peut être rejouée sur l'état PGR obtenu sans aspirer les architectures métier des corpus.
|
||||
|
||||
| Domaine | Owner / artefact PGR après réconciliation | Statut intégré | Décision durable |
|
||||
|---------------------------------------------------------------|---------------------------------------------------------------------------------------|----------------|-------------------------------------------------------------------------------------------------------|
|
||||
| prompt de démarrage versionné | `210-WORKFLOW.md` + prompts de release | `OWNED` | contrat générique renforcé ; commandes et baselines propres au projet restent locales |
|
||||
| contrats de fichiers/familles | `300-DOCUMENTATION.md` + `004-FILE_FAMILY_CONTRACTS.md` | `OWNED` | pattern facultatif, jamais inventaire obligatoire |
|
||||
| lifecycle inter-release / horizon | `200-GOVERNANCE.md`, `210-WORKFLOW.md`, `300-DOCUMENTATION.md`, `005-RELEASE_PLAN.md` | `OWNED` | fermeture, transition et revue d'horizon ont désormais des owners explicites |
|
||||
| profil Rust contrôlé | `510-RUST_CARGO.md` + skeleton `002` | `OWNED` | explicité, crate-root, suffixes architecturaux, séparation lib/bin et tracing transverse bornés |
|
||||
| audits Rust structurels | `002-RUST_STYLE_AUDITS.md`, `003-RUST_EXPORT_COMPLETENESS.md`, scripts monotâches | `OWNED` | pas d'audit composite ; `const_blocks` reste sélectionné lorsque l'ordre est sémantique |
|
||||
| Tauri 2 | `700-FRAMEWORKS.md` + `710-TAURI.md` | `OWNED` | host/layout contrôlé, capabilities/plugins, TS-RS, versions et gate framework possédés |
|
||||
| skeleton Tauri contrôlé complet | étude `002-TAURI_SKELETON_DECISION.md` | `DEFER` | report durable jusqu'à matérialisation d'owners Web ; repris dans `ROADMAP.md` sans numéro de release |
|
||||
| Web / Vite / TypeScript / Sass | aucun owner dédié en `0.0.5` | `DEFER` | ne pas créer de profils placeholders pour satisfaire le skeleton Tauri |
|
||||
| Android/JNI Rust, distribution Games, architecture métier KSP | owners locaux ou preuves insuffisantes | `LOCAL/DEFER` | aucune aspiration dans PGR central |
|
||||
|
||||
La navigation durable pointe désormais vers les owners correspondant réellement aux décisions livrées. Les skeletons `001` et `002` restent composables ; aucun `003-TAURI...` n'est créé par anticipation. Les audits réutilisables restent opt-in ou sélectionnés par profil selon leur propriété, et aucune divergence historique des corpus n'est transformée rétroactivement en dette PGR.
|
||||
|
||||
Le `DEFER` Tauri est le seul travail différé de cette réconciliation suffisamment décidé pour être reporté explicitement dans la roadmap. Les trois axes plus larges identifiés pendant `alpha.8` restent des **candidats d'horizon**, pas des engagements : maturation de profils techniques composables, projet documentaire/spécification avec `saselang-bible` comme corpus pilote possible, et audit de généricité de PGR hors développement logiciel.
|
||||
|
||||
Cette réconciliation confirme que la mission de `0.0.5` est suffisamment fermée pour entrer en RC après la gate `beta.1`, sous réserve qu'aucune incohérence documentaire ou de navigation ne soit révélée par l'opérateur.
|
||||
141
docs/studies/002-TAURI_SKELETON_DECISION.md
Normal file
141
docs/studies/002-TAURI_SKELETON_DECISION.md
Normal file
@@ -0,0 +1,141 @@
|
||||
<!-- file: docs/studies/002-TAURI_SKELETON_DECISION.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Décision de skeleton Tauri pour projets contrôlés
|
||||
|
||||
## Objet
|
||||
|
||||
Cette étude enregistre la décision `0.0.5-alpha.9` sur la matérialisation d'un skeleton Tauri pour les nouveaux projets que l'organisation contrôle.
|
||||
|
||||
Elle ne redéfinit pas les règles Tauri. Leur owner normatif reste [`../rules/710-TAURI.md`](../rules/710-TAURI.md). Le contrat des skeletons reste possédé par [`../rules/220-SKELETONS.md`](../rules/220-SKELETONS.md).
|
||||
|
||||
## Corpus et état observé
|
||||
|
||||
Le corpus de réconciliation reste celui de `0.0.5` :
|
||||
|
||||
```text
|
||||
KSP 0.3.16 6 hosts Tauri
|
||||
Games 0.3.5 2 hosts Tauri
|
||||
```
|
||||
|
||||
Les `8` hosts possèdent le même socle structurel :
|
||||
|
||||
```text
|
||||
Cargo.toml
|
||||
build.rs
|
||||
package.json
|
||||
tsconfig.json
|
||||
tauri.conf.json
|
||||
vite.config.ts
|
||||
capabilities/
|
||||
src/lib.rs
|
||||
src/main.rs
|
||||
src/tauri.rs
|
||||
frontend/
|
||||
```
|
||||
|
||||
Aucun des `8` hosts n'utilise `src-tauri/`. Tous utilisent Vite et TypeScript. Les `6` hosts KSP utilisent en plus Bootstrap et `sass-embedded`, tandis que les `2` POC Games ne constituent pas une preuve suffisante pour imposer ces deux choix au profil Tauri universel.
|
||||
|
||||
KSP apporte également l'usage éprouvé de TS-RS pour les structures Rust partagées avec le frontend. Cette frontière est déjà cadrée par `710-TAURI.md` pour les projets contrôlés.
|
||||
|
||||
Ces observations qualifient un **candidat de skeleton organisationnel** ; elles ne suffisent pas à créer des règles Web générales.
|
||||
|
||||
## Owners déjà suffisants
|
||||
|
||||
Les responsabilités suivantes ont un owner PGR matérialisé :
|
||||
|
||||
- gouvernance et composition des skeletons : `200`, `210`, `220` ;
|
||||
- Rust/Cargo et skeleton Rust : `510` + `002-RUST_CARGO_WORKSPACE.md` ;
|
||||
- plateformes déjà matérialisées lorsqu'elles s'appliquent, notamment Android : `610` ;
|
||||
- host Tauri, capabilities, plugins, hooks, version produit et frontière Rust/frontend : `710`.
|
||||
|
||||
La partie native du candidat n'a donc pas besoin d'un nouveau propriétaire caché dans le skeleton.
|
||||
|
||||
## Owner manquant
|
||||
|
||||
PGR `0.0.5` ne possède aucun profil Web dédié pour :
|
||||
|
||||
- organisation des sources frontend ;
|
||||
- TypeScript comme langage frontend ;
|
||||
- Vite comme bundler/dev server ;
|
||||
- Sass/CSS et ownership des sorties générées ;
|
||||
- framework CSS généraliste tel que Bootstrap ;
|
||||
- validation Web proportionnée et artefacts de build correspondants.
|
||||
|
||||
Créer immédiatement un skeleton qui configure ces éléments ferait du skeleton le propriétaire normatif implicite de la stack Web. Ce serait contraire au principe suivant : un skeleton sélectionne et compose des owners ; il ne remplace pas les owners manquants.
|
||||
|
||||
## Vérification externe Tauri 2
|
||||
|
||||
La documentation Tauri 2 courante confirme deux points utiles mais ne comble pas le manque d'owner Web :
|
||||
|
||||
- `create-tauri-app` fournit plusieurs choix frontend et Tauri peut aussi être ajouté manuellement à un frontend existant ; le layout standard `src-tauri/` est donc un scaffold supporté, pas une obligation conceptuelle pour les projets PGR contrôlés ;
|
||||
- les documentations de plugins décrivent aussi l'installation explicite des dépendances Cargo, l'initialisation Rust, les bindings JavaScript lorsque nécessaires et les permissions/capabilities, ce qui reste compatible avec la convention PGR d'intégration explicite.
|
||||
|
||||
Références vérifiées le `2026-09-25` :
|
||||
|
||||
- <https://v2.tauri.app/start/create-project/>
|
||||
- <https://v2.tauri.app/start/project-structure/>
|
||||
- <https://v2.tauri.app/plugin/file-system/>
|
||||
- <https://v2.tauri.app/learn/security/using-plugin-permissions/>
|
||||
|
||||
## Décision
|
||||
|
||||
Décision `alpha.9` :
|
||||
|
||||
```text
|
||||
DEFER
|
||||
```
|
||||
|
||||
PGR `0.0.5` **ne crée pas** de skeleton Tauri `003`.
|
||||
|
||||
Le report est intentionnel : le profil Tauri est suffisamment mûr, mais le skeleton complet ne peut pas encore être instancié sans absorber prématurément les responsabilités Web.
|
||||
|
||||
Ce `DEFER` ne remet pas en cause les conventions Tauri déjà normalisées dans `710-TAURI.md` et ne réouvre pas les décisions `alpha.6` à `alpha.8`.
|
||||
|
||||
## Candidat conservé
|
||||
|
||||
Lorsque les owners Web seront suffisants, le skeleton candidat pour une nouvelle baseline contrôlée devra réévaluer puis, si toujours justifié, composer :
|
||||
|
||||
```text
|
||||
001-PROJECT_GOVERNANCE_FOUNDATION
|
||||
+ 002-RUST_CARGO_WORKSPACE
|
||||
+ profil Tauri 710
|
||||
+ profils Web réellement applicables
|
||||
```
|
||||
|
||||
Le candidat organisationnel conserve les choix suivants sans les promouvoir aujourd'hui en règles Web :
|
||||
|
||||
- host Cargo direct sans `src-tauri/` ajouté uniquement pour reproduire le scaffold standard ;
|
||||
- `frontend/` pour les sources Web ;
|
||||
- Vite + TypeScript ;
|
||||
- Sass pour la chaîne de styles ;
|
||||
- Bootstrap comme baseline de présentation lorsqu'un framework CSS généraliste est utile ;
|
||||
- TS-RS pour les DTO Rust possédés par le host et partagés avec TypeScript ;
|
||||
- `tauri.rs` comme owner de l'assemblage et des wrappers `#[tauri::command]` ;
|
||||
- ajout explicite et revu des plugins, dépendances frontend et capabilities minimales ;
|
||||
- WASM dans une unité séparée par défaut ;
|
||||
- politique de versions classifiée `CANONICAL` / `MIRROR-EXACT` / `MIRROR-STABLE` selon les owners concernés.
|
||||
|
||||
## Conditions de sortie du report
|
||||
|
||||
Un futur plan MAY promouvoir ce candidat lorsqu'il existe au minimum des owners suffisants pour :
|
||||
|
||||
1. TypeScript et conventions Web contrôlées ;
|
||||
2. Vite et ownership des commandes/dev server/build outputs ;
|
||||
3. Sass/CSS et statut des artefacts générés ;
|
||||
4. validation frontend indépendante de la validation Tauri ;
|
||||
5. choix Bootstrap ou alternative clairement classifié comme décision de skeleton plutôt que règle Tauri.
|
||||
|
||||
Le futur travail devra alors réexaminer le corpus courant au lieu de supposer que les versions ou outils observés dans KSP/Games restent les bons choix.
|
||||
|
||||
## Hors scope
|
||||
|
||||
Cette décision ne :
|
||||
|
||||
- crée pas de profil Web placeholder ;
|
||||
- réserve pas un numéro de release futur ;
|
||||
- transforme pas Bootstrap en dépendance Tauri ;
|
||||
- impose pas npm plutôt qu'un autre package manager ;
|
||||
- intègre pas WASM dans le host ;
|
||||
- migre KSP ou Games vers PGR ;
|
||||
- modifie pas les règles Tauri déjà stabilisées.
|
||||
45
docs/templates/001-RUST_CARGO_TOOLING.md
vendored
Normal file
45
docs/templates/001-RUST_CARGO_TOOLING.md
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
<!-- file: docs/templates/001-RUST_CARGO_TOOLING.md -->
|
||||
<!-- version: 3 -->
|
||||
|
||||
# Templates d'outillage Rust/Cargo
|
||||
|
||||
## Rôle et sélection
|
||||
|
||||
Ces trois fichiers fournissent une baseline de configuration issue des conventions réellement utilisées dans KSP et Games. Ils s'appliquent à un projet Rust/Cargo qui choisit ce profil d'outillage ; ils ne créent pas une dépendance vers PGR après copie.
|
||||
|
||||
- [`rustfmt.toml`](../../templates/rust-cargo/rustfmt.toml) — formatage canonique, avec notamment largeur `160` et édition `2024` dans l'exemple ;
|
||||
- [`clippy.toml`](../../templates/rust-cargo/clippy.toml) — paramètres de lints (seuils, exceptions de tests, identifiants courts) issus du noyau partagé des deux projets ;
|
||||
- [`.cargo/config.toml`](../../templates/rust-cargo/.cargo/config.toml) — emplacements des artefacts Cargo hors de la racine source.
|
||||
|
||||
Les niveaux `deny`, `allow`, `warn` et `forbid` des lints Rust/Clippy appartiennent au `Cargo.toml` du workspace, selon [`510-RUST_CARGO.md`](../rules/510-RUST_CARGO.md). `clippy.toml` règle des paramètres de lints, pas leur niveau. Les deux modèles Cargo et l'héritage `[lints] workspace = true` sont documentés dans [`002-CARGO_MANIFESTS.md`](002-CARGO_MANIFESTS.md).
|
||||
|
||||
## Copier et adapter
|
||||
|
||||
Copier ces fichiers aux chemins suivants dans le projet destinataire :
|
||||
|
||||
```text
|
||||
rustfmt.toml
|
||||
clippy.toml
|
||||
.cargo/config.toml
|
||||
```
|
||||
|
||||
Adapter le header `# file:` de chacun à son nouveau chemin relatif. Comme il s'agit de nouveaux fichiers locaux, leur révision interne commence à `1` si le projet suit cette convention. Vérifier les choix avant de les utiliser :
|
||||
|
||||
1. `rustfmt.toml` : aligner `edition` sur l'édition déclarée dans le manifeste du projet. La largeur et les autres options constituent la convention de départ de KSP/Games et peuvent être ajustées pour le projet ;
|
||||
2. `clippy.toml` : revoir les seuils au regard des types et API du projet ; adapter `allowed-idents-below-min-chars` à ses abréviations réelles. Les exceptions `allow-*-in-tests` sont une décision explicite du profil retenu ; elles ne relâchent pas les lints de production ;
|
||||
3. `.cargo/config.toml` : remplacer `project-name` par un identifiant propre au projet pour éviter la collision de deux workspaces sous `../builds/`. Depuis une configuration placée dans `<racine>/.cargo/`, Cargo résout ici les chemins relatifs par rapport à `<racine>/` : la sortie se trouve donc sous le dossier frère `<parent>/builds/<projet>/target/` ;
|
||||
4. conserver les deux entrées `target-dir` et `build-dir` lorsque cette politique est choisie. Elles ciblent volontairement le même dossier, même si Cargo utilise actuellement `target-dir` comme valeur par défaut de `build-dir` ;
|
||||
5. ajouter séparément les flags de cible, chemins particuliers ou ajustements Clippy nécessaires à un projet. Les flags Web présents dans Games ne sont pas un défaut de tous les projets Rust.
|
||||
|
||||
Le chemin de sortie sous `builds/` est externe au dépôt source ; il ne doit pas être inclus dans les archives du projet. Si l'environnement impose un autre emplacement, ajuster la configuration du projet au lieu de copier un chemin machine depuis KSP ou Games.
|
||||
|
||||
## Validation dans un projet Rust
|
||||
|
||||
Après adaptation, les contrôles utiles dépendent du code et des manifests effectivement présents :
|
||||
|
||||
```bash
|
||||
cargo fmt --all -- --check
|
||||
cargo clippy --workspace --all-targets --all-features -- -D warnings
|
||||
```
|
||||
|
||||
Vérifier l'emplacement effectif des artefacts sur un build ou un check pertinent. La validation de PGR lui-même peut vérifier la syntaxe TOML et la cohérence des chemins sans demander de compiler un workspace Rust absent de son dépôt.
|
||||
53
docs/templates/002-CARGO_MANIFESTS.md
vendored
Normal file
53
docs/templates/002-CARGO_MANIFESTS.md
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
<!-- file: docs/templates/002-CARGO_MANIFESTS.md -->
|
||||
<!-- version: 3 -->
|
||||
|
||||
# Modèles de manifests Cargo workspace et crate membre
|
||||
|
||||
## Rôle des deux fichiers
|
||||
|
||||
Le [manifest racine](../../templates/rust-cargo/Cargo.toml) est celui d'un workspace virtuel à une unité de release ; le [manifest membre](../../templates/rust-cargo/crates/project-core-lib/Cargo.toml) montre une crate bibliothèque ordinaire. Les deux fichiers forment un exemple TOML syntaxiquement valide. Après copie dans un nouveau projet, il faut aussi fournir le code source de la crate avant de demander à Cargo de la compiler. Le dépôt PGR ne devient pas lui-même un workspace Cargo.
|
||||
|
||||
Ces modèles prolongent les trois configurations de [`001-RUST_CARGO_TOOLING.md`](001-RUST_CARGO_TOOLING.md). Le propriétaire des choix normatifs reste [`510-RUST_CARGO.md`](../rules/510-RUST_CARGO.md). Les chemins `project-core-lib`, le nom du package et la version `0.1.0` sont des **valeurs d'exemple à remplacer** : cette version ne reflète pas `VERSION` de PGR et ne définit pas la version d'un autre projet.
|
||||
|
||||
## Adopter le manifest racine
|
||||
|
||||
Copier `templates/rust-cargo/Cargo.toml` vers `Cargo.toml` du projet, corriger son header `# file:` et commencer sa propre révision de fichier à `1`. Adapter `members` aux répertoires qui existent effectivement, puis choisir la version canonique de l'unité de release. Lorsque toutes les crates partagent une seule release, aligner `[workspace.package].version` sur le `VERSION` de ce projet ; plusieurs unités de release indépendantes ne doivent pas hériter d'une version fictive commune.
|
||||
|
||||
L'édition `2024` et `resolver = "3"` sont cohérents avec l'exemple [`rustfmt.toml`](../../templates/rust-cargo/rustfmt.toml). Pour un workspace virtuel, fixer explicitement le resolver souhaité ; adapter ensemble l'édition, Rustfmt et la toolchain compatible si le projet prend d'autres valeurs. `publish = false` est un défaut prudent pour cet exemple ; définir la politique de publication réelle avant de publier une crate.
|
||||
|
||||
`license`, `repository` et `authors` ne sont volontairement pas renseignés avec des identités fictives. Si ces métadonnées ont une valeur vraie et commune, les déclarer dans `[workspace.package]` et les hériter explicitement dans chaque crate concernée, par exemple `license.workspace = true` seulement après avoir déclaré `license` à la racine. Ne pas imposer un auteur, une licence ou une URL propres à KSP/Games.
|
||||
|
||||
Le bloc `[workspace.dependencies]` est vide tant qu'aucune dépendance concrète ne sert plusieurs crates. Déclarer à la racine seulement les contraintes et features réellement communes ; les features propres à un membre sont activées sur sa dépendance locale. Cargo ajoute les features demandées au membre à celles déjà sélectionnées au workspace ; éviter d'activer globalement une feature de test ou de plateforme par facilité. Les dépendances de test appartiennent à `[dev-dependencies]` du membre qui les utilise.
|
||||
|
||||
Les trois lints Rust et les `18` niveaux Clippy reprennent la politique partagée observée dans KSP et Games. Les `allow` retiennent leurs choix de style explicite, notamment `needless_return` malgré `implicit_return = "deny"`, et évitent qu'un lint de suggestion réécrive systématiquement ce style. Réviser leur pertinence pour le projet avant adoption. Les seuils et réglages supplémentaires appartiennent au [`clippy.toml`](../../templates/rust-cargo/clippy.toml) distinct : ce fichier ne définit aucun niveau de lint.
|
||||
|
||||
## Adopter le manifest membre
|
||||
|
||||
Copier le membre vers `crates/<nom>/Cargo.toml`, adapter `name`, son chemin dans `members` et le header `# file:`. Pour un nouveau projet contrôlé, `<nom>` commence par le nom court ou l'abréviation canonique du projet et rend lisibles la responsabilité puis le rôle/cible utiles, conformément à [`510-RUST_CARGO.md`](../rules/510-RUST_CARGO.md). Ne pas conserver `project-core-lib` comme nom réel et ne pas ajouter un suffixe uniquement par symétrie. `version.workspace = true`, `edition.workspace = true` et `publish.workspace = true` rendent visibles les héritages choisis ; ajouter séparément `license.workspace = true`, `repository.workspace = true` ou `authors.workspace = true` si les valeurs existent à la racine et concernent cette crate. `[lints] workspace = true` est requis pour reprendre les niveaux du workspace : leur présence à la racine ne suffit pas à les appliquer automatiquement aux membres.
|
||||
|
||||
Le bloc `[dependencies]` vide se remplit selon les besoins de la crate. Pour une dépendance déjà déclarée sous `[workspace.dependencies]`, utiliser localement `nom = { workspace = true }`, avec `features = [...]` au besoin. Pour une dépendance strictement locale, choisir sa contrainte directement dans ce membre ; aucune liste tierce arbitraire n'est copiée par ce modèle.
|
||||
|
||||
Pour une nouvelle baseline contrôlée, une bibliothèque réutilisable et son exécutable sont normalement deux packages Cargo distincts. Le package binaire peut reprendre les mêmes héritages de workspace, mais son manifest est légitime parce qu'il exprime une frontière de packaging et de dépendances différente : il dépend des crates `-lib`, conserve un `main.rs` mince et porte un nom révélant son rôle (`-cli`, `-desk`, `-worker`, `-job`, `-server`, etc.) lorsque ce classificateur est réellement applicable. Ne pas fusionner `lib` + `bin` dans un seul package uniquement pour éviter un manifest membre supplémentaire.
|
||||
|
||||
Une paire `*-api` / `*-lib` n'est créée que si un vrai contrat séparé le justifie. Une crate `-api` purement déclarative ne reçoit normalement ni subscriber global ni dépendance vers la crate de logging. Une crate `-lib` unique suffit lorsqu'il n'existe qu'une implémentation utile et aucune frontière d'extension/backend/lifecycle.
|
||||
|
||||
Tauri est une exception framework documentée par [`710-TAURI.md`](../rules/710-TAURI.md) : son host peut être un package mixte `lib + bin`, mais les deux targets doivent alors posséder des noms distincts selon le contrat Tauri.
|
||||
|
||||
Une crate à version ou politique de publication réellement indépendante doit déclarer ses valeurs locales et ne plus hériter ces champs par automatisme.
|
||||
|
||||
## Exception locale de lints
|
||||
|
||||
Une frontière FFI peut avoir besoin de `unsafe_code = "allow"` dans une crate particulière, comme l'entrée Android observée dans Games. Cette exception demande justification, portée étroite et validation du code `unsafe` concerné. Cargo ne permet pas de combiner `workspace = true` avec des définitions de lints locaux dans le même manifest membre : retirer l'héritage `[lints]` pour cette crate et déclarer localement `[lints.rust]` ainsi que `[lints.clippy]`, en recopiant les niveaux partagés réellement conservés puis en ajustant seulement l'exception motivée. Les autres membres continuent d'hériter des lints racine.
|
||||
|
||||
## Vérification dans le projet destinataire
|
||||
|
||||
Après avoir ajouté le code source nécessaire, vérifier d'abord la résolution des manifests et les héritages, puis les contrôles réellement applicables :
|
||||
|
||||
```bash
|
||||
cargo metadata --format-version 1 --no-deps
|
||||
cargo fmt --all -- --check
|
||||
cargo check --workspace
|
||||
cargo clippy --workspace --all-targets --all-features -- -D warnings
|
||||
```
|
||||
|
||||
Vérifier séparément le cas d'une crate à lints locaux lorsque le projet comporte réellement une exception. `Cargo.lock` et les artefacts créés par ces commandes suivent la politique du projet et la configuration Cargo de [`001-RUST_CARGO_TOOLING.md`](001-RUST_CARGO_TOOLING.md).
|
||||
32
docs/templates/003-NEW_SESSION_PROMPT.md
vendored
Normal file
32
docs/templates/003-NEW_SESSION_PROMPT.md
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
<!-- file: docs/templates/003-NEW_SESSION_PROMPT.md -->
|
||||
<!-- version: 2 -->
|
||||
|
||||
# Spécification du prompt manuel de nouvelle session
|
||||
|
||||
## Usage
|
||||
|
||||
Cette spécification sert à préparer le court message opérateur remis après une stable publiée. Le prompt de démarrage propre à la version suivante reste un fichier `prompts/NNN-VX_Y_Z_START_PROMPT.md` finalisé selon [`210-WORKFLOW.md`](../rules/210-WORKFLOW.md). Le message manuel indique où commencer et quelles preuves fournir ; il ne copie ni ce prompt, ni le plan, ni le history de la release.
|
||||
|
||||
Lorsque la cible suivante est connue et que la vérification post-tag applicable est terminée, ce message doit être remis spontanément à l'opérateur sans attendre qu'il le réclame. Lorsque la cible suivante n'est pas suffisamment décidée, PGR ne fabrique pas de version ou de prompt : le message de clôture indique que l'horizon reste ouvert et pointe vers le handoff ou la revue d'horizon applicable.
|
||||
|
||||
## Champs à renseigner
|
||||
|
||||
1. **Baseline** : identifier le tag stable, le nom réel de l'archive source téléchargée depuis ce tag et la forge d'origine. Une archive sans `.git` est normale pour une archive de tag et se vérifie par sa cohérence interne ; elle ne porte pas elle-même les métadonnées Git du dépôt.
|
||||
2. **Preuve post-tag** : si un rapport de publication/vérification distinct existe et est réellement `PASS`, indiquer son chemin exact et demander qu'il soit fourni avec l'archive. Sinon, signaler explicitement son état réel ; ne jamais fabriquer cette preuve ni la confondre avec le tag.
|
||||
3. **Contrat de reprise** : indiquer le chemin du prompt `prompts/NNN-VX_Y_Z_START_PROMPT.md` existant dans la baseline, la version cible et la première tranche attendue. Le prompt versionné possède la mission détaillée et le scope de la release.
|
||||
4. **Intake** : demander la vérification de l'archive, des règles applicables, de la gouvernance, de la structure documentaire et des deltas/histories avant de préparer la première tranche. Adapter la liste aux artefacts effectivement présents et aux risques du projet.
|
||||
5. **Horizon ouvert** : si aucune version suivante n'est encore suffisamment décidée, remplacer le contrat de reprise de version par l'instruction exacte de revue/handoff applicable ; ne pas inventer un `NEXT` artificiel.
|
||||
|
||||
## Forme à remplir et à remettre
|
||||
|
||||
Après vérification des chemins et de l'état réel du rapport, écrire **une seule phrase** adaptée au projet lorsque la cible suivante est connue. Si le rapport est `PASS` et fourni :
|
||||
|
||||
```text
|
||||
Partir de l'archive <nom exact du ZIP issu du tag vX.Y.Z> et du rapport post-tag <chemin exact du rapport PASS>. Lire et exécuter <chemin du prompt de démarrage dans la baseline>. Vérifier l'archive, les règles, la gouvernance, la structure documentaire, les deltas/histories et la cohérence globale avant de préparer <version cible-alpha.1>.
|
||||
```
|
||||
|
||||
Si le rapport est absent ou non validé, retirer « et du rapport post-tag ... » de la phrase et préciser séparément son état réel à la nouvelle session. Conserver les noms exacts de la forge et des fichiers du projet : la forme `<nom exact du ZIP>` n'est qu'un champ de rédaction.
|
||||
|
||||
Si l'horizon est ouvert, remettre plutôt une consigne courte qui identifie la stable publiée, les preuves disponibles et le handoff/revue d'horizon à reprendre. Cette consigne ne doit contenir ni numéro de version hypothétique, ni faux prompt de démarrage.
|
||||
|
||||
Une interruption au milieu d'une prerelease suit le mécanisme de reprise de la tranche courante prévu dans `210-WORKFLOW.md` ; elle ne crée pas artificiellement un nouveau prompt de version.
|
||||
80
docs/templates/004-FILE_FAMILY_CONTRACTS.md
vendored
Normal file
80
docs/templates/004-FILE_FAMILY_CONTRACTS.md
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
<!-- file: docs/templates/004-FILE_FAMILY_CONTRACTS.md -->
|
||||
<!-- version: 2 -->
|
||||
|
||||
# Pattern — contrats locaux de fichiers ou familles
|
||||
|
||||
## Objectif
|
||||
|
||||
Ce pattern aide un projet à expliciter quelques responsabilités de fichiers ou familles durables lorsqu'elles deviennent difficiles à déduire de l'arborescence, de la toolchain ou des règles déjà existantes.
|
||||
|
||||
Il complète le contrat documentaire de [`../rules/300-DOCUMENTATION.md`](../rules/300-DOCUMENTATION.md). Il n'impose aucun fichier particulier au projet destinataire.
|
||||
|
||||
## Quand l'utiliser
|
||||
|
||||
Créer un registre local seulement lorsqu'il réduit une ambiguïté réelle, par exemple lorsque :
|
||||
|
||||
- plusieurs familles voisines ont des rôles différents qui provoquent régulièrement des erreurs de placement ;
|
||||
- un fichier est une source de vérité tandis qu'un autre est généré ou dérivé ;
|
||||
- une famille possède une règle de modification ou de synchronisation non évidente ;
|
||||
- des contributeurs doivent savoir quel owner modifier sans relire plusieurs documents spécialisés.
|
||||
|
||||
Ne pas l'utiliser pour inventorier chaque fichier d'un petit dépôt, recopier les rôles standards déjà décrits par PGR ou dupliquer un manifeste/build system qui possède déjà l'information.
|
||||
|
||||
## Forme minimale
|
||||
|
||||
Le nom et l'emplacement appartiennent au projet destinataire. `docs/rules/FILE_CONTRACTS.md` est un nom possible, pas une convention PGR obligatoire.
|
||||
|
||||
Une entrée utile contient au minimum :
|
||||
|
||||
```text
|
||||
file or family
|
||||
responsibility
|
||||
modification rule
|
||||
```
|
||||
|
||||
Lorsque ces informations sont utiles, le projet MAY ajouter :
|
||||
|
||||
```text
|
||||
source of truth / generated status
|
||||
local owner or reference
|
||||
validation or synchronization requirement
|
||||
```
|
||||
|
||||
Une table Markdown convient aux registres structurés :
|
||||
|
||||
```markdown
|
||||
| Fichier ou famille | Responsabilité | Règle de modification |
|
||||
|---------------------|------------------|----------------------------|
|
||||
| `<path-or-pattern>` | `<rôle durable>` | `<quand/comment modifier>` |
|
||||
```
|
||||
|
||||
Une liste courte est préférable lorsqu'elle reste plus lisible. La forme n'est pas normative ; la clarté de la responsabilité l'est pour le projet qui choisit d'adopter ce contrat.
|
||||
|
||||
## Règles d'adaptation
|
||||
|
||||
Lors de l'instanciation :
|
||||
|
||||
1. sélectionner uniquement les fichiers ou familles dont le contrat local apporte une information non évidente ;
|
||||
2. référencer l'owner détaillé existant au lieu de recopier ses règles ;
|
||||
3. regrouper les chemins qui partagent réellement le même contrat plutôt que créer une entrée par fichier ;
|
||||
4. distinguer explicitement source de vérité et artefact généré lorsque cette distinction existe ;
|
||||
5. supprimer ou fusionner une entrée devenue redondante lorsque son rôle est désormais évident ailleurs.
|
||||
|
||||
Le registre SHOULD évoluer lorsqu'une responsabilité ou règle de modification change réellement. Il SHOULD NOT être modifié uniquement parce qu'un nouveau fichier respecte déjà une famille décrite.
|
||||
|
||||
## Exemple abstrait
|
||||
|
||||
```markdown
|
||||
| Fichier ou famille | Responsabilité | Règle de modification |
|
||||
|--------------------|---------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------|
|
||||
| `config/*.example` | Décrire les exemples versionnés de configuration locale. | Mettre à jour lorsqu'une option utilisateur versionnée est ajoutée ou retirée ; ne jamais y placer de secret réel. |
|
||||
| `generated/**` | Contenir les sorties reconstruisibles produites par la toolchain choisie. | Ne pas modifier manuellement ; régénérer depuis la source de vérité documentée. |
|
||||
```
|
||||
|
||||
Cet exemple illustre la forme uniquement. Il ne crée aucune règle universelle sur les chemins `config/` ou `generated/`.
|
||||
|
||||
## Critère de sortie
|
||||
|
||||
Le pattern est utile si un nouveau contributeur peut déterminer plus vite où une responsabilité vit et quand modifier une famille sans devoir maintenir un catalogue parallèle du dépôt.
|
||||
|
||||
S'il ajoute davantage de cérémonie que d'information, ne pas l'instancier ou le retirer.
|
||||
85
docs/templates/005-RELEASE_PLAN.md
vendored
Normal file
85
docs/templates/005-RELEASE_PLAN.md
vendored
Normal file
@@ -0,0 +1,85 @@
|
||||
<!-- file: docs/templates/005-RELEASE_PLAN.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Pattern — plan de release
|
||||
|
||||
## Usage
|
||||
|
||||
Ce pattern aide un projet gouverné par PGR à construire un plan de release suffisamment précis pour piloter plusieurs tranches sans transformer le plan en journal d'activité. Il complète `alpha.1` et [`210-WORKFLOW.md`](../rules/210-WORKFLOW.md) ; il n'impose ni le titre exact des sections, ni un nombre fixe de prereleases.
|
||||
|
||||
Un petit changement qui ne nécessite pas de plan dédié n'a pas à instancier ce pattern.
|
||||
|
||||
## Contrat minimal
|
||||
|
||||
Un plan utile doit permettre de comprendre :
|
||||
|
||||
- d'où part la release et quelle mission elle doit rendre vraie ;
|
||||
- ce qui est acquis, ouvert, inclus et explicitement hors-scope ;
|
||||
- comment les risques, validations et smokes importants seront traités ;
|
||||
- comment le travail est découpé actuellement et quels signaux imposeraient un REPLAN ;
|
||||
- **où et quand la release sera clôturée** : documentation durable, `CHANGELOG`, `ROADMAP`, prompt/handoff suivant, plan et publication ;
|
||||
- si l'horizon de roadmap doit être revu avant la fermeture et, si oui, à quel moment ou selon quel déclencheur.
|
||||
|
||||
## Forme candidate
|
||||
|
||||
```markdown
|
||||
# Plan X.Y.Z — <mission courte>
|
||||
|
||||
## Statut et sources
|
||||
|
||||
Baseline, prompt, rapports ou corpus réellement autoritaires.
|
||||
|
||||
## Mission
|
||||
|
||||
Résultat attendu de la release.
|
||||
|
||||
## État acquis et questions ouvertes
|
||||
|
||||
Décisions déjà établies et points qui doivent encore être instruits.
|
||||
|
||||
## Scope et hors-scope
|
||||
|
||||
Frontières fonctionnelles, techniques et documentaires.
|
||||
|
||||
## Stratégie de validation
|
||||
|
||||
Gates, smokes et preuves importantes ; renvois vers la matrice plutôt que copie exhaustive.
|
||||
|
||||
## Trajectoire prévisionnelle
|
||||
|
||||
Responsabilité attendue de chaque tranche. Le forecast reste révisable.
|
||||
|
||||
## Déclencheurs de REPLAN
|
||||
|
||||
Signaux qui obligeraient à recalculer le travail restant.
|
||||
|
||||
## Clôture et transition
|
||||
|
||||
- réconciliation documentaire durable : <tranche/moment> ;
|
||||
- entrée CHANGELOG candidate/finale : <tranche/moment> ;
|
||||
- revue/mise à jour ROADMAP : <tranche/moment> ;
|
||||
- prompt ou handoff de reprise : <tranche/moment ou cible encore ouverte> ;
|
||||
- fermeture du plan : <tranche/moment> ;
|
||||
- promotion stable et vérification post-tag : <mécanisme>.
|
||||
|
||||
## Revue d'horizon
|
||||
|
||||
- état : <non nécessaire / requise / horizon volontairement ouvert> ;
|
||||
- raison : <pourquoi> ;
|
||||
- moment ou déclencheur : <quand> ;
|
||||
- sorties autorisées : <étendre / laisser ouvert / différer-pause / objectif accompli>.
|
||||
```
|
||||
|
||||
## Règles d'adaptation
|
||||
|
||||
Le plan doit rester proportionné. Une responsabilité déjà possédée par une règle, une matrice ou une étude est référencée plutôt que recopiée. Les résultats détaillés des gates restent dans `history/`.
|
||||
|
||||
La rubrique `Clôture et transition` est un contrat d'attribution des responsabilités, pas l'obligation d'exécuter tous les travaux en fin de release. Une documentation directement liée à une fonctionnalité continue d'évoluer dans la tranche qui la modifie.
|
||||
|
||||
La rubrique `Revue d'horizon` peut simplement indiquer qu'aucune revue n'est nécessaire parce que la roadmap s'étend déjà suffisamment. Si la prochaine version n'est pas décidée, cette rubrique doit l'assumer explicitement plutôt que fabriquer une roadmap.
|
||||
|
||||
PGR n'impose pas un journal de révisions systématique dans le plan. Un REPLAN met à jour les parties devenues fausses et le delta/history correspondant conserve la preuve du changement.
|
||||
|
||||
## Critère de sortie
|
||||
|
||||
Le plan est prêt lorsqu'il autorise le développement sans laisser ambiguës les responsabilités de fermeture, les validations majeures ni le devenir de l'horizon macro. Après stable, abandon ou supersession, il devient une référence historique de la release.
|
||||
@@ -1,5 +1,5 @@
|
||||
<!-- file: docs/validation/001-VALIDATION_MATRIX.md -->
|
||||
<!-- version: 4 -->
|
||||
<!-- version: 12 -->
|
||||
|
||||
# Matrice de validation PGR
|
||||
|
||||
@@ -14,17 +14,35 @@ Les catégories et règles de sélection sont définies dans [`../rules/400-VALI
|
||||
## Contrôles actifs
|
||||
|
||||
| ID | Catégorie | Commande / contrôle | Prérequis | Trigger | Phase | Coût | Acteur |
|
||||
|-------------------|-----------|------------------------------------------------------------------------------------------|------------------------|-------------------------------|----------------------|--------|-----------------|
|
||||
|---------------------|-----------|--------------------------------------------------------------------------------------|------------------------|---------------------------------|----------------------|--------|-----------------|
|
||||
| `PGR-GIT-001` | `CHECK` | `git diff --check` ou `git diff --cached --check` selon l'état de l'index | Git | toute modification suivie | alpha/beta/RC/stable | faible | opérateur |
|
||||
| `PGR-VERSION-001` | `CHECK` | comparer `VERSION` à la version attendue par le delta courant | fichier `VERSION` | changement de tranche/version | alpha/beta/RC/stable | faible | opérateur |
|
||||
| `PGR-LAYOUT-001` | `AUDIT` | comparer les fichiers ajoutés/remplacés/supprimés au scope déclaré du delta | scope du delta | changement de structure | alpha/beta/RC/stable | faible | opérateur/revue |
|
||||
| `PGR-DOC-001` | `AUDIT` | vérifier headers `file/version`, chemins, liens et responsabilités des documents touchés | fichiers documentaires | modification documentaire | alpha/beta/RC/stable | faible | opérateur/revue |
|
||||
| `PGR-NAV-001` | `AUDIT` | vérifier que les points d'entrée et liens canoniques ciblent des fichiers existants | index et docs racine | navigation ou réconciliation | beta/RC/stable | faible | opérateur/revue |
|
||||
| `PGR-DOC-001` | `AUDIT` | vérifier chemins, rôles et responsabilités des documents touchés | fichiers documentaires | modification documentaire | alpha/beta/RC/stable | faible | opérateur/revue |
|
||||
| `PGR-MD-HEADER-001` | `AUDIT` | `python3 -B scripts/audit_markdown_headers.py <paths...>` | Python 3 | Markdown gouverné modifié | alpha/beta/RC/stable | faible | opérateur/CI |
|
||||
| `PGR-MD-TABLE-001` | `AUDIT` | `python3 -B scripts/audit_markdown_tables.py <paths...>` | Python 3 | table Markdown ajoutée/modifiée | alpha/beta/RC/stable | faible | opérateur/CI |
|
||||
| `PGR-NAV-001` | `AUDIT` | `python3 -B scripts/audit_markdown_links.py <paths...>` | Python 3 | navigation ou réconciliation | alpha/beta/RC/stable | faible | opérateur/CI |
|
||||
| `PGR-SCOPE-001` | `AUDIT` | vérifier que les documents vivants pointent vers les propriétaires normatifs actuels | documents vivants | réconciliation de phase | beta/RC/stable | faible | revue |
|
||||
| `PGR-STATUS-001` | `CHECK` | `git status --short` | Git | avant fermeture d'une tranche | alpha/beta/RC/stable | faible | opérateur |
|
||||
|
||||
Un contrôle manuel peut rester dans la matrice lorsqu'aucun audit automatisé fiable n'existe encore. PGR SHOULD automatiser uniquement les propriétés stables et objectivement contrôlables.
|
||||
|
||||
`PGR-MD-TABLE-001` reste volontairement monotâche : il contrôle uniquement la structure et l'alignement source des tableaux Markdown. Il couvre les tableaux Markdown ordinaires ainsi que les exemples placés dans des fences explicitement `markdown` ou `md`. Les autres blocs fenced restent ignorés afin de ne pas interpréter comme Markdown des sorties terminal, extraits de code ou tableaux ASCII d'un autre langage.
|
||||
|
||||
`PGR-MD-HEADER-001` contrôle seulement les deux premières lignes des fichiers Markdown sélectionnés : chemin relatif depuis la racine et révision interne positive. La revue `PGR-DOC-001` reste responsable du rôle documentaire et de la pertinence réelle d'un incrément de révision.
|
||||
|
||||
`PGR-NAV-001` est automatisé séparément par `audit_markdown_links.py`. Il vérifie uniquement l'existence des cibles de liens Markdown locaux inline, sans contrôler les anchors, les headers, les responsabilités documentaires ou la forme des tableaux.
|
||||
|
||||
PGR préfère plusieurs audits simples avec une responsabilité identifiable à un script unique qui agrège des règles indépendantes.
|
||||
|
||||
## Contrôles Rust réutilisables, hors gate du dépôt PGR
|
||||
|
||||
[`002-RUST_STYLE_AUDITS.md`](002-RUST_STYLE_AUDITS.md) décrit les audits monotâches de structure Rust : lignes vides, blocs `const`, séparation des items, ordre des modules, disposition des imports de traits et blocs de réexports. Ils acceptent des chemins Rust sélectionnés et partagent un petit support lexical ; leur validation ciblée dans PGR est `python3 -B -m unittest discover -s tests -p test_rust_audits.py -v`.
|
||||
|
||||
Pour une nouvelle baseline contrôlée, les propriétés sans ordre métier peuvent faire partie du profil strict. L'audit `const_blocks` reste explicitement sélectionné, car une table de protocole, un schéma ou une séquence normative ne doit jamais être réordonné pour satisfaire un tri mécanique. Leur disponibilité ne transforme pas PGR en workspace Rust ; le projet propriétaire exécute ces audits après `cargo fmt`, et Rustfmt/Clippy/rustc conservent les contrôles qu'ils possèdent.
|
||||
|
||||
[`003-RUST_EXPORT_COMPLETENESS.md`](003-RUST_EXPORT_COMPLETENESS.md) décrit séparément `audit_rust_export_completeness.py`, audit facultatif de façade crate-root. Sa validation ciblée dans PGR est `python3 -B -m unittest discover -s tests -p test_rust_export_completeness.py -v`. L'audit est destiné aux projets Rust qui choisissent explicitement ce contrat ; PGR n'exécute pas ce script sur son propre dépôt comme gate, car il ne constitue pas lui-même un workspace Rust.
|
||||
|
||||
## Politique Eclipse actuelle
|
||||
|
||||
Les métadonnées Eclipse spécifiques à une machine restent ignorées, notamment `.project`, `.classpath` et les préférences non partagées.
|
||||
|
||||
79
docs/validation/002-RUST_STYLE_AUDITS.md
Normal file
79
docs/validation/002-RUST_STYLE_AUDITS.md
Normal file
@@ -0,0 +1,79 @@
|
||||
<!-- file: docs/validation/002-RUST_STYLE_AUDITS.md -->
|
||||
<!-- version: 2 -->
|
||||
|
||||
# Audits monotâches de structure Rust
|
||||
|
||||
## Responsabilité et provenance
|
||||
|
||||
Les sources KSP `0.3.16` et Games `0.3.5` possèdent chacune un `audit_rust_general_rules.py` composite. `0.0.3` avait déjà extrait deux propriétés ciblées ; `0.0.5-alpha.8` termine la réconciliation des propriétés de forme communes sans importer cet orchestrateur monolithique ni ses règles locales.
|
||||
|
||||
Le contrat normatif est dans [`510-RUST_CARGO.md`](../rules/510-RUST_CARGO.md). Les scripts disponibles sont read-only et chacun possède une seule famille de preuve :
|
||||
|
||||
```text
|
||||
audit_rust_blank_lines.py
|
||||
lignes vides consécutives et lignes vides dans fn/méthode/struct/enum
|
||||
|
||||
audit_rust_const_blocks.py
|
||||
ordre visibilité/nom et espacement des blocs const explicitement sélectionnés
|
||||
|
||||
audit_rust_item_spacing.py
|
||||
exactement une ligne vide entre items Rust distincts voisins d'un même scope
|
||||
|
||||
audit_rust_module_order.py
|
||||
modules de production avant tests, ordre alphabétique de chaque groupe
|
||||
|
||||
audit_rust_trait_import_blocks.py
|
||||
bloc de use non exportés au module, avant les déclarations et sans ligne vide interne
|
||||
|
||||
audit_rust_reexport_blocks.py
|
||||
bloc pub use avant pub(crate) use, espacement exact entre/à l'intérieur des blocs
|
||||
```
|
||||
|
||||
`scripts/_rust_audit_common.py` partage seulement la sélection de fichiers et le masquage lexical des commentaires/littéraux. Il ne définit aucune politique. `audit_rust_export_completeness.py` reste séparé dans [`003-RUST_EXPORT_COMPLETENESS.md`](003-RUST_EXPORT_COMPLETENESS.md), car il possède la façade et les chemins canoniques plutôt que le formatage.
|
||||
|
||||
## Adoption et commandes
|
||||
|
||||
Pour une nouvelle baseline Rust contrôlée qui sélectionne le profil strict, les audits sans interprétation métier peuvent être exécutés sur les sources concernées après Rustfmt :
|
||||
|
||||
```bash
|
||||
cargo fmt --all -- --check
|
||||
python3 -B scripts/audit_rust_blank_lines.py crates
|
||||
python3 -B scripts/audit_rust_item_spacing.py crates
|
||||
python3 -B scripts/audit_rust_module_order.py crates
|
||||
python3 -B scripts/audit_rust_trait_import_blocks.py crates
|
||||
python3 -B scripts/audit_rust_reexport_blocks.py crates
|
||||
```
|
||||
|
||||
L'audit des constantes reste différent : sélectionner seulement les fichiers dont les blocs `const` doivent réellement suivre l'ordre mécanique PGR. Exemple :
|
||||
|
||||
```bash
|
||||
python3 -B scripts/audit_rust_const_blocks.py crates/example/src/constants.rs
|
||||
```
|
||||
|
||||
Une invocation sans chemin est une erreur, de même qu'un chemin absent ou aucun fichier Rust sélectionné. Un répertoire sélectionne récursivement les fichiers `.rs` hors répertoires générés habituels. Les audits ne modifient ni les sources ni l'arborescence de build. Le code de sortie est `0` si propre, `1` pour violation et `2` pour sélection/lecture impossible.
|
||||
|
||||
`audit_rust_trait_import_blocks.py` ne prouve pas qu'un `use` importe réellement un trait ; cette sémantique appartient au profil et à la revue/compilation. `audit_rust_reexport_blocks.py` ne trie pas les symboles exportés. Dans les deux cas, Rustfmt reste l'owner de l'ordre intra-bloc lorsque les lignes sont contiguës.
|
||||
|
||||
`audit_rust_item_spacing.py` ne possède pas l'espacement des blocs compacts homogènes `const`/`static`/`type` : il les délègue afin de ne pas transformer une séparation sémantique entre deux grandes tables en faux positif. L'audit spécialisé `const_blocks` reste opt-in sur des fichiers explicitement choisis.
|
||||
|
||||
## Mesure croisée KSP / Games
|
||||
|
||||
La prévalidation `alpha.8` a exécuté les quatre nouveaux audits sur l'ensemble des fichiers Rust sous `crates/` des archives fournies : `603` fichiers KSP `0.3.16` et `87` fichiers Games `0.3.5`. Les quatre contrôles sont propres sur les deux corpus :
|
||||
|
||||
```text
|
||||
KSP 0.3.16 Games 0.3.5
|
||||
item spacing clean / 603 clean / 87
|
||||
module order clean / 603 clean / 87
|
||||
trait import blocks clean / 603 clean / 87
|
||||
re-export blocks clean / 603 clean / 87
|
||||
```
|
||||
|
||||
L'audit des lignes vides est également propre sur les `603` et `87` fichiers. En revanche, l'audit `const_blocks` appliqué aveuglément à tout le corpus produit `18` signaux KSP et `0` Games. Certains signaux KSP concernent des tables/schémas dont l'ordre est intentionnel, ce qui confirme qu'il ne doit pas devenir une gate globale par défaut. Ces mesures sont des preuves de réconciliation PGR, pas une validation opérateur de KSP/Games.
|
||||
|
||||
## Limites et owners
|
||||
|
||||
Les analyses masquent les commentaires et littéraux courants, y compris chaînes brutes et commentaires imbriqués, mais ne constituent pas un parseur Rust. Elles n'essaient pas de comprendre les expansions de macros, l'ordre métier, les protocoles ou les dépendances sémantiques entre items.
|
||||
|
||||
PGR ne crée pas d'audit automatique pour imposer un ordre global des catégories `enum`, `struct`, `impl`, fonctions ou helpers privés. Le rapprochement `struct` puis `impl`, et la préférence des éléments visibles avant les helpers privés, restent des conventions de lisibilité soumises à la sémantique locale.
|
||||
|
||||
Rustfmt possède le formatage et les tris qu'il sait réellement réécrire ; rustc et Clippy conservent leurs diagnostics. Les tests PGR de ces scripts vivent dans `tests/test_rust_audits.py`.
|
||||
145
docs/validation/003-RUST_EXPORT_COMPLETENESS.md
Normal file
145
docs/validation/003-RUST_EXPORT_COMPLETENESS.md
Normal file
@@ -0,0 +1,145 @@
|
||||
<!-- file: docs/validation/003-RUST_EXPORT_COMPLETENESS.md -->
|
||||
<!-- version: 2 -->
|
||||
|
||||
# Audit facultatif de façade Rust et canonicalisation intra-crate
|
||||
|
||||
## Responsabilité
|
||||
|
||||
`scripts/audit_rust_export_completeness.py` contrôle un contrat Rust optionnel plus strict que les garanties du compilateur et de Clippy : une crate qui adopte cette convention possède une façade crate-root explicite pour ses items partagés, et toute consommation intra-crate d'un item possédant cette identité canonique passe par `crate::Item`.
|
||||
|
||||
Le propriétaire normatif reste [`../rules/510-RUST_CARGO.md`](../rules/510-RUST_CARGO.md). Le script ne définit pas une architecture à lui seul ; il matérialise uniquement le contrat strict lorsqu'un projet choisit de l'adopter.
|
||||
|
||||
L'audit émet deux familles de diagnostics :
|
||||
|
||||
```text
|
||||
RUST-API-201
|
||||
item `pub` d'un module fichier sans réexport explicite au crate-root,
|
||||
ou item `pub(crate)` clairement consommé hors de son module sans réexport crate-root
|
||||
|
||||
RUST-IMPORT-201
|
||||
référence intra-crate non canonique à un item possédant une identité crate-root ;
|
||||
la forme attendue est `crate::Item`
|
||||
```
|
||||
|
||||
`RUST-IMPORT-201` ne se limite donc pas à `crate::module::Item`. Il couvre notamment :
|
||||
|
||||
```text
|
||||
Item
|
||||
self::Item
|
||||
super::Item
|
||||
module::Item
|
||||
crate::module::Item
|
||||
```
|
||||
|
||||
lorsque ces formes désignent un item partagé déjà exposé comme `crate::Item`.
|
||||
|
||||
La règle s'applique également **dans le module qui déclare l'item**. Par exemple :
|
||||
|
||||
```rust
|
||||
pub struct Runtime;
|
||||
|
||||
impl Runtime {
|
||||
pub fn new() -> Runtime {
|
||||
return Runtime;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
n'est pas canonique après réexport de `Runtime`. Le contrat strict attend :
|
||||
|
||||
```rust
|
||||
pub struct Runtime;
|
||||
|
||||
impl crate::Runtime {
|
||||
pub fn new() -> crate::Runtime {
|
||||
return crate::Runtime;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Le même principe vaut pour une fonction partagée appelée depuis son module propriétaire : `crate::build()` est canonique, `build()` ne l'est pas.
|
||||
|
||||
Les lignes de déclaration de l'item et les lignes de réexport qui construisent la façade sont naturellement exemptées. Un item strictement privé n'appartient pas à ce contrat ; dans un test unitaire attaché à son module parent, `super::PrivateItem` reste une forme locale légitime.
|
||||
|
||||
## Pourquoi Cargo/Clippy ne suffisent pas
|
||||
|
||||
Le compilateur vérifie la résolution et la visibilité des noms ; il ne possède pas la convention « tout accès partagé passe par `crate::Item` ». Clippy peut signaler certains imports ou réexports inutilisés, mais une seule consommation correcte de `crate::Item` peut suffire à rendre le réexport utilisé tandis que d'autres références continuent d'employer un nom nu ou un chemin interne.
|
||||
|
||||
L'audit fournit donc une preuve distincte : **uniformité de la façade et des chemins intra-crate**, pas simple compilabilité.
|
||||
|
||||
## Cibles Cargo et graphes de modules
|
||||
|
||||
La `version: 2` ne confond plus automatiquement tous les fichiers d'un package Cargo dans une seule crate. Un package peut contenir simultanément une bibliothèque `src/lib.rs` et un binaire `src/main.rs` ; ces deux cibles sont compilées comme des crates distinctes et `crate::Item` n'y désigne pas la même racine.
|
||||
|
||||
L'audit découvre les packages récursivement puis traite séparément les cibles standard/explicites `lib` et `bin`. Pour chaque cible, il suit les modules fichiers déclarés par `mod name;` et les modules `#[path = "..."]`, ce qui couvre notamment les `unit_tests/` attachés utilisés dans le corpus KSP/Games sans englober les tests d'intégration Cargo sous `tests/`, qui sont des crates externes.
|
||||
|
||||
Cette distinction évite de considérer à tort `owner_crate::Item` utilisé dans un binaire comme une violation de la bibliothèque du même package.
|
||||
|
||||
## Provenance et correction du corpus
|
||||
|
||||
KSP `0.3.16` et Games `0.3.5` contiennent un `audit_rust_export_completeness.py` historiquement identique à l'exception de sa révision. Cette convergence justifie l'extraction du concept, mais pas une copie littérale.
|
||||
|
||||
Deux limites historiques ont été identifiées :
|
||||
|
||||
1. la découverte `crates/*/Cargo.toml` couvrait les `22` packages KSP directement sous `crates/`, mais aucune des `23` crates Games imbriquées sous `crates/apps/`, `crates/common/`, `crates/engines/`, etc. ;
|
||||
2. la canonicalisation détectait surtout `crate::module::Item` et quelques cas particuliers de tests, mais pas les références ordinaires par nom nu dans les modules de production, y compris le module propriétaire.
|
||||
|
||||
La première version PGR de `alpha.5` corrigeait seulement la découverte récursive et le chemin interne long. La revue opérateur après sa gate a explicitement révélé la seconde lacune ; `alpha.5` est donc conservé `FAIL` et `alpha.5.fix.1` étend `RUST-IMPORT-201` au contrat réellement attendu.
|
||||
|
||||
## Mesure de réconciliation après le fix
|
||||
|
||||
Avec la `version: 2`, en mode `--report-only --summary-only`, les baselines autoritaires de la réconciliation donnent :
|
||||
|
||||
```text
|
||||
KSP 0.3.16
|
||||
22 package(s)
|
||||
1525 candidate(s)
|
||||
RUST-IMPORT-201: 1525
|
||||
|
||||
Games 0.3.5
|
||||
23 package(s)
|
||||
181 candidate(s)
|
||||
RUST-API-201: 2
|
||||
RUST-IMPORT-201: 179
|
||||
```
|
||||
|
||||
Ces nombres représentent des **lignes candidates**, pas des déclarations distinctes. Ils sont beaucoup plus élevés que la première mesure `0 / 2` parce que le contrat corrige précisément le blind spot signalé : les références nues déjà répandues dans les modules propriétaires et consumers deviennent enfin visibles.
|
||||
|
||||
KSP et Games n'étant pas encore gouvernés par cette version de PGR, ces résultats ne sont pas qualifiés de défauts rétroactifs et ne déclenchent aucune migration dans `0.0.5`. Ils constituent un inventaire d'adoption future. Pour un projet existant, l'usage initial en `--report-only` est donc particulièrement important.
|
||||
|
||||
## Adoption
|
||||
|
||||
Pour adopter cette convention dans un projet Rust, copier :
|
||||
|
||||
```text
|
||||
scripts/_rust_audit_common.py
|
||||
scripts/audit_rust_export_completeness.py
|
||||
```
|
||||
|
||||
puis adapter les headers de fichiers au dépôt destinataire.
|
||||
|
||||
Commande canonique :
|
||||
|
||||
```bash
|
||||
python3 -B scripts/audit_rust_export_completeness.py --root .
|
||||
```
|
||||
|
||||
Le code de sortie est `0` lorsque le corpus est propre, `1` lorsqu'au moins un candidat est trouvé et `2` lorsque la racine est invalide, illisible ou ne contient aucun package Rust détectable. `--report-only` permet un inventaire sans bloquer la gate ; `--summary-only` réduit la sortie aux comptes.
|
||||
|
||||
Une adoption progressive d'un projet existant devrait commencer par :
|
||||
|
||||
```bash
|
||||
python3 -B scripts/audit_rust_export_completeness.py --root . --report-only --summary-only
|
||||
```
|
||||
|
||||
puis inventorier/corriger les familles d'écarts avant de rendre l'audit bloquant. Une nouvelle crate créée sous le contrat peut au contraire l'activer immédiatement.
|
||||
|
||||
## Limites
|
||||
|
||||
L'analyse reste lexicale et ne remplace pas un parseur Rust complet. Elle vise les déclarations module-level `pub`/`pub(crate)`, les réexports explicites et les références dans le graphe de modules d'une cible. Les macros générant des items, modules inline complexes, `include!`, formes de `#[path]` atypiques et réexports élaborés peuvent nécessiter une revue humaine.
|
||||
|
||||
Pour réduire les faux positifs, une fonction partagée est reconnue comme référence lorsqu'elle apparaît sous une forme d'appel directe ; l'usage d'une fonction comme valeur de premier ordre peut donc échapper à cette version. Les chemins explicitement qualifiés par une crate externe et les appels de méthodes `.name()` ne sont pas assimilés à un item local de même nom.
|
||||
|
||||
Un item `pub(crate)` qui n'est pas clairement consommé hors de son module n'est pas forcé au crate-root par `RUST-API-201`; sa visibilité peut nécessiter une revue séparée. Dès qu'un réexport crate-root existe, ses références détectées sont toutefois soumises à `RUST-IMPORT-201`, y compris dans son module de déclaration.
|
||||
|
||||
L'audit ne remplace ni `cargo check`, ni Clippy, ni rustdoc. Il complète ces outils avec une convention architecturale qu'ils ne possèdent pas.
|
||||
104
history/0.0.2/alpha.1.fix.1.md
Normal file
104
history/0.0.2/alpha.1.fix.1.md
Normal file
@@ -0,0 +1,104 @@
|
||||
<!-- file: history/0.0.2/alpha.1.fix.1.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# History 0.0.2-alpha.1.fix.1 — correction du cadrage, sizing et audit Markdown
|
||||
|
||||
## Statut
|
||||
|
||||
PASS
|
||||
|
||||
Le correctif de cadrage `0.0.2-alpha.1.fix.1` a été validé par l'opérateur. Le sizing réduit, la reconnaissance de la preuve post-tag et le premier audit Markdown monotâche sont cohérents avec l'objectif de `alpha.1`.
|
||||
|
||||
## Baseline
|
||||
|
||||
La tranche précédente `0.0.2-alpha.1` a été enregistrée `FAIL`, puis committée et poussée sous le commit observé :
|
||||
|
||||
```text
|
||||
d3f1e13
|
||||
```
|
||||
|
||||
Version validée après application du fix :
|
||||
|
||||
```text
|
||||
0.0.2-alpha.1.fix.1
|
||||
```
|
||||
|
||||
## Validation opérateur observée
|
||||
|
||||
L'opérateur a confirmé la présence et le contenu attendu des artefacts du fix :
|
||||
|
||||
```bash
|
||||
test "$(cat VERSION)" = "0.0.2-alpha.1.fix.1"
|
||||
|
||||
test -f scripts/audit_markdown_tables.py
|
||||
test -f deltas/0.0.2/alpha.1.fix.1.md
|
||||
|
||||
grep -F '### Preuve post-tag `publish.001`' docs/plans/002-V0_0_2_RULE_PROFILES_PLAN.md
|
||||
grep -F '### alpha.5 — Android' docs/plans/002-V0_0_2_RULE_PROFILES_PLAN.md
|
||||
grep -F 'Rust + Android / JNI' docs/plans/002-V0_0_2_RULE_PROFILES_PLAN.md
|
||||
grep -F '`PGR-MD-TABLE-001`' docs/validation/001-VALIDATION_MATRIX.md
|
||||
```
|
||||
|
||||
L'audit Markdown PGR a ensuite été exécuté sur le corpus documentaire courant :
|
||||
|
||||
```bash
|
||||
python3 -B scripts/audit_markdown_tables.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
```
|
||||
|
||||
Résultat observé :
|
||||
|
||||
```text
|
||||
Markdown table audit: clean (2 table(s), 45 file(s))
|
||||
```
|
||||
|
||||
Les contrôles Git ont également réussi :
|
||||
|
||||
```bash
|
||||
git diff --check
|
||||
|
||||
git add VERSION \
|
||||
docs/plans/002-V0_0_2_RULE_PROFILES_PLAN.md \
|
||||
docs/validation/001-VALIDATION_MATRIX.md \
|
||||
scripts/audit_markdown_tables.py \
|
||||
deltas/0.0.2/alpha.1.fix.1.md
|
||||
|
||||
git diff --cached --check
|
||||
git status --short
|
||||
```
|
||||
|
||||
`git diff --check` et `git diff --cached --check` n'ont produit aucun diagnostic.
|
||||
|
||||
La sortie finale observée avant ajout du présent history était exactement :
|
||||
|
||||
```text
|
||||
M VERSION
|
||||
A deltas/0.0.2/alpha.1.fix.1.md
|
||||
M docs/plans/002-V0_0_2_RULE_PROFILES_PLAN.md
|
||||
M docs/validation/001-VALIDATION_MATRIX.md
|
||||
A scripts/audit_markdown_tables.py
|
||||
```
|
||||
|
||||
## Revue qualitative
|
||||
|
||||
Les décisions qualitatives ayant motivé le fix avaient déjà été explicitées par l'opérateur avant son application :
|
||||
|
||||
- conserver `publish.001` comme preuve post-tag externe plutôt que l'injecter dans le tag stable ;
|
||||
- réduire le nombre de profils matérialisés afin de ne pas surcharger la session ;
|
||||
- différer les profils C/C++/CMake, PHP/Composer, Python et les compositions plus larges au lieu de s'éparpiller ;
|
||||
- commencer à introduire des audits PGR uniquement lorsque l'occasion révèle une propriété stable et objectivement contrôlable ;
|
||||
- préférer des audits simples et monotâches aux scripts combinés historiques lorsqu'une responsabilité unique suffit.
|
||||
|
||||
Le résultat mécanique du fix est conforme à ces décisions.
|
||||
|
||||
## Résultat
|
||||
|
||||
`0.0.2-alpha.1.fix.1` est validée `PASS`.
|
||||
|
||||
Le cadrage de `0.0.2` est désormais autorisé à progresser vers :
|
||||
|
||||
```text
|
||||
0.0.2-alpha.2
|
||||
```
|
||||
|
||||
Cette tranche suivante est limitée au modèle de profils PGR : ownership, composition général → spécifique, résolution des overrides, non-duplication et activation des seules familles documentaires nécessaires aux profils retenus pour `0.0.2`.
|
||||
105
history/0.0.2/alpha.1.md
Normal file
105
history/0.0.2/alpha.1.md
Normal file
@@ -0,0 +1,105 @@
|
||||
<!-- file: history/0.0.2/alpha.1.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# History 0.0.2-alpha.1 — baseline audit and profile sizing
|
||||
|
||||
## Statut
|
||||
|
||||
FAIL
|
||||
|
||||
Les commandes mécaniques prévues par le delta `alpha.1` ont toutes réussi, mais la revue opérateur a identifié des défauts dans le cadrage lui-même. Comme `alpha.1` est précisément la gate d'audit, de sizing et de planification de `0.0.2`, la tranche ne doit pas être déclarée PASS tant que ces défauts ne sont pas corrigés.
|
||||
|
||||
## Baseline
|
||||
|
||||
Archive source issue du tag stable Gitea :
|
||||
|
||||
```text
|
||||
v0.0.1
|
||||
```
|
||||
|
||||
Version observée après application du delta :
|
||||
|
||||
```text
|
||||
0.0.2-alpha.1
|
||||
```
|
||||
|
||||
L'absence de `.git` dans l'archive de baseline reste normale et n'a pas été traitée comme une anomalie.
|
||||
|
||||
## Validation opérateur observée
|
||||
|
||||
Les commandes communiquées par l'opérateur ont réussi :
|
||||
|
||||
```bash
|
||||
test "$(cat VERSION)" = "0.0.2-alpha.1"
|
||||
|
||||
test -f docs/plans/002-V0_0_2_RULE_PROFILES_PLAN.md
|
||||
test -f deltas/0.0.2/alpha.1.md
|
||||
|
||||
grep -F 'Plan actif créé pendant `0.0.2-alpha.1`' docs/plans/002-V0_0_2_RULE_PROFILES_PLAN.md
|
||||
grep -F 'Aucun défaut bloquant de gouvernance' docs/plans/002-V0_0_2_RULE_PROFILES_PLAN.md
|
||||
grep -F '### alpha.2 — Rule profile model' docs/plans/002-V0_0_2_RULE_PROFILES_PLAN.md
|
||||
grep -F '### alpha.8 — Tauri desktop/mobile' docs/plans/002-V0_0_2_RULE_PROFILES_PLAN.md
|
||||
|
||||
grep -F -- '- `( ) 0.0.2`' ROADMAP.md
|
||||
grep -F 'v0.0.1' prompts/002-V0_0_2_START_PROMPT.md
|
||||
|
||||
git diff --check
|
||||
|
||||
git add VERSION docs/plans/002-V0_0_2_RULE_PROFILES_PLAN.md deltas/0.0.2/alpha.1.md
|
||||
|
||||
git diff --cached --check
|
||||
|
||||
git status --short
|
||||
```
|
||||
|
||||
`git diff --check` et `git diff --cached --check` n'ont produit aucun diagnostic.
|
||||
|
||||
La sortie finale observée avant ajout du présent history est exactement :
|
||||
|
||||
```text
|
||||
M VERSION
|
||||
A deltas/0.0.2/alpha.1.md
|
||||
A docs/plans/002-V0_0_2_RULE_PROFILES_PLAN.md
|
||||
```
|
||||
|
||||
## Défauts identifiés par revue
|
||||
|
||||
### Tableau Markdown non aligné
|
||||
|
||||
Le tableau `Inventaire des profils candidats` est syntaxiquement lisible par Markdown, mais ses colonnes ne sont pas alignées dans le source. Le défaut est visible immédiatement lors d'une revue et n'a pas été détecté par la gate `alpha.1`.
|
||||
|
||||
Un audit réutilisé en diagnostic depuis les projets sources confirme le défaut sur les quatre colonnes du tableau.
|
||||
|
||||
Ce cas fournit une propriété stable et objectivement automatisable : l'alignement source des tableaux Markdown. Il justifie l'introduction d'un premier audit PGR monotâche et read-only au lieu d'ajouter un contrôle manuel supplémentaire.
|
||||
|
||||
### Sizing trop large
|
||||
|
||||
Le plan initial conservait, après `alpha.1`, sept tranches technologiques `alpha.2` à `alpha.8` avant réconciliation et RC.
|
||||
|
||||
Ce découpage est trop ambitieux pour l'objectif de dimensionnement « une version complète par session », surtout avant d'avoir mesuré le coût réel du premier profil. L'opérateur demande explicitement de privilégier l'exécution correcte du scope retenu plutôt que de matérialiser trop de profils dans `0.0.2`.
|
||||
|
||||
Le fix doit donc réduire le scope initial de la release à un ensemble minimal mais représentatif : modèle de profil, Rust/Cargo, Java/Maven/Gradle et Android. Les compositions Rust+Android/JNI, Web/WASM et Tauri restent candidates mais sont différées.
|
||||
|
||||
### Preuve post-tag `publish.001` déjà disponible
|
||||
|
||||
La revue initiale avait correctement conclu que `publish.001` ne pouvait pas faire partie du tag `v0.0.1`, mais elle n'avait pas retrouvé le rapport post-tag déjà conservé hors du tag.
|
||||
|
||||
Le rapport `pgr-0.0.1-publish.001-report.md` existe dans la bibliothèque de travail et indique `Status: PASS` pour l'archive `pgr-v0.0.1.zip`, avec le SHA-256 attendu.
|
||||
|
||||
Cette preuve ne doit pas être injectée rétroactivement dans le tag stable. Elle doit simplement être reconnue comme preuve post-publication externe à la baseline source.
|
||||
|
||||
La maturité future de PGR devra également permettre aux handoffs/prompts de reprise d'indiquer explicitement si un tel rapport post-publication doit être fourni à la session suivante. Cette amélioration de workflow ne doit toutefois pas élargir `0.0.2`.
|
||||
|
||||
## Conséquence
|
||||
|
||||
`0.0.2-alpha.1` est enregistré en `FAIL`.
|
||||
|
||||
La tranche suivante est `0.0.2-alpha.1.fix.1`, strictement limitée au cadrage de `alpha.1` :
|
||||
|
||||
- corriger le tableau Markdown du plan ;
|
||||
- reconnaître correctement le rapport post-tag `publish.001` déjà disponible sans modifier `v0.0.1` ;
|
||||
- réduire le nombre de profils matérialisés dans `0.0.2` ;
|
||||
- introduire un premier audit Markdown monotâche, read-only et sans dépendance externe, parce qu'un défaut réel vient d'en démontrer la nécessité ;
|
||||
- enregistrer ce nouvel audit dans la matrice de validation.
|
||||
|
||||
Aucune règle technologique prévue pour `alpha.2+` ne doit être absorbée dans le fix.
|
||||
123
history/0.0.2/alpha.2.md
Normal file
123
history/0.0.2/alpha.2.md
Normal file
@@ -0,0 +1,123 @@
|
||||
<!-- file: history/0.0.2/alpha.2.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# History 0.0.2-alpha.2 — modèle de profils PGR
|
||||
|
||||
## Statut
|
||||
|
||||
PASS
|
||||
|
||||
La tranche `0.0.2-alpha.2` a été validée par l'opérateur. Le modèle d'ownership, d'applicabilité et de composition des profils est en place avant l'introduction du premier profil technologique réel.
|
||||
|
||||
## Baseline
|
||||
|
||||
La tranche précédente `0.0.2-alpha.1.fix.1` a été enregistrée `PASS`, puis committée et poussée sous le commit observé :
|
||||
|
||||
```text
|
||||
1a5dd09
|
||||
```
|
||||
|
||||
Version validée après application de `alpha.2` :
|
||||
|
||||
```text
|
||||
0.0.2-alpha.2
|
||||
```
|
||||
|
||||
## Validation opérateur observée
|
||||
|
||||
L'opérateur a confirmé la version et la présence des nouveaux propriétaires documentaires :
|
||||
|
||||
```bash
|
||||
test "$(cat VERSION)" = "0.0.2-alpha.2"
|
||||
|
||||
test -f docs/architecture/003-RULE_PROFILE_MODEL.md
|
||||
test -f docs/rules/500-LANGUAGES.md
|
||||
test -f docs/rules/600-PLATFORMS.md
|
||||
test -f deltas/0.0.2/alpha.2.md
|
||||
```
|
||||
|
||||
Les contrats principaux du modèle ont été vérifiés par recherche littérale :
|
||||
|
||||
```text
|
||||
Toute règle durable doit posséder un seul propriétaire normatif canonique.
|
||||
L'ordre des fichiers dans un répertoire ne crée jamais une priorité normative.
|
||||
PGR ne crée pas automatiquement un profil composite pour chaque combinaison possible.
|
||||
```
|
||||
|
||||
Les contrats des familles `500` et `600` ont également été retrouvés, notamment :
|
||||
|
||||
```text
|
||||
Les profils spécifiques utilisent la plage `510` à `599`.
|
||||
Une spécialisation de build tool ne devient pas une règle du langage entier.
|
||||
La modernité de la toolchain de build et la version minimale du runtime ou de la target sont deux décisions distinctes.
|
||||
Les profils spécifiques utilisent la plage `610` à `699`.
|
||||
```
|
||||
|
||||
Les liens depuis `RULES.md`, l'index `docs/rules/000-README.md` et le plan `0.0.2` ont été vérifiés.
|
||||
|
||||
L'audit Markdown PGR a ensuite été exécuté :
|
||||
|
||||
```bash
|
||||
python3 -B scripts/audit_markdown_tables.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
```
|
||||
|
||||
Résultat observé :
|
||||
|
||||
```text
|
||||
Markdown table audit: clean (2 table(s), 50 file(s))
|
||||
```
|
||||
|
||||
Les contrôles Git ont réussi :
|
||||
|
||||
```bash
|
||||
git diff --check
|
||||
|
||||
git add VERSION RULES.md \
|
||||
docs/architecture/003-RULE_PROFILE_MODEL.md \
|
||||
docs/plans/002-V0_0_2_RULE_PROFILES_PLAN.md \
|
||||
docs/rules/000-README.md \
|
||||
docs/rules/500-LANGUAGES.md \
|
||||
docs/rules/600-PLATFORMS.md \
|
||||
deltas/0.0.2/alpha.2.md
|
||||
|
||||
git diff --cached --check
|
||||
git status --short
|
||||
```
|
||||
|
||||
`git diff --check` et `git diff --cached --check` n'ont produit aucun diagnostic.
|
||||
|
||||
La sortie finale observée avant ajout du présent history était exactement :
|
||||
|
||||
```text
|
||||
M RULES.md
|
||||
M VERSION
|
||||
A deltas/0.0.2/alpha.2.md
|
||||
A docs/architecture/003-RULE_PROFILE_MODEL.md
|
||||
M docs/plans/002-V0_0_2_RULE_PROFILES_PLAN.md
|
||||
M docs/rules/000-README.md
|
||||
A docs/rules/500-LANGUAGES.md
|
||||
A docs/rules/600-PLATFORMS.md
|
||||
```
|
||||
|
||||
## Revue qualitative
|
||||
|
||||
L'état livré respecte les frontières prévues par `alpha.2` :
|
||||
|
||||
- l'ownership d'une règle dépend de son scope et non du numéro ou de l'ordre lexical des fichiers ;
|
||||
- une spécialisation de build tool peut rester plus spécifique que son langage sans contaminer ce dernier ;
|
||||
- une contrainte plateforme peut surcharger localement un langage/build tool sans devenir une règle générale ;
|
||||
- les familles `700 — frameworks` et `800 — architecture` restent réservées et ne sont pas matérialisées sans contenu réel ;
|
||||
- aucune règle Rust, Cargo, Java, Maven, Gradle ou Android détaillée n'a été absorbée prématurément dans le modèle transversal.
|
||||
|
||||
## Résultat
|
||||
|
||||
`0.0.2-alpha.2` est validée `PASS`.
|
||||
|
||||
La tranche suivante autorisée est :
|
||||
|
||||
```text
|
||||
0.0.2-alpha.3
|
||||
```
|
||||
|
||||
Elle est consacrée au premier profil réel `Rust / Cargo` et sert de point de mesure du coût d'un profil complet avant de confirmer ou replanifier les tranches `alpha.4+`.
|
||||
122
history/0.0.2/alpha.3.md
Normal file
122
history/0.0.2/alpha.3.md
Normal file
@@ -0,0 +1,122 @@
|
||||
<!-- file: history/0.0.2/alpha.3.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# History 0.0.2-alpha.3 — premier profil Rust / Cargo
|
||||
|
||||
## Statut
|
||||
|
||||
PASS
|
||||
|
||||
La tranche `0.0.2-alpha.3` a été validée par l'opérateur. Le premier profil technologique réel de PGR est en place et le point de mesure prévu par le plan ne révèle pas de dérive nécessitant un REPLAN avant `alpha.4`.
|
||||
|
||||
## Baseline
|
||||
|
||||
La tranche précédente `0.0.2-alpha.2` a été enregistrée `PASS`, puis committée et poussée sous le commit observé :
|
||||
|
||||
```text
|
||||
5f9b84c
|
||||
```
|
||||
|
||||
Version validée après application de `alpha.3` :
|
||||
|
||||
```text
|
||||
0.0.2-alpha.3
|
||||
```
|
||||
|
||||
## Validation opérateur observée
|
||||
|
||||
L'opérateur a confirmé la version et la présence du nouveau profil :
|
||||
|
||||
```bash
|
||||
test "$(cat VERSION)" = "0.0.2-alpha.3"
|
||||
test -f docs/rules/510-RUST_CARGO.md
|
||||
test -f deltas/0.0.2/alpha.3.md
|
||||
```
|
||||
|
||||
Les contrats principaux ont été retrouvés par recherche littérale, notamment :
|
||||
|
||||
```text
|
||||
PGR MUST NOT imposer un pin exact de toolchain uniquement parce qu'un projet source historique utilisait cette version.
|
||||
le fichier PGR `VERSION` reste la version canonique de l'unité de release
|
||||
Une crate membre SHOULD consommer cette dépendance avec `workspace = true`
|
||||
PGR ne généralise pas automatiquement la politique de lockfile
|
||||
unsafe_code = "forbid"
|
||||
PGR ne généralise pas l'interdiction KSP plus stricte de tous les `use` non-traits
|
||||
cargo clippy --workspace --all-targets --all-features -- -D warnings
|
||||
PGR SHOULD préférer plusieurs audits monotâches et lisibles
|
||||
```
|
||||
|
||||
Les liens vers `510-RUST_CARGO.md` ont été retrouvés depuis `RULES.md` et `docs/rules/000-README.md`.
|
||||
|
||||
L'audit Markdown PGR a été exécuté :
|
||||
|
||||
```bash
|
||||
python3 -B scripts/audit_markdown_tables.py README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
```
|
||||
|
||||
Résultat observé :
|
||||
|
||||
```text
|
||||
Markdown table audit: clean (2 table(s), 53 file(s))
|
||||
```
|
||||
|
||||
Les contrôles Git ont réussi :
|
||||
|
||||
```bash
|
||||
git diff --check
|
||||
|
||||
git add VERSION RULES.md docs/rules/000-README.md docs/rules/510-RUST_CARGO.md deltas/0.0.2/alpha.3.md
|
||||
|
||||
git diff --cached --check
|
||||
git status --short
|
||||
```
|
||||
|
||||
`git diff --check` et `git diff --cached --check` n'ont produit aucun diagnostic.
|
||||
|
||||
La sortie finale observée avant ajout du présent history était exactement :
|
||||
|
||||
```text
|
||||
M RULES.md
|
||||
M VERSION
|
||||
A deltas/0.0.2/alpha.3.md
|
||||
M docs/rules/000-README.md
|
||||
A docs/rules/510-RUST_CARGO.md
|
||||
```
|
||||
|
||||
Les marqueurs `EXEC >>` visibles dans la transcription proviennent du prompt Bash personnalisé de l'opérateur. Ils n'indiquent pas une erreur ou une commande supplémentaire dans la gate.
|
||||
|
||||
## Revue qualitative
|
||||
|
||||
L'état validé respecte le scope de `alpha.3` :
|
||||
|
||||
- les règles Rust/Cargo réutilisables sont séparées des conventions propres à KSP et `sasedev-games` ;
|
||||
- la politique de `Cargo.lock` reste une décision explicitement liée au type de projet au lieu d'être généralisée depuis les corpus historiques ;
|
||||
- les exceptions FFI et plateforme restent bornées au scope qui les impose ;
|
||||
- aucune version de crate, dépendance ou toolchain historique n'est devenue un pin universel ;
|
||||
- aucun audit Rust complexe n'a été ajouté sans workspace Rust réel ni propriété stable à contrôler ;
|
||||
- le profil tient dans un propriétaire documentaire unique et cohérent sans matérialiser prématurément de famille supplémentaire.
|
||||
|
||||
## Point de mesure
|
||||
|
||||
Le point de mesure prévu par le plan est satisfaisant.
|
||||
|
||||
La matérialisation d'un profil complet n'a pas nécessité de série de fixes ni de découpage supplémentaire. Le forecast suivant reste raisonnable :
|
||||
|
||||
```text
|
||||
0.0.2-alpha.4 — Java / Maven / Gradle
|
||||
0.0.2-alpha.5 — Android
|
||||
```
|
||||
|
||||
Un REPLAN reste obligatoire si une tranche ultérieure révèle une dérive significative ; aucune dérive de cette nature n'est observée ici.
|
||||
|
||||
## Résultat
|
||||
|
||||
`0.0.2-alpha.3` est validée `PASS`.
|
||||
|
||||
La tranche suivante autorisée est :
|
||||
|
||||
```text
|
||||
0.0.2-alpha.4
|
||||
```
|
||||
|
||||
Elle est consacrée au profil `Java / Maven / Gradle`, en maintenant une frontière nette entre règles du langage Java, politique de build Maven/Gradle et contraintes de plateforme qui appartiendront notamment au futur profil Android.
|
||||
81
history/0.0.2/alpha.4.fix.1.md
Normal file
81
history/0.0.2/alpha.4.fix.1.md
Normal file
@@ -0,0 +1,81 @@
|
||||
<!-- file: history/0.0.2/alpha.4.fix.1.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# History 0.0.2-alpha.4.fix.1 — cohérence de la gate Java
|
||||
|
||||
## Statut
|
||||
|
||||
PASS
|
||||
|
||||
Le correctif `0.0.2-alpha.4.fix.1` a été validé par l'opérateur. Le défaut de cohérence entre le profil Java/Maven/Gradle et sa gate est corrigé sans modification de scope fonctionnel.
|
||||
|
||||
## Baseline
|
||||
|
||||
La tranche `0.0.2-alpha.4` a été enregistrée `FAIL`, puis committée et poussée sous le commit observé :
|
||||
|
||||
```text
|
||||
70ff272
|
||||
```
|
||||
|
||||
Version validée après application du correctif :
|
||||
|
||||
```text
|
||||
0.0.2-alpha.4.fix.1
|
||||
```
|
||||
|
||||
## Validation opérateur observée
|
||||
|
||||
La version et les fichiers attendus ont été confirmés :
|
||||
|
||||
```bash
|
||||
test "$(cat VERSION)" = "0.0.2-alpha.4.fix.1"
|
||||
test -f docs/rules/520-JAVA_MAVEN_GRADLE.md
|
||||
test -f deltas/0.0.2/alpha.4.fix.1.md
|
||||
```
|
||||
|
||||
Les quatre chemins Java canoniques ajoutés par le correctif ont été retrouvés :
|
||||
|
||||
```text
|
||||
src/main/java/
|
||||
src/main/resources/
|
||||
src/test/java/
|
||||
src/test/resources/
|
||||
```
|
||||
|
||||
Les invariants principaux du profil sont toujours présents :
|
||||
|
||||
```text
|
||||
le JDK de développement SHOULD être une version LTS
|
||||
PGR MUST NOT ajouter un Maven Wrapper uniquement par cérémonie.
|
||||
Un Gradle Wrapper SHOULD être versionné lorsqu'il apporte une reproductibilité utile
|
||||
```
|
||||
|
||||
L'audit Markdown PGR a réussi :
|
||||
|
||||
```text
|
||||
Markdown table audit: clean (2 table(s), 58 file(s))
|
||||
```
|
||||
|
||||
`git diff --check` et `git diff --cached --check` n'ont produit aucun diagnostic.
|
||||
|
||||
Le scope Git observé avant le présent history est exactement :
|
||||
|
||||
```text
|
||||
M VERSION
|
||||
A deltas/0.0.2/alpha.4.fix.1.md
|
||||
M docs/rules/520-JAVA_MAVEN_GRADLE.md
|
||||
```
|
||||
|
||||
## Résultat
|
||||
|
||||
`0.0.2-alpha.4.fix.1` est validée `PASS`.
|
||||
|
||||
Le profil Java/Maven/Gradle est clos pour le scope de `0.0.2`.
|
||||
|
||||
La tranche suivante autorisée est :
|
||||
|
||||
```text
|
||||
0.0.2-alpha.5
|
||||
```
|
||||
|
||||
Elle est consacrée au premier profil plateforme Android. Les spécialisations Rust/JNI, Tauri et autres compositions restent explicitement hors scope de cette tranche.
|
||||
119
history/0.0.2/alpha.4.md
Normal file
119
history/0.0.2/alpha.4.md
Normal file
@@ -0,0 +1,119 @@
|
||||
<!-- file: history/0.0.2/alpha.4.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# History 0.0.2-alpha.4 — profil Java / Maven / Gradle
|
||||
|
||||
## Statut
|
||||
|
||||
FAIL
|
||||
|
||||
La tranche `0.0.2-alpha.4` n'est pas validée `PASS` telle quelle.
|
||||
|
||||
Le contenu principal est cohérent et presque toute la gate a réussi, mais une commande obligatoire du delta n'a produit aucun match :
|
||||
|
||||
```bash
|
||||
grep -F 'src/main/' docs/rules/520-JAVA_MAVEN_GRADLE.md
|
||||
```
|
||||
|
||||
La sortie observée est vide. Pour `grep -F`, l'absence de correspondance correspond à un code de retour non nul.
|
||||
|
||||
Il s'agit d'un défaut de cohérence entre le texte du profil et la gate de validation, pas d'un défaut de la politique Java/Maven/Gradle elle-même.
|
||||
|
||||
## Baseline
|
||||
|
||||
Version contrôlée :
|
||||
|
||||
```text
|
||||
0.0.2-alpha.4
|
||||
```
|
||||
|
||||
Le profil attendu et le delta sont présents :
|
||||
|
||||
```text
|
||||
docs/rules/520-JAVA_MAVEN_GRADLE.md
|
||||
deltas/0.0.2/alpha.4.md
|
||||
```
|
||||
|
||||
## Contrôles réussis observés
|
||||
|
||||
Les contrôles suivants ont produit les correspondances attendues :
|
||||
|
||||
```text
|
||||
le JDK de développement SHOULD être une version LTS
|
||||
JDK utilisé pour construire
|
||||
Lombok et les outils équivalents de convenience/codegen implicite SHOULD NOT être utilisés par défaut
|
||||
Le fichier PGR `VERSION` reste la version canonique de l'unité de release
|
||||
PGR MUST NOT ajouter un Maven Wrapper uniquement par cérémonie.
|
||||
minimum seulement
|
||||
Un Gradle Wrapper SHOULD être versionné lorsqu'il apporte une reproductibilité utile
|
||||
Groovy DSL et Kotlin DSL sont tous deux reconnus.
|
||||
`gradle clean` est une opération de maintenance
|
||||
Aucune commande Maven/Gradle n'est donc ajoutée à la gate documentaire de cette tranche.
|
||||
```
|
||||
|
||||
Les références de navigation vers `520-JAVA_MAVEN_GRADLE.md` ont également été trouvées dans :
|
||||
|
||||
```text
|
||||
RULES.md
|
||||
docs/rules/000-README.md
|
||||
```
|
||||
|
||||
L'audit Markdown a réussi :
|
||||
|
||||
```text
|
||||
Markdown table audit: clean (2 table(s), 56 file(s))
|
||||
```
|
||||
|
||||
`git diff --check` et `git diff --cached --check` n'ont produit aucun diagnostic.
|
||||
|
||||
Le scope Git observé avant le présent history est :
|
||||
|
||||
```text
|
||||
M RULES.md
|
||||
M VERSION
|
||||
A deltas/0.0.2/alpha.4.md
|
||||
M docs/rules/000-README.md
|
||||
A docs/rules/520-JAVA_MAVEN_GRADLE.md
|
||||
```
|
||||
|
||||
## Défaut exact
|
||||
|
||||
Le document contient une arborescence structurée :
|
||||
|
||||
```text
|
||||
src/
|
||||
├── main/
|
||||
│ ├── java/
|
||||
│ └── resources/
|
||||
└── test/
|
||||
├── java/
|
||||
└── resources/
|
||||
```
|
||||
|
||||
mais la gate cherche littéralement la chaîne :
|
||||
|
||||
```text
|
||||
src/main/
|
||||
```
|
||||
|
||||
Cette chaîne n'existe pas dans cette représentation arborescente.
|
||||
|
||||
La tranche ne peut donc pas être enregistrée `PASS` tant que sa propre gate n'est pas reproductible telle qu'elle est spécifiée.
|
||||
|
||||
## Décision
|
||||
|
||||
Aucun REPLAN n'est requis.
|
||||
|
||||
Le correctif est local et conserve exactement l'objectif de `alpha.4` :
|
||||
|
||||
```text
|
||||
0.0.2-alpha.4.fix.1
|
||||
```
|
||||
|
||||
Il doit seulement rendre explicites dans le profil les chemins Java canoniques déjà décrits conceptuellement, puis rejouer une gate cohérente.
|
||||
|
||||
## Résultat
|
||||
|
||||
`0.0.2-alpha.4` est enregistré `FAIL`.
|
||||
|
||||
La seule transition autorisée est `0.0.2-alpha.4.fix.1`.
|
||||
104
history/0.0.2/alpha.5.md
Normal file
104
history/0.0.2/alpha.5.md
Normal file
@@ -0,0 +1,104 @@
|
||||
<!-- file: history/0.0.2/alpha.5.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# History 0.0.2-alpha.5 — profil plateforme Android
|
||||
|
||||
## Statut
|
||||
|
||||
PASS
|
||||
|
||||
La tranche `0.0.2-alpha.5` a été validée par l'opérateur. Le premier profil plateforme Android est matérialisé sans absorber les spécialisations Rust/JNI, Tauri ou Web différées.
|
||||
|
||||
## Baseline
|
||||
|
||||
La correction précédente `0.0.2-alpha.4.fix.1` a été enregistrée `PASS`, puis committée et poussée sous le commit observé :
|
||||
|
||||
```text
|
||||
368dedb
|
||||
```
|
||||
|
||||
Version validée après application de `alpha.5` :
|
||||
|
||||
```text
|
||||
0.0.2-alpha.5
|
||||
```
|
||||
|
||||
## Validation opérateur observée
|
||||
|
||||
La version et les fichiers attendus ont été confirmés :
|
||||
|
||||
```bash
|
||||
test "$(cat VERSION)" = "0.0.2-alpha.5"
|
||||
test -f docs/rules/610-ANDROID.md
|
||||
test -f deltas/0.0.2/alpha.5.md
|
||||
```
|
||||
|
||||
Les contrats principaux du profil Android ont été retrouvés, notamment :
|
||||
|
||||
```text
|
||||
Les profils Rust/JNI et Tauri ne sont pas définis ici.
|
||||
Dans un dépôt multi-plateforme où une zone Android distincte est nécessaire
|
||||
Java est le langage applicatif Android par défaut du profil PGR
|
||||
Android Gradle Plugin
|
||||
PGR MUST NOT déduire une hausse de `minSdk`
|
||||
`versionCode` est un compteur Android monotone distinct du SemVer.
|
||||
`local.properties` est un fichier local Android typique
|
||||
Les secrets de signature ne sont jamais versionnés.
|
||||
Une ABI annoncée comme supportée doit disposer d'une preuve adaptée.
|
||||
JVM unit
|
||||
`AndroidManifest.xml` MUST déclarer uniquement les permissions
|
||||
APK debug
|
||||
PGR lui-même ne contient actuellement aucun projet Android
|
||||
```
|
||||
|
||||
La navigation vers `610-ANDROID.md` a été retrouvée depuis `RULES.md` et `docs/rules/000-README.md`.
|
||||
|
||||
L'audit Markdown PGR a réussi :
|
||||
|
||||
```text
|
||||
Markdown table audit: clean (2 table(s), 61 file(s))
|
||||
```
|
||||
|
||||
`git diff --check` et `git diff --cached --check` n'ont produit aucun diagnostic.
|
||||
|
||||
Le scope Git observé avant le présent history est exactement :
|
||||
|
||||
```text
|
||||
M RULES.md
|
||||
M VERSION
|
||||
A deltas/0.0.2/alpha.5.md
|
||||
M docs/rules/000-README.md
|
||||
A docs/rules/610-ANDROID.md
|
||||
```
|
||||
|
||||
## Revue qualitative
|
||||
|
||||
Le profil validé conserve les frontières prévues :
|
||||
|
||||
- Android possède les contraintes de plateforme, SDK, packaging, signing et compatibilité de target ;
|
||||
- Java/Gradle restent possédés par le profil langage/build et sont seulement raffinés lorsque la plateforme impose une contrainte ;
|
||||
- `compileSdk`, `targetSdk` et `minSdk` restent trois contrats distincts ;
|
||||
- une toolchain moderne ne relève pas automatiquement `minSdk` ;
|
||||
- `versionCode` reste un compteur Android distinct du SemVer ;
|
||||
- les niveaux `JVM unit`, instrumentation/intégration et smoke device/AVD ne sont pas confondus ;
|
||||
- aucune validation Android réelle n'est revendiquée pour PGR lui-même en l'absence d'un projet Android à compiler ou exécuter.
|
||||
|
||||
## Résultat
|
||||
|
||||
`0.0.2-alpha.5` est validée `PASS`.
|
||||
|
||||
Les trois profils technologiques retenus pour `0.0.2` sont maintenant matérialisés :
|
||||
|
||||
```text
|
||||
510 — Rust / Cargo
|
||||
520 — Java / Maven / Gradle
|
||||
610 — Android
|
||||
```
|
||||
|
||||
La tranche suivante autorisée est :
|
||||
|
||||
```text
|
||||
0.0.2-beta.1
|
||||
```
|
||||
|
||||
Elle est consacrée à leur réconciliation, à la vérification des owners/scopes/overrides et à la navigation. Aucun nouveau profil technologique majeur n'est autorisé en beta sans REPLAN.
|
||||
75
history/0.0.2/beta.1.fix.1.md
Normal file
75
history/0.0.2/beta.1.fix.1.md
Normal file
@@ -0,0 +1,75 @@
|
||||
<!-- file: history/0.0.2/beta.1.fix.1.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# History 0.0.2-beta.1.fix.1 — correction du quoting de la gate beta
|
||||
|
||||
## Statut
|
||||
|
||||
PASS
|
||||
|
||||
Le correctif `0.0.2-beta.1.fix.1` a été validé par l'opérateur. La commande de validation défectueuse de `beta.1` est remplacée par une recherche littérale Bash sûre, sans modification des profils ni des audits introduits en beta.
|
||||
|
||||
## Baseline
|
||||
|
||||
La tranche `0.0.2-beta.1` a été enregistrée `FAIL`, puis committée sous :
|
||||
|
||||
```text
|
||||
0719955
|
||||
```
|
||||
|
||||
Le premier `git push origin master` a été interrompu à l'invite d'authentification, puis le second a réussi et a publié ce commit sur `origin/master`.
|
||||
|
||||
Version validée après application du correctif :
|
||||
|
||||
```text
|
||||
0.0.2-beta.1.fix.1
|
||||
```
|
||||
|
||||
## Validation opérateur observée
|
||||
|
||||
La version et le delta attendu ont été confirmés :
|
||||
|
||||
```bash
|
||||
test "$(cat VERSION)" = "0.0.2-beta.1.fix.1"
|
||||
test -f deltas/0.0.2/beta.1.fix.1.md
|
||||
```
|
||||
|
||||
La recherche littérale corrigée a réussi :
|
||||
|
||||
```bash
|
||||
grep -F 'reste possédée par `RULES.md`.' docs/rules/610-ANDROID.md
|
||||
```
|
||||
|
||||
Sortie observée :
|
||||
|
||||
```text
|
||||
L'interdiction générale de versionner ou distribuer des secrets reste possédée par `RULES.md`. Le profil Android ajoute uniquement les conséquences propres au signing de cette plateforme.
|
||||
```
|
||||
|
||||
Les deux audits PGR ont réussi :
|
||||
|
||||
```text
|
||||
Markdown table audit: clean (2 table(s), 65 file(s))
|
||||
Markdown link audit: clean (49 local link(s), 65 file(s))
|
||||
```
|
||||
|
||||
`git diff --check` et `git diff --cached --check` n'ont produit aucun diagnostic.
|
||||
|
||||
Le scope Git observé avant le présent history est exactement :
|
||||
|
||||
```text
|
||||
M VERSION
|
||||
A deltas/0.0.2/beta.1.fix.1.md
|
||||
```
|
||||
|
||||
## Résultat
|
||||
|
||||
`0.0.2-beta.1.fix.1` est validée `PASS`.
|
||||
|
||||
La beta est réconciliée et la tranche suivante autorisée est :
|
||||
|
||||
```text
|
||||
0.0.2-rc.1
|
||||
```
|
||||
|
||||
La RC doit geler le scope, préparer l'entrée candidate `0.0.2` du changelog, finaliser le prompt de démarrage `0.0.3` et exécuter la gate documentaire complète sans introduire de nouveau profil technologique.
|
||||
103
history/0.0.2/beta.1.md
Normal file
103
history/0.0.2/beta.1.md
Normal file
@@ -0,0 +1,103 @@
|
||||
<!-- file: history/0.0.2/beta.1.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# History 0.0.2-beta.1 — réconciliation des profils
|
||||
|
||||
## Statut
|
||||
|
||||
FAIL
|
||||
|
||||
La tranche `0.0.2-beta.1` n'est pas enregistrée `PASS` telle quelle.
|
||||
|
||||
Le contenu réconcilié et les deux audits PGR ont produit les résultats attendus, mais une commande obligatoire de la gate possède un quoting Bash invalide.
|
||||
|
||||
## Baseline
|
||||
|
||||
La tranche précédente `0.0.2-alpha.5` a été enregistrée `PASS`, puis committée et poussée sous le commit observé :
|
||||
|
||||
```text
|
||||
ead2e87
|
||||
```
|
||||
|
||||
Version contrôlée après application de `beta.1` :
|
||||
|
||||
```text
|
||||
0.0.2-beta.1
|
||||
```
|
||||
|
||||
## Contrôles réussis observés
|
||||
|
||||
Les contrôles initiaux ont confirmé la version, les fichiers attendus et plusieurs contrats de réconciliation :
|
||||
|
||||
```text
|
||||
Aucune contradiction non résolue de même niveau n'a été identifiée entre les profils `510`, `520` et `610`.
|
||||
La forme condensée de cette composition est `GENERAL + 500 + 520 + 600 + 610`.
|
||||
Aucune famille `700` ou `800` n'est activée.
|
||||
```
|
||||
|
||||
Après interruption de la commande défectueuse, les contrôles restants ont été exécutés et ont réussi.
|
||||
|
||||
La matrice contient bien `PGR-NAV-001`, la commande `audit_markdown_links.py` et la règle de séparation des audits monotâches.
|
||||
|
||||
Résultats observés :
|
||||
|
||||
```text
|
||||
Markdown table audit: clean (2 table(s), 63 file(s))
|
||||
Markdown link audit: clean (49 local link(s), 63 file(s))
|
||||
```
|
||||
|
||||
`git diff --check` et `git diff --cached --check` n'ont produit aucun diagnostic.
|
||||
|
||||
Le scope Git observé avant le présent history est exactement :
|
||||
|
||||
```text
|
||||
M VERSION
|
||||
A deltas/0.0.2/beta.1.md
|
||||
M docs/architecture/003-RULE_PROFILE_MODEL.md
|
||||
M docs/plans/002-V0_0_2_RULE_PROFILES_PLAN.md
|
||||
M docs/rules/610-ANDROID.md
|
||||
M docs/validation/001-VALIDATION_MATRIX.md
|
||||
A scripts/audit_markdown_links.py
|
||||
```
|
||||
|
||||
## Défaut exact
|
||||
|
||||
La gate contient :
|
||||
|
||||
```bash
|
||||
grep -F 'L'interdiction générale de versionner ou distribuer des secrets reste possédée par `RULES.md`.' docs/rules/610-ANDROID.md
|
||||
```
|
||||
|
||||
L'apostrophe de `L'interdiction` ferme prématurément la chaîne Bash délimitée par apostrophes simples.
|
||||
|
||||
Le shell passe alors en invite de continuation :
|
||||
|
||||
```text
|
||||
>
|
||||
```
|
||||
|
||||
et la commande a dû être interrompue avec `Ctrl-C`.
|
||||
|
||||
Le contenu à vérifier existe bien dans `docs/rules/610-ANDROID.md`. Le défaut appartient uniquement au quoting de la commande de validation.
|
||||
|
||||
## Décision
|
||||
|
||||
Aucun REPLAN n'est requis.
|
||||
|
||||
La correction reste strictement locale :
|
||||
|
||||
```text
|
||||
0.0.2-beta.1.fix.1
|
||||
```
|
||||
|
||||
Le delta `beta.1` livré reste immuable. Le fix remplace uniquement la commande défectueuse par une recherche littérale sans apostrophe ambiguë et rejoue les preuves nécessaires.
|
||||
|
||||
## Résultat
|
||||
|
||||
`0.0.2-beta.1` est enregistré `FAIL`.
|
||||
|
||||
La seule transition autorisée est :
|
||||
|
||||
```text
|
||||
0.0.2-beta.1.fix.1
|
||||
```
|
||||
75
history/0.0.2/rc.1.fix.1.md
Normal file
75
history/0.0.2/rc.1.fix.1.md
Normal file
@@ -0,0 +1,75 @@
|
||||
<!-- file: history/0.0.2/rc.1.fix.1.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# History 0.0.2-rc.1.fix.1 — correction de l'audit inline des headers
|
||||
|
||||
## Statut
|
||||
|
||||
PASS
|
||||
|
||||
Le correctif `0.0.2-rc.1.fix.1` a été validé par l'opérateur. L'audit ponctuel des headers Markdown s'exécute désormais correctement sans élargir le scope de la RC.
|
||||
|
||||
## Baseline
|
||||
|
||||
La tranche `0.0.2-rc.1` a été enregistrée `FAIL`, puis committée et poussée sous le commit observé :
|
||||
|
||||
```text
|
||||
8272cfe
|
||||
```
|
||||
|
||||
Version validée après application du correctif :
|
||||
|
||||
```text
|
||||
0.0.2-rc.1.fix.1
|
||||
```
|
||||
|
||||
## Validation opérateur observée
|
||||
|
||||
La version et le delta de correction ont été confirmés :
|
||||
|
||||
```bash
|
||||
test "$(cat VERSION)" = "0.0.2-rc.1.fix.1"
|
||||
test -f deltas/0.0.2/rc.1.fix.1.md
|
||||
```
|
||||
|
||||
Les deux audits PGR permanents ont réussi :
|
||||
|
||||
```text
|
||||
Markdown table audit: clean (2 table(s), 70 file(s))
|
||||
Markdown link audit: clean (49 local link(s), 70 file(s))
|
||||
```
|
||||
|
||||
L'audit ponctuel des headers Markdown s'est exécuté sans erreur et a produit :
|
||||
|
||||
```text
|
||||
Markdown header audit: clean (70 file(s))
|
||||
```
|
||||
|
||||
`git diff --check` et `git diff --cached --check` n'ont produit aucun diagnostic.
|
||||
|
||||
Le scope Git observé avant le présent history est exactement :
|
||||
|
||||
```text
|
||||
M VERSION
|
||||
A deltas/0.0.2/rc.1.fix.1.md
|
||||
```
|
||||
|
||||
## Revue qualitative
|
||||
|
||||
Le correctif n'a modifié aucune règle, aucun profil, aucun audit permanent, aucun changelog et aucun prompt.
|
||||
|
||||
Le scope RC reste gelé sur les trois profils technologiques retenus et les deux audits PGR monotâches `tables` et `liens locaux`.
|
||||
|
||||
La correction concerne exclusivement la forme exécutable de la gate RC.
|
||||
|
||||
## Résultat
|
||||
|
||||
`0.0.2-rc.1.fix.1` est validée `PASS`.
|
||||
|
||||
La promotion stable peut maintenant être préparée sous l'identifiant opérationnel :
|
||||
|
||||
```text
|
||||
rel.001
|
||||
```
|
||||
|
||||
La promotion reste une opération pré-tag. Le tag `v0.0.2` ne doit être créé qu'après validation et history `PASS` de `rel.001`.
|
||||
115
history/0.0.2/rc.1.md
Normal file
115
history/0.0.2/rc.1.md
Normal file
@@ -0,0 +1,115 @@
|
||||
<!-- file: history/0.0.2/rc.1.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# History 0.0.2-rc.1 — gel du scope et préparation de clôture
|
||||
|
||||
## Statut
|
||||
|
||||
FAIL
|
||||
|
||||
La tranche `0.0.2-rc.1` n'est pas enregistrée `PASS` telle quelle.
|
||||
|
||||
Les contrôles documentaires principaux, les deux audits PGR et les contrôles Git ont réussi, mais l'audit inline des headers Markdown contenu dans la gate possède une chaîne Python invalide et se termine par une `SyntaxError`.
|
||||
|
||||
## Baseline
|
||||
|
||||
La tranche précédente `0.0.2-beta.1.fix.1` a été enregistrée `PASS`, puis committée et poussée sous le commit observé :
|
||||
|
||||
```text
|
||||
d0ac835
|
||||
```
|
||||
|
||||
Version contrôlée après application de `rc.1` :
|
||||
|
||||
```text
|
||||
0.0.2-rc.1
|
||||
```
|
||||
|
||||
## Contrôles réussis observés
|
||||
|
||||
La version, le prompt de reprise et le delta RC ont été confirmés.
|
||||
|
||||
Le `CHANGELOG.md` contient l'entrée `0.0.2` et les trois profils attendus :
|
||||
|
||||
```text
|
||||
510 — Rust / Cargo
|
||||
520 — Java / Maven / Gradle
|
||||
610 — Android
|
||||
```
|
||||
|
||||
Le plan confirme le gel du scope RC et l'état `PASS` de `beta.1.fix.1`.
|
||||
|
||||
Le prompt `prompts/003-V0_0_3_START_PROMPT.md` contient :
|
||||
|
||||
```text
|
||||
pgr-0.0.2-publish.001-report.md
|
||||
Prompt manuel de nouvelle session
|
||||
Partir de v0.0.2
|
||||
Ce texte doit être présenté spontanément
|
||||
```
|
||||
|
||||
Les deux audits PGR ont réussi :
|
||||
|
||||
```text
|
||||
Markdown table audit: clean (2 table(s), 68 file(s))
|
||||
Markdown link audit: clean (49 local link(s), 68 file(s))
|
||||
```
|
||||
|
||||
`git diff --check` et `git diff --cached --check` n'ont produit aucun diagnostic.
|
||||
|
||||
Le scope Git observé avant le présent history est exactement :
|
||||
|
||||
```text
|
||||
M CHANGELOG.md
|
||||
M VERSION
|
||||
A deltas/0.0.2/rc.1.md
|
||||
M docs/plans/002-V0_0_2_RULE_PROFILES_PLAN.md
|
||||
A prompts/003-V0_0_3_START_PROMPT.md
|
||||
```
|
||||
|
||||
## Défaut exact
|
||||
|
||||
La gate RC contient un audit Python inline destiné à contrôler les deux premiers headers de chaque fichier Markdown.
|
||||
|
||||
Lors de son exécution, la séquence destinée à joindre les erreurs avec un saut de ligne a été matérialisée ainsi :
|
||||
|
||||
```text
|
||||
raise SystemExit('
|
||||
'.join(errors))
|
||||
```
|
||||
|
||||
Python l'interprète comme une chaîne littérale non terminée et produit :
|
||||
|
||||
```text
|
||||
SyntaxError: unterminated string literal
|
||||
```
|
||||
|
||||
Le défaut appartient uniquement au script inline de validation livré dans `deltas/0.0.2/rc.1.md`.
|
||||
|
||||
Aucun défaut de header Markdown n'a été démontré par cette exécution, puisque l'audit n'a pas pu s'exécuter jusqu'au contrôle des fichiers.
|
||||
|
||||
## Décision
|
||||
|
||||
Aucun REPLAN n'est requis.
|
||||
|
||||
Le correctif reste strictement limité à la gate RC :
|
||||
|
||||
```text
|
||||
0.0.2-rc.1.fix.1
|
||||
```
|
||||
|
||||
Le delta RC livré reste immuable.
|
||||
|
||||
Le fix rejoue l'audit des headers avec une forme Python qui n'utilise aucune séquence d'échappement ambiguë : chaque erreur est imprimée individuellement puis le processus sort avec le code `1`.
|
||||
|
||||
Aucune règle, aucun profil, aucun audit PGR permanent et aucun contenu fonctionnel RC n'est ajouté ou modifié.
|
||||
|
||||
## Résultat
|
||||
|
||||
`0.0.2-rc.1` est enregistré `FAIL`.
|
||||
|
||||
La seule transition autorisée est :
|
||||
|
||||
```text
|
||||
0.0.2-rc.1.fix.1
|
||||
```
|
||||
116
history/0.0.2/rel.001.md
Normal file
116
history/0.0.2/rel.001.md
Normal file
@@ -0,0 +1,116 @@
|
||||
<!-- file: history/0.0.2/rel.001.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# History 0.0.2-rel.001 — promotion stable pré-tag
|
||||
|
||||
## Statut
|
||||
|
||||
PASS
|
||||
|
||||
La tranche `0.0.2-rel.001` a été validée par l'opérateur.
|
||||
|
||||
La promotion stable vers `0.0.2` est cohérente avant création du tag. Le contrôle post-tag `publish.001` reste une étape séparée et doit porter sur l'archive réellement produite depuis le tag `v0.0.2`.
|
||||
|
||||
## Baseline
|
||||
|
||||
La tranche précédente `0.0.2-rc.1.fix.1` a été validée `PASS`, puis committée et poussée sous le commit observé :
|
||||
|
||||
```text
|
||||
3ba513d
|
||||
```
|
||||
|
||||
Version contrôlée après application de `rel.001` :
|
||||
|
||||
```text
|
||||
0.0.2
|
||||
```
|
||||
|
||||
## Validation opérateur observée
|
||||
|
||||
La version stable a été confirmée :
|
||||
|
||||
```bash
|
||||
test "$(cat VERSION)" = "0.0.2"
|
||||
```
|
||||
|
||||
Les marqueurs de clôture stable ont été retrouvés :
|
||||
|
||||
```text
|
||||
README.md
|
||||
→ La release `0.0.2` ajoute le premier modèle de profils réutilisables
|
||||
|
||||
README.md
|
||||
→ plan historique des premiers profils `0.0.2`
|
||||
|
||||
ROADMAP.md
|
||||
→ `(x) 0.0.2`
|
||||
|
||||
docs/plans/002-V0_0_2_RULE_PROFILES_PLAN.md
|
||||
→ Plan clôturé par la promotion stable `0.0.2` après validation de `0.0.2-rc.1.fix.1`.
|
||||
|
||||
docs/plans/002-V0_0_2_RULE_PROFILES_PLAN.md
|
||||
→ Le contrôle post-tag `publish.001` reste une preuve séparée
|
||||
```
|
||||
|
||||
Le `CHANGELOG.md` contient exactement l'entrée :
|
||||
|
||||
```text
|
||||
## 0.0.2
|
||||
```
|
||||
|
||||
Le prompt de reprise `prompts/003-V0_0_3_START_PROMPT.md` existe et référence correctement :
|
||||
|
||||
```text
|
||||
v0.0.2
|
||||
pgr-v0.0.2.zip
|
||||
pgr-0.0.2-publish.001-report.md
|
||||
```
|
||||
|
||||
## Pairing deltas / histories
|
||||
|
||||
La boucle de contrôle a vérifié que chaque delta `deltas/0.0.2/*.md` antérieur à `rel.001.md` possède son history correspondant.
|
||||
|
||||
Aucun history manquant n'a été signalé.
|
||||
|
||||
## Audits documentaires
|
||||
|
||||
Résultats observés :
|
||||
|
||||
```text
|
||||
Markdown table audit: clean (2 table(s), 72 file(s))
|
||||
Markdown link audit: clean (50 local link(s), 72 file(s))
|
||||
Markdown header audit: clean (72 file(s))
|
||||
```
|
||||
|
||||
## Contrôles Git
|
||||
|
||||
`git diff --check` et `git diff --cached --check` n'ont produit aucun diagnostic.
|
||||
|
||||
Le scope Git observé avant ajout du présent history est exactement :
|
||||
|
||||
```text
|
||||
M README.md
|
||||
M ROADMAP.md
|
||||
M VERSION
|
||||
A deltas/0.0.2/rel.001.md
|
||||
M docs/plans/002-V0_0_2_RULE_PROFILES_PLAN.md
|
||||
```
|
||||
|
||||
## Résultat
|
||||
|
||||
`0.0.2-rel.001` est validée `PASS`.
|
||||
|
||||
L'état est prêt pour :
|
||||
|
||||
```text
|
||||
1. application du présent history ;
|
||||
2. commit stable `0.0.2` ;
|
||||
3. push du commit stable ;
|
||||
4. création du tag `v0.0.2` sur ce commit ;
|
||||
5. push du tag ;
|
||||
6. téléchargement de l'archive ZIP produite depuis ce tag ;
|
||||
7. contrôle post-tag `publish.001` de cette archive réelle ;
|
||||
8. production de `pgr-0.0.2-publish.001-report.md`.
|
||||
```
|
||||
|
||||
Le tag ne doit pas être considéré publié correctement tant que `publish.001` n'a pas contrôlé l'archive réellement servie par la forge.
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user