42 Commits

Author SHA1 Message Date
c41b69badf 0.1.4 2026-09-29 18:11:44 +02:00
4fc3cd5e7e 0.1.4-rc.1 2026-09-29 18:01:37 +02:00
091685af50 0.1.4-beta.1 2026-09-29 15:07:38 +02:00
e4f405ea9d 0.1.4-alpha.3 2026-09-29 14:00:25 +02:00
9b140e85b3 0.1.4-alpha.2.fix.1 2026-09-29 13:36:20 +02:00
ed794d66a0 0.1.4-alpha.2 2026-09-29 11:45:01 +02:00
7f475584d6 0.1.4-alpha.1 2026-09-29 11:33:56 +02:00
fe80dbbb73 0.1.3 2026-09-28 13:04:53 +02:00
a9fba6c5c3 0.1.3-rc.1 2026-09-28 13:00:04 +02:00
3f3de726c2 0.1.3-beta.1 2026-09-28 12:49:31 +02:00
8cbd686f47 0.1.3-alpha.3 2026-09-28 11:32:26 +02:00
1223a705c0 0.1.3-alpha.2 2026-09-28 10:41:03 +02:00
eaa9c399be 0.1.3-alpha.1 2026-09-28 10:28:40 +02:00
585b508578 0.1.2 2026-09-28 01:27:41 +02:00
36b2b2162c 0.1.2-rc.1 2026-09-28 01:21:44 +02:00
4dcb0dd89e 0.1.2-beta.1 2026-09-28 01:03:26 +02:00
226d61b041 0.1.2-alpha.3 2026-09-28 00:05:12 +02:00
8de2daa716 0.1.2-alpha.2.fix.1 2026-09-27 23:12:36 +02:00
17b7ef23a1 0.1.2-alpha.2 2026-09-27 22:44:02 +02:00
6e978bfed8 0.0.1-alpha.3.fix.1 2026-09-27 22:36:07 +02:00
46a159a3bc 0.1.2-alpha.1 2026-09-27 22:27:45 +02:00
4893a04f49 0.1.1 2026-09-27 12:27:09 +02:00
fbde0c2073 0.1.1-rc.1 2026-09-27 12:08:21 +02:00
9ef9549f2d 0.1.1-beta.1 2026-09-27 11:57:09 +02:00
55c6f7b05d 0.1.1-alpha.5 2026-09-27 11:43:09 +02:00
89b8ea88c1 0.1.1-alpha.4 2026-09-27 11:33:12 +02:00
56e3d37879 0.1.1-alpha.3.fix.2 2026-09-27 11:15:26 +02:00
889d9cbcbd 0.1.1-alpha.3.fix.1 2026-09-27 11:03:58 +02:00
5033547534 0.1.1-alpha.3 2026-09-27 10:56:05 +02:00
e351f57be4 0.1.1-alpha.2.fix.1 2026-09-27 10:42:38 +02:00
dc63b543ac 0.1.1-alpha.2 2026-09-27 10:18:43 +02:00
7b7565d5d4 0.1.1-alpha.1 2026-09-27 10:09:35 +02:00
2ed8742f3b 0.1.0 2026-09-26 23:31:54 +02:00
d5e1fc4300 0.1.0-rc.1 2026-09-26 23:26:23 +02:00
5393257d93 0.1.0-beta.1 2026-09-26 23:10:02 +02:00
a65a183ee4 0.1.0-alpha.5 2026-09-26 20:33:53 +02:00
e4b5992266 0.1.0-alpha.4 2026-09-26 19:31:22 +02:00
351025b4f2 0.1.0-alpha.3.fix.1 2026-09-26 19:19:20 +02:00
f37481627a 0.1.0-alpha.3 2026-09-26 19:06:59 +02:00
3230356cd6 0.1.0-alpha.2.fix.1 2026-09-26 19:00:32 +02:00
62f3d252d8 0.1.0-alpha.2 2026-09-26 17:33:23 +02:00
c22cf39ba9 0.1.0-alpha.1 2026-09-26 17:25:10 +02:00
138 changed files with 21028 additions and 426 deletions

View File

@@ -1,5 +1,5 @@
<!-- file: CHANGELOG.md -->
<!-- version: 9 -->
<!-- version: 19 -->
# Changelog Project Governance Rules
@@ -7,6 +7,52 @@ 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.1.4
- réexamine le `DEFER` historique du skeleton Tauri contre les corpus Games/KSP fournis, confirme les prérequis Web désormais couverts et lève le blocage sans généraliser les choix locaux de ces projets ;
- recentre l’owner `710-TAURI` sur le host, l’orchestration, la configuration, les commandes, permissions et capabilities, les plugins et la frontière d’intégration, tandis que TypeScript, Vite, CSS/Sass, package manager et bindings restent possédés par leurs owners dédiés ;
- matérialise `docs/skeletons/004-TAURI.md` comme specification organisationnelle composable avec la fondation, Rust/Cargo et Web, en laissant identifiants, capabilities, plugins, fenêtres, bundles et plateformes au projet destinataire ;
- confirme qu’aucun template technique Tauri générique, contrat `006-TAURI_VALIDATION.md` ni dry-run de faux projet n’est justifié tant qu’aucune responsabilité réutilisable non couverte n’est démontrée ;
- ajoute un audit réutilisable d’hygiène texte imposant LF, absence de whitespace terminal et exactement une newline finale, et durcit le contrat des archives delta/history pour interdire un répertoire englobant autour des chemins du dépôt ;
- effectue une revue d’horizon de fermeture : la clarification de `SHOULD`, l’autonomie des projets après adoption et la frontière future avec SaseDev Knowledge deviennent la cible `0.1.5`, avant les adoptions Games `0.1.6`, KSP `0.1.7` et les audits Rust `0.1.8`.
## 0.1.3
- réévalue le profil Android contre le corpus Games réel tout en conservant Android neutre vis-à-vis du langage applicatif et en composant Java/Gradle uniquement lorsqu'ils sont réellement présents ;
- clarifie les responsabilités `compileSdk` / `targetSdk` / `minSdk`, l'identité `namespace` / `applicationId`, la configuration locale, le signing et les manifests/resources sans promouvoir les valeurs particulières de Games ;
- borne NDK, ABI et code natif aux projets réellement concernés, distingue compilation native, packaging et preuve runtime, et conserve les choix Rust/JNI/SDL de Games hors du profil Android générique ;
- rend Android Lint explicite, sépare tests JVM, tests instrumentés et smokes device/AVD, et distingue APK/AAB des preuves d'installation ou d'exécution ;
- normalise la compatibilité pages mémoire 16 KB uniquement comme contrainte conditionnelle au code natif, au package et au canal de distribution applicables, sans imposer une version AGP/NDK, un `targetSdk` ou une liste d'ABI universels ;
- confirme que les owners existants `400 + 600 + 610`, complétés par `520` et `522` lorsqu'ils s'appliquent, suffisent sans créer de skeleton Android, template, audit Python, owner JNI/Rust/SDL ou contrat de validation redondant ;
- prépare le réexamen Tauri distinct de `0.1.4` sans lever son `DEFER` par anticipation et conserve l'adoption Games comme cible séparée `0.1.5`.
## 0.1.2
- sépare l'ancien profil combiné Java/Maven/Gradle en trois owners indépendants et composables : `520-JAVA`, `521-MAVEN` et `522-GRADLE`, afin qu'un build tool ne devienne pas implicitement applicable à tout projet Java ;
- clarifie la distinction entre JDK utilisé pour construire, niveau Java du code source et niveau de bytecode/runtime supporté, sans généraliser les versions particulières observées dans Games ;
- formalise pour Gradle l'ownership `settings` / root / modules / propriétés partagées, ainsi que le choix proportionné entre Wrapper et Gradle système avec contrainte effectivement vérifiée ;
- conserve Maven comme spécialisation indépendante et cohérente sans prétendre l'avoir éprouvée par Games ni créer d'artefact Maven en l'absence de corpus réel ;
- conserve l'ancien chemin `520-JAVA_MAVEN_GRADLE.md` uniquement comme bridge documentaire `SUPERSEDED` pour les références historiques et n'ajoute aucun template, skeleton, audit Python ou contrat de validation Java/Maven/Gradle non justifié ;
- maintient les responsabilités AGP, SDK/NDK, ABI/JNI, manifests/resources, packaging/signing et smokes Android dans l'owner Android, dont la réévaluation pratique reste la cible distincte `0.1.3`.
## 0.1.1
- établit une fondation frontend Web composable avec quatre owners indépendants : TypeScript, écosystème de package JavaScript, Vite et CSS/Sass, sans transformer un outil concret en obligation universelle ;
- recommande TypeScript pour les frontends durables avec vérification stricte et `noEmit`, tout en distinguant les types embarqués des packages `@types/*` réellement nécessaires à l'analyse, à l'intégration IDE et aux API consommées ;
- formalise un écosystème de package neutre vis-à-vis de npm/pnpm/yarn, un script `typecheck` indépendant et une politique de lockfile dépendant du rôle application/bibliothèque plutôt qu'une règle unique artificielle ;
- recommande Vite lorsque son modèle convient, avec ownership explicite du dev server, du cache, des outputs, des assets et des paramètres de sécurité, sans fournir de `vite.config.ts`, port, `base` ou layout universels ;
- conserve CSS comme baseline valide et recommande Sass lorsqu'il apporte une valeur réelle, notamment pour les packages exposant une API Sass, avec préférence pour `@use` / `@forward` et séparation stricte entre sources et styles générés ;
- ajoute une validation frontend indépendante du host et un skeleton Web composable, puis confirme que les cinq prérequis Web du futur réexamen Tauri sont couverts sans lever le `DEFER`, qui reste réservé à `0.1.4`.
## 0.1.0
- établit la première baseline PGR réellement réutilisable pour initialiser de nouveaux projets et adopter progressivement des projets existants, avec une fondation de gouvernance, des skeleton specifications composables et une validation proportionnée ;
- stabilise le socle Rust/Cargo réutilisable : cinq templates techniques, composition `001 + 002`, dry-run `NEW` avec Cargo/rustfmt/Clippy et chemin `ADOPTION` non destructif ;
- formalise l'adoption de projets existants avec baseline autoritaire, migration progressive et décisions `ADOPT / KEEP-LOCAL / OVERRIDE / DEFER`, sans réécriture rétroactive de l'historique ;
- corrige la convention de clôture stable vers `rel.N` sans zéro de padding et garantit que la première clôture qui obtient réellement `PASS` produit le commit produit `X.Y.Z` avant le tag `vX.Y.Z` ;
- rend obligatoire le handoff automatique des commandes opérateur entre history, commit/push, delta suivant et publication stable, avec distinction entre objet tag, commit déréférencé et rapport `publish.*` post-tag ;
- matérialise la revue d'horizon suivante : frontend Web, Java/Gradle, Android, Tauri conditionnel, adoption Games puis KSP et audits Rust/Clippy statiques Python-only, tout en laissant WASM, serveur Rust et deployment/operations sans réservation prématurée.
## 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 ;

View File

@@ -1,5 +1,5 @@
<!-- file: README.md -->
<!-- version: 14 -->
<!-- version: 27 -->
# Project Governance Rules
@@ -11,9 +11,9 @@ Le dépôt officiel est `https://git.sasedev.com/Sasedev/pgr`.
## Statut
PGR est actuellement en phase de fondation `0.0.x`.
PGR a clôturé sa phase de fondation `0.0.x` et dispose désormais d’une suite de baselines stables `0.1.x`. La stable `0.1.4` réexamine le domaine Tauri contre les corpus Games/KSP, consolide l’owner `710`, matérialise le skeleton organisationnel `004-TAURI.md`, confirme qu’aucun template technique ni contrat de validation Tauri séparé n’est justifié et ajoute un audit réutilisable d’hygiène texte. La revue d’horizon de fermeture réserve `0.1.5` à la sémantique normative, à l’autonomie des projets après adoption et à la frontière PGR / SaseDev Knowledge avant les adoptions Games `0.1.6` et KSP `0.1.7`.
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.
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. La release `0.1.0` stabilise la première baseline réutilisable : adoption `ADOPT / KEEP-LOCAL / OVERRIDE / DEFER`, skeletons/templates Rust/Cargo exercés par dry-run, clôture `rel.N`, handoff opérateur automatique et trajectoire `0.1.1` à `0.1.7` issue d'une revue d'horizon explicite. La release `0.1.1` stabilise la fondation frontend Web : owners indépendants TypeScript/package/Vite/CSS-Sass, déclarations de types externes conditionnelles, package manager neutre, validation frontend indépendante du host et skeleton Web composable, tout en conservant le skeleton Tauri en `DEFER` jusqu’à son réexamen `0.1.4`. La release `0.1.2` stabilise trois owners indépendants `520-JAVA`, `521-MAVEN` et `522-GRADLE`, clarifie JDK/source/bytecode et l'ownership Gradle, conserve Maven cohérent sans corpus artificiel et maintient les responsabilités Android dans `610-ANDROID.md` pour leur réévaluation distincte en `0.1.3`. La release `0.1.3` stabilise le profil Android générique : séparation des responsabilités SDK et identité applicative, contraintes natives conditionnelles, Android Lint explicite, niveaux de tests distincts, frontières APK/AAB et compatibilité 16 KB liée au code natif et au canal de distribution, sans imposer les versions ou ABI propres à Games. La release `0.1.4` stabilise le domaine Tauri : owner `710` recentré sur host/orchestration/ACL/plugins, skeleton `004` composable avec Rust/Cargo et Web, absence assumée de template technique générique ou de validation Tauri redondante, audit d’hygiène texte réutilisable et handoff vers `0.1.5` pour clarifier la sémantique normative et l’autonomie des projets.
## Entrées principales
@@ -29,10 +29,17 @@ La version courante est définie par [`VERSION`](VERSION). La release `0.0.1` é
- [`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/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md`](docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md) — plan historique de la première baseline réutilisable `0.1.0` ;
- [`docs/plans/007-V0_1_1_WEB_FRONTEND_FOUNDATION_PLAN.md`](docs/plans/007-V0_1_1_WEB_FRONTEND_FOUNDATION_PLAN.md) — plan historique de la fondation frontend Web stable `0.1.1` ;
- [`docs/plans/008-V0_1_2_JAVA_GRADLE_REEVALUATION_PLAN.md`](docs/plans/008-V0_1_2_JAVA_GRADLE_REEVALUATION_PLAN.md) — plan historique de la stable `0.1.2` : réévaluation Games, scission Java/Maven/Gradle et maintien d'Android hors scope ;
- [`docs/plans/009-V0_1_3_ANDROID_REEVALUATION_PLAN.md`](docs/plans/009-V0_1_3_ANDROID_REEVALUATION_PLAN.md) — plan historique de la stable Android `0.1.3`, fondée sur Games avec classification `ADOPT / KEEP-LOCAL / OVERRIDE / DEFER` ;
- [`docs/plans/010-V0_1_4_TAURI_REEVALUATION_PLAN.md`](docs/plans/010-V0_1_4_TAURI_REEVALUATION_PLAN.md) — plan historique de la stable Tauri `0.1.4`, du réexamen Games/KSP au skeleton `004`, à la décision d’artefacts et à la revue d’horizon ;
- [`docs/skeletons/004-TAURI.md`](docs/skeletons/004-TAURI.md) — specialization Tauri 2 composable, sans template technique universel ni defaults de capabilities/plugins/fenêtres/bundles ;
- [`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/skeletons/003-WEB_FRONTEND.md`](docs/skeletons/003-WEB_FRONTEND.md) — specialization composable pour un frontend Web contrôlé, avec TypeScript/Vite recommandés, Sass optionnel et validation indépendante du host ;
- [`docs/validation/001-VALIDATION_MATRIX.md`](docs/validation/001-VALIDATION_MATRIX.md) — matrice de validation.
## Langue et nomenclature

View File

@@ -1,5 +1,5 @@
<!-- file: ROADMAP.md -->
<!-- version: 8 -->
<!-- version: 17 -->
# Roadmap Project Governance Rules
@@ -17,18 +17,30 @@ Statuts : `( )` planifié, `(x)` terminé, `(d)` différé, `(c)` annulé.
## 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.
- `(x) 0.1.0` — première baseline PGR destinée à initialiser de nouveaux projets et à adopter progressivement des projets existants à partir de règles, templates, skeleton specifications et validations éprouvés.
## Horizon après `0.1.0`
## Trajectoire engagée `0.1.x`
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é.
La revue d'horizon de `0.1.0-beta.1` engage les releases suivantes, chacune avec un domaine cohérent et une session/release indépendante :
### Trajectoire explicitement différée
- `(x) 0.1.1` — fondation frontend Web : TypeScript, Vite, Sass/CSS, package/build outputs et validation frontend indépendante ;
- `(x) 0.1.2` — réévaluation pratique de Java/Maven/Gradle, séparation des owners lorsque leurs applicabilités divergent et matérialisation uniquement des artefacts génériques réellement nécessaires ;
- `(x) 0.1.3` — réévaluation pratique du profil Android existant à partir de Games, sans absorber les décisions propres aux jeux ou à SDL ;
- `(x) 0.1.4` — domaine Tauri : réexamen du `DEFER`, consolidation de l’owner `710`, matérialisation du skeleton contrôlé `004` et décision explicite de ne pas créer d’artefacts techniques redondants ;
- `( ) 0.1.5` — sémantique normative et autonomie : clarifier `MUST / SHOULD / MAY`, rendre explicite l’autorité locale d’un projet après instanciation/adoption et fixer la frontière durable entre PGR et SaseDev Knowledge ;
- `( ) 0.1.6` — adoption réelle de PGR par `sasedev-games` avec mapping `ADOPT / KEEP-LOCAL / OVERRIDE / DEFER`, après stabilisation du contrat d’autonomie ;
- `( ) 0.1.7` — adoption réelle de PGR par `khadhroony-solana-project`, principalement sur Rust/Cargo + Tauri et sans dépendance aux profils non applicables ;
- `( ) 0.1.8` — audits Python read-only d’un sous-ensemble statique des conventions Rust/Clippy, après les deux adoptions, sans prétendre remplacer `cargo clippy`.
- `(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.
Le détail et les conditions de cette séquence sont conservés dans [`docs/studies/003-V0_1_0_HORIZON_REVIEW.md`](docs/studies/003-V0_1_0_HORIZON_REVIEW.md).
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.
## Trajectoires différées ou non numérotées
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.
- `WASM` — candidat séparé à réévaluer pendant l'adoption Games si un owner PGR apporte une valeur immédiate ;
- `serveur Web Rust / Actix Web ou alternative` — candidat à partir d'un corpus d'implémentation réel, pas sur la seule base d'une trajectoire roadmap ;
- `saselang-bible`, projets documentaires/spécifications et généricité hors logiciel — candidats d'une trajectoire ultérieure `0.2.x` / `0.3.x` à décider ;
- `deployment & operations` — famille future pour reverse proxies, bases de données, Docker/Compose, services Linux, secrets, migrations/backups, health et observabilité ; un horizon `0.4.x` ou `0.5.x` est plausible mais aucun numéro précis n'est réservé.
La revue d’horizon `0.1.4-rc.1` remplace l’ordre initial `0.1.5` Games / `0.1.6` KSP / `0.1.7` audits par le contrat ci-dessus. Une nouvelle revue d’horizon doit intervenir si `0.1.5` démontre que l’autonomie ne peut pas être stabilisée sans scope supplémentaire, ou si Games/KSP exigent un owner réellement préalable à une adoption proportionné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`.

View File

@@ -1,5 +1,5 @@
<!-- file: RULES.md -->
<!-- version: 11 -->
<!-- version: 14 -->
# Index normatif Project Governance Rules
@@ -77,11 +77,18 @@ 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/230-ADOPTION.md`](docs/rules/230-ADOPTION.md) — adoption proportionnée de PGR par un projet existant, mapping des owners, décisions locales et migration progressive.
- [`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/520-JAVA.md`](docs/rules/520-JAVA.md) — profil Java : JDK LTS, compatibilité source/bytecode, structure, packages, API et tests.
- [`docs/rules/521-MAVEN.md`](docs/rules/521-MAVEN.md) — spécialisation Maven : ownership du reactor, wrapper conditionnel, validation et outputs.
- [`docs/rules/522-GRADLE.md`](docs/rules/522-GRADLE.md) — spécialisation Gradle : ownership du build, version/wrapper, DSL, propriétés, validation et outputs.
- [`docs/rules/530-TYPESCRIPT.md`](docs/rules/530-TYPESCRIPT.md) — profil TypeScript : recommandation contrôlée, type-check et frontières typées.
- [`docs/rules/540-JAVASCRIPT_PACKAGE_ECOSYSTEM.md`](docs/rules/540-JAVASCRIPT_PACKAGE_ECOSYSTEM.md) — manifest `package.json`, sélection du package manager, dépendances et responsabilité du lockfile.
- [`docs/rules/550-VITE.md`](docs/rules/550-VITE.md) — profil Vite : build tool/dev server recommandé, cache, outputs et frontière avec le host.
- [`docs/rules/560-CSS_SASS.md`](docs/rules/560-CSS_SASS.md) — profil CSS/Sass : styles sources, prétraitement optionnel recommandé et dépendances de styles.
- [`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.

View File

@@ -1 +1 @@
0.0.5
0.1.4

202
deltas/0.1.0/alpha.1.md Normal file
View File

@@ -0,0 +1,202 @@
<!-- file: deltas/0.1.0/alpha.1.md -->
<!-- version: 1 -->
# Delta 0.1.0-alpha.1 — audit de la stable et cadrage de la baseline réutilisable
## Baseline et sources
Baseline PGR autoritaire : `pgr-v0.0.5.zip`, archive source téléchargée depuis le tag Gitea `v0.0.5`, accompagnée du rapport externe `pgr-0.0.5-publish.001-report.md` avec statut `PASS`.
SHA-256 vérifiés :
```text
pgr-v0.0.5.zip 1fb72bafb24b5a0f3406561b96caa8245142a5f099e692842d9ef1ba44f41b49
pgr-0.0.5-publish.001-report.md a6727fd1f3122dbb19eb79d6b904ebaed2bbfc360ed4a34cc1299cb2166efd96
games-v0.3.6.zip ad6e44a1332eb7d6069cf1189d9433f0fbb8fac19c5aac9f4641ac45c1c556e8
khadhroony-solana-project-v0.3.16.zip db3cc1b3fc3fb07ee864b02e2a7346c673d4cf63b33e8e872aca6c6458856ca0
```
Games et KSP sont uniquement des corpus de pression pour préparer l'adoption future ; ils ne sont ni modifiés ni incorporés à cette archive delta.
Version avant application :
```text
0.0.5
```
Version après application :
```text
0.1.0-alpha.1
```
## Objet
Exécuter `prompts/006-V0_1_0_START_PROMPT.md` : auditer intégralement la stable `v0.0.5`, ses règles, profils, templates, skeletons, audits, décisions différées et chaîne de gouvernance, puis créer le plan de la première baseline réellement réutilisable avant tout changement normatif important.
La tranche consigne également les décisions de cadrage acquises pendant la reprise :
- corriger en `0.1.0` la convention future `rel.001` vers `rel.1` sans réécrire l'historique ;
- distinguer le nom de tranche de fermeture du commit qui établit finalement la stable `X.Y.Z` ;
- formaliser le handoff automatique des commandes Git après chaque history et des commandes/preuves de publication avant/après tag ;
- traiter Web, serveur Rust/Actix, Java/Android, WASM et Tauri dans des releases `0.1.x` séparées, jamais comme un bloc unique `0.1.0` ;
- préparer l'adoption de PGR par Games dès que son sous-ensemble requis est prêt, puis par KSP dont la pression est principalement Rust/Cargo + Tauri.
Aucune de ces corrections n'est encore matérialisée normativement dans `alpha.1`.
## Résultat de l'audit d'intake
La stable et son rapport post-tag sont cohérents. L'archive contient `225` entrées sous `pgr/`, `194` fichiers et `31` répertoires, CRC propre, aucun symlink et aucune métadonnée `.git` attendue.
La suite PGR donne `48/48` tests `PASS`. Les audits Markdown sont propres : `171` fichiers pour les headers, `8` tables sur `171` fichiers et `161` liens locaux sur `171` fichiers.
Les `62` couples delta/history de `0.0.1` à `0.0.5` sont complets. Les `19` histories de `0.0.5` conservent leurs statuts réels, notamment `rel.001` `FAIL` puis `rel.001.fix.1` `PASS`.
Les owners actuels couvrent déjà Rust/Cargo (`510`), Java/Maven/Gradle (`520`), Android (`610`) et Tauri (`710`). Les templates techniques actuels sont Rust/Cargo ; les skeletons concrets sont la fondation de gouvernance et le workspace Rust/Cargo. Le skeleton Tauri reste correctement `DEFER` tant que les owners Web manquants ne sont pas matérialisés.
Games `0.3.6` confirme une pression réelle Web/Vite/TypeScript/Sass, Android/Gradle, Rust/WASM et Tauri, avec `0.3.7` réservé dans son propre roadmap à l'alignement PGR. KSP `0.3.16` contient six applications Tauri et un socle essentiellement Rust/Cargo. Ces observations servent au sizing futur et ne créent aucun profil dans cette tranche.
## Scope
REPLACE :
```text
VERSION
README.md
docs/000-README.md
```
ADD :
```text
docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md
deltas/0.1.0/alpha.1.md
```
DELETE : aucun.
`RULES.md`, `ROADMAP.md`, `CHANGELOG.md`, les règles, profils, templates, skeletons, scripts et histories existants restent inchangés dans `alpha.1`.
Aucun `history/0.1.0/alpha.1.md` n'est anticipé avant la gate opérateur.
## Validation opérateur
Après application sur la stable `0.0.5`, depuis la racine du dépôt :
```bash
test "$(cat VERSION)" = '0.1.0-alpha.1'
test -f docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md
test -f deltas/0.1.0/alpha.1.md
test ! -e history/0.1.0/alpha.1.md
grep -Fx '<!-- version: 15 -->' README.md
grep -Fx '<!-- version: 18 -->' docs/000-README.md
grep -F '006-V0_1_0_REUSABLE_BASELINE_PLAN.md' README.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
expected = {
'0.0.1': 12,
'0.0.2': 12,
'0.0.3': 10,
'0.0.4': 9,
'0.0.5': 19,
}
for release, count in expected.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) == count, (release, len(deltas))
assert deltas == histories, (release, sorted(deltas ^ histories))
statuses = {}
for path in Path('history/0.0.5').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[path.name] = match.group(1)
assert statuses['rel.001.md'] == 'FAIL'
assert statuses['rel.001.fix.1.md'] == 'PASS'
for path in (
Path('docs/rules/510-RUST_CARGO.md'),
Path('docs/rules/520-JAVA_MAVEN_GRADLE.md'),
Path('docs/rules/610-ANDROID.md'),
Path('docs/rules/710-TAURI.md'),
Path('docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md'),
Path('docs/skeletons/002-RUST_CARGO_WORKSPACE.md'),
Path('docs/studies/002-TAURI_SKELETON_DECISION.md'),
):
assert path.is_file(), path
plan = Path('docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md').read_text(encoding='utf-8')
for phrase in (
'rel.1',
'première tranche qui obtient le PASS stable',
'Commandes opérateur et publication',
'une release/session par domaine cohérent',
'Games',
'KSP',
'TypeScript',
'Vite',
'Android',
'WASM',
'Tauri',
'Actix Web ou autre framework',
'beta.1 — réconciliation finale et revue d\'horizon',
):
assert phrase in plan, phrase
assert '- `( ) 0.1.0`' in Path('ROADMAP.md').read_text(encoding='utf-8')
assert '- `( ) 0.1.1`' not in Path('ROADMAP.md').read_text(encoding='utf-8')
print('0.1.0 alpha.1 structural audit: clean (62 prior pairs, stable workflow truth preserved, future 0.1.x unnumbered)')
PY
git diff --check
git add VERSION README.md docs/000-README.md \
docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md \
deltas/0.1.0/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.1.0/alpha.1.md
M docs/000-README.md
A docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md
```
La revue opérateur doit également confirmer que :
- le plan ne transforme pas les futurs axes `0.1.x` en versions numérotées prématurément ;
- Java/Android et Tauri sont reconnus comme profils existants, non recréés artificiellement ;
- le `DEFER` du skeleton Tauri reste intact dans cette tranche ;
- Games et KSP restent des corpus externes non modifiés ;
- aucune règle Web/WASM/Actix n'est introduite dans `alpha.1` ;
- les anciennes occurrences `rel.001*` restent intactes et historiques.
## Transition
### PASS
Produire `history/0.1.0/alpha.1.md` à partir des résultats réellement observés. Dans la même réponse, si aucune décision nouvelle n'est ouverte, préparer séparément le delta `0.1.0-alpha.2` consacré uniquement à la clôture stable `rel.N` et à l'identité du commit final.
Après remise du history, fournir spontanément le bloc Git exact à exécuter pour fermer `alpha.1` avant application du delta suivant, même si la règle normative des handoffs automatiques ne sera matérialisée qu'en `alpha.3`.
### FAIL
Consigner le résultat réel dans le history, puis ouvrir `0.1.0-alpha.1.fix.1` ou un REPLAN selon la cause. Aucun changement de `alpha.2` ne doit être absorbé silencieusement dans le fix.

View File

@@ -0,0 +1,178 @@
<!-- file: deltas/0.1.0/alpha.2.fix.1.md -->
<!-- version: 1 -->
# Delta 0.1.0-alpha.2.fix.1 — correction de la gate `rel.N`
## Baseline et version
Baseline attendue : commit opérateur de `0.1.0-alpha.2`, réalisé après application de `history/0.1.0/alpha.2.md` avec statut `FAIL`.
Le hash de ce commit n'est pas anticipé.
Version avant application :
```text
0.1.0-alpha.2
```
Version après application :
```text
0.1.0-alpha.2.fix.1
```
## Objet
Corriger uniquement la gate opérateur défectueuse de `alpha.2`.
Le contenu normatif de `docs/rules/200-GOVERNANCE.md` et `docs/rules/210-WORKFLOW.md` a déjà été couvert par la preuve Python de `alpha.2` et n'est pas modifié. Le défaut constaté provient de motifs `grep -F` entourés de quotes simples alors qu'ils contenaient des apostrophes littérales, notamment `n'utilise` et `l'exploitation`.
Le delta historique `deltas/0.1.0/alpha.2.md` reste immuable.
## Scope
REPLACE :
```text
VERSION
docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md
```
ADD :
```text
deltas/0.1.0/alpha.2.fix.1.md
```
DELETE : aucun.
Aucun owner normatif, profil technologique, skeleton, template, script d'audit ou test n'est modifié par ce correctif.
## Correction
La validation du fix n'utilise plus de `grep` pour les phrases contenant apostrophes, backticks ou autres caractères shell sensibles. Ces assertions sont regroupées dans un bloc Python littéral sous heredoc quoté.
Le fix vérifie à nouveau :
- le history `alpha.2` en `FAIL` ;
- la convention `rel.N` sans padding ;
- la conservation des quatre artefacts historiques `rel.001*` de `0.0.5` ;
- la distinction entre tranche de clôture et commit stable `X.Y.Z` ;
- l'indépendance de `publish.001` ;
- les horizons Clippy statique et deployment/operations différés ;
- l'absence de réservation prématurée de `0.1.1` ;
- les tests/audits globaux et le scope exact du fix.
## Validation opérateur
Après application du history `FAIL`, commit/push de `alpha.2`, puis application du présent delta :
```bash
test "$(cat VERSION)" = '0.1.0-alpha.2.fix.1'
git cat-file -e HEAD:history/0.1.0/alpha.2.md
test -f history/0.1.0/alpha.2.md
test -f deltas/0.1.0/alpha.2.md
test -f deltas/0.1.0/alpha.2.fix.1.md
test ! -e history/0.1.0/alpha.2.fix.1.md
grep -A2 '^## Statut$' history/0.1.0/alpha.2.md | grep -Fx 'FAIL'
grep -Fx '<!-- version: 5 -->' docs/rules/200-GOVERNANCE.md
grep -Fx '<!-- version: 6 -->' docs/rules/210-WORKFLOW.md
grep -Fx '<!-- version: 3 -->' docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md
python3 -B - <<'PYGATE'
from pathlib import Path
import re
history = Path('history/0.1.0/alpha.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')
workflow = Path('docs/rules/210-WORKFLOW.md').read_text(encoding='utf-8')
plan = Path('docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md').read_text(encoding='utf-8')
roadmap = Path('ROADMAP.md').read_text(encoding='utf-8')
for phrase in (
'rel.1',
'rel.1.fix.1',
"représentation canonique n'utilise pas de zéro de padding",
'première tranche de clôture PASS',
'Le commit `X.Y.Z` MUST',
):
assert phrase in governance or phrase in workflow, phrase
for phrase in (
'history rel.1 FAIL / PARTIAL / BLOCKED',
'premier history rel.N[/fix.M] PASS qui établit réellement la stable',
'La présente règle ne renomme pas `publish.001`',
):
assert phrase in workflow, phrase
for phrase in (
'sous-ensemble des conventions Rust/Clippy',
"série dédiée au déploiement et à l'exploitation",
'### alpha.2.fix.1 — correction de la gate `rel.N`',
):
assert phrase in plan, phrase
for path in (
Path('deltas/0.0.5/rel.001.md'),
Path('history/0.0.5/rel.001.md'),
Path('deltas/0.0.5/rel.001.fix.1.md'),
Path('history/0.0.5/rel.001.fix.1.md'),
):
assert path.is_file(), path
assert 'publish.001' in workflow
assert '- `( ) 0.1.1`' not in roadmap
print('0.1.0 alpha.2.fix.1 rel gate audit: clean (failed gate preserved, rel.N content reconfirmed, shell-sensitive assertions safe)')
PYGATE
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
git diff --check
git add VERSION docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md \
deltas/0.1.0/alpha.2.fix.1.md
git diff --cached --check
git status --short
```
Le scope indexé attendu avant ajout du history du fix est exactement :
```text
M VERSION
A deltas/0.1.0/alpha.2.fix.1.md
M docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md
```
## Revue opérateur complémentaire
Confirmer que :
- le `FAIL` de `alpha.2` est conservé historiquement ;
- `docs/rules/200-GOVERNANCE.md` et `docs/rules/210-WORKFLOW.md` ne sont pas modifiés par le fix ;
- le delta historique `alpha.2.md` n'est pas réécrit ;
- aucun élément du handoff automatique réservé à `alpha.3` n'est absorbé dans le correctif ;
- aucun profil Web, Java/Android, WASM, Tauri ou serveur n'est ajouté ou modifié.
## Transition
### PASS
Produire `history/0.1.0/alpha.2.fix.1.md`, l'appliquer puis committer/pousser le fix. Dans la même réponse, reprendre la trajectoire normale avec `0.1.0-alpha.3`, consacré au handoff automatique des commandes opérateur.
Après remise du history, fournir spontanément le bloc Git exact permettant de fermer `alpha.2.fix.1` avant application de `alpha.3`.
### FAIL
Consigner le diagnostic réel dans `history/0.1.0/alpha.2.fix.1.md` et rester dans `alpha.2.fix.M`. Le scope MUST rester limité à la correction de la gate `rel.N` tant qu'aucun défaut plus large ne justifie un REPLAN.

201
deltas/0.1.0/alpha.2.md Normal file
View File

@@ -0,0 +1,201 @@
<!-- file: deltas/0.1.0/alpha.2.md -->
<!-- version: 1 -->
# Delta 0.1.0-alpha.2 — clôture stable et identité `rel.N`
## Baseline
Baseline attendue : `0.1.0-alpha.1` committée avec `history/0.1.0/alpha.1.md` en `PASS`.
Cette tranche MUST être appliquée uniquement après le commit/push complet de `alpha.1` ; elle ne doit pas être superposée au workspace encore non committé de la gate précédente.
Version avant application :
```text
0.1.0-alpha.1
```
Version après application :
```text
0.1.0-alpha.2
```
## Objet
Corriger la convention normative de clôture stable avant diffusion plus large de PGR :
- utiliser `rel.1`, `rel.2`, etc. sans padding pour les nouvelles releases ;
- conserver sans renommage tous les artefacts historiques `rel.001*` déjà publiés ;
- distinguer le nom de la tranche de clôture de l'identité du commit stable ;
- rendre explicite qu'une clôture `FAIL`, `PARTIAL` ou `BLOCKED` conserve le suffixe opérationnel dans son commit ;
- rendre explicite que la première tranche `rel.N[/fix.M]` qui obtient réellement le `PASS` stable est committée sous `X.Y.Z` avant création du tag `vX.Y.Z`.
La tranche ne modifie aucun profil technologique, skeleton, template, script d'audit ou convention de publication post-tag `publish.001`.
## Scope
REPLACE :
```text
VERSION
docs/rules/200-GOVERNANCE.md
docs/rules/210-WORKFLOW.md
docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md
```
ADD :
```text
deltas/0.1.0/alpha.2.md
```
DELETE : aucun.
Le plan actif est révisé parce qu'il enregistre `alpha.1 PASS` et deux horizons différés explicitement décidés pendant la session — audit Python d'un sous-ensemble Clippy après Games/KSP et future famille deployment/operations — sans leur attribuer de numéro ni les absorber dans `0.1.0`.
Aucun `history/0.1.0/alpha.2.md` n'est anticipé avant la gate opérateur.
## Convention obtenue
La représentation future canonique est :
```text
rel.1
rel.1.fix.1
rel.2
...
```
Pour le message du commit de clôture, le défaut PGR devient :
```text
history rel.1 FAIL / PARTIAL / BLOCKED
-> X.Y.Z-rel.1
history rel.1.fix.1 FAIL / PARTIAL / BLOCKED
-> X.Y.Z-rel.1.fix.1
premier history rel.N[/fix.M] PASS établissant réellement la stable
-> X.Y.Z
```
`VERSION` MAY déjà être `X.Y.Z` pendant ces tranches de fermeture : `rel.N` n'est pas une prerelease SemVer. Le tag `vX.Y.Z` intervient uniquement après le commit final `X.Y.Z` contenant le history `PASS` stable.
Les fichiers historiques comme :
```text
deltas/0.0.5/rel.001.md
history/0.0.5/rel.001.md
deltas/0.0.5/rel.001.fix.1.md
history/0.0.5/rel.001.fix.1.md
```
restent intacts.
## Validation opérateur
Après application sur le commit de `0.1.0-alpha.1`, depuis la racine du dépôt :
```bash
test "$(cat VERSION)" = '0.1.0-alpha.2'
test -f history/0.1.0/alpha.1.md
test -f deltas/0.1.0/alpha.2.md
test ! -e history/0.1.0/alpha.2.md
grep -Fx '<!-- version: 5 -->' docs/rules/200-GOVERNANCE.md
grep -Fx '<!-- version: 6 -->' docs/rules/210-WORKFLOW.md
grep -Fx '<!-- version: 2 -->' docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md
grep -F 'représentation canonique n'utilise pas de zéro de padding' docs/rules/200-GOVERNANCE.md
grep -F 'première tranche de clôture PASS' docs/rules/200-GOVERNANCE.md
grep -F 'history rel.1 FAIL / PARTIAL / BLOCKED' docs/rules/210-WORKFLOW.md
grep -F 'premier history rel.N[/fix.M] PASS qui établit réellement la stable' docs/rules/210-WORKFLOW.md
grep -F 'La présente règle ne renomme pas `publish.001`' docs/rules/210-WORKFLOW.md
grep -F 'sous-ensemble des conventions Rust/Clippy' docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md
grep -F 'série dédiée au déploiement et à l'exploitation' docs/plans/006-V0_1_0_REUSABLE_BASELINE_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.1.0/alpha.1.md').read_text(encoding='utf-8')
assert re.search(r'## Statut\s+PASS\s', history)
governance = Path('docs/rules/200-GOVERNANCE.md').read_text(encoding='utf-8')
workflow = Path('docs/rules/210-WORKFLOW.md').read_text(encoding='utf-8')
plan = Path('docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md').read_text(encoding='utf-8')
for phrase in (
'rel.1',
'rel.1.fix.1',
'représentation canonique n\'utilise pas de zéro de padding',
'première tranche de clôture PASS',
'Le commit `X.Y.Z` MUST',
):
assert phrase in governance or phrase in workflow, phrase
for path in (
Path('deltas/0.0.5/rel.001.md'),
Path('history/0.0.5/rel.001.md'),
Path('deltas/0.0.5/rel.001.fix.1.md'),
Path('history/0.0.5/rel.001.fix.1.md'),
):
assert path.is_file(), path
assert 'publish.001' in workflow
assert 'La présente règle ne renomme pas `publish.001`' in workflow
assert 'sous-ensemble des conventions Rust/Clippy' in plan
assert "série dédiée au déploiement et à l'exploitation" in plan
assert '- `( ) 0.1.1`' not in Path('ROADMAP.md').read_text(encoding='utf-8')
print('0.1.0 alpha.2 rel identity audit: clean (rel.N unpadded, historical rel.001 preserved, stable commit identity explicit)')
PY
git diff --check
git add VERSION docs/rules/200-GOVERNANCE.md docs/rules/210-WORKFLOW.md \
docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md \
deltas/0.1.0/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.1.0/alpha.2.md
M docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md
M docs/rules/200-GOVERNANCE.md
M docs/rules/210-WORKFLOW.md
```
La revue opérateur doit également confirmer que :
- aucune occurrence historique `rel.001*` n'a été renommée ;
- `publish.001` reste une convention indépendante et n'est pas modifiée par cette tranche ;
- aucune commande de handoff Git automatique n'est encore rendue normative ici — ce sujet appartient à `alpha.3` ;
- les horizons Clippy statique et deployment/operations restent de simples candidats différés dans le plan ;
- aucun profil Web, Java/Android, WASM, Tauri ou serveur n'est ajouté ou modifié.
## Transition
### PASS
Produire `history/0.1.0/alpha.2.md` à partir des résultats réellement observés. Dans la même réponse, si aucune décision nouvelle n'est ouverte, préparer séparément `0.1.0-alpha.3` consacré au handoff automatique des commandes opérateur après history, au commit/push, au tag stable et aux preuves requises pour `publish.001`.
Après remise du history, fournir déjà spontanément le bloc Git exact de fermeture de `alpha.2`, conformément à la décision acquise, même si `alpha.3` sera la tranche qui rendra ce comportement normatif.
### FAIL
Consigner le résultat réel dans le history puis ouvrir `0.1.0-alpha.2.fix.1` ou un REPLAN selon la cause. Aucun élément du handoff automatique prévu pour `alpha.3` ne doit être absorbé silencieusement dans le fix.

View File

@@ -0,0 +1,167 @@
<!-- file: deltas/0.1.0/alpha.3.fix.1.md -->
<!-- version: 1 -->
# Delta 0.1.0-alpha.3.fix.1 — correction de la gate du handoff opérateur
## Baseline et version
Baseline attendue : commit opérateur de `0.1.0-alpha.3`, réalisé après application de `history/0.1.0/alpha.3.md` avec statut `FAIL`.
Le hash de ce commit n'est pas anticipé.
Version avant application :
```text
0.1.0-alpha.3
```
Version après application :
```text
0.1.0-alpha.3.fix.1
```
## Objet
Corriger uniquement la syntaxe défectueuse de la gate opérateur de `alpha.3`.
Le contenu normatif de `docs/rules/210-WORKFLOW.md`, le pattern `docs/templates/006-OPERATOR_COMMAND_HANDOFF.md`, l'index `docs/000-README.md` et le delta historique `deltas/0.1.0/alpha.3.md` restent inchangés.
Le défaut observé était un littéral Python entouré de quotes simples alors que son texte contenait l'apostrophe de `d'une` :
```python
'## Fermeture d'une tranche non stable'
```
Le fix rend les assertions textuelles syntaxiquement sûres sans modifier ce qu'elles vérifient.
## Scope
REPLACE :
```text
VERSION
docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md
```
ADD :
```text
deltas/0.1.0/alpha.3.fix.1.md
```
DELETE : aucun.
Aucun owner normatif, template, profil technologique, skeleton, script d'audit ou test n'est modifié par ce correctif.
## Validation opérateur
Après application du history `FAIL`, commit/push de `alpha.3`, puis application du présent delta :
```bash
test "$(cat VERSION)" = '0.1.0-alpha.3.fix.1'
git cat-file -e HEAD:history/0.1.0/alpha.3.md
test -f history/0.1.0/alpha.3.md
test -f deltas/0.1.0/alpha.3.md
test -f deltas/0.1.0/alpha.3.fix.1.md
test -f docs/templates/006-OPERATOR_COMMAND_HANDOFF.md
test ! -e history/0.1.0/alpha.3.fix.1.md
grep -A2 '^## Statut$' history/0.1.0/alpha.3.md | grep -Fx 'FAIL'
grep -Fx '<!-- version: 7 -->' docs/rules/210-WORKFLOW.md
grep -Fx '<!-- version: 1 -->' docs/templates/006-OPERATOR_COMMAND_HANDOFF.md
grep -Fx '<!-- version: 19 -->' docs/000-README.md
grep -Fx '<!-- version: 5 -->' docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md
python3 -B - <<'PYGATE'
from pathlib import Path
import re
history = Path('history/0.1.0/alpha.3.md').read_text(encoding='utf-8')
assert re.search(r'## Statut\s+FAIL\s', history)
workflow = Path('docs/rules/210-WORKFLOW.md').read_text(encoding='utf-8')
template = Path('docs/templates/006-OPERATOR_COMMAND_HANDOFF.md').read_text(encoding='utf-8')
plan = Path('docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md').read_text(encoding='utf-8')
index = Path('docs/000-README.md').read_text(encoding='utf-8')
workflow_phrases = (
'## Remise automatique des commandes opérateur',
'le générateur MUST remettre spontanément les commandes nécessaires pour fermer cette tranche',
'Le générateur MUST NOT inventer un remote, une branche ou une politique de tag non établis.',
'première clôture `rel.N[/fix.M]` qui établit réellement la stable',
'refs/tags/vX.Y.Z^{}',
'Le rapport `publish.*` est produit seulement à partir des artefacts et preuves réellement disponibles après publication.',
'../templates/006-OPERATOR_COMMAND_HANDOFF.md',
)
for phrase in workflow_phrases:
assert phrase in workflow, phrase
template_phrases = (
"## Fermeture d'une tranche non stable",
'git diff --cached --check',
'git push <remote> <branche>',
"## Tranche échouée suivie d'un fix",
'## Première clôture qui établit réellement la stable',
'git tag -a vX.Y.Z -m "vX.Y.Z"',
"git ls-remote <remote> 'refs/tags/vX.Y.Z^{}'",
'## Remise nécessaire pour `publish.*`',
'## Après `publish.* PASS`',
)
for phrase in template_phrases:
assert phrase in template, phrase
assert '006-OPERATOR_COMMAND_HANDOFF.md' in index
assert 'Statut opérateur : **FAIL**.' in plan
assert '### alpha.3.fix.1 — correction de la gate du handoff opérateur' in plan
print('0.1.0 alpha.3.fix.1 operator handoff gate: clean (alpha.3 FAIL preserved, workflow/template reconfirmed, Python literals safe)')
PYGATE
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
git diff --check
git add VERSION docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md \
deltas/0.1.0/alpha.3.fix.1.md
git diff --cached --check
git status --short
```
Le scope indexé attendu avant ajout du history du fix est exactement :
```text
M VERSION
A deltas/0.1.0/alpha.3.fix.1.md
M docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md
```
## Revue opérateur complémentaire
Confirmer que :
- le `FAIL` de `alpha.3` est conservé historiquement ;
- `docs/rules/210-WORKFLOW.md`, `docs/templates/006-OPERATOR_COMMAND_HANDOFF.md` et `docs/000-README.md` ne sont pas modifiés par le fix ;
- le delta historique `alpha.3.md` n'est pas réécrit ;
- aucun contenu prévu pour `alpha.4` n'est absorbé dans le correctif ;
- aucun profil technologique n'est ajouté ou modifié.
## Transition
### PASS
Produire `history/0.1.0/alpha.3.fix.1.md`, l'appliquer puis committer/pousser le fix. Reprendre ensuite la trajectoire normale avec `0.1.0-alpha.4`, consacré à l'adoption proportionnée de PGR par un projet existant.
Le handoff remis après ce PASS doit lui-même suivre le contrat `210-WORKFLOW` et `006-OPERATOR_COMMAND_HANDOFF.md` désormais reconfirmé.
### FAIL
Consigner le diagnostic réel dans `history/0.1.0/alpha.3.fix.1.md` et rester dans `alpha.3.fix.M`. Le scope MUST rester limité à la correction de la gate du handoff tant qu'aucun défaut plus large ne justifie un REPLAN.

185
deltas/0.1.0/alpha.3.md Normal file
View File

@@ -0,0 +1,185 @@
<!-- file: deltas/0.1.0/alpha.3.md -->
<!-- version: 1 -->
# Delta 0.1.0-alpha.3 — handoff automatique des commandes opérateur
## Baseline et version
Baseline attendue : commit opérateur de `0.1.0-alpha.2.fix.1`, réalisé après application de `history/0.1.0/alpha.2.fix.1.md` avec statut `PASS`.
Le hash de ce commit n'est pas anticipé.
Version avant application :
```text
0.1.0-alpha.2.fix.1
```
Version après application :
```text
0.1.0-alpha.3
```
## Objet
Rendre normative la remise automatique des commandes opérateur après chaque history et pendant la publication stable.
La tranche doit supprimer le besoin récurrent de demander séparément :
```text
quel message de commit utiliser ?
quand pousser ?
quand appliquer le prochain delta ?
quelles commandes exécuter pour le tag ?
quelles preuves fournir pour produire publish.* ?
```
Le workflow reste l'owner normatif. Un nouveau pattern documentaire fournit uniquement une forme de rendu réutilisable.
## Scope
REPLACE :
```text
VERSION
docs/000-README.md
docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md
docs/rules/210-WORKFLOW.md
```
ADD :
```text
docs/templates/006-OPERATOR_COMMAND_HANDOFF.md
deltas/0.1.0/alpha.3.md
```
DELETE : aucun.
## Changements normatifs
`210-WORKFLOW.md` impose désormais qu'après production d'un history destiné à l'opérateur, le générateur fournisse spontanément le bloc de fermeture correspondant. Le rendu doit utiliser les valeurs Git réelles lorsqu'elles sont établies et ne doit jamais inventer branche, remote ou politique de tag.
Le contrat distingue explicitement :
- fermeture ordinaire `history -> commit/push -> delta suivant` ;
- fermeture `FAIL/PARTIAL/BLOCKED -> commit de la tranche -> fix` ;
- première clôture `rel.N[/fix.M] PASS -> commit X.Y.Z -> tag` ;
- vérification d'un tag annoté avec distinction objet tag / commit déréférencé ;
- artefacts et preuves que l'opérateur doit fournir pour produire `publish.*` ;
- message manuel de reprise après `publish.* PASS` déjà possédé par `003-NEW_SESSION_PROMPT.md`.
## Nouveau pattern documentaire
`docs/templates/006-OPERATOR_COMMAND_HANDOFF.md` fournit les blocs adaptables pour :
```text
history ZIP
commit / push
fix ou delta suivant
tag stable
preuves post-tag
transition après publish.*
```
Il ne fixe pas `origin`, `master` ou une forge particulière comme valeurs universelles. Une commande concrète livrée à l'opérateur doit employer les valeurs déjà établies pour le projet.
## Validation opérateur
Exécuter depuis la racine du workspace après application du delta :
```bash
test "$(cat VERSION)" = '0.1.0-alpha.3'
test -f history/0.1.0/alpha.2.fix.1.md
test -f deltas/0.1.0/alpha.3.md
test -f docs/templates/006-OPERATOR_COMMAND_HANDOFF.md
test ! -e history/0.1.0/alpha.3.md
grep -Fx '<!-- version: 7 -->' docs/rules/210-WORKFLOW.md
grep -Fx '<!-- version: 19 -->' docs/000-README.md
grep -Fx '<!-- version: 4 -->' docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md
python3 -B - <<'PYGATE'
from pathlib import Path
import re
history = Path('history/0.1.0/alpha.2.fix.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')
template = Path('docs/templates/006-OPERATOR_COMMAND_HANDOFF.md').read_text(encoding='utf-8')
plan = Path('docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md').read_text(encoding='utf-8')
index = Path('docs/000-README.md').read_text(encoding='utf-8')
for phrase in (
'## Remise automatique des commandes opérateur',
"le générateur MUST remettre spontanément les commandes nécessaires pour fermer cette tranche",
'Le générateur MUST NOT inventer un remote, une branche ou une politique de tag non établis.',
'première clôture `rel.N[/fix.M]` qui établit réellement la stable',
'refs/tags/vX.Y.Z^{}',
'Le rapport `publish.*` est produit seulement à partir des artefacts et preuves réellement disponibles après publication.',
'../templates/006-OPERATOR_COMMAND_HANDOFF.md',
):
assert phrase in workflow, phrase
for phrase in (
'## Fermeture d'une tranche non stable',
'git diff --cached --check',
'git push <remote> <branche>',
'## Tranche échouée suivie d'un fix',
'## Première clôture qui établit réellement la stable',
'git tag -a vX.Y.Z -m "vX.Y.Z"',
"git ls-remote <remote> 'refs/tags/vX.Y.Z^{}'",
'## Remise nécessaire pour `publish.*`',
'## Après `publish.* PASS`',
):
assert phrase in template, phrase
assert '006-OPERATOR_COMMAND_HANDOFF.md' in index
assert 'Statut opérateur : **PASS**.' in plan
assert '### alpha.3 — handoff automatique des commandes opérateur' in plan
print('0.1.0 alpha.3 operator handoff audit: clean (history-to-commit, stable tag and publish evidence rendered explicitly)')
PYGATE
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
git diff --check
git add VERSION docs/000-README.md \
docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md \
docs/rules/210-WORKFLOW.md \
docs/templates/006-OPERATOR_COMMAND_HANDOFF.md \
deltas/0.1.0/alpha.3.md
git diff --cached --check
git status --short
```
## Résultat attendu
La gate est `PASS` si :
- le history `alpha.2.fix.1` est présent et `PASS` ;
- le workflow impose la remise spontanée des commandes et interdit d'inventer les paramètres Git ;
- le pattern couvre tranche ordinaire, échec + fix, stable/tag et preuves `publish.*` ;
- la vérification d'un tag annoté distingue objet tag et commit déréférencé ;
- les `48` tests existants restent propres ;
- les trois audits Markdown restent propres ;
- le scope Git correspond exactement aux six fichiers de `alpha.3`.
## Transition
Si `PASS` :
1. produire `history/0.1.0/alpha.3.md` ;
2. remettre automatiquement le bloc opérateur conforme au nouveau pattern pour committer/pousser `0.1.0-alpha.3` ;
3. préparer `0.1.0-alpha.4`, consacré à l'adoption proportionnée de PGR par un projet existant.
Si `FAIL` : conserver le history réel et corriger uniquement la cause dans `alpha.3.fix.N`, sauf preuve imposant un REPLAN.

232
deltas/0.1.0/alpha.4.md Normal file
View File

@@ -0,0 +1,232 @@
<!-- file: deltas/0.1.0/alpha.4.md -->
<!-- version: 1 -->
# Delta 0.1.0-alpha.4 — adoption PGR d’un projet existant
## Baseline et version
Baseline attendue : commit opérateur de `0.1.0-alpha.3.fix.1`, réalisé après application de `history/0.1.0/alpha.3.fix.1.md` avec statut `PASS`.
Le hash de ce commit n’est pas anticipé.
Version avant application :
```text
0.1.0-alpha.3.fix.1
```
Version après application :
```text
0.1.0-alpha.4
```
## Objet
Formaliser le contrat d’adoption de PGR par un projet existant, distinct de l’instanciation d’un nouveau projet.
La tranche introduit :
- un owner normatif `230-ADOPTION.md` ;
- un pattern documentaire `007-EXISTING_PROJECT_ADOPTION.md` ;
- la représentation architecturale du flux d’adoption ;
- les index nécessaires pour rendre ces artefacts découvrables ;
- le mapping canonique `ADOPT / KEEP-LOCAL / OVERRIDE / DEFER` ;
- la préservation explicite de l’historique antérieur au point d’adoption.
Cette tranche ne migre ni Games ni KSP. Elle ne crée aucun nouveau profil Web, Android, Tauri, WASM ou serveur.
## Scope
REPLACE :
```text
VERSION
RULES.md
docs/000-README.md
docs/architecture/002-GOVERNANCE_ARCHITECTURE.md
docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md
docs/rules/000-README.md
```
ADD :
```text
deltas/0.1.0/alpha.4.md
docs/rules/230-ADOPTION.md
docs/templates/007-EXISTING_PROJECT_ADOPTION.md
```
DELETE : aucun.
Les profils technologiques, skeletons existants, scripts d’audit, tests et `ROADMAP.md` restent inchangés.
## Décisions normatives
### Adoption distincte de l’instanciation
Un projet existant part de sa baseline réelle. Un skeleton MAY servir de référence de comparaison, mais PGR ne prétend pas que le dépôt a été créé depuis ce skeleton.
L’adoption ne doit pas imposer toute la bibliothèque PGR ni réécrire l’historique pour simuler une conformité passée.
### Classification canonique
Chaque owner ou contrat candidat dans le scope d’adoption est classifié selon :
```text
ADOPT
KEEP-LOCAL
OVERRIDE
DEFER
```
`KEEP-LOCAL` préserve une décision locale qui n’a pas besoin d’être remplacée. `OVERRIDE` remplace ou raffine explicitement une règle PGR applicable et doit porter scope et justification. `DEFER` enregistre un report réel et ne peut pas être présenté comme une adoption terminée.
### Migration progressive
L’adoption SHOULD être découpée en tranches validables et proportionnées lorsque cela réduit le risque. L’adoption d’un profil n’entraîne pas automatiquement celle des profils voisins.
Les conventions nouvelles commencent au point d’adoption établi ; les commits, tags, histories et autres snapshots antérieurs restent historiques.
## Validation opérateur
Après application du history `PASS`, commit/push de `alpha.3.fix.1`, puis application du présent delta :
```bash
test "$(cat VERSION)" = '0.1.0-alpha.4'
git cat-file -e HEAD:history/0.1.0/alpha.3.fix.1.md
test -f history/0.1.0/alpha.3.fix.1.md
test -f deltas/0.1.0/alpha.4.md
test -f docs/rules/230-ADOPTION.md
test -f docs/templates/007-EXISTING_PROJECT_ADOPTION.md
test ! -e history/0.1.0/alpha.4.md
grep -A2 '^## Statut$' history/0.1.0/alpha.3.fix.1.md | grep -Fx 'PASS'
grep -Fx '<!-- version: 12 -->' RULES.md
grep -Fx '<!-- version: 14 -->' docs/rules/000-README.md
grep -Fx '<!-- version: 20 -->' docs/000-README.md
grep -Fx '<!-- version: 4 -->' docs/architecture/002-GOVERNANCE_ARCHITECTURE.md
grep -Fx '<!-- version: 1 -->' docs/rules/230-ADOPTION.md
grep -Fx '<!-- version: 1 -->' docs/templates/007-EXISTING_PROJECT_ADOPTION.md
grep -Fx '<!-- version: 6 -->' docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md
python3 -B - <<'PYGATE'
from pathlib import Path
import re
history = Path('history/0.1.0/alpha.3.fix.1.md').read_text(encoding='utf-8')
rules = Path('RULES.md').read_text(encoding='utf-8')
rules_index = Path('docs/rules/000-README.md').read_text(encoding='utf-8')
index = Path('docs/000-README.md').read_text(encoding='utf-8')
architecture = Path('docs/architecture/002-GOVERNANCE_ARCHITECTURE.md').read_text(encoding='utf-8')
adoption = Path('docs/rules/230-ADOPTION.md').read_text(encoding='utf-8')
template = Path('docs/templates/007-EXISTING_PROJECT_ADOPTION.md').read_text(encoding='utf-8')
plan = Path('docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md').read_text(encoding='utf-8')
roadmap = Path('ROADMAP.md').read_text(encoding='utf-8')
assert re.search(r'## Statut\s+PASS\s', history)
for phrase in (
'ADOPT',
'KEEP-LOCAL',
'OVERRIDE',
'DEFER',
'baseline autoritaire',
'Migration progressive',
'Préservation de l’historique',
'MUST NOT demander de réécrire des commits, tags, histories, changelogs',
'Un skeleton PGR MAY servir de checklist de comparaison pour un projet existant.',
'../templates/007-EXISTING_PROJECT_ADOPTION.md',
):
assert phrase in adoption, phrase
for phrase in (
'## Baseline autoritaire',
'## Mapping d’adoption',
'ADOPT / KEEP-LOCAL / OVERRIDE / DEFER',
'## Découpage de migration',
'## Historique et compatibilité',
'## Validation de sortie',
):
assert phrase in template, phrase
for phrase in (
'## Adoption d’un projet existant',
'ADOPT / KEEP-LOCAL / OVERRIDE / DEFER',
'projet autonome avec historique préservé',
'../rules/230-ADOPTION.md',
):
assert phrase in architecture, phrase
assert 'docs/rules/230-ADOPTION.md' in rules
assert '230-ADOPTION.md' in rules_index
assert 'rules/230-ADOPTION.md' in index
assert 'templates/007-EXISTING_PROJECT_ADOPTION.md' in index
assert 'Statut opérateur : **PASS**.' in plan
assert 'Statut opérateur : **à valider**.' in plan
assert 'Cette tranche ne migre ni Games ni KSP.' in Path('deltas/0.1.0/alpha.4.md').read_text(encoding='utf-8')
assert '- `( ) 0.1.1`' not in roadmap
print('0.1.0 alpha.4 existing-project adoption audit: clean (baseline, owner mapping, decision classes, progressive migration and history preservation explicit)')
PYGATE
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
git diff --check
git add VERSION RULES.md docs/000-README.md \
docs/architecture/002-GOVERNANCE_ARCHITECTURE.md \
docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md \
docs/rules/000-README.md docs/rules/230-ADOPTION.md \
docs/templates/007-EXISTING_PROJECT_ADOPTION.md \
deltas/0.1.0/alpha.4.md
git diff --cached --check
git status --short
```
Le scope indexé attendu avant ajout du history de `alpha.4` est exactement :
```text
M RULES.md
M VERSION
A deltas/0.1.0/alpha.4.md
M docs/000-README.md
M docs/architecture/002-GOVERNANCE_ARCHITECTURE.md
M docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md
M docs/rules/000-README.md
A docs/rules/230-ADOPTION.md
A docs/templates/007-EXISTING_PROJECT_ADOPTION.md
```
## Revue opérateur complémentaire
Confirmer que :
- le contrat d’adoption n’impose pas tous les profils PGR à un projet existant ;
- `KEEP-LOCAL` n’est pas utilisé comme alias silencieux d’un override ;
- `OVERRIDE` exige bien scope et justification ;
- `DEFER` reste distinct d’un résultat adopté ;
- un skeleton sert seulement de référence de comparaison lorsqu’il est utile ;
- aucun historique du projet destinataire ne doit être réécrit pour rendre le passé rétroactivement conforme ;
- Games et KSP restent des futurs consommateurs, pas des dépendances de `0.1.0` ;
- aucun numéro futur `0.1.x` n’est réservé par cette tranche.
## Transition
### PASS
Produire `history/0.1.0/alpha.4.md`, l’appliquer puis remettre automatiquement les commandes de commit/push conformément à `210-WORKFLOW.md` et `006-OPERATOR_COMMAND_HANDOFF.md`.
Reprendre ensuite la trajectoire avec `0.1.0-alpha.5`, consacré à la réconciliation de la fondation, du skeleton Rust/Cargo et au dry-run de composition/adoption.
### FAIL
Consigner le diagnostic réel dans `history/0.1.0/alpha.4.md` et rester dans `alpha.4.fix.N` sauf REPLAN justifié. Le fix MUST rester borné au défaut réellement observé.

371
deltas/0.1.0/alpha.5.md Normal file
View File

@@ -0,0 +1,371 @@
<!-- file: deltas/0.1.0/alpha.5.md -->
<!-- version: 1 -->
# Delta 0.1.0-alpha.5 — baseline Rust/Cargo réutilisable et dry-run
## Baseline et version
Baseline attendue : commit opérateur de `0.1.0-alpha.4`, réalisé après application de `history/0.1.0/alpha.4.md` avec statut `PASS`.
Le hash de ce commit n’est pas anticipé.
Version avant application :
```text
0.1.0-alpha.4
```
Version après application :
```text
0.1.0-alpha.5
```
## Objet
Prouver que la première baseline Rust/Cargo de PGR est réellement réutilisable dans deux situations distinctes :
```text
NEW nouveau workspace gouverné depuis une baseline vide
ADOPTION workspace Rust existant conservant ses décisions locales légitimes
```
La tranche réconcilie les skeletons `001` / `002`, les guides des templates Rust/Cargo et la validation. Elle ajoute un contrat durable de dry-run, mais aucun générateur de projet permanent et aucun nouveau profil technologique.
Games et KSP ne servent pas de fixtures et ne sont pas modifiés.
## Scope
REPLACE :
```text
VERSION
docs/000-README.md
docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md
docs/skeletons/000-README.md
docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md
docs/skeletons/002-RUST_CARGO_WORKSPACE.md
docs/templates/001-RUST_CARGO_TOOLING.md
docs/templates/002-CARGO_MANIFESTS.md
docs/validation/001-VALIDATION_MATRIX.md
```
ADD :
```text
deltas/0.1.0/alpha.5.md
docs/validation/004-RUST_CARGO_BASELINE_DRY_RUN.md
```
DELETE : aucun.
Les templates techniques sous `templates/rust-cargo/`, les scripts d’audit, les profils Java/Android/Tauri, `ROADMAP.md` et `CHANGELOG.md` restent inchangés.
## Décisions
### Nouveau projet
Le chemin d’instanciation reste `001 + 002`. Les cinq templates techniques sont adaptés dans un répertoire temporaire, les placeholders sont résolus et une crate source triviale est créée uniquement pour permettre à Cargo de vérifier la baseline.
Le code temporaire du dry-run n’est pas ajouté aux templates PGR.
### Projet existant
Le chemin d’adoption passe par `230-ADOPTION.md`. Les skeletons et templates servent de checklists de comparaison et ne sont jamais copiés aveuglément.
Le dry-run doit inclure plusieurs décisions et prouver qu’un choix local classé `KEEP-LOCAL` ou `DEFER` reste inchangé.
### Autorité de la toolchain
La syntaxe TOML et les assertions structurelles peuvent être prévalidées avec Python. En revanche, le mode `NEW` complet exige Cargo : une absence de toolchain ne peut pas être convertie en `PASS`.
## Validation opérateur
Après application du history `PASS`, commit/push de `alpha.4`, puis application du présent delta :
```bash
test "$(cat VERSION)" = '0.1.0-alpha.5'
git cat-file -e HEAD:history/0.1.0/alpha.4.md
test -f history/0.1.0/alpha.4.md
test -f deltas/0.1.0/alpha.5.md
test -f docs/validation/004-RUST_CARGO_BASELINE_DRY_RUN.md
test ! -e history/0.1.0/alpha.5.md
grep -A2 '^## Statut$' history/0.1.0/alpha.4.md | grep -Fx 'PASS'
grep -Fx '<!-- version: 21 -->' docs/000-README.md
grep -Fx '<!-- version: 5 -->' docs/skeletons/000-README.md
grep -Fx '<!-- version: 4 -->' docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md
grep -Fx '<!-- version: 6 -->' docs/skeletons/002-RUST_CARGO_WORKSPACE.md
grep -Fx '<!-- version: 4 -->' docs/templates/001-RUST_CARGO_TOOLING.md
grep -Fx '<!-- version: 4 -->' docs/templates/002-CARGO_MANIFESTS.md
grep -Fx '<!-- version: 13 -->' docs/validation/001-VALIDATION_MATRIX.md
grep -Fx '<!-- version: 1 -->' docs/validation/004-RUST_CARGO_BASELINE_DRY_RUN.md
grep -Fx '<!-- version: 7 -->' docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md
```
Contrôle structurel et prévalidation TOML :
```bash
python3 -B - <<'PYGATE'
from pathlib import Path
import re
import tomllib
history = Path("history/0.1.0/alpha.4.md").read_text(encoding="utf-8")
foundation = Path("docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md").read_text(encoding="utf-8")
rust_skeleton = Path("docs/skeletons/002-RUST_CARGO_WORKSPACE.md").read_text(encoding="utf-8")
tooling = Path("docs/templates/001-RUST_CARGO_TOOLING.md").read_text(encoding="utf-8")
manifests = Path("docs/templates/002-CARGO_MANIFESTS.md").read_text(encoding="utf-8")
dryrun = Path("docs/validation/004-RUST_CARGO_BASELINE_DRY_RUN.md").read_text(encoding="utf-8")
plan = Path("docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md").read_text(encoding="utf-8")
roadmap = Path("ROADMAP.md").read_text(encoding="utf-8")
assert re.search(r"## Statut\s+PASS\s", history)
assert "../rules/230-ADOPTION.md" in foundation
assert "../rules/230-ADOPTION.md" in rust_skeleton
assert "004-RUST_CARGO_BASELINE_DRY_RUN.md" in rust_skeleton
assert "KEEP-LOCAL" in tooling
assert "ADOPT / KEEP-LOCAL / OVERRIDE / DEFER" in manifests
for phrase in (
"NEW nouveau projet",
"ADOPTION projet existant",
"cargo metadata --format-version 1 --no-deps",
"cargo clippy --workspace --all-targets --all-features -- -D warnings",
"KEEP-LOCAL",
"DEFER",
"ne constitue pas un `PASS` de la toolchain",
):
assert phrase in dryrun, phrase
for path in (
Path("templates/rust-cargo/Cargo.toml"),
Path("templates/rust-cargo/clippy.toml"),
Path("templates/rust-cargo/rustfmt.toml"),
Path("templates/rust-cargo/.cargo/config.toml"),
Path("templates/rust-cargo/crates/project-core-lib/Cargo.toml"),
):
with path.open("rb") as handle:
tomllib.load(handle)
assert "Statut opérateur : **PASS**." in plan
assert "Statut opérateur : **à valider**." in plan
assert "Games et KSP ne sont pas utilisés comme fixtures du dry-run." in plan
assert "- `( ) 0.1.1`" not in roadmap
print("0.1.0 alpha.5 structural/TOML audit: clean (NEW and ADOPTION paths explicit, templates parse, external corpora not required)")
PYGATE
```
Dry-run `NEW` avec la toolchain officielle :
```bash
python3 -B - <<'PYNEW'
from pathlib import Path
import shutil
import subprocess
import tempfile
import tomllib
cargo = shutil.which("cargo")
if cargo is None:
raise SystemExit("BLOCKED: cargo is required for the alpha.5 NEW dry-run")
source = Path("templates/rust-cargo")
with tempfile.TemporaryDirectory(prefix="pgr-alpha5-new-") as temporary:
root = Path(temporary)
(root / ".cargo").mkdir(parents=True)
(root / "crates/pgr-dryrun-core-lib/src").mkdir(parents=True)
shutil.copy2(source / "Cargo.toml", root / "Cargo.toml")
shutil.copy2(source / "clippy.toml", root / "clippy.toml")
shutil.copy2(source / "rustfmt.toml", root / "rustfmt.toml")
shutil.copy2(source / ".cargo/config.toml", root / ".cargo/config.toml")
shutil.copy2(source / "crates/project-core-lib/Cargo.toml", root / "crates/pgr-dryrun-core-lib/Cargo.toml")
workspace = (root / "Cargo.toml").read_text(encoding="utf-8")
workspace = workspace.replace("crates/project-core-lib", "crates/pgr-dryrun-core-lib")
workspace = workspace.replace('version = "0.1.0"', 'version = "9.9.9"')
(root / "Cargo.toml").write_text(workspace, encoding="utf-8")
member = (root / "crates/pgr-dryrun-core-lib/Cargo.toml").read_text(encoding="utf-8")
member = member.replace("project-core-lib", "pgr-dryrun-core-lib")
(root / "crates/pgr-dryrun-core-lib/Cargo.toml").write_text(member, encoding="utf-8")
config = (root / ".cargo/config.toml").read_text(encoding="utf-8")
config = config.replace("project-name", "pgr-alpha5-new")
(root / ".cargo/config.toml").write_text(config, encoding="utf-8")
(root / "crates/pgr-dryrun-core-lib/src/lib.rs").write_text(
"//! Minimal source used only by the PGR alpha.5 dry-run.\n\n"
"/// Returns the dry-run marker.\n"
"#[must_use]\n"
"pub const fn dry_run_marker() -> u32 {\n"
" return 1;\n"
"}\n",
encoding="utf-8",
)
for path in (
root / "Cargo.toml",
root / "clippy.toml",
root / "rustfmt.toml",
root / ".cargo/config.toml",
root / "crates/pgr-dryrun-core-lib/Cargo.toml",
):
with path.open("rb") as handle:
tomllib.load(handle)
text = path.read_text(encoding="utf-8")
assert "project-name" not in text
assert "project-core-lib" not in text
commands = (
[cargo, "metadata", "--format-version", "1", "--no-deps"],
[cargo, "fmt", "--all", "--", "--check"],
[cargo, "check", "--workspace"],
[cargo, "clippy", "--workspace", "--all-targets", "--all-features", "--", "-D", "warnings"],
)
for command in commands:
subprocess.run(command, cwd=root, check=True)
print("0.1.0 alpha.5 NEW dry-run: clean (temporary templates accepted by Cargo/rustfmt/Clippy)")
PYNEW
```
Dry-run `ADOPTION` non destructif :
```bash
python3 -B - <<'PYADOPT'
from pathlib import Path
import hashlib
import shutil
import subprocess
import tempfile
cargo = shutil.which("cargo")
if cargo is None:
raise SystemExit("BLOCKED: cargo is required for the alpha.5 ADOPTION dry-run")
valid_decisions = {"ADOPT", "KEEP-LOCAL", "OVERRIDE", "DEFER"}
with tempfile.TemporaryDirectory(prefix="pgr-alpha5-adoption-") as temporary:
root = Path(temporary)
(root / "crates/legacy-core-lib/src").mkdir(parents=True)
(root / "Cargo.toml").write_text(
'[workspace]\nresolver = "3"\nmembers = ["crates/legacy-core-lib"]\n\n'
'[workspace.package]\nversion = "2.3.4"\nedition = "2024"\npublish = false\n',
encoding="utf-8",
)
(root / "rustfmt.toml").write_text('edition = "2024"\nmax_width = 120\n', encoding="utf-8")
(root / "crates/legacy-core-lib/Cargo.toml").write_text(
'[package]\nname = "legacy-core-lib"\nversion.workspace = true\nedition.workspace = true\npublish.workspace = true\n',
encoding="utf-8",
)
(root / "crates/legacy-core-lib/src/lib.rs").write_text(
"//! Existing synthetic library.\n\n"
"/// Returns the existing marker.\n"
"#[must_use]\n"
"pub const fn existing_marker() -> u32 {\n"
" 7\n"
"}\n",
encoding="utf-8",
)
protected = (root / "Cargo.toml", root / "rustfmt.toml", root / "crates/legacy-core-lib/Cargo.toml")
before = {path: hashlib.sha256(path.read_bytes()).hexdigest() for path in protected}
decisions = {
"510-RUST_CARGO": "ADOPT",
"rustfmt.max_width=120": "KEEP-LOCAL",
"PGR external artifact configuration": "DEFER",
"strict crate-root export audit": "DEFER",
}
assert set(decisions.values()) <= valid_decisions
assert "KEEP-LOCAL" in decisions.values()
assert "DEFER" in decisions.values()
for command in (
[cargo, "metadata", "--format-version", "1", "--no-deps"],
[cargo, "fmt", "--all", "--", "--check"],
[cargo, "check", "--workspace"],
[cargo, "clippy", "--workspace", "--all-targets", "--all-features", "--", "-D", "warnings"],
):
subprocess.run(command, cwd=root, check=True)
after = {path: hashlib.sha256(path.read_bytes()).hexdigest() for path in protected}
assert before == after
assert "max_width = 120" in (root / "rustfmt.toml").read_text(encoding="utf-8")
assert not (root / ".cargo/config.toml").exists()
print("0.1.0 alpha.5 ADOPTION dry-run: clean (local KEEP-LOCAL/DEFER choices preserved, workspace remains valid)")
PYADOPT
```
Puis rejouer les preuves PGR :
```bash
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
git diff --check
git add VERSION docs/000-README.md \
docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md \
docs/skeletons/000-README.md \
docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md \
docs/skeletons/002-RUST_CARGO_WORKSPACE.md \
docs/templates/001-RUST_CARGO_TOOLING.md \
docs/templates/002-CARGO_MANIFESTS.md \
docs/validation/001-VALIDATION_MATRIX.md \
docs/validation/004-RUST_CARGO_BASELINE_DRY_RUN.md \
deltas/0.1.0/alpha.5.md
git diff --cached --check
git status --short
```
Le scope indexé attendu avant ajout du history de `alpha.5` est exactement :
```text
M VERSION
A deltas/0.1.0/alpha.5.md
M docs/000-README.md
M docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md
M docs/skeletons/000-README.md
M docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md
M docs/skeletons/002-RUST_CARGO_WORKSPACE.md
M docs/templates/001-RUST_CARGO_TOOLING.md
M docs/templates/002-CARGO_MANIFESTS.md
M docs/validation/001-VALIDATION_MATRIX.md
A docs/validation/004-RUST_CARGO_BASELINE_DRY_RUN.md
```
## Revue opérateur complémentaire
Confirmer que :
- le mode `NEW` n’introduit aucun `src/lib.rs` universel dans PGR ;
- le mode `ADOPTION` ne remplace pas les fichiers existants classés `KEEP-LOCAL` ou `DEFER` ;
- les templates techniques eux-mêmes restent inchangés dans cette tranche ;
- la réussite de la prévalidation Python n’est pas confondue avec la réussite Cargo ;
- Games et KSP ne sont ni modifiés ni nécessaires à la preuve ;
- aucun profil Java, Android, Tauri, Web, WASM ou serveur n’est matérialisé ;
- aucun numéro futur `0.1.x` n’est réservé.
## Transition
### PASS
Produire `history/0.1.0/alpha.5.md`, l’appliquer puis remettre automatiquement les commandes de commit/push.
Passer ensuite à `0.1.0-beta.1` pour la réconciliation finale et la revue d’horizon obligatoire avant RC.
### FAIL / BLOCKED
Consigner le résultat réel dans `history/0.1.0/alpha.5.md`. Un défaut des templates/skeletons reste dans `alpha.5.fix.N` sauf REPLAN. Une toolchain Cargo absente qui empêche les dry-runs requis doit être enregistrée `BLOCKED`, pas transformée en `PASS` par la seule prévalidation Python.

237
deltas/0.1.0/beta.1.md Normal file
View File

@@ -0,0 +1,237 @@
<!-- file: deltas/0.1.0/beta.1.md -->
<!-- version: 1 -->
# Delta 0.1.0-beta.1 — réconciliation finale et revue d'horizon
## Baseline et version
Baseline attendue : commit opérateur de `0.1.0-alpha.5`, réalisé après application de `history/0.1.0/alpha.5.md` avec statut `PASS`.
Le hash de ce commit n'est pas anticipé.
Version avant application :
```text
0.1.0-alpha.5
```
Version après application :
```text
0.1.0-beta.1
```
## Objet
Fermer la phase alpha de `0.1.0` en réconciliant la baseline réellement validée et en exécutant la revue d'horizon obligatoire avant RC.
La tranche :
- enregistre le `PASS` de `alpha.5` dans le plan actif ;
- matérialise `003-V0_1_0_HORIZON_REVIEW.md` ;
- engage dans `ROADMAP.md` uniquement les prochaines releases `0.1.x` suffisamment décidées ;
- conserve WASM, serveur Rust et deployment/operations sans réservation prématurée ;
- prépare `007-V0_1_1_START_PROMPT.md` pour la prochaine cible Web, sans l'activer avant publication de `v0.1.0`.
Aucun profil technique, template Rust/Cargo, skeleton ou script d'audit n'est modifié dans `beta.1`.
## Scope
REPLACE :
```text
VERSION
ROADMAP.md
docs/000-README.md
docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md
docs/studies/000-README.md
```
ADD :
```text
deltas/0.1.0/beta.1.md
docs/studies/003-V0_1_0_HORIZON_REVIEW.md
prompts/007-V0_1_1_START_PROMPT.md
```
DELETE : aucun.
`README.md`, `RULES.md`, `CHANGELOG.md`, les profils, skeletons, templates techniques et scripts restent inchangés.
## Décision de revue d'horizon
Les releases suivantes sont engagées :
```text
0.1.1 fondation frontend Web
0.1.2 réévaluation Java / Gradle
0.1.3 réévaluation Android
0.1.4 domaine Tauri et levée conditionnelle du DEFER
0.1.5 adoption Games
0.1.6 adoption KSP
0.1.7 audits Rust/Clippy statiques Python-only
```
Cette séquence applique le principe « une release/session par domaine cohérent » et conserve Games avant KSP.
`0.1.4` n'autorise pas par avance le skeleton Tauri : la release doit d'abord vérifier que `0.1.1` a réellement fourni les owners Web nécessaires.
WASM et serveur Rust/Actix ou alternative restent non numérotés. Le futur domaine deployment/operations reste un horizon majeur possible, notamment `0.4.x` ou `0.5.x`, sans réservation précise.
## Prochaine cible
Après stable `v0.1.0` et `publish.* PASS`, la prochaine cible engagée est :
```text
0.1.1 — fondation frontend Web
```
Le prompt `prompts/007-V0_1_1_START_PROMPT.md` demande un audit indépendant de la stable et du corpus Games réellement fourni. Il ne migre pas Games et ne crée ni Tauri, ni WASM, ni serveur Rust.
## Validation opérateur
Après application du history `PASS`, commit/push de `alpha.5`, puis application du présent delta :
```bash
test "$(cat VERSION)" = '0.1.0-beta.1'
git cat-file -e HEAD:history/0.1.0/alpha.5.md
test -f history/0.1.0/alpha.5.md
test -f deltas/0.1.0/beta.1.md
test -f docs/studies/003-V0_1_0_HORIZON_REVIEW.md
test -f prompts/007-V0_1_1_START_PROMPT.md
test ! -e history/0.1.0/beta.1.md
grep -A2 '^## Statut$' history/0.1.0/alpha.5.md | grep -Fx 'PASS'
grep -Fx '<!-- version: 9 -->' ROADMAP.md
grep -Fx '<!-- version: 22 -->' docs/000-README.md
grep -Fx '<!-- version: 8 -->' docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md
grep -Fx '<!-- version: 3 -->' docs/studies/000-README.md
grep -Fx '<!-- version: 1 -->' docs/studies/003-V0_1_0_HORIZON_REVIEW.md
grep -Fx '<!-- version: 1 -->' prompts/007-V0_1_1_START_PROMPT.md
```
Contrôle structurel de la revue :
```bash
python3 -B - <<'PYGATE'
from pathlib import Path
import re
history = Path("history/0.1.0/alpha.5.md").read_text(encoding="utf-8")
roadmap = Path("ROADMAP.md").read_text(encoding="utf-8")
plan = Path("docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md").read_text(encoding="utf-8")
study = Path("docs/studies/003-V0_1_0_HORIZON_REVIEW.md").read_text(encoding="utf-8")
prompt = Path("prompts/007-V0_1_1_START_PROMPT.md").read_text(encoding="utf-8")
tauri = Path("docs/studies/002-TAURI_SKELETON_DECISION.md").read_text(encoding="utf-8")
assert re.search(r"## Statut\s+PASS\s", history)
expected = {
"0.1.1": "fondation frontend Web",
"0.1.2": "Java/Maven/Gradle",
"0.1.3": "Android",
"0.1.4": "Tauri",
"0.1.5": "sasedev-games",
"0.1.6": "khadhroony-solana-project",
"0.1.7": "Rust/Clippy",
}
for version, phrase in expected.items():
assert f"- `( ) {version}`" in roadmap, version
assert phrase in roadmap, phrase
assert "- `( ) 0.1.8`" not in roadmap
assert "WASM" in roadmap
assert "serveur Web Rust / Actix Web ou alternative" in roadmap
assert "deployment & operations" in roadmap
assert "aucun numéro précis n'est réservé" in roadmap
for phrase in (
"`0.1.1` — fondation frontend Web",
"`0.1.5` — adoption de Games",
"`0.1.6` — adoption de KSP",
"`0.1.7` — audits Rust/Clippy statiques Python",
"Candidats laissés sans numéro",
"Déploiement et exploitation",
"La décision `DEFER` de `002-TAURI_SKELETON_DECISION.md` reste vraie pendant `0.1.0`.",
):
assert phrase in study, phrase
assert "Statut opérateur : **PASS**." in plan
assert "Statut opérateur : **à valider**." in plan
assert "0.1.7 audits Rust/Clippy statiques Python-only" in plan
assert "WASM, serveur Rust et deployment restent non numérotés." in plan
for phrase in (
"# Prompt de démarrage 0.1.1 — fondation frontend Web",
"games-v0.3.6.zip",
"TypeScript",
"Vite",
"Sass/CSS",
"Le skeleton Tauri reste `DEFER` pendant cette release.",
"0.1.2",
"0.1.3",
):
assert phrase in prompt, phrase
assert "DEFER" in tauri
print("0.1.0 beta.1 horizon review audit: clean (0.1.1..0.1.7 engaged, Tauri conditional, deferred domains remain unnumbered)")
PYGATE
```
Puis rejouer les preuves PGR :
```bash
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
git diff --check
git add VERSION ROADMAP.md docs/000-README.md \
docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md \
docs/studies/000-README.md \
docs/studies/003-V0_1_0_HORIZON_REVIEW.md \
prompts/007-V0_1_1_START_PROMPT.md \
deltas/0.1.0/beta.1.md
git diff --cached --check
git status --short
```
Le scope indexé attendu avant ajout du history de `beta.1` est exactement :
```text
M ROADMAP.md
M VERSION
A deltas/0.1.0/beta.1.md
M docs/000-README.md
M docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md
M docs/studies/000-README.md
A docs/studies/003-V0_1_0_HORIZON_REVIEW.md
A prompts/007-V0_1_1_START_PROMPT.md
```
## Revue opérateur complémentaire
Confirmer que :
- la roadmap n'engage pas un catalogue exhaustif de technologies ;
- chaque release `0.1.1` à `0.1.7` possède un domaine cohérent ;
- Games reste avant KSP ;
- le skeleton Tauri n'est pas présenté comme déjà autorisé ;
- WASM et serveur Rust restent réellement sans numéro ;
- deployment/operations n'est pas artificiellement fixé à `0.4.0` ou `0.5.0` ;
- `007-V0_1_1_START_PROMPT.md` ne doit être exécuté qu'après `v0.1.0` publié et vérifié ;
- aucun profil, skeleton technique ou script d'audit n'est ajouté/modifié dans cette tranche.
## Transition
PASS : produire `history/0.1.0/beta.1.md`, fermer la tranche avec le handoff opérateur automatique, puis préparer `0.1.0-rc.1`.
FAIL : conserver le résultat réel dans le history et corriger par `beta.1.fix.N` ou REPLAN si la revue macro elle-même doit changer.

333
deltas/0.1.0/rc.1.md Normal file
View File

@@ -0,0 +1,333 @@
<!-- file: deltas/0.1.0/rc.1.md -->
<!-- version: 1 -->
# Delta 0.1.0-rc.1 — gel du scope et gate de release candidate
## Baseline et version
Baseline attendue : commit opérateur de `0.1.0-beta.1`, réalisé après application de `history/0.1.0/beta.1.md` avec statut `PASS`.
Le hash de ce commit n'est pas anticipé.
Version avant application :
```text
0.1.0-beta.1
```
Version après application :
```text
0.1.0-rc.1
```
## Objet et gel
La RC gèle le scope fonctionnel de `0.1.0` sur :
- la fondation de gouvernance et les skeleton specifications réutilisables ;
- le socle Rust/Cargo, ses cinq templates techniques et les dry-runs `NEW` / `ADOPTION` ;
- le contrat d'adoption de projets existants `ADOPT / KEEP-LOCAL / OVERRIDE / DEFER` ;
- la convention de clôture stable `rel.N` sans zéro de padding et l'identité du premier commit stable `X.Y.Z` ;
- le handoff automatique des commandes opérateur, du commit/push au tag et à la preuve `publish.*` ;
- la revue d'horizon validée et le prompt `007` vers `0.1.1`.
Le changelog reçoit une entrée candidate `0.1.0` orientée utilisateurs. `ROADMAP.md`, `RULES.md`, les owners, profils, templates techniques, skeletons et scripts d'audit sont vérifiés mais non modifiés.
Aucun scope Web, Java/Gradle, Android, Tauri, WASM, serveur Rust, Games/KSP ou deployment/operations n'entre fonctionnellement dans cette RC au-delà des décisions de trajectoire déjà validées.
## Scope
REPLACE :
```text
VERSION
CHANGELOG.md
docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md
```
ADD :
```text
deltas/0.1.0/rc.1.md
```
DELETE : aucun.
Le history `beta.1` est livré séparément et MUST être appliqué/committé avant ce delta.
## Gate opérateur de release candidate
Après application du history `PASS` de `beta.1`, commit/push de `beta.1`, puis application du présent delta :
```bash
test "$(cat VERSION)" = '0.1.0-rc.1'
git cat-file -e HEAD:history/0.1.0/beta.1.md
test -f history/0.1.0/beta.1.md
test -f deltas/0.1.0/rc.1.md
test -f prompts/007-V0_1_1_START_PROMPT.md
test ! -e history/0.1.0/rc.1.md
grep -A2 '^## Statut$' history/0.1.0/beta.1.md | grep -Fx 'PASS'
grep -Fx '<!-- version: 10 -->' CHANGELOG.md
grep -Fx '## 0.1.0 (candidate)' CHANGELOG.md
grep -Fx '<!-- version: 9 -->' docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md
grep -Fx '<!-- version: 9 -->' ROADMAP.md
grep -Fx '<!-- version: 1 -->' prompts/007-V0_1_1_START_PROMPT.md
```
Contrôle d'intégration de la RC :
```bash
python3 -B - <<'PYGATE'
from pathlib import Path
import re
expected = {
"alpha.1.md": "PASS",
"alpha.2.md": "FAIL",
"alpha.2.fix.1.md": "PASS",
"alpha.3.md": "FAIL",
"alpha.3.fix.1.md": "PASS",
"alpha.4.md": "PASS",
"alpha.5.md": "PASS",
"beta.1.md": "PASS",
}
histories = {path.name for path in Path("history/0.1.0").glob("*.md")}
assert histories == set(expected), histories
for name, status in expected.items():
text = Path("history/0.1.0", 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.1.0").glob("*.md")}
assert deltas == set(expected) | {"rc.1.md"}, deltas
changelog = Path("CHANGELOG.md").read_text(encoding="utf-8")
assert "## 0.1.0 (candidate)" in changelog
section = changelog.split("## 0.1.0 (candidate)", 1)[1].split("## 0.0.5", 1)[0]
for phrase in (
"première baseline PGR réellement réutilisable",
"ADOPT / KEEP-LOCAL / OVERRIDE / DEFER",
"rel.N",
"publish.*",
"frontend Web",
):
assert phrase in section, phrase
for forbidden in ("alpha.2", "alpha.3", "beta.1", "rc.1"):
assert forbidden not in section, forbidden
workflow = Path("docs/rules/210-WORKFLOW.md").read_text(encoding="utf-8")
for phrase in (
"La famille `rel.N` utilise la représentation sans zéro de padding",
"première de ces tranches qui obtient réellement `PASS` est incluse dans le commit stable `X.Y.Z`",
"Le rapport `publish.*` est produit seulement à partir des artefacts et preuves réellement disponibles après publication.",
"../templates/006-OPERATOR_COMMAND_HANDOFF.md",
):
assert phrase in workflow, phrase
adoption = Path("docs/rules/230-ADOPTION.md").read_text(encoding="utf-8")
for phrase in ("ADOPT", "KEEP-LOCAL", "OVERRIDE", "DEFER", "Préservation de l’historique"):
assert phrase in adoption, phrase
rust_dryrun = Path("docs/validation/004-RUST_CARGO_BASELINE_DRY_RUN.md").read_text(encoding="utf-8")
assert "NEW nouveau projet" in rust_dryrun
assert "ADOPTION projet existant" in rust_dryrun
roadmap = Path("ROADMAP.md").read_text(encoding="utf-8")
for version in ("0.1.1", "0.1.2", "0.1.3", "0.1.4", "0.1.5", "0.1.6", "0.1.7"):
assert f"- `( ) {version}`" in roadmap, version
assert "- `( ) 0.1.8`" not in roadmap
assert "WASM" in roadmap
assert "serveur Web Rust / Actix Web ou alternative" in roadmap
assert "deployment & operations" in roadmap
prompt = Path("prompts/007-V0_1_1_START_PROMPT.md").read_text(encoding="utf-8")
for phrase in (
"archive source téléchargée depuis le tag Gitea `v0.1.0`",
"pgr-0.1.0-publish.001-report.md",
"0.1.1-alpha.1",
"games-v0.3.6.zip",
"TypeScript",
"Vite",
"Sass/CSS",
"Le skeleton Tauri reste `DEFER` pendant cette release.",
):
assert phrase in prompt, phrase
plan = Path("docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md").read_text(encoding="utf-8")
assert "### beta.1 — réconciliation finale et revue d'horizon\n\nStatut opérateur : **PASS**." in plan
assert "### rc.1 — release candidate\n\nStatut opérateur : **à valider**." in plan
assert "État : **validée `PASS` par la gate opérateur de `beta.1`**." in plan
print("0.1.0 rc.1 integration audit: clean (8 prior histories, frozen reusable baseline, candidate changelog, horizon and prompt 007 verified)")
PYGATE
```
Rejouer également les deux chemins Rust/Cargo avec la toolchain réelle :
```bash
python3 -B - <<'PYRUST'
from pathlib import Path
import hashlib
import shutil
import subprocess
import tempfile
import tomllib
cargo = shutil.which("cargo")
if cargo is None:
raise SystemExit("BLOCKED: cargo is required for the 0.1.0 RC Rust/Cargo release gate")
commands = (
[cargo, "metadata", "--format-version", "1", "--no-deps"],
[cargo, "fmt", "--all", "--", "--check"],
[cargo, "check", "--workspace"],
[cargo, "clippy", "--workspace", "--all-targets", "--all-features", "--", "-D", "warnings"],
)
source = Path("templates/rust-cargo")
with tempfile.TemporaryDirectory(prefix="pgr-rc1-new-") as temporary:
root = Path(temporary)
(root / ".cargo").mkdir(parents=True)
(root / "crates/pgr-rc-core-lib/src").mkdir(parents=True)
shutil.copy2(source / "Cargo.toml", root / "Cargo.toml")
shutil.copy2(source / "clippy.toml", root / "clippy.toml")
shutil.copy2(source / "rustfmt.toml", root / "rustfmt.toml")
shutil.copy2(source / ".cargo/config.toml", root / ".cargo/config.toml")
shutil.copy2(source / "crates/project-core-lib/Cargo.toml", root / "crates/pgr-rc-core-lib/Cargo.toml")
workspace = (root / "Cargo.toml").read_text(encoding="utf-8")
workspace = workspace.replace("crates/project-core-lib", "crates/pgr-rc-core-lib")
workspace = workspace.replace('version = "0.1.0"', 'version = "9.9.9"')
(root / "Cargo.toml").write_text(workspace, encoding="utf-8")
member = (root / "crates/pgr-rc-core-lib/Cargo.toml").read_text(encoding="utf-8")
member = member.replace("project-core-lib", "pgr-rc-core-lib")
(root / "crates/pgr-rc-core-lib/Cargo.toml").write_text(member, encoding="utf-8")
config = (root / ".cargo/config.toml").read_text(encoding="utf-8")
config = config.replace("project-name", "pgr-rc1-new")
(root / ".cargo/config.toml").write_text(config, encoding="utf-8")
(root / "crates/pgr-rc-core-lib/src/lib.rs").write_text(
"//! Minimal source used only by the PGR RC dry-run.\n\n"
"/// Returns the RC marker.\n"
"#[must_use]\n"
"pub const fn rc_marker() -> u32 {\n"
" return 1;\n"
"}\n",
encoding="utf-8",
)
for path in (
root / "Cargo.toml",
root / "clippy.toml",
root / "rustfmt.toml",
root / ".cargo/config.toml",
root / "crates/pgr-rc-core-lib/Cargo.toml",
):
with path.open("rb") as handle:
tomllib.load(handle)
text = path.read_text(encoding="utf-8")
assert "project-name" not in text
assert "project-core-lib" not in text
for command in commands:
subprocess.run(command, cwd=root, check=True)
with tempfile.TemporaryDirectory(prefix="pgr-rc1-adoption-") as temporary:
root = Path(temporary)
(root / "crates/legacy-core-lib/src").mkdir(parents=True)
(root / "Cargo.toml").write_text(
'[workspace]\nresolver = "3"\nmembers = ["crates/legacy-core-lib"]\n\n'
'[workspace.package]\nversion = "2.3.4"\nedition = "2024"\npublish = false\n',
encoding="utf-8",
)
(root / "rustfmt.toml").write_text('edition = "2024"\nmax_width = 120\n', encoding="utf-8")
(root / "crates/legacy-core-lib/Cargo.toml").write_text(
'[package]\nname = "legacy-core-lib"\nversion.workspace = true\nedition.workspace = true\npublish.workspace = true\n',
encoding="utf-8",
)
(root / "crates/legacy-core-lib/src/lib.rs").write_text(
"//! Existing synthetic library.\n\n"
"/// Returns the existing marker.\n"
"#[must_use]\n"
"pub const fn existing_marker() -> u32 {\n"
" 7\n"
"}\n",
encoding="utf-8",
)
protected = (root / "Cargo.toml", root / "rustfmt.toml", root / "crates/legacy-core-lib/Cargo.toml")
before = {path: hashlib.sha256(path.read_bytes()).hexdigest() for path in protected}
decisions = {
"510-RUST_CARGO": "ADOPT",
"rustfmt.max_width=120": "KEEP-LOCAL",
"PGR external artifact configuration": "DEFER",
"strict crate-root export audit": "DEFER",
}
assert set(decisions.values()) <= {"ADOPT", "KEEP-LOCAL", "OVERRIDE", "DEFER"}
for command in commands:
subprocess.run(command, cwd=root, check=True)
after = {path: hashlib.sha256(path.read_bytes()).hexdigest() for path in protected}
assert before == after
assert "max_width = 120" in (root / "rustfmt.toml").read_text(encoding="utf-8")
print("0.1.0 rc.1 Rust/Cargo release dry-runs: clean (NEW and ADOPTION accepted by Cargo/rustfmt/Clippy)")
PYRUST
```
Puis la suite PGR complète :
```bash
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
git diff --check
git add VERSION CHANGELOG.md \
docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md \
deltas/0.1.0/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.1.0/rc.1.md
M docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md
```
## Revue opérateur complémentaire
Confirmer que :
- le changelog décrit les capacités de `0.1.0` et non ses tranches internes ;
- aucune règle/profil/template/skeleton/audit fonctionnel nouveau n'entre dans la RC ;
- `ROADMAP.md` conserve `0.1.0` en cours jusqu'à la promotion stable ;
- `0.1.1..0.1.7` restent la trajectoire engagée et les domaines non numérotés restent réellement différés ;
- le prompt `007` exige bien l'archive taggée `v0.1.0` et le rapport `publish.001` seulement lorsqu'il existe réellement avec statut `PASS` ;
- la RC n'est ni le commit stable `0.1.0`, ni le tag `v0.1.0`, ni la vérification post-tag.
## Transition
### PASS
Produire séparément `history/0.1.0/rc.1.md`, l'appliquer puis committer/pousser `0.1.0-rc.1` avant le delta stable `rel.1`.
### FAIL
Consigner l'échec réel dans `history/0.1.0/rc.1.md` puis corriger uniquement le scope gelé dans `rc.1.fix.1`, sauf REPLAN si la candidate révèle un défaut fonctionnel plus large.

202
deltas/0.1.0/rel.1.md Normal file
View File

@@ -0,0 +1,202 @@
<!-- file: deltas/0.1.0/rel.1.md -->
<!-- version: 1 -->
# Delta 0.1.0 rel.1 — promotion stable pré-tag
## Baseline et version
Baseline : `0.1.0-rc.1`, avec `history/0.1.0/rc.1.md` appliqué et committé. Ce delta MUST NOT être appliqué avant ce commit.
Version avant application :
```text
0.1.0-rc.1
```
Version après application :
```text
0.1.0
```
`rel.1` identifie la clôture opérationnelle ; il ne fait pas partie de la version SemVer du produit.
## Objet
Promouvoir mécaniquement la RC validée vers la stable `0.1.0` sans rouvrir le scope fonctionnel.
La tranche finalise uniquement la présentation et les métadonnées de release : version stable, roadmap terminée, changelog sans marqueur `candidate`, README/index en état stable et plan `006` historique. Aucun owner, profil, template, skeleton, script d'audit ou contrat technique n'est modifié.
La validation de cette tranche est **pré-tag**. Le tag `v0.1.0`, son archive source Gitea et le rapport `pgr-0.1.0-publish.001-report.md` ne sont pas déclarés existants par ce delta. Ils suivent uniquement un history `rel.1` `PASS`, le commit stable `0.1.0` et la publication réelle du tag.
## Scope
REPLACE :
```text
VERSION
README.md
ROADMAP.md
CHANGELOG.md
docs/000-README.md
docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md
```
ADD :
```text
deltas/0.1.0/rel.1.md
```
DELETE : aucun.
Le history `rc.1` est livré séparément. Le history `rel.1` sera produit uniquement après la gate opérateur.
## Validation opérateur pré-tag
Après application sur le commit contenant `history/0.1.0/rc.1.md` :
```bash
test "$(cat VERSION)" = '0.1.0'
git cat-file -e HEAD:history/0.1.0/rc.1.md
test -f history/0.1.0/rc.1.md
test -f deltas/0.1.0/rel.1.md
test -f prompts/007-V0_1_1_START_PROMPT.md
test ! -e history/0.1.0/rel.1.md
grep -A2 '^## Statut$' history/0.1.0/rc.1.md | grep -Fx 'PASS'
grep -Fx '<!-- version: 16 -->' README.md
grep -Fx '<!-- version: 10 -->' ROADMAP.md
grep -Fx '<!-- version: 11 -->' CHANGELOG.md
grep -Fx '<!-- version: 23 -->' docs/000-README.md
grep -Fx '<!-- version: 10 -->' docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md
grep -F -- '- `(x) 0.1.0`' ROADMAP.md
grep -Fx '## 0.1.0' CHANGELOG.md
grep -F 'première baseline réutilisable stable' README.md
grep -F 'plan historique de la stable `0.1.0`' docs/000-README.md
python3 -B - <<'PYGATE'
from pathlib import Path
import re
expected = {
"alpha.1.md": "PASS",
"alpha.2.md": "FAIL",
"alpha.2.fix.1.md": "PASS",
"alpha.3.md": "FAIL",
"alpha.3.fix.1.md": "PASS",
"alpha.4.md": "PASS",
"alpha.5.md": "PASS",
"beta.1.md": "PASS",
"rc.1.md": "PASS",
}
for name, status in expected.items():
delta = Path("deltas/0.1.0", name)
history = Path("history/0.1.0", 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 = {path.name for path in Path("deltas/0.1.0").glob("*.md")} - {
path.name for path in Path("history/0.1.0").glob("*.md")
}
assert pending == {"rel.1.md"}, pending
roadmap = Path("ROADMAP.md").read_text(encoding="utf-8")
assert "- `(x) 0.1.0`" in roadmap
for version in ("0.1.1", "0.1.2", "0.1.3", "0.1.4", "0.1.5", "0.1.6", "0.1.7"):
assert f"- `( ) {version}`" in roadmap, version
assert "- `( ) 0.1.8`" not in roadmap
changelog = Path("CHANGELOG.md").read_text(encoding="utf-8")
assert "## 0.1.0" in changelog.splitlines()
assert "## 0.1.0 (candidate)" not in changelog
assert "produit produit" not in changelog
readme = Path("README.md").read_text(encoding="utf-8")
assert "première baseline réutilisable stable" in readme
assert "plan historique de la première baseline réutilisable `0.1.0`" in readme
index = Path("docs/000-README.md").read_text(encoding="utf-8")
assert "plan historique de la stable `0.1.0`" in index
plan = Path("docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md").read_text(encoding="utf-8")
assert "Statut opérateur : **PASS**." in plan
assert "history/0.1.0/rel.1.md" in plan
assert "pgr-0.1.0-publish.001-report.md" in plan
prompt = Path("prompts/007-V0_1_1_START_PROMPT.md").read_text(encoding="utf-8")
assert "tag Gitea `v0.1.0`" in prompt
assert "pgr-0.1.0-publish.001-report.md" in prompt
assert "0.1.1-alpha.1" in prompt
workflow = Path("docs/rules/210-WORKFLOW.md").read_text(encoding="utf-8")
assert "history rel.1 FAIL / PARTIAL / BLOCKED" in workflow
assert "premier history rel.N[/fix.M] PASS qui établit réellement la stable" in workflow
assert "commit X.Y.Z" in workflow
print("0.1.0 rel.1 stable gate audit: clean (9 prior histories, rel.1 pending, stable presentation and post-tag handoff coherent)")
PYGATE
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
git diff --check
git add VERSION README.md ROADMAP.md CHANGELOG.md docs/000-README.md \
docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md \
deltas/0.1.0/rel.1.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.1.0/rel.1.md
M docs/000-README.md
M docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md
```
Les deux dry-runs Rust/Cargo ont été reconfirmés en `rc.1` avec Cargo/rustfmt/Clippy et aucun artefact Rust/Cargo n'est modifié par `rel.1`; ils ne sont donc pas rejoués une troisième fois dans la promotion mécanique. La suite Python PGR et les audits documentaires restent exécutés dans la gate stable.
## Revue opérateur complémentaire
Confirmer que :
- le scope fonctionnel de `rc.1` ne change pas ;
- `0.1.0` est présenté comme stable de manière cohérente dans VERSION/README/ROADMAP/CHANGELOG/index/plan ;
- les `FAIL` historiques `alpha.2` et `alpha.3` restent conservés avec leurs fixes `PASS` ;
- la roadmap engagée `0.1.1` à `0.1.7` reste intacte ;
- WASM, serveur Rust et deployment/operations restent non numérotés ;
- le prompt `007` reste conditionnel à une vraie publication de `v0.1.0` et à un rapport post-tag `PASS` réel ;
- aucune preuve post-tag n'est anticipée.
## Transition
### PASS
Produire séparément `history/0.1.0/rel.1.md`, l'appliquer, puis créer le commit stable sous le message exact :
```text
0.1.0
```
Après push de la branche canonique, créer et publier le tag annoté `v0.1.0`. Vérifier localement et à distance l'objet tag et son commit déréférencé. Télécharger ensuite l'archive source depuis le tag Gitea et la fournir au générateur avec les sorties Git de publication afin de produire `pgr-0.1.0-publish.001-report.md` à partir de preuves réelles.
Le prompt `007-V0_1_1_START_PROMPT.md` n'est remis comme reprise effective de `0.1.1` qu'après un rapport post-tag `PASS`.
### FAIL
Consigner le diagnostic réel dans `history/0.1.0/rel.1.md`, ne pas créer le tag et corriger uniquement la fermeture dans `rel.1.fix.1` avant toute publication.

219
deltas/0.1.1/alpha.1.md Normal file
View File

@@ -0,0 +1,219 @@
<!-- file: deltas/0.1.1/alpha.1.md -->
<!-- version: 1 -->
# Delta 0.1.1-alpha.1 — audit de la stable et cadrage frontend Web
## Baseline et sources
Baseline PGR autoritaire : `pgr-v0.1.0.zip`, archive source téléchargée depuis le tag Gitea `v0.1.0`, accompagnée du rapport externe `pgr-0.1.0-publish.001-report.md` avec statut `PASS`.
SHA-256 vérifiés :
```text
pgr-v0.1.0.zip bc8f3a8117d04afc1280344eceaaac8c6a4724ca94c285a6234fe42c1023b2be
pgr-0.1.0-publish.001-report.md a64dc4a5a81e1776b641894d8493eec3ef315932fffb2881e52ff4147eb8b6a5
games-v0.3.6(1).zip ad6e44a1332eb7d6069cf1189d9433f0fbb8fac19c5aac9f4641ac45c1c556e8
khadhroony-solana-project-v0.3.17.zip 2a9cabcb9f147a348dcf8d24df8bc6c5029089b6d49feb17bd4a42b4293c329a
```
Le fichier Games fourni sous le nom local `games-v0.3.6(1).zip` a exactement le SHA-256 de la baseline canonique `games-v0.3.6.zip` attendue par le prompt `007`.
KSP `0.3.17` est uniquement un corpus secondaire de corroboration pour éviter de confondre règles frontend génériques et choix d'un host particulier. Il n'est ni requis par la baseline `0.1.1`, ni modifié, ni adopté dans cette tranche.
Version avant application :
```text
0.1.0
```
Version après application :
```text
0.1.1-alpha.1
```
## Objet
Exécuter `prompts/007-V0_1_1_START_PROMPT.md` : vérifier intégralement la stable `v0.1.0`, ses règles, profils, templates, skeletons, audits, décisions différées et chaîne de gouvernance, puis auditer le corpus Games réellement fourni et créer le plan `0.1.1` avant toute normalisation Web importante.
`alpha.1` reste un gate de cadrage. Aucun owner Web, template frontend, skeleton, audit ou règle normative n'est encore créé.
## Résultat de l'audit d'intake
La stable PGR et son rapport post-tag concordent : archive SHA-256 attendue, CRC propre, racine unique `pgr/`, `221` fichiers, `33` répertoires, aucun symlink et absence normale de `.git`.
La suite de tests donne `48/48 PASS`. Les audits Markdown sont propres : `198` fichiers pour les headers, `8` tables sur `198` fichiers et `193` liens locaux sur `198` fichiers. Les cinq templates TOML Rust/Cargo sont parsables et aucun output de build courant n'est embarqué.
Les `72` couples delta/history de `0.0.1` à `0.1.0` sont complets. `0.1.0` conserve explicitement `alpha.2 FAIL`, `alpha.2.fix.1 PASS`, `alpha.3 FAIL`, `alpha.3.fix.1 PASS`, puis `rel.1 PASS`. Le commit stable et le tag suivent la nouvelle convention sans réécrire les historiques antérieurs.
La stable possède déjà les profils `510` Rust/Cargo, `520` Java/Maven/Gradle, `610` Android et `710` Tauri. Le skeleton Tauri reste correctement `DEFER`; la décision existante identifie précisément TypeScript, Vite, Sass/CSS, outputs et validation frontend indépendante comme responsabilités encore manquantes.
Le corpus Games fourni est sain et correspond au hash canonique attendu. Il contient trois packages frontend réels : deux hosts Web directs et un host Tauri. Tous exercent TypeScript, Vite, `frontend/` et des sorties/cache externes à l'arborescence source. Sass/Bootstrap n'est exercé que là où la chaîne de styles le requiert. Les lockfiles Node sont ignorés par Games, mais cette politique reste locale et n'est pas généralisée par `alpha.1`.
KSP `0.3.17` contient six applications Tauri avec frontend Vite/TypeScript et corrobore le caractère transversal de ces owners, sans devenir un corpus d'adoption dans cette release.
Le plan conserve explicitement WASM, serveur Rust/Actix et deployment hors scope, et ne lève pas le `DEFER` Tauri.
## Scope
REPLACE :
```text
VERSION
README.md
docs/000-README.md
```
ADD :
```text
docs/plans/007-V0_1_1_WEB_FRONTEND_FOUNDATION_PLAN.md
deltas/0.1.1/alpha.1.md
```
DELETE : aucun.
`RULES.md`, `ROADMAP.md`, `CHANGELOG.md`, les règles, profils, templates, skeletons, scripts, studies, validations et histories existants restent inchangés dans `alpha.1`.
Aucun `history/0.1.1/alpha.1.md` n'est anticipé avant la gate opérateur.
## Validation opérateur
Après application sur la stable `0.1.0`, depuis la racine du dépôt :
```bash
test "$(cat VERSION)" = '0.1.1-alpha.1'
test -f docs/plans/007-V0_1_1_WEB_FRONTEND_FOUNDATION_PLAN.md
test -f deltas/0.1.1/alpha.1.md
test ! -e history/0.1.1/alpha.1.md
grep -Fx '<!-- version: 17 -->' README.md
grep -Fx '<!-- version: 24 -->' docs/000-README.md
grep -F '007-V0_1_1_WEB_FRONTEND_FOUNDATION_PLAN.md' README.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
expected = {
'0.0.1': 12,
'0.0.2': 12,
'0.0.3': 10,
'0.0.4': 9,
'0.0.5': 19,
'0.1.0': 10,
}
for release, count in expected.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) == count, (release, len(deltas))
assert deltas == histories, (release, sorted(deltas ^ histories))
statuses = {}
for path in Path('history/0.1.0').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[path.name] = match.group(1)
assert statuses['alpha.2.md'] == 'FAIL'
assert statuses['alpha.2.fix.1.md'] == 'PASS'
assert statuses['alpha.3.md'] == 'FAIL'
assert statuses['alpha.3.fix.1.md'] == 'PASS'
assert statuses['rel.1.md'] == 'PASS'
roadmap = Path('ROADMAP.md').read_text(encoding='utf-8')
for release in range(1, 8):
assert f'- `( ) 0.1.{release}`' in roadmap, release
assert '0.1.8' not in roadmap
assert 'skeleton Tauri avant owners Web suffisants' in roadmap
assert 'WASM' in roadmap
assert 'serveur Web Rust / Actix Web ou alternative' in roadmap
assert 'deployment & operations' in roadmap
prompt = Path('prompts/007-V0_1_1_START_PROMPT.md').read_text(encoding='utf-8')
for phrase in (
'Version cible : `0.1.1`',
'Première tranche attendue : `0.1.1-alpha.1`',
'ad6e44a1332eb7d6069cf1189d9433f0fbb8fac19c5aac9f4641ac45c1c556e8',
'TypeScript et configuration applicable',
'Vite, dev server et contrat de build outputs',
'package manager, manifest et lockfile sans imposer arbitrairement npm',
'Le skeleton Tauri reste `DEFER` pendant cette release.',
):
assert phrase in prompt, phrase
study = Path('docs/studies/002-TAURI_SKELETON_DECISION.md').read_text(encoding='utf-8')
for phrase in (
'DEFER',
'TypeScript et conventions Web contrôlées',
'Vite et ownership des commandes/dev server/build outputs',
'Sass/CSS et statut des artefacts générés',
'validation frontend indépendante de la validation Tauri',
):
assert phrase in study, phrase
plan = Path('docs/plans/007-V0_1_1_WEB_FRONTEND_FOUNDATION_PLAN.md').read_text(encoding='utf-8')
for phrase in (
'Frontières d\'ownership à décider',
'alpha.2 — frontières d\'ownership Web',
'alpha.3 — TypeScript et écosystème de package',
'alpha.4 — Vite, dev server et outputs',
'alpha.5 — CSS/Sass et validation frontend',
'beta.1 — réconciliation et preuve de préparation Tauri',
'La réussite de `0.1.1` devra produire les owners nécessaires à ce réexamen, mais ne lèvera pas automatiquement le `DEFER`.',
'WASM, sans numéro réservé',
'serveur Web Rust / Actix Web ou alternative',
):
assert phrase in plan, phrase
print('0.1.1 alpha.1 structural audit: clean (72 prior pairs, Web scope bounded, Tauri DEFER preserved)')
PY
git diff --check
git add VERSION README.md docs/000-README.md \
docs/plans/007-V0_1_1_WEB_FRONTEND_FOUNDATION_PLAN.md \
deltas/0.1.1/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.1.1/alpha.1.md
M docs/000-README.md
A docs/plans/007-V0_1_1_WEB_FRONTEND_FOUNDATION_PLAN.md
```
La revue opérateur doit également confirmer que :
- le plan n'impose pas npm, Sass ou Bootstrap comme obligation frontend universelle ;
- la politique Games sur les lockfiles reste une observation locale, pas une règle PGR acquise ;
- les numéros/frontières exacts des futurs owners Web restent à décider en `alpha.2` ;
- aucun profil WASM ou serveur Rust n'est créé par proximité ;
- aucun skeleton Tauri n'est créé et son `DEFER` n'est pas levé ;
- Games et KSP restent des corpus externes non modifiés ;
- aucun nouveau numéro de release au-delà de `0.1.7` n'est réservé.
## Transition
### PASS
Produire `history/0.1.1/alpha.1.md` à partir des résultats réellement observés. Dans la même réponse, si aucune décision nouvelle n'est ouverte, préparer séparément le delta `0.1.1-alpha.2` consacré aux frontières d'ownership Web et à la classification `ADOPT / KEEP-LOCAL / OVERRIDE / DEFER` des choix Games pertinents.
Après remise du history, fournir automatiquement le bloc Git exact de fermeture conformément à `docs/templates/006-OPERATOR_COMMAND_HANDOFF.md`, puis indiquer l'application du delta suivant seulement après succès du commit/push.
### FAIL
Consigner le résultat réel dans le history, puis ouvrir `0.1.1-alpha.1.fix.1` ou un REPLAN selon la cause. Un fix de `alpha.1` doit rester limité au cadrage et ne doit pas absorber les décisions normatives prévues pour `alpha.2`.

View File

@@ -0,0 +1,204 @@
<!-- file: deltas/0.1.1/alpha.2.fix.1.md -->
<!-- version: 1 -->
# Delta 0.1.1-alpha.2.fix.1 — correction de la gate d'ownership Web
## Baseline et version
Baseline attendue : commit opérateur de `0.1.1-alpha.2`, réalisé après application de `history/0.1.1/alpha.2.md` avec statut `FAIL`.
Le hash de ce commit n'est pas anticipé.
Version avant application :
```text
0.1.1-alpha.2
```
Version après application :
```text
0.1.1-alpha.2.fix.1
```
## Objet
Corriger uniquement la syntaxe défectueuse de la gate opérateur de `alpha.2`.
Les nouveaux owners Web et tous les documents normatifs livrés par `alpha.2` restent inchangés. Le delta historique `deltas/0.1.1/alpha.2.md` reste également inchangé.
Le défaut observé était un littéral Python entouré de quotes simples alors que son texte contenait l'apostrophe de `s'applique` :
```python
'Le profil s'applique uniquement lorsqu'un projet utilise réellement Vite.'
```
Le fix utilise des littéraux syntaxiquement sûrs dans la nouvelle gate sans modifier les assertions sémantiques.
## Scope
REPLACE :
```text
VERSION
docs/plans/007-V0_1_1_WEB_FRONTEND_FOUNDATION_PLAN.md
```
ADD :
```text
deltas/0.1.1/alpha.2.fix.1.md
```
DELETE : aucun.
Aucun profil, règle normative, template, skeleton, script d'audit ou test n'est modifié par ce correctif.
## Validation opérateur
Après application du history `FAIL`, commit/push de `alpha.2`, puis application du présent delta :
```bash
test "$(cat VERSION)" = '0.1.1-alpha.2.fix.1'
git cat-file -e HEAD:history/0.1.1/alpha.2.md
test -f history/0.1.1/alpha.2.md
test -f deltas/0.1.1/alpha.2.md
test -f deltas/0.1.1/alpha.2.fix.1.md
test ! -e history/0.1.1/alpha.2.fix.1.md
grep -A2 '^## Statut$' history/0.1.1/alpha.2.md | grep -Fx 'FAIL'
grep -Fx '<!-- version: 13 -->' RULES.md
grep -Fx '<!-- version: 25 -->' docs/000-README.md
grep -Fx '<!-- version: 6 -->' docs/architecture/003-RULE_PROFILE_MODEL.md
grep -Fx '<!-- version: 3 -->' docs/plans/007-V0_1_1_WEB_FRONTEND_FOUNDATION_PLAN.md
grep -Fx '<!-- version: 15 -->' docs/rules/000-README.md
grep -Fx '<!-- version: 6 -->' docs/rules/710-TAURI.md
python3 -B - <<'PYGATE'
from pathlib import Path
import re
history = Path('history/0.1.1/alpha.2.md').read_text(encoding='utf-8')
assert re.search(r'## Statut\s+FAIL\s', history)
expected = {
'530-TYPESCRIPT.md': (
'TypeScript **SHOULD** être préféré',
'TS-RS',
'ni Vite',
),
'540-JAVASCRIPT_PACKAGE_ECOSYSTEM.md': (
'MUST NOT imposer npm',
'Lockfile',
'alpha.3',
),
'550-VITE.md': (
'Vite **SHOULD** être le build tool/dev server privilégié',
"Le profil s'applique uniquement lorsqu'un projet utilise réellement Vite.",
'alpha.4',
),
'560-CSS_SASS.md': (
'Sass **SHOULD** être préféré',
'Bootstrap constitue un exemple concret',
'`@use` / `@forward`',
'`@import` Sass est déprécié',
'alpha.5',
),
}
for name, phrases in expected.items():
profile = Path('docs/rules', name).read_text(encoding='utf-8')
for phrase in phrases:
assert phrase in profile, (name, phrase)
rules = Path('RULES.md').read_text(encoding='utf-8')
rules_index = Path('docs/rules/000-README.md').read_text(encoding='utf-8')
architecture = Path('docs/architecture/003-RULE_PROFILE_MODEL.md').read_text(encoding='utf-8')
tauri = Path('docs/rules/710-TAURI.md').read_text(encoding='utf-8')
plan = Path('docs/plans/007-V0_1_1_WEB_FRONTEND_FOUNDATION_PLAN.md').read_text(encoding='utf-8')
roadmap = Path('ROADMAP.md').read_text(encoding='utf-8')
for owner in ('530-TYPESCRIPT.md', '540-JAVASCRIPT_PACKAGE_ECOSYSTEM.md', '550-VITE.md', '560-CSS_SASS.md'):
assert owner in rules
assert owner in rules_index
for phrase in (
'530 — TypeScript',
'540 — JavaScript package ecosystem',
'550 — Vite',
'560 — CSS / Sass',
"Un frontend minimal peut n'en sélectionner qu'une partie.",
):
assert phrase in architecture, phrase
for phrase in (
'TypeScript et Vite sont fortement recommandés mais restent des `SHOULD`',
'Sass est également fortement recommandé',
'profils `530`, `550` et `560`',
):
assert phrase in tauri, phrase
for phrase in (
'Décisions de revue après `alpha.1`',
'**TypeScript** : fortement recommandé',
'**Vite** : fortement recommandé',
'**Sass** : fortement recommandé',
'`@use` / `@forward`',
'| TypeScript pour les frontends durables | `ADOPT`',
'| npm comme package manager concret | `KEEP-LOCAL`',
'| commandes/génération WASM dans les scripts | `DEFER`',
'Statut opérateur : **FAIL**.',
"### alpha.2.fix.1 — correction de la gate d'ownership Web",
):
assert phrase in plan, phrase
assert '0.1.8' not in roadmap
assert 'skeleton Tauri avant owners Web suffisants' in roadmap
print('0.1.1 alpha.2.fix.1 ownership gate: clean (alpha.2 FAIL preserved, 530/540/550/560 reconfirmed, Python literals safe)')
PYGATE
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
git diff --check
git add VERSION docs/plans/007-V0_1_1_WEB_FRONTEND_FOUNDATION_PLAN.md \
deltas/0.1.1/alpha.2.fix.1.md
git diff --cached --check
git status --short
```
Le scope indexé attendu avant ajout du history du fix est exactement :
```text
M VERSION
A deltas/0.1.1/alpha.2.fix.1.md
M docs/plans/007-V0_1_1_WEB_FRONTEND_FOUNDATION_PLAN.md
```
## Revue opérateur complémentaire
Confirmer que :
- le `FAIL` de `alpha.2` est conservé historiquement ;
- `deltas/0.1.1/alpha.2.md` n'est pas réécrit ;
- `RULES.md`, `docs/000-README.md`, `docs/architecture/003-RULE_PROFILE_MODEL.md`, `docs/rules/000-README.md` et `docs/rules/710-TAURI.md` ne sont pas modifiés par le fix ;
- les profils `530-TYPESCRIPT.md`, `540-JAVASCRIPT_PACKAGE_ECOSYSTEM.md`, `550-VITE.md` et `560-CSS_SASS.md` ne sont pas modifiés par le fix ;
- aucun contenu prévu pour `alpha.3` n'est absorbé dans le correctif.
## Transition
### PASS
Produire `history/0.1.1/alpha.2.fix.1.md`, l'appliquer puis committer/pousser le fix. Reprendre ensuite la trajectoire normale avec `0.1.1-alpha.3`, consacré à TypeScript et à l'écosystème de package.
### FAIL
Consigner le diagnostic réel dans `history/0.1.1/alpha.2.fix.1.md` et rester dans `alpha.2.fix.M`. Le scope MUST rester limité à la correction de la gate d'ownership Web tant qu'aucun défaut plus large ne justifie un REPLAN.

269
deltas/0.1.1/alpha.2.md Normal file
View File

@@ -0,0 +1,269 @@
<!-- file: deltas/0.1.1/alpha.2.md -->
<!-- version: 1 -->
# Delta 0.1.1-alpha.2 — frontières d'ownership frontend Web
## Baseline et version
Baseline attendue : commit opérateur de `0.1.1-alpha.1`, réalisé après application de `history/0.1.1/alpha.1.md` avec statut `PASS`.
Le hash de ce commit n'est pas anticipé.
Version avant application :
```text
0.1.1-alpha.1
```
Version après application :
```text
0.1.1-alpha.2
```
## Objet
Matérialiser les frontières d'ownership frontend nécessaires avant d'écrire les configurations détaillées de `alpha.3` à `alpha.5`.
La tranche crée quatre profils indépendants dans la famille `500` :
```text
530 TypeScript
540 JavaScript package ecosystem
550 Vite
560 CSS / Sass
```
Elle inscrit également les trois préférences validées pendant la revue de `alpha.1` : TypeScript, Vite et Sass sont fortement recommandés dans leurs scopes applicables pour les nouveaux frontends contrôlés, donc exprimés en `SHOULD`, mais aucun n'est une obligation universelle.
La tranche ne crée encore aucun template `package.json`, `tsconfig.json` ou `vite.config.ts`, aucun skeleton Web, aucun audit frontend et aucune politique finale de lockfile. Ces responsabilités restent prévues dans les tranches suivantes.
## Scope
REPLACE :
```text
VERSION
RULES.md
docs/000-README.md
docs/architecture/003-RULE_PROFILE_MODEL.md
docs/plans/007-V0_1_1_WEB_FRONTEND_FOUNDATION_PLAN.md
docs/rules/000-README.md
docs/rules/710-TAURI.md
```
ADD :
```text
deltas/0.1.1/alpha.2.md
docs/rules/530-TYPESCRIPT.md
docs/rules/540-JAVASCRIPT_PACKAGE_ECOSYSTEM.md
docs/rules/550-VITE.md
docs/rules/560-CSS_SASS.md
```
DELETE : aucun.
`ROADMAP.md`, `CHANGELOG.md`, les templates, skeletons, scripts, tests, validations et studies restent inchangés.
Aucun `history/0.1.1/alpha.2.md` n'est anticipé.
## Décisions normatives
### TypeScript
Pour un frontend contrôlé portant une logique durable non triviale, TypeScript `SHOULD` être préféré au JavaScript non typé. Du JavaScript direct reste valide lorsqu'il est plus proportionné.
Le type-check TypeScript et la génération éventuelle de bindings depuis une autre source de vérité sont des responsabilités distinctes du bundler. TS-RS reste un outil de frontière Rust/TypeScript lorsqu'un owner plus spécifique l'exige ; il n'est pas une dépendance TypeScript universelle.
### Écosystème de package
`package.json`, le package manager concret, les scripts de package, les dépendances téléchargées et la décision de lockfile appartiennent au profil `540`.
PGR MUST NOT imposer npm par défaut. La politique du lockfile sera définie en `alpha.3` à partir du rôle du package et de la reproductibilité recherchée, pas à partir de l'absence de lockfile observée dans Games.
### Vite
Pour un frontend contrôlé compatible avec ses capacités, Vite `SHOULD` être le build tool/dev server privilégié. Une alternative justifiée reste permise.
Le profil Vite possède sa configuration, son cache et ses outputs ; il ne possède ni TypeScript, ni Sass/CSS, ni le package manager, ni Tauri, ni WASM.
### CSS / Sass
CSS direct reste une baseline valide. Sass `SHOULD` être préféré lorsqu'une chaîne de styles non triviale ou une dépendance Sass/SCSS configurable en tire une valeur claire.
Bootstrap est un exemple réel de bibliothèque pouvant être personnalisée à partir de ses sources Sass et de variables/maps ; il reste un choix de skeleton/projet, pas une dépendance Web universelle.
Pour du nouveau code Sass, `@use` / `@forward` SHOULD être préférés lorsque compatibles. `@import` MAY rester utilisé pour la compatibilité avec des dépendances existantes qui l'exigent.
## Classification Games de cadrage
La classification préparatoire est inscrite dans le plan :
```text
TypeScript durable ADOPT
Vite ADOPT
package.json ADOPT
npm concret KEEP-LOCAL
lockfiles Games KEEP-LOCAL jusqu'à décision alpha.3
Sass ADOPT quand applicable
Bootstrap KEEP-LOCAL
frontend/ layout KEEP-LOCAL / candidat skeleton
ports / aliases / plugins KEEP-LOCAL
WASM dans scripts DEFER
```
Aucun `OVERRIDE` n'est nécessaire avant l'adoption réelle de Games en `0.1.5`.
## Validation opérateur
Après application du history `PASS`, commit/push de `alpha.1`, puis application du présent delta :
```bash
test "$(cat VERSION)" = '0.1.1-alpha.2'
git cat-file -e HEAD:history/0.1.1/alpha.1.md
test -f history/0.1.1/alpha.1.md
test -f deltas/0.1.1/alpha.2.md
test ! -e history/0.1.1/alpha.2.md
for path in docs/rules/530-TYPESCRIPT.md docs/rules/540-JAVASCRIPT_PACKAGE_ECOSYSTEM.md docs/rules/550-VITE.md docs/rules/560-CSS_SASS.md; do
test -f "$path"
done
grep -A2 '^## Statut$' history/0.1.1/alpha.1.md | grep -Fx 'PASS'
grep -Fx '<!-- version: 13 -->' RULES.md
grep -Fx '<!-- version: 25 -->' docs/000-README.md
grep -Fx '<!-- version: 6 -->' docs/architecture/003-RULE_PROFILE_MODEL.md
grep -Fx '<!-- version: 2 -->' docs/plans/007-V0_1_1_WEB_FRONTEND_FOUNDATION_PLAN.md
grep -Fx '<!-- version: 15 -->' docs/rules/000-README.md
grep -Fx '<!-- version: 6 -->' 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 - <<'PYGATE'
from pathlib import Path
import re
history = Path('history/0.1.1/alpha.1.md').read_text(encoding='utf-8')
assert re.search(r'## Statut\s+PASS\s', history)
expected = {
'530-TYPESCRIPT.md': (
'TypeScript **SHOULD** être préféré',
'TS-RS',
'ni Vite',
),
'540-JAVASCRIPT_PACKAGE_ECOSYSTEM.md': (
'MUST NOT imposer npm',
'Lockfile',
'alpha.3',
),
'550-VITE.md': (
'Vite **SHOULD** être le build tool/dev server privilégié',
'Le profil s'applique uniquement lorsqu'un projet utilise réellement Vite.',
'alpha.4',
),
'560-CSS_SASS.md': (
'Sass **SHOULD** être préféré',
'Bootstrap constitue un exemple concret',
'`@use` / `@forward`',
'`@import` Sass est déprécié',
'alpha.5',
),
}
for name, phrases in expected.items():
text = Path('docs/rules', name).read_text(encoding='utf-8')
for phrase in phrases:
assert phrase in text, (name, phrase)
rules = Path('RULES.md').read_text(encoding='utf-8')
rules_index = Path('docs/rules/000-README.md').read_text(encoding='utf-8')
architecture = Path('docs/architecture/003-RULE_PROFILE_MODEL.md').read_text(encoding='utf-8')
tauri = Path('docs/rules/710-TAURI.md').read_text(encoding='utf-8')
plan = Path('docs/plans/007-V0_1_1_WEB_FRONTEND_FOUNDATION_PLAN.md').read_text(encoding='utf-8')
roadmap = Path('ROADMAP.md').read_text(encoding='utf-8')
for owner in ('530-TYPESCRIPT.md', '540-JAVASCRIPT_PACKAGE_ECOSYSTEM.md', '550-VITE.md', '560-CSS_SASS.md'):
assert owner in rules
assert owner in rules_index
for phrase in (
'530 — TypeScript',
'540 — JavaScript package ecosystem',
'550 — Vite',
'560 — CSS / Sass',
'Un frontend minimal peut n'en sélectionner qu'une partie.',
):
assert phrase in architecture, phrase
for phrase in (
'TypeScript et Vite sont fortement recommandés mais restent des `SHOULD`',
'Sass est également fortement recommandé',
'profils `530`, `550` et `560`',
):
assert phrase in tauri, phrase
for phrase in (
'Décisions de revue après `alpha.1`',
'**TypeScript** : fortement recommandé',
'**Vite** : fortement recommandé',
'**Sass** : fortement recommandé',
'`@use` / `@forward`',
'| TypeScript pour les frontends durables | `ADOPT` |',
'| npm comme package manager concret | `KEEP-LOCAL` |',
'| commandes/génération WASM dans les scripts | `DEFER` |',
):
assert phrase in plan, phrase
assert '0.1.8' not in roadmap
assert 'skeleton Tauri avant owners Web suffisants' in roadmap
print('0.1.1 alpha.2 ownership audit: clean (530/540/550/560 independent, SHOULD recommendations explicit, Games classified)')
PYGATE
git diff --check
git add VERSION RULES.md docs/000-README.md docs/architecture/003-RULE_PROFILE_MODEL.md docs/plans/007-V0_1_1_WEB_FRONTEND_FOUNDATION_PLAN.md docs/rules/000-README.md docs/rules/710-TAURI.md docs/rules/530-TYPESCRIPT.md docs/rules/540-JAVASCRIPT_PACKAGE_ECOSYSTEM.md docs/rules/550-VITE.md docs/rules/560-CSS_SASS.md deltas/0.1.1/alpha.2.md
git diff --cached --check
git status --short
```
Le scope indexé attendu avant ajout du history est :
```text
M RULES.md
M VERSION
A deltas/0.1.1/alpha.2.md
M docs/000-README.md
M docs/architecture/003-RULE_PROFILE_MODEL.md
M docs/plans/007-V0_1_1_WEB_FRONTEND_FOUNDATION_PLAN.md
M docs/rules/000-README.md
A docs/rules/530-TYPESCRIPT.md
A docs/rules/540-JAVASCRIPT_PACKAGE_ECOSYSTEM.md
A docs/rules/550-VITE.md
A docs/rules/560-CSS_SASS.md
M docs/rules/710-TAURI.md
```
La revue qualitative doit confirmer que :
- `SHOULD` représente bien « fortement recommandé » et qu'aucun des profils `530`, `550`, `560` n'est activé universellement ;
- TypeScript n'est pas rendu dépendant de Rust ou TS-RS ;
- Vite est recommandé sans interdire un autre build tool ;
- Sass est recommandé conditionnellement et CSS direct reste valide ;
- Bootstrap reste un exemple/choix de skeleton, pas une dépendance universelle ;
- npm et la politique Games des lockfiles restent non généralisés ;
- WASM, serveur Rust et skeleton Tauri restent hors scope de la tranche.
## Transition
### PASS
Produire `history/0.1.1/alpha.2.md`, puis préparer `0.1.1-alpha.3` consacré aux règles et artefacts TypeScript + écosystème de package : `tsconfig`, manifest, scripts utiles, sélection du package manager et politique du lockfile.
### FAIL
Consigner le diagnostic réel dans `history/0.1.1/alpha.2.md` et rester dans `alpha.2.fix.N` sauf REPLAN justifié. Le fix MUST rester borné au défaut d'ownership ou de formulation observé.

View File

@@ -0,0 +1,242 @@
<!-- file: deltas/0.1.1/alpha.3.fix.1.md -->
<!-- version: 1 -->
# Delta 0.1.1-alpha.3.fix.1 — déclarations de types externes
## Baseline et version
Baseline attendue : commit opérateur de `0.1.1-alpha.3`, réalisé après application de `history/0.1.1/alpha.3.md` avec statut `PASS`.
Le hash de ce commit n'est pas anticipé.
Version avant application :
```text
0.1.1-alpha.3
```
Version après application :
```text
0.1.1-alpha.3.fix.1
```
## Objet
Compléter le contrat TypeScript/package de `alpha.3` avec la gestion explicite des déclarations de types externes nécessaires au type-check et à l'intégration IDE.
Le correctif formalise l'ordre de décision suivant :
```text
package consommé
↓
types TypeScript embarqués ?
├─ oui → les utiliser, sans @types redondant
└─ non → rechercher @types/<package> ou une déclaration maintenue équivalente
↓
vérifier besoin et compatibilité
↓
classer correctement dans package.json
```
Pour une application privée, les packages de déclarations nécessaires seulement au développement `SHOULD` normalement appartenir à `devDependencies`. `@types/node` et `@types/bootstrap` sont des exemples conditionnels, pas des dépendances PGR universelles.
Le template `package.json` minimal reste volontairement inchangé : PGR ne connaît ni les dépendances réelles, ni leurs versions, ni la version TypeScript au niveau générique.
Vite reste réservé à `alpha.4`. CSS/Sass et la validation frontend réconciliée restent réservés à `alpha.5`.
## Scope
REPLACE :
```text
VERSION
docs/plans/007-V0_1_1_WEB_FRONTEND_FOUNDATION_PLAN.md
docs/rules/530-TYPESCRIPT.md
docs/rules/540-JAVASCRIPT_PACKAGE_ECOSYSTEM.md
docs/templates/008-WEB_TYPESCRIPT_PACKAGE.md
```
ADD :
```text
deltas/0.1.1/alpha.3.fix.1.md
```
DELETE : aucun.
`templates/web-typescript/package.json`, `templates/web-typescript/tsconfig.json`, `RULES.md`, `ROADMAP.md`, `CHANGELOG.md`, les profils `550`, `560`, `710`, les skeletons, scripts Python, tests et matrices de validation restent inchangés.
Aucun `history/0.1.1/alpha.3.fix.1.md` n'est anticipé.
## Règles ajoutées
Le correctif précise que :
- un package qui fournit déjà ses propres déclarations TypeScript ne doit pas recevoir arbitrairement un `@types/*` redondant ;
- lorsqu'une dépendance utilisée depuis TypeScript ne fournit pas de déclarations suffisantes, le projet `SHOULD` rechercher un package `@types/<nom>` maintenu ou une autre déclaration appropriée ;
- pour une application privée, les déclarations utilisées seulement au développement `SHOULD` normalement être dans `devDependencies` ;
- `@types/node` est applicable lorsque du code, de la configuration ou de l'outillage TypeScript utilise réellement l'environnement Node ;
- `@types/bootstrap` est applicable lorsque les API JavaScript Bootstrap sont consommées depuis TypeScript et nécessitent des déclarations externes ;
- un usage CSS/Sass seul de Bootstrap ne justifie pas `@types/bootstrap` ;
- si `compilerOptions.types` est utilisé, les packages de déclarations globales nécessaires doivent être sélectionnés explicitement de manière cohérente ;
- pour une bibliothèque publiée, une déclaration externe requise par les `.d.ts` publics doit rester disponible aux consommateurs et ne peut pas être cachée arbitrairement dans les seules `devDependencies` ;
- les versions runtime, `@types/*` et TypeScript doivent rester compatibles.
## Preuve corpus
Games `0.3.6` exerce déjà :
```text
Web/game-snake-poc @types/bootstrap + @types/node
Web/game-realtime-webtransport-browser-smoke @types/node
crates/apps/game-snake-poc-tauri @types/node
```
KSP `0.3.17` corrobore la pratique sur ses applications Tauri avec `@types/bootstrap` et `@types/node` en `devDependencies`.
Cette répétition justifie la règle de découverte/classification, pas l'installation universelle de ces packages.
## Validation opérateur
Après application du history `PASS`, commit/push de `alpha.3`, puis application du présent delta :
```bash
test "$(cat VERSION)" = '0.1.1-alpha.3.fix.1'
git cat-file -e HEAD:history/0.1.1/alpha.3.md
test -f history/0.1.1/alpha.3.md
test -f deltas/0.1.1/alpha.3.md
test -f deltas/0.1.1/alpha.3.fix.1.md
test ! -e history/0.1.1/alpha.3.fix.1.md
grep -A2 '^## Statut$' history/0.1.1/alpha.3.md | grep -Fx 'PASS'
grep -Fx '<!-- version: 5 -->' docs/plans/007-V0_1_1_WEB_FRONTEND_FOUNDATION_PLAN.md
grep -Fx '<!-- version: 3 -->' docs/rules/530-TYPESCRIPT.md
grep -Fx '<!-- version: 3 -->' docs/rules/540-JAVASCRIPT_PACKAGE_ECOSYSTEM.md
grep -Fx '<!-- version: 2 -->' docs/templates/008-WEB_TYPESCRIPT_PACKAGE.md
python3 -B - <<'PYGATE'
from pathlib import Path
import json
import re
history = Path('history/0.1.1/alpha.3.md').read_text(encoding='utf-8')
assert re.search(r'## Statut\s+PASS\s', history)
typescript = Path('docs/rules/530-TYPESCRIPT.md').read_text(encoding='utf-8')
for phrase in (
'Déclarations de types externes et intégration IDE',
'fournit déjà ses propres fichiers de déclaration TypeScript',
'@types/<nom>',
'`devDependencies`',
'`@types/node`',
'`@types/bootstrap`',
'Un projet qui ne consomme que le CSS/Sass de Bootstrap',
'`compilerOptions.types`',
'bibliothèque publiée',
):
assert phrase in typescript, phrase
packages = Path('docs/rules/540-JAVASCRIPT_PACKAGE_ECOSYSTEM.md').read_text(encoding='utf-8')
for phrase in (
'Dépendances de développement et packages de déclarations',
'la dépendance runtime fournit déjà ses propres types',
'@types/<nom>',
'`@types/node` est pertinent',
'`@types/bootstrap` est pertinent',
'Le template PGR générique conserve volontairement un `package.json` sans `devDependencies` préremplies',
'Pour une bibliothèque publiée',
):
assert phrase in packages, phrase
guide = Path('docs/templates/008-WEB_TYPESCRIPT_PACKAGE.md').read_text(encoding='utf-8')
for phrase in (
'`devDependencies` et déclarations de types',
'fournit-il déjà ses propres types ?',
'ne pas ajouter un @types redondant',
'"@types/node": "<si Node est réellement utilisé>"',
'"@types/bootstrap": "<si les API JavaScript Bootstrap sont réellement utilisées et nécessitent des types externes>"',
'qualité TypeScript et à l'expérience IDE',
):
assert phrase in guide, phrase
package = json.loads(Path('templates/web-typescript/package.json').read_text(encoding='utf-8'))
assert package == {
'name': 'project-web',
'private': True,
'scripts': {'typecheck': 'tsc --noEmit'},
}
tsconfig = json.loads(Path('templates/web-typescript/tsconfig.json').read_text(encoding='utf-8'))
assert tsconfig == {
'compilerOptions': {
'strict': True,
'noEmit': True,
'noUnusedLocals': True,
'noUnusedParameters': True,
'noFallthroughCasesInSwitch': True,
}
}
plan = Path('docs/plans/007-V0_1_1_WEB_FRONTEND_FOUNDATION_PLAN.md').read_text(encoding='utf-8')
for phrase in (
'Statut opérateur : **PASS**.',
'### alpha.3.fix.1 — déclarations de types externes',
'@types/bootstrap + @types/node',
'types embarqués → @types si nécessaire',
'Vite/CSS/Sass hors scope',
):
assert phrase in plan, phrase
assert Path('docs/rules/550-VITE.md').read_text(encoding='utf-8').splitlines()[1] == '<!-- version: 1 -->'
assert Path('docs/rules/560-CSS_SASS.md').read_text(encoding='utf-8').splitlines()[1] == '<!-- version: 1 -->'
assert Path('docs/rules/710-TAURI.md').read_text(encoding='utf-8').splitlines()[1] == '<!-- version: 6 -->'
print('0.1.1 alpha.3.fix.1 type declarations audit: clean (bundled types first, conditional @types, app/library dependency roles preserved)')
PYGATE
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
git diff --check
git add VERSION docs/plans/007-V0_1_1_WEB_FRONTEND_FOUNDATION_PLAN.md docs/rules/530-TYPESCRIPT.md docs/rules/540-JAVASCRIPT_PACKAGE_ECOSYSTEM.md docs/templates/008-WEB_TYPESCRIPT_PACKAGE.md deltas/0.1.1/alpha.3.fix.1.md
git diff --cached --check
git status --short
```
Le scope indexé attendu avant ajout du history du fix est exactement :
```text
M VERSION
A deltas/0.1.1/alpha.3.fix.1.md
M docs/plans/007-V0_1_1_WEB_FRONTEND_FOUNDATION_PLAN.md
M docs/rules/530-TYPESCRIPT.md
M docs/rules/540-JAVASCRIPT_PACKAGE_ECOSYSTEM.md
M docs/templates/008-WEB_TYPESCRIPT_PACKAGE.md
```
## Revue opérateur complémentaire
Confirmer que :
- `alpha.3` reste historisé `PASS` et son delta n'est pas réécrit ;
- le fix n'ajoute aucune dépendance fictive au template générique `package.json` ;
- les `@types/*` ne sont recherchés qu'après vérification des types embarqués ;
- `@types/node` et `@types/bootstrap` restent des exemples conditionnels ;
- les applications privées et les bibliothèques publiées conservent des règles de classification distinctes ;
- Vite, CSS/Sass, WASM et Tauri restent hors scope du correctif.
## Transition
### PASS
Produire `history/0.1.1/alpha.3.fix.1.md`, l'appliquer puis committer/pousser le fix. Reprendre ensuite la trajectoire normale avec `0.1.1-alpha.4`, consacré à Vite, au dev server, aux caches et aux outputs de production.
### FAIL
Consigner le diagnostic réel dans `history/0.1.1/alpha.3.fix.1.md` et rester dans `alpha.3.fix.M`. Le scope MUST rester limité au contrat TypeScript/package tant qu'aucun défaut plus large ne justifie un REPLAN.

View File

@@ -0,0 +1,199 @@
<!-- file: deltas/0.1.1/alpha.3.fix.2.md -->
<!-- version: 1 -->
# Delta 0.1.1-alpha.3.fix.2 — correction de la gate des déclarations de types
## Baseline et version
Baseline attendue : commit opérateur de `0.1.1-alpha.3.fix.1`, réalisé après application de `history/0.1.1/alpha.3.fix.1.md` avec statut `FAIL`.
Le hash de ce commit n'est pas anticipé.
Version avant application :
```text
0.1.1-alpha.3.fix.1
```
Version après application :
```text
0.1.1-alpha.3.fix.2
```
## Objet
Corriger uniquement la syntaxe défectueuse de la gate opérateur de `alpha.3.fix.1`.
Les règles et guides livrés par `alpha.3.fix.1` restent inchangés. Le delta historique `deltas/0.1.1/alpha.3.fix.1.md` reste également inchangé.
Le défaut observé était un littéral Python entouré de quotes simples alors que son texte contenait l'apostrophe de `l'expérience` :
```python
'qualité TypeScript et à l'expérience IDE'
```
Le fix utilise des littéraux syntaxiquement sûrs dans la nouvelle gate et généralise cette précaution aux assertions contenant des apostrophes, sans modifier leur sens.
## Scope
REPLACE :
```text
VERSION
docs/plans/007-V0_1_1_WEB_FRONTEND_FOUNDATION_PLAN.md
```
ADD :
```text
deltas/0.1.1/alpha.3.fix.2.md
```
DELETE : aucun.
Aucune règle normative, aucun template, skeleton, script d'audit ou test n'est modifié par ce correctif.
## Validation opérateur
Après application du history `FAIL`, commit/push de `alpha.3.fix.1`, puis application du présent delta :
```bash
test "$(cat VERSION)" = '0.1.1-alpha.3.fix.2'
git cat-file -e HEAD:history/0.1.1/alpha.3.fix.1.md
test -f history/0.1.1/alpha.3.fix.1.md
test -f deltas/0.1.1/alpha.3.fix.1.md
test -f deltas/0.1.1/alpha.3.fix.2.md
test ! -e history/0.1.1/alpha.3.fix.2.md
grep -A2 '^## Statut$' history/0.1.1/alpha.3.fix.1.md | grep -Fx 'FAIL'
grep -Fx '<!-- version: 6 -->' docs/plans/007-V0_1_1_WEB_FRONTEND_FOUNDATION_PLAN.md
grep -Fx '<!-- version: 3 -->' docs/rules/530-TYPESCRIPT.md
grep -Fx '<!-- version: 3 -->' docs/rules/540-JAVASCRIPT_PACKAGE_ECOSYSTEM.md
grep -Fx '<!-- version: 2 -->' docs/templates/008-WEB_TYPESCRIPT_PACKAGE.md
python3 -B - <<'PYGATE'
from pathlib import Path
import json
import re
history = Path('history/0.1.1/alpha.3.fix.1.md').read_text(encoding='utf-8')
assert re.search(r'## Statut\s+FAIL\s', history)
typescript = Path('docs/rules/530-TYPESCRIPT.md').read_text(encoding='utf-8')
for phrase in (
'Déclarations de types externes et intégration IDE',
'fournit déjà ses propres fichiers de déclaration TypeScript',
'@types/<nom>',
'`devDependencies`',
'`@types/node`',
'`@types/bootstrap`',
'Un projet qui ne consomme que le CSS/Sass de Bootstrap',
'`compilerOptions.types`',
'bibliothèque publiée',
):
assert phrase in typescript, phrase
packages = Path('docs/rules/540-JAVASCRIPT_PACKAGE_ECOSYSTEM.md').read_text(encoding='utf-8')
for phrase in (
'Dépendances de développement et packages de déclarations',
'la dépendance runtime fournit déjà ses propres types',
'@types/<nom>',
'`@types/node` est pertinent',
'`@types/bootstrap` est pertinent',
'Le template PGR générique conserve volontairement un `package.json` sans `devDependencies` préremplies',
'Pour une bibliothèque publiée',
):
assert phrase in packages, phrase
guide = Path('docs/templates/008-WEB_TYPESCRIPT_PACKAGE.md').read_text(encoding='utf-8')
for phrase in (
'`devDependencies` et déclarations de types',
'fournit-il déjà ses propres types ?',
'ne pas ajouter un @types redondant',
'"@types/node": "<si Node est réellement utilisé>"',
'"@types/bootstrap": "<si les API JavaScript Bootstrap sont réellement utilisées et nécessitent des types externes>"',
"qualité TypeScript et à l'expérience IDE",
):
assert phrase in guide, phrase
package = json.loads(Path('templates/web-typescript/package.json').read_text(encoding='utf-8'))
assert package == {
'name': 'project-web',
'private': True,
'scripts': {'typecheck': 'tsc --noEmit'},
}
tsconfig = json.loads(Path('templates/web-typescript/tsconfig.json').read_text(encoding='utf-8'))
assert tsconfig == {
'compilerOptions': {
'strict': True,
'noEmit': True,
'noUnusedLocals': True,
'noUnusedParameters': True,
'noFallthroughCasesInSwitch': True,
}
}
plan = Path('docs/plans/007-V0_1_1_WEB_FRONTEND_FOUNDATION_PLAN.md').read_text(encoding='utf-8')
for phrase in (
'Statut opérateur : **FAIL**.',
"### alpha.3.fix.2 — correction de la gate des déclarations de types",
'types embarqués → @types si nécessaire',
'Aucun défaut normatif du correctif',
'assertions contenant des apostrophes',
):
assert phrase in plan, phrase
assert Path('docs/rules/550-VITE.md').read_text(encoding='utf-8').splitlines()[1] == '<!-- version: 1 -->'
assert Path('docs/rules/560-CSS_SASS.md').read_text(encoding='utf-8').splitlines()[1] == '<!-- version: 1 -->'
assert Path('docs/rules/710-TAURI.md').read_text(encoding='utf-8').splitlines()[1] == '<!-- version: 6 -->'
print('0.1.1 alpha.3.fix.2 type declarations gate: clean (alpha.3.fix.1 FAIL preserved, type declarations reconfirmed, Python literals safe)')
PYGATE
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
git diff --check
git add VERSION docs/plans/007-V0_1_1_WEB_FRONTEND_FOUNDATION_PLAN.md \
deltas/0.1.1/alpha.3.fix.2.md
git diff --cached --check
git status --short
```
Le scope indexé attendu avant ajout du history du fix est exactement :
```text
M VERSION
A deltas/0.1.1/alpha.3.fix.2.md
M docs/plans/007-V0_1_1_WEB_FRONTEND_FOUNDATION_PLAN.md
```
## Revue opérateur complémentaire
Confirmer que :
- le `FAIL` de `alpha.3.fix.1` est conservé historiquement ;
- `deltas/0.1.1/alpha.3.fix.1.md` n'est pas réécrit ;
- `docs/rules/530-TYPESCRIPT.md`, `docs/rules/540-JAVASCRIPT_PACKAGE_ECOSYSTEM.md` et `docs/templates/008-WEB_TYPESCRIPT_PACKAGE.md` ne sont pas modifiés par le fix ;
- `templates/web-typescript/package.json` et `templates/web-typescript/tsconfig.json` ne sont pas modifiés par le fix ;
- aucun contenu Vite, CSS/Sass, WASM ou Tauri n'est absorbé dans le correctif.
## Transition
### PASS
Produire `history/0.1.1/alpha.3.fix.2.md`, l'appliquer puis committer/pousser le fix. Reprendre ensuite la trajectoire normale avec `0.1.1-alpha.4`, consacré à Vite, au dev server, aux caches et aux outputs de production.
### FAIL
Consigner le diagnostic réel dans `history/0.1.1/alpha.3.fix.2.md` et rester dans `alpha.3.fix.M`. Le scope MUST rester limité à la correction de la gate tant qu'aucun défaut plus large ne justifie un REPLAN.

310
deltas/0.1.1/alpha.3.md Normal file
View File

@@ -0,0 +1,310 @@
<!-- file: deltas/0.1.1/alpha.3.md -->
<!-- version: 1 -->
# Delta 0.1.1-alpha.3 — TypeScript et écosystème de package
## Baseline et version
Baseline attendue : commit opérateur de `0.1.1-alpha.2.fix.1`, réalisé après application de `history/0.1.1/alpha.2.fix.1.md` avec statut `PASS`.
Le hash de ce commit n'est pas anticipé.
Version avant application :
```text
0.1.1-alpha.2.fix.1
```
Version après application :
```text
0.1.1-alpha.3
```
## Objet
Détailler les owners `530 TypeScript` et `540 JavaScript package ecosystem`, puis fournir une baseline minimale réutilisable pour une application Web TypeScript privée.
La tranche définit :
- une baseline TypeScript stricte et indépendante du bundler ;
- le script canonique `typecheck` ;
- la responsabilité de `package.json` et de la sélection explicite du package manager ;
- une politique de lockfile fondée sur le rôle du package et la reproductibilité ;
- une paire minimale `package.json` + `tsconfig.json` sans version TypeScript, package manager, Vite, Sass, framework UI, host ou WASM imposés.
Vite reste réservé à `alpha.4`. CSS/Sass et la validation frontend réconciliée restent réservés à `alpha.5`.
## Scope
REPLACE :
```text
VERSION
docs/000-README.md
docs/plans/007-V0_1_1_WEB_FRONTEND_FOUNDATION_PLAN.md
docs/rules/530-TYPESCRIPT.md
docs/rules/540-JAVASCRIPT_PACKAGE_ECOSYSTEM.md
```
ADD :
```text
deltas/0.1.1/alpha.3.md
docs/templates/008-WEB_TYPESCRIPT_PACKAGE.md
templates/web-typescript/package.json
templates/web-typescript/tsconfig.json
```
DELETE : aucun.
`RULES.md`, `ROADMAP.md`, `CHANGELOG.md`, les profils `550`, `560`, `710`, les skeletons, scripts Python, tests et matrices de validation restent inchangés.
Aucun `history/0.1.1/alpha.3.md` n'est anticipé.
## Décisions TypeScript
La baseline générique contrôlée active :
```text
strict
noEmit
noUnusedLocals
noUnusedParameters
noFallthroughCasesInSwitch
```
Elle n'impose pas :
```text
target
module
moduleResolution
lib
types
jsx
include/exclude
aliases
Vite
WASM
Tauri
```
Ces choix dépendent du runtime, du host, du bundler ou du layout réel.
Le script `typecheck` SHOULD exposer la vérification TypeScript indépendamment du bundler. Le template utilise :
```text
tsc --noEmit
```
Le package manager reste responsable de l'invocation réelle de ce script.
## Décisions package manager / manifest
PGR ne choisit toujours pas npm, pnpm, yarn, Bun ou un autre outil par défaut.
Le projet MUST rendre son choix de package manager explicite dans un owner local approprié. Le champ `packageManager` de `package.json` MAY être utilisé lorsque la toolchain le permet, mais PGR ne peut pas y inscrire une version fictive dans son template générique.
Pour une application non publiée, `private: true` SHOULD être utilisé.
Le template `package.json` n'invente ni version de package, ni dépendance, ni champ de publication. Il fournit seulement un nom d'exemple, `private: true` et le script `typecheck`.
## Politique de lockfile
La politique PGR est désormais :
```text
application privée / déployable
-> lockfile SHOULD être versionné
bibliothèque publiée
-> lockfile MAY être versionné pour dev/CI
mais le manifest reste le contrat consommateur
template / fixture sans résolution réelle
-> lockfile MAY être absent
```
Un package SHOULD NOT conserver plusieurs lockfiles concurrents sauf migration temporaire explicitement documentée.
Lorsqu'un lockfile est versionné, CI SHOULD utiliser le mode gelé/immutable/clean-install équivalent du package manager choisi.
La politique historique Games sans lockfile n'est donc ni réécrite ni qualifiée rétroactivement de défaut. Son adoption `0.1.5` décidera package par package entre `ADOPT` et `OVERRIDE`.
## Templates
Les deux fichiers copiables sont :
```text
templates/web-typescript/package.json
templates/web-typescript/tsconfig.json
```
Ils sont volontairement du JSON strict, donc ne portent pas de commentaires internes `file/version`.
Leur contrat et leurs étapes d'adaptation sont documentés dans :
```text
docs/templates/008-WEB_TYPESCRIPT_PACKAGE.md
```
La paire ne constitue pas encore un skeleton frontend.
## Validation opérateur
Après application du history `PASS`, commit/push de `alpha.2.fix.1`, puis application du présent delta :
```bash
test "$(cat VERSION)" = '0.1.1-alpha.3'
git cat-file -e HEAD:history/0.1.1/alpha.2.fix.1.md
test -f history/0.1.1/alpha.2.fix.1.md
test -f deltas/0.1.1/alpha.3.md
test ! -e history/0.1.1/alpha.3.md
grep -A2 '^## Statut$' history/0.1.1/alpha.2.fix.1.md | grep -Fx 'PASS'
grep -Fx '<!-- version: 26 -->' docs/000-README.md
grep -Fx '<!-- version: 4 -->' docs/plans/007-V0_1_1_WEB_FRONTEND_FOUNDATION_PLAN.md
grep -Fx '<!-- version: 2 -->' docs/rules/530-TYPESCRIPT.md
grep -Fx '<!-- version: 2 -->' docs/rules/540-JAVASCRIPT_PACKAGE_ECOSYSTEM.md
grep -Fx '<!-- version: 1 -->' docs/templates/008-WEB_TYPESCRIPT_PACKAGE.md
python3 -B - <<'PYGATE'
from pathlib import Path
import json
import re
history = Path('history/0.1.1/alpha.2.fix.1.md').read_text(encoding='utf-8')
assert re.search(r'## Statut\s+PASS\s', history)
typescript = Path('docs/rules/530-TYPESCRIPT.md').read_text(encoding='utf-8')
for phrase in (
'strict = true',
'noEmit = true',
'noUnusedLocals = true',
'noUnusedParameters = true',
'noFallthroughCasesInSwitch = true',
'typecheck',
'tsc --noEmit',
'MUST NOT les figer',
):
assert phrase in typescript, phrase
packages = Path('docs/rules/540-JAVASCRIPT_PACKAGE_ECOSYSTEM.md').read_text(encoding='utf-8')
for phrase in (
'private: true',
'MUST sélectionner explicitement son package manager',
'typecheck',
'SHOULD** être versionné',
'SHOULD NOT** conserver simultanément plusieurs lockfiles',
'MUST NOT transformer `npm ci` en commande universelle',
'`ADOPT` cette recommandation',
'`OVERRIDE`',
):
assert phrase in packages, phrase
package = json.loads(Path('templates/web-typescript/package.json').read_text(encoding='utf-8'))
tsconfig = json.loads(Path('templates/web-typescript/tsconfig.json').read_text(encoding='utf-8'))
assert package == {
'name': 'project-web',
'private': True,
'scripts': {'typecheck': 'tsc --noEmit'},
}
assert tsconfig == {
'compilerOptions': {
'strict': True,
'noEmit': True,
'noUnusedLocals': True,
'noUnusedParameters': True,
'noFallthroughCasesInSwitch': True,
}
}
guide = Path('docs/templates/008-WEB_TYPESCRIPT_PACKAGE.md').read_text(encoding='utf-8')
for phrase in (
'package manager concret',
'version TypeScript',
'target ECMAScript',
'Vite ou autre bundler',
"n'acceptent pas un header commentaire PGR",
'npm run typecheck',
'pnpm typecheck',
'yarn typecheck',
):
assert phrase in guide, phrase
plan = Path('docs/plans/007-V0_1_1_WEB_FRONTEND_FOUNDATION_PLAN.md').read_text(encoding='utf-8')
for phrase in (
'Statut opérateur : **PASS**.',
'application privée ou déployable `SHOULD` versionner le lockfile',
"`DEFER` jusqu'à l'adoption `0.1.5`",
'script canonique `typecheck`',
'Vite reste réservé à `alpha.4`',
):
assert phrase in plan, phrase
assert Path('docs/rules/550-VITE.md').read_text(encoding='utf-8').splitlines()[1] == '<!-- version: 1 -->'
assert Path('docs/rules/560-CSS_SASS.md').read_text(encoding='utf-8').splitlines()[1] == '<!-- version: 1 -->'
assert Path('docs/rules/710-TAURI.md').read_text(encoding='utf-8').splitlines()[1] == '<!-- version: 6 -->'
print('0.1.1 alpha.3 TypeScript/package audit: clean (strict typecheck, package-manager neutral, role-based lockfile policy, 2 JSON templates parsed)')
PYGATE
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
git diff --check
git add VERSION docs/000-README.md \
docs/plans/007-V0_1_1_WEB_FRONTEND_FOUNDATION_PLAN.md \
docs/rules/530-TYPESCRIPT.md docs/rules/540-JAVASCRIPT_PACKAGE_ECOSYSTEM.md \
docs/templates/008-WEB_TYPESCRIPT_PACKAGE.md \
templates/web-typescript/package.json templates/web-typescript/tsconfig.json \
deltas/0.1.1/alpha.3.md
git diff --cached --check
git status --short
```
Le scope indexé attendu avant ajout du history est exactement :
```text
M VERSION
A deltas/0.1.1/alpha.3.md
M docs/000-README.md
M docs/plans/007-V0_1_1_WEB_FRONTEND_FOUNDATION_PLAN.md
M docs/rules/530-TYPESCRIPT.md
M docs/rules/540-JAVASCRIPT_PACKAGE_ECOSYSTEM.md
A docs/templates/008-WEB_TYPESCRIPT_PACKAGE.md
A templates/web-typescript/package.json
A templates/web-typescript/tsconfig.json
```
## Revue opérateur complémentaire
Confirmer que :
- la baseline TypeScript générique ne fige aucun choix propre à Vite, Node, WASM ou Tauri ;
- `typecheck` reste une preuve indépendante et ne devient pas une responsabilité du bundler ;
- PGR ne sélectionne aucun package manager universel ;
- le lockfile est recommandé pour les applications privées/déployables sans imposer la même politique aux bibliothèques publiées ;
- le template `package.json` n'invente aucune version de dépendance ou de package manager ;
- les deux JSON restent des templates minimaux, pas un skeleton frontend ;
- aucun contenu de `alpha.4` ou `alpha.5` n'est absorbé.
## Transition
### PASS
Produire `history/0.1.1/alpha.3.md`, l'appliquer puis committer/pousser la tranche. Préparer ensuite `0.1.1-alpha.4` consacré à Vite, au dev server et aux outputs.
### FAIL
Consigner le diagnostic réel dans `history/0.1.1/alpha.3.md` et rester dans `alpha.3.fix.M` sauf REPLAN explicitement justifié.

226
deltas/0.1.1/alpha.4.md Normal file
View File

@@ -0,0 +1,226 @@
<!-- file: deltas/0.1.1/alpha.4.md -->
<!-- version: 1 -->
# Delta 0.1.1-alpha.4 — Vite, dev server et outputs
## Baseline et version
Baseline attendue : commit opérateur de `0.1.1-alpha.3.fix.2`, réalisé après application de `history/0.1.1/alpha.3.fix.2.md` avec statut `PASS`.
Le hash de ce commit n'est pas anticipé.
Version avant application :
```text
0.1.1-alpha.3.fix.2
```
Version après application :
```text
0.1.1-alpha.4
```
## Objet
Compléter l'owner `550-VITE.md` avec un contrat générique de dev server, cache, outputs et assets, puis documenter l'adaptation d'un projet Vite sans inventer un `vite.config.ts` universel.
La tranche conserve Vite comme recommandation `SHOULD`, pas comme obligation.
Elle ne modifie pas :
- la baseline TypeScript/package de `alpha.3` ;
- les règles de déclarations `@types/*` ;
- le profil CSS/Sass réservé à `alpha.5` ;
- le profil Tauri ;
- WASM, backend ou deployment/operations.
## Décisions matérialisées
Le contrat Vite distingue désormais explicitement :
```text
sources versionnées
cache Vite reproductible
outputs build générés
assets sources
assets copiés/transformés
```
Le cache et les outputs `SHOULD` rester hors Git et `SHOULD` être externalisés hors de l'arborescence source lorsqu'un emplacement de build externe est raisonnablement disponible.
`build.emptyOutDir = true` n'est acceptable que sur un répertoire dédié dont Vite possède entièrement le contenu généré.
Le dev server reste local/loopback par défaut. L'exposition réseau est une décision explicite. `server.allowedHosts = true` et `server.cors = true` ne sont pas des défauts PGR.
Lorsqu'une intégration dépend d'un port déterministe, le couple `server.port` + `server.strictPort = true` est recommandé. Les ports eux-mêmes restent locaux.
`vite preview` est classifié comme prévisualisation/smoke local du build, jamais comme serveur de production.
## Pas de `vite.config.ts` générique artificiel
La tranche ajoute [`docs/templates/009-WEB_VITE.md`](../../docs/templates/009-WEB_VITE.md), mais aucun fichier copiable `templates/web-vite/vite.config.ts`.
Cette absence est volontaire : le corpus prouve l'owner et les responsabilités, mais pas une valeur universelle pour `root`, `base`, `cacheDir`, `outDir`, ports, aliases ou plugins.
Un template exécutable pourra être ajouté ultérieurement si une configuration minimale réellement neutre est démontrée. PGR ne crée pas un fichier vide ou rempli de placeholders uniquement pour satisfaire un catalogue.
## Scope
REPLACE :
```text
VERSION
docs/000-README.md
docs/plans/007-V0_1_1_WEB_FRONTEND_FOUNDATION_PLAN.md
docs/rules/550-VITE.md
```
ADD :
```text
docs/templates/009-WEB_VITE.md
deltas/0.1.1/alpha.4.md
```
DELETE : aucun.
## Validation opérateur
Après application du history `PASS`, commit/push de `alpha.3.fix.2`, puis application du présent delta :
```bash
test "$(cat VERSION)" = '0.1.1-alpha.4'
git cat-file -e HEAD:history/0.1.1/alpha.3.fix.2.md
test -f history/0.1.1/alpha.3.fix.2.md
test -f deltas/0.1.1/alpha.4.md
test ! -e history/0.1.1/alpha.4.md
grep -A2 '^## Statut$' history/0.1.1/alpha.3.fix.2.md | grep -Fx 'PASS'
grep -Fx '<!-- version: 27 -->' docs/000-README.md
grep -Fx '<!-- version: 7 -->' docs/plans/007-V0_1_1_WEB_FRONTEND_FOUNDATION_PLAN.md
grep -Fx '<!-- version: 2 -->' docs/rules/550-VITE.md
grep -Fx '<!-- version: 1 -->' docs/templates/009-WEB_VITE.md
python3 -B - <<'PYGATE'
from pathlib import Path
import re
history = Path("history/0.1.1/alpha.3.fix.2.md").read_text(encoding="utf-8")
assert re.search(r"## Statut\s+PASS\s", history)
vite = Path("docs/rules/550-VITE.md").read_text(encoding="utf-8")
for phrase in (
"Vite **SHOULD** être le build tool/dev server privilégié",
"PGR ne fournit pas de `vite.config.ts` universel",
"`cacheDir` **SHOULD** être externalisé",
"Le contenu de `build.outDir` est un output généré",
"`build.emptyOutDir = true`",
"`publicDir` est une capacité optionnelle",
"PGR MUST NOT imposer le nom `frontend/`",
"PGR MUST NOT imposer `./`, `/` ou un chemin de sous-répertoire universel",
"Le dev server **SHOULD** rester limité à la machine locale/loopback",
"`server.port` avec `server.strictPort = true`",
"`server.allowedHosts = true` et `server.cors = true` **SHOULD NOT**",
"Il MUST NOT être présenté comme serveur de production",
"le build de production via le package manager choisi **SHOULD** faire partie de la gate",
):
assert phrase in vite, phrase
guide = Path("docs/templates/009-WEB_VITE.md").read_text(encoding="utf-8")
for phrase in (
"ne fournit volontairement pas de `vite.config.ts` copiable universel",
'"dev": "vite"',
'"build": "vite build"',
'"preview": "vite preview"',
"typecheck -> tsc --noEmit",
"build -> vite build",
"Le nom `frontend/` observé dans Games est une convention locale",
"PGR ne copie donc pas automatiquement `base: \"./\"`",
"Le cache Vite est reproductible",
"`build.outDir` contient des artefacts générés",
"server.allowedHosts = true",
"server.cors = true",
"server.strictPort true",
"Il ne constitue pas un serveur de production PGR",
"PGR ne livre pas encore de `vite.config.ts` exécutable générique",
):
assert phrase in guide, phrase
plan = Path("docs/plans/007-V0_1_1_WEB_FRONTEND_FOUNDATION_PLAN.md").read_text(encoding="utf-8")
for phrase in (
"### alpha.3.fix.2 — correction de la gate des déclarations de types",
"Statut opérateur : **PASS**.",
"### alpha.4 — Vite, dev server et outputs",
"sans créer un `vite.config.ts` universel artificiel",
"TypeScript reste validé séparément ; CSS/Sass reste réservé à `alpha.5`.",
):
assert phrase in plan, phrase
index = Path("docs/000-README.md").read_text(encoding="utf-8")
assert "templates/009-WEB_VITE.md" in index
assert not Path("templates/web-vite/vite.config.ts").exists()
assert Path("docs/rules/530-TYPESCRIPT.md").read_text(encoding="utf-8").splitlines()[1] == "<!-- version: 3 -->"
assert Path("docs/rules/540-JAVASCRIPT_PACKAGE_ECOSYSTEM.md").read_text(encoding="utf-8").splitlines()[1] == "<!-- version: 3 -->"
assert Path("docs/rules/560-CSS_SASS.md").read_text(encoding="utf-8").splitlines()[1] == "<!-- version: 1 -->"
assert Path("docs/rules/710-TAURI.md").read_text(encoding="utf-8").splitlines()[1] == "<!-- version: 6 -->"
print("0.1.1 alpha.4 Vite contract audit: clean (outputs/cache explicit, dev server bounded, no fake universal config, alpha.5 untouched)")
PYGATE
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
git diff --check
git add VERSION docs/000-README.md \
docs/plans/007-V0_1_1_WEB_FRONTEND_FOUNDATION_PLAN.md \
docs/rules/550-VITE.md docs/templates/009-WEB_VITE.md \
deltas/0.1.1/alpha.4.md
git diff --cached --check
git status --short
```
Le scope indexé attendu avant ajout du history de `alpha.4` est exactement :
```text
M VERSION
A deltas/0.1.1/alpha.4.md
M docs/000-README.md
M docs/plans/007-V0_1_1_WEB_FRONTEND_FOUNDATION_PLAN.md
M docs/rules/550-VITE.md
A docs/templates/009-WEB_VITE.md
```
## Revue opérateur complémentaire
Confirmer que :
- Vite reste `SHOULD`, jamais `MUST` universel ;
- aucun package manager n'est imposé ;
- aucun port, host, `base`, alias ou plugin n'est transformé en valeur universelle ;
- aucun `vite.config.ts` artificiellement générique n'est ajouté ;
- cache et outputs sont classifiés comme générés et hors Git ;
- `emptyOutDir` ne peut viser qu'un output dédié ;
- `preview` n'est pas présenté comme serveur de production ;
- TypeScript/package ne sont pas réouverts ;
- CSS/Sass reste réservé à `alpha.5` ;
- Tauri/WASM/deployment restent hors scope.
## Transition
### PASS
Produire `history/0.1.1/alpha.4.md`, l'appliquer puis committer/pousser `alpha.4`. Continuer avec `0.1.1-alpha.5`, consacré à CSS/Sass et à la validation frontend indépendante du host.
### FAIL
Consigner le diagnostic réel dans `history/0.1.1/alpha.4.md`, puis produire `alpha.4.fix.N` ou effectuer un REPLAN si le défaut révèle une frontière d'ownership incorrecte. Ne pas absorber `alpha.5` dans un correctif Vite.

325
deltas/0.1.1/alpha.5.md Normal file
View File

@@ -0,0 +1,325 @@
<!-- file: deltas/0.1.1/alpha.5.md -->
<!-- version: 1 -->
# Delta 0.1.1-alpha.5 — CSS/Sass, validation frontend et skeleton Web
## Baseline et version
Baseline attendue : commit opérateur de `0.1.1-alpha.4`, réalisé après application de `history/0.1.1/alpha.4.md` avec statut `PASS`.
Le hash de ce commit n'est pas anticipé.
Version avant application :
```text
0.1.1-alpha.4
```
Version après application :
```text
0.1.1-alpha.5
```
## Objet
Compléter l'owner `560-CSS_SASS.md`, définir une validation frontend réutilisable indépendante du host et matérialiser un skeleton Web uniquement parce que les owners `530/540/550/560` sont désormais suffisamment séparés et actionnables.
La tranche conserve les décisions suivantes :
- CSS reste valide sans Sass ;
- Sass reste optionnel mais recommandé (`SHOULD`) lorsqu'il apporte une valeur réelle ;
- `@use` / `@forward` sont préférés pour le nouveau Sass contrôlé ;
- `@import` reste une compatibilité possible pour les dépendances qui l'exigent encore ;
- les sources CSS/Sass et leurs outputs générés sont distingués sans ambiguïté ;
- un package de styles est consommé via son entrypoint public/documenté plutôt que par un chemin interne arbitraire ;
- Bootstrap/Tailwind CSS/alternative restent des choix de projet ou skeleton, pas des obligations de `560` ;
- la validation frontend est séparée de la validation du host ;
- le skeleton Web compose des owners existants et ne devient pas leur propriétaire.
Le `DEFER` Tauri n'est pas levé par cette tranche.
## Validation frontend indépendante du host
[`docs/validation/005-WEB_FRONTEND_VALIDATION.md`](../../docs/validation/005-WEB_FRONTEND_VALIDATION.md) définit les couches de preuve réutilisables :
```text
restore reproductible
TypeScript typecheck
styles si preuve distincte
build frontend de production
browser smoke si nécessaire
host integration séparée
```
La matrice évite les doublons : si Sass est déjà compilé par le build Vite et qu'aucun contrat Sass autonome n'existe, une seconde compilation identique n'est pas requise.
Un `PASS` frontend ne vaut jamais automatiquement `PASS` du host.
## Skeleton Web
[`docs/skeletons/003-WEB_FRONTEND.md`](../../docs/skeletons/003-WEB_FRONTEND.md) devient la première specialization Web PGR.
Il peut composer :
```text
GENERAL + 500 + 530 + 540 + 550 + 560
```
mais chaque profil reste sélectionné selon les faits du projet. TypeScript et Vite restent des recommandations `SHOULD`; Sass reste conditionnel.
Le skeleton MUST NOT imposer :
```text
npm
Bootstrap
Tailwind CSS
frontend/
vite.config.ts générique
main.scss générique
port fixe
base fixe
WASM
Tauri
backend
deployment
```
## Pas de faux templates techniques
La tranche ajoute un guide CSS/Sass :
```text
docs/templates/010-WEB_CSS_SASS.md
```
mais aucun `templates/web-css/main.scss` ni autre source de style factice.
Le skeleton réutilise les templates TypeScript/package existants et les guides Vite/CSS-Sass. Les valeurs réellement dépendantes du projet restent à décider pendant l'instanciation.
## Scope
REPLACE :
```text
VERSION
README.md
docs/000-README.md
docs/plans/007-V0_1_1_WEB_FRONTEND_FOUNDATION_PLAN.md
docs/rules/560-CSS_SASS.md
docs/skeletons/000-README.md
docs/validation/001-VALIDATION_MATRIX.md
```
ADD :
```text
docs/skeletons/003-WEB_FRONTEND.md
docs/templates/010-WEB_CSS_SASS.md
docs/validation/005-WEB_FRONTEND_VALIDATION.md
deltas/0.1.1/alpha.5.md
```
DELETE : aucun.
## Validation opérateur
Après application du history `PASS`, commit/push de `alpha.4`, puis application du présent delta :
```bash
test "$(cat VERSION)" = '0.1.1-alpha.5'
git cat-file -e HEAD:history/0.1.1/alpha.4.md
test -f history/0.1.1/alpha.4.md
test -f deltas/0.1.1/alpha.5.md
test ! -e history/0.1.1/alpha.5.md
grep -A2 '^## Statut$' history/0.1.1/alpha.4.md | grep -Fx 'PASS'
grep -Fx '<!-- version: 18 -->' README.md
grep -Fx '<!-- version: 28 -->' docs/000-README.md
grep -Fx '<!-- version: 8 -->' docs/plans/007-V0_1_1_WEB_FRONTEND_FOUNDATION_PLAN.md
grep -Fx '<!-- version: 2 -->' docs/rules/560-CSS_SASS.md
grep -Fx '<!-- version: 6 -->' docs/skeletons/000-README.md
grep -Fx '<!-- version: 1 -->' docs/skeletons/003-WEB_FRONTEND.md
grep -Fx '<!-- version: 1 -->' docs/templates/010-WEB_CSS_SASS.md
grep -Fx '<!-- version: 14 -->' docs/validation/001-VALIDATION_MATRIX.md
grep -Fx '<!-- version: 1 -->' docs/validation/005-WEB_FRONTEND_VALIDATION.md
python3 -B - <<'PYGATE'
from pathlib import Path
import re
history = Path("history/0.1.1/alpha.4.md").read_text(encoding="utf-8")
assert re.search(r"## Statut\s+PASS\s", history)
styles = Path("docs/rules/560-CSS_SASS.md").read_text(encoding="utf-8")
for phrase in (
"Sass **SHOULD** être préféré",
"Sass n'est donc jamais requis",
"MUST NOT être modifié manuellement",
"`@use` / `@forward`",
"L'ancien `@import` Sass est déprécié",
"entrypoint Sass public",
"`sass-embedded` **SHOULD** être préféré",
"Un package npm apportant uniquement des styles n'impose pas l'ajout de déclarations `@types/*`",
"un build Vite réussi peut constituer la preuve de compilation des styles",
"005-WEB_FRONTEND_VALIDATION.md",
):
assert phrase in styles, phrase
guide = Path("docs/templates/010-WEB_CSS_SASS.md").read_text(encoding="utf-8")
for phrase in (
"ne fournit volontairement pas de `main.scss`",
"CSS seul reste valide",
"sass-embedded",
"@use",
"@forward",
"Les dépendances `@types/*` ne concernent que les API JavaScript/TypeScript",
"PGR ne fixe ni Bootstrap, ni Bootswatch",
"host gate séparée",
):
assert phrase in guide, phrase
validation = Path("docs/validation/005-WEB_FRONTEND_VALIDATION.md").read_text(encoding="utf-8")
for phrase in (
"Le frontend **SHOULD** être validable indépendamment du host",
"Un résultat frontend `PASS`",
"restauration reproductible des dépendances",
"type-check TypeScript",
"build frontend de production",
"preview / smoke navigateur",
"PGR MUST NOT imposer `npm ci`",
"PGR SHOULD NOT lancer deux compilations équivalentes",
"Un host tel que Tauri",
"Il ne vaut pas `PASS` Tauri",
):
assert phrase in validation, phrase
skeleton = Path("docs/skeletons/003-WEB_FRONTEND.md").read_text(encoding="utf-8")
for phrase in (
"GENERAL",
"+ 530 TypeScript",
"+ 540 JavaScript package ecosystem",
"+ 550 Vite",
"+ 560 CSS / Sass",
"Le skeleton ne transforme pas une recommandation `SHOULD` en `MUST`",
"PGR ne fournit pas de `vite.config.ts` universel",
"PGR ne fournit pas non plus de `main.scss`",
"Le nom `frontend/` est une convention possible",
"le package manager réel",
"Bootstrap, Tailwind CSS ou autre",
"Le skeleton Tauri reste `DEFER` pendant `0.1.1`",
):
assert phrase in skeleton, phrase
matrix = Path("docs/validation/001-VALIDATION_MATRIX.md").read_text(encoding="utf-8")
assert "005-WEB_FRONTEND_VALIDATION.md" in matrix
index = Path("docs/000-README.md").read_text(encoding="utf-8")
for target in (
"templates/010-WEB_CSS_SASS.md",
"validation/005-WEB_FRONTEND_VALIDATION.md",
"skeletons/003-WEB_FRONTEND.md",
):
assert target in index, target
skeleton_index = Path("docs/skeletons/000-README.md").read_text(encoding="utf-8")
assert "003-WEB_FRONTEND.md" in skeleton_index
assert "La création du skeleton Web ne lève pas automatiquement ce `DEFER`." in skeleton_index
plan = Path("docs/plans/007-V0_1_1_WEB_FRONTEND_FOUNDATION_PLAN.md").read_text(encoding="utf-8")
for phrase in (
"### alpha.4 — Vite, dev server et outputs",
"Statut opérateur : **PASS**.",
"### alpha.5 — CSS/Sass et validation frontend",
"Les owners `530/540/550/560` sont désormais assez complets",
"Le skeleton ne lève pas le `DEFER` Tauri",
):
assert phrase in plan, phrase
study = Path("docs/studies/002-TAURI_SKELETON_DECISION.md").read_text(encoding="utf-8")
assert "DEFER" in study
for phrase in (
"TypeScript et conventions Web contrôlées",
"Vite et ownership des commandes/dev server/build outputs",
"Sass/CSS et statut des artefacts générés",
"validation frontend indépendante de la validation Tauri",
"choix Bootstrap ou alternative clairement classifié",
):
assert phrase in study, phrase
assert not Path("templates/web-vite/vite.config.ts").exists()
assert not Path("templates/web-css/main.scss").exists()
assert Path("docs/rules/530-TYPESCRIPT.md").read_text(encoding="utf-8").splitlines()[1] == "<!-- version: 3 -->"
assert Path("docs/rules/540-JAVASCRIPT_PACKAGE_ECOSYSTEM.md").read_text(encoding="utf-8").splitlines()[1] == "<!-- version: 3 -->"
assert Path("docs/rules/550-VITE.md").read_text(encoding="utf-8").splitlines()[1] == "<!-- version: 2 -->"
assert Path("docs/rules/710-TAURI.md").read_text(encoding="utf-8").splitlines()[1] == "<!-- version: 6 -->"
assert "0.1.8" not in Path("ROADMAP.md").read_text(encoding="utf-8")
print("0.1.1 alpha.5 Web frontend audit: clean (CSS/Sass bounded, host-independent validation explicit, Web skeleton composable, Tauri DEFER preserved)")
PYGATE
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
git diff --check
git add VERSION README.md docs/000-README.md \
docs/plans/007-V0_1_1_WEB_FRONTEND_FOUNDATION_PLAN.md \
docs/rules/560-CSS_SASS.md \
docs/skeletons/000-README.md docs/skeletons/003-WEB_FRONTEND.md \
docs/templates/010-WEB_CSS_SASS.md \
docs/validation/001-VALIDATION_MATRIX.md docs/validation/005-WEB_FRONTEND_VALIDATION.md \
deltas/0.1.1/alpha.5.md
git diff --cached --check
git status --short
```
Le scope indexé attendu avant ajout du history de `alpha.5` est exactement :
```text
M README.md
M VERSION
A deltas/0.1.1/alpha.5.md
M docs/000-README.md
M docs/plans/007-V0_1_1_WEB_FRONTEND_FOUNDATION_PLAN.md
M docs/rules/560-CSS_SASS.md
M docs/skeletons/000-README.md
A docs/skeletons/003-WEB_FRONTEND.md
A docs/templates/010-WEB_CSS_SASS.md
M docs/validation/001-VALIDATION_MATRIX.md
A docs/validation/005-WEB_FRONTEND_VALIDATION.md
```
## Revue opérateur complémentaire
Confirmer que :
- Sass reste `SHOULD` et conditionnel ;
- CSS seul reste une baseline valide ;
- `@use` / `@forward` sont préférés sans casser les dépendances encore basées sur `@import` ;
- aucun CSS compilé n'est présenté comme source à modifier ;
- aucune dépendance Sass/Vite/Bootstrap n'est injectée dans le template `package.json` générique ;
- aucun `main.scss` ou `vite.config.ts` artificiel n'est ajouté ;
- le skeleton `003-WEB_FRONTEND.md` compose les owners au lieu de recopier leurs règles ;
- npm, Bootstrap, Tailwind CSS, `frontend/`, ports et `base` restent des décisions locales ;
- la validation frontend peut être exécutée séparément du host autant que le graphe réel le permet ;
- un `PASS` frontend n'est pas présenté comme un `PASS` Tauri ;
- le `DEFER` du skeleton Tauri reste intact ;
- WASM, backend et deployment restent hors scope.
## Transition
### PASS
Produire `history/0.1.1/alpha.5.md`, l'appliquer puis committer/pousser `alpha.5`. Continuer avec `0.1.1-beta.1` pour la réconciliation large, le dry-run proportionné du skeleton Web et la preuve factuelle de préparation du futur réexamen Tauri.
### FAIL
Consigner le diagnostic réel dans `history/0.1.1/alpha.5.md`, puis produire `alpha.5.fix.N` ou effectuer un REPLAN si le défaut révèle une frontière d'ownership incorrecte. Ne pas absorber `beta.1` dans un correctif CSS/Sass.

264
deltas/0.1.1/beta.1.md Normal file
View File

@@ -0,0 +1,264 @@
<!-- file: deltas/0.1.1/beta.1.md -->
<!-- version: 1 -->
# Delta 0.1.1-beta.1 — réconciliation Web et préparation du réexamen Tauri
## Baseline et version
Baseline attendue : commit opérateur de `0.1.1-alpha.5`, réalisé après application de `history/0.1.1/alpha.5.md` avec statut `PASS`.
Le hash de ce commit n'est pas anticipé.
Version avant application :
```text
0.1.1-alpha.5
```
Version après application :
```text
0.1.1-beta.1
```
## Objet
Fermer la phase alpha de `0.1.1` en réconciliant la fondation frontend Web désormais matérialisée et en vérifiant factuellement si les cinq conditions de sortie du `DEFER` Tauri possèdent des owners PGR suffisants.
La tranche :
- enregistre le `PASS` de `alpha.5` dans le plan actif ;
- exécute un dry-run structurel du skeleton `003-WEB_FRONTEND.md` sans simuler les toolchains qu'un projet réel doit exécuter ;
- révise `002-TAURI_SKELETON_DECISION.md` pour comparer chacune des cinq conditions historiques aux owners réels `530/540/550/560`, guides, templates et validation désormais disponibles ;
- met à jour la roadmap pour distinguer « prérequis Web couverts » de « skeleton Tauri adopté » ;
- conserve le skeleton Tauri en `DEFER` jusqu'au réexamen autonome prévu en `0.1.4`.
Aucun profil Web, template technique, skeleton ou contrat de validation n'est modifié dans `beta.1`.
## Dry-run structurel du skeleton Web
Le dry-run vérifie uniquement ce que PGR peut prouver sans inventer un projet concret :
```text
skeleton 003 référence owners 530 / 540 / 550 / 560
skeleton 003 référence validation 005
package.json + tsconfig.json génériques se copient et se parsèrent comme JSON
aucun vite.config.ts universel n'est injecté
aucun main.scss universel n'est injecté
aucun host Tauri n'est injecté
aucune devDependency arbitraire n'est ajoutée au package.json générique
```
Cette preuve ne vaut pas type-check/build Sass/Vite. Une instanciation réelle doit sélectionner ses versions, dépendances, layout et configuration puis exécuter les outils propriétaires conformément à `005-WEB_FRONTEND_VALIDATION.md`.
## Réconciliation des cinq conditions Tauri
`docs/studies/002-TAURI_SKELETON_DECISION.md` enregistre désormais les correspondances suivantes :
```text
TypeScript contrôlé -> 530 + 008 + templates web-typescript
Vite/dev server/build outputs -> 550 + 009
CSS/Sass + artefacts générés -> 560 + 010
validation frontend indépendante du host -> validation 005
framework CSS = choix local -> 560 + skeleton 003
```
Les cinq prérequis sont donc **couverts pour préparer un réexamen**.
Cette conclusion ne signifie pas :
- que Vite, Sass, Bootstrap ou `frontend/` sont obligatoires pour Tauri ;
- que le candidat historique reste optimal en `0.1.4` ;
- que le corpus `0.0.5` peut être réutilisé sans réaudit ;
- que le skeleton Tauri est créé, adopté ou autorisé pendant `0.1.1`.
## Scope
REPLACE :
```text
VERSION
ROADMAP.md
docs/000-README.md
docs/plans/007-V0_1_1_WEB_FRONTEND_FOUNDATION_PLAN.md
docs/studies/000-README.md
docs/studies/002-TAURI_SKELETON_DECISION.md
```
ADD :
```text
deltas/0.1.1/beta.1.md
```
DELETE : aucun.
`README.md`, `RULES.md`, `CHANGELOG.md`, les profils `530/540/550/560/710`, les skeletons, templates techniques, contrats de validation et scripts restent inchangés.
## Validation opérateur
Après application du history `PASS`, commit/push de `alpha.5`, puis application du présent delta :
```bash
test "$(cat VERSION)" = '0.1.1-beta.1'
git cat-file -e HEAD:history/0.1.1/alpha.5.md
test -f history/0.1.1/alpha.5.md
test -f deltas/0.1.1/beta.1.md
test ! -e history/0.1.1/beta.1.md
grep -A2 '^## Statut$' history/0.1.1/alpha.5.md | grep -Fx 'PASS'
grep -Fx '<!-- version: 11 -->' ROADMAP.md
grep -Fx '<!-- version: 29 -->' docs/000-README.md
grep -Fx '<!-- version: 9 -->' docs/plans/007-V0_1_1_WEB_FRONTEND_FOUNDATION_PLAN.md
grep -Fx '<!-- version: 4 -->' docs/studies/000-README.md
grep -Fx '<!-- version: 2 -->' docs/studies/002-TAURI_SKELETON_DECISION.md
```
Réconciliation et dry-run structurel :
```bash
python3 -B - <<'PYGATE'
from pathlib import Path
import json
import re
import shutil
import tempfile
history = Path("history/0.1.1/alpha.5.md").read_text(encoding="utf-8")
assert re.search(r"## Statut\s+PASS\s", history)
plan = Path("docs/plans/007-V0_1_1_WEB_FRONTEND_FOUNDATION_PLAN.md").read_text(encoding="utf-8")
for phrase in (
"### alpha.5 — CSS/Sass et validation frontend",
"Statut opérateur : **PASS**.",
"### beta.1 — réconciliation et preuve de préparation Tauri",
"Statut opérateur : **à valider**.",
"dry-run structurel du skeleton Web",
"Ce dry-run ne prétend pas remplacer `tsc`, Vite ou Sass",
):
assert phrase in plan, phrase
study = Path("docs/studies/002-TAURI_SKELETON_DECISION.md").read_text(encoding="utf-8")
for phrase in (
"DEFER",
"## Réexamen de préparation 0.1.1-beta.1",
"### Condition 1 — TypeScript et conventions Web contrôlées",
"### Condition 2 — Vite et ownership des commandes/dev server/build outputs",
"### Condition 3 — Sass/CSS et statut des artefacts générés",
"### Condition 4 — validation frontend indépendante de la validation Tauri",
"### Condition 5 — framework CSS classé comme décision de skeleton/projet",
"Les cinq conditions de sortie formulées en `0.0.5-alpha.9` possèdent désormais des owners PGR matérialisés et non redondants.",
"skeleton Tauri dans 0.1.1 toujours DEFER",
"réexamen autorisé 0.1.4",
"La présente étude ne préjuge pas de cette décision.",
):
assert phrase in study, phrase
roadmap = Path("ROADMAP.md").read_text(encoding="utf-8")
assert "skeleton Tauri jusqu'au réexamen 0.1.4" in roadmap
assert "0.1.1-beta.1` confirme que ses cinq prérequis Web disposent désormais d'owners PGR" in roadmap
assert "- `( ) 0.1.4`" in roadmap
assert "0.1.8" not in roadmap
skeleton = Path("docs/skeletons/003-WEB_FRONTEND.md").read_text(encoding="utf-8")
for phrase in (
"+ 530 TypeScript",
"+ 540 JavaScript package ecosystem",
"+ 550 Vite",
"+ 560 CSS / Sass",
"005-WEB_FRONTEND_VALIDATION.md",
"Le skeleton Tauri reste `DEFER` pendant `0.1.1`",
):
assert phrase in skeleton, phrase
package_source = Path("templates/web-typescript/package.json")
tsconfig_source = Path("templates/web-typescript/tsconfig.json")
with tempfile.TemporaryDirectory(prefix="pgr-web-skeleton-") as temp_name:
temp = Path(temp_name)
shutil.copy2(package_source, temp / "package.json")
shutil.copy2(tsconfig_source, temp / "tsconfig.json")
package = json.loads((temp / "package.json").read_text(encoding="utf-8"))
tsconfig = json.loads((temp / "tsconfig.json").read_text(encoding="utf-8"))
assert package == {
"name": "project-web",
"private": True,
"scripts": {"typecheck": "tsc --noEmit"},
}
assert tsconfig["compilerOptions"]["strict"] is True
assert tsconfig["compilerOptions"]["noEmit"] is True
assert "dependencies" not in package
assert "devDependencies" not in package
assert not (temp / "vite.config.ts").exists()
assert not (temp / "main.scss").exists()
assert not (temp / "src-tauri").exists()
assert not Path("templates/web-vite/vite.config.ts").exists()
assert not Path("templates/web-css/main.scss").exists()
assert Path("docs/rules/530-TYPESCRIPT.md").read_text(encoding="utf-8").splitlines()[1] == "<!-- version: 3 -->"
assert Path("docs/rules/540-JAVASCRIPT_PACKAGE_ECOSYSTEM.md").read_text(encoding="utf-8").splitlines()[1] == "<!-- version: 3 -->"
assert Path("docs/rules/550-VITE.md").read_text(encoding="utf-8").splitlines()[1] == "<!-- version: 2 -->"
assert Path("docs/rules/560-CSS_SASS.md").read_text(encoding="utf-8").splitlines()[1] == "<!-- version: 2 -->"
assert Path("docs/rules/710-TAURI.md").read_text(encoding="utf-8").splitlines()[1] == "<!-- version: 6 -->"
assert Path("docs/skeletons/003-WEB_FRONTEND.md").read_text(encoding="utf-8").splitlines()[1] == "<!-- version: 1 -->"
assert Path("docs/validation/005-WEB_FRONTEND_VALIDATION.md").read_text(encoding="utf-8").splitlines()[1] == "<!-- version: 1 -->"
print("0.1.1 beta.1 reconciliation audit: clean (Web skeleton composes structurally, five Tauri Web prerequisites covered, DEFER preserved for 0.1.4)")
PYGATE
```
Puis rejouer les preuves PGR :
```bash
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
git diff --check
git add VERSION ROADMAP.md docs/000-README.md \
docs/plans/007-V0_1_1_WEB_FRONTEND_FOUNDATION_PLAN.md \
docs/studies/000-README.md docs/studies/002-TAURI_SKELETON_DECISION.md \
deltas/0.1.1/beta.1.md
git diff --cached --check
git status --short
```
Le scope indexé attendu avant ajout du history de `beta.1` est exactement :
```text
M ROADMAP.md
M VERSION
A deltas/0.1.1/beta.1.md
M docs/000-README.md
M docs/plans/007-V0_1_1_WEB_FRONTEND_FOUNDATION_PLAN.md
M docs/studies/000-README.md
M docs/studies/002-TAURI_SKELETON_DECISION.md
```
## Revue opérateur complémentaire
Confirmer que :
- les cinq conditions historiques du `DEFER` Tauri sont toutes rattachées à des owners/artifacts PGR existants ;
- cette couverture est décrite comme préparation de `0.1.4`, pas comme promotion du skeleton Tauri ;
- le corpus Tauri devra être réexaminé en `0.1.4` au lieu d'être supposé inchangé ;
- le dry-run structurel ne prétend pas remplacer `tsc`, Vite, Sass ou un package manager réel ;
- aucun profil, skeleton, template technique ou contrat de validation n'est modifié dans `beta.1` ;
- `frontend/`, Vite, Sass, Bootstrap, npm, TS-RS et WASM ne deviennent pas des obligations Tauri ;
- `0.1.8` n'est pas réservé et l'horizon engagé reste inchangé.
## Transition
### PASS
Produire `history/0.1.1/beta.1.md`, l'appliquer puis committer/pousser `beta.1`. Continuer avec `0.1.1-rc.1` pour geler le scope, préparer l'entrée `CHANGELOG`, rejouer le release gate complet et vérifier le prompt de reprise `0.1.2` si la roadmap reste valide.
### FAIL
Consigner le diagnostic réel dans `history/0.1.1/beta.1.md`, puis produire `beta.1.fix.N` ou effectuer un REPLAN si la réconciliation révèle un owner Web manquant. Ne pas masquer une lacune en créant prématurément le skeleton Tauri.

331
deltas/0.1.1/rc.1.md Normal file
View File

@@ -0,0 +1,331 @@
<!-- file: deltas/0.1.1/rc.1.md -->
<!-- version: 1 -->
# Delta 0.1.1-rc.1 — gel du scope et gate de release candidate
## Baseline et version
Baseline attendue : commit opérateur de `0.1.1-beta.1`, réalisé après application de `history/0.1.1/beta.1.md` avec statut `PASS`.
Le hash de ce commit n'est pas anticipé.
Version avant application :
```text
0.1.1-beta.1
```
Version après application :
```text
0.1.1-rc.1
```
## Objet et gel
La RC gèle le scope fonctionnel de `0.1.1` sur :
- les quatre owners indépendants `530 — TypeScript`, `540 — JavaScript package ecosystem`, `550 — Vite` et `560 — CSS / Sass` ;
- la baseline TypeScript/package avec `strict`, `noEmit`, script `typecheck`, politique de lockfile par rôle et déclarations de types externes conditionnelles ;
- Vite comme build tool/dev server recommandé mais non obligatoire, avec ownership explicite des caches, outputs, assets et limites d'exposition du dev server ;
- CSS comme baseline valide et Sass recommandé lorsqu'il apporte une valeur réelle, avec préférence `@use` / `@forward`, consommation des entrypoints publics et séparation source/généré ;
- la validation frontend `005` indépendante du host ;
- le skeleton Web `003` composable sans `vite.config.ts`, `main.scss`, package manager, framework CSS ou layout universels ;
- la preuve `beta.1` que les cinq prérequis Web du futur réexamen Tauri sont couverts, sans lever le `DEFER` avant `0.1.4`.
Le changelog reçoit une entrée candidate `0.1.1` orientée utilisateurs. Le prompt `008-V0_1_2_START_PROMPT.md` est préparé pour la prochaine cible engagée Java/Maven/Gradle avec frontière Android explicite.
Aucune nouvelle fonctionnalité normative n'entre dans cette RC. Les profils, skeletons, templates techniques et contrats de validation Web sont vérifiés mais non modifiés.
## Scope
REPLACE :
```text
VERSION
CHANGELOG.md
docs/000-README.md
docs/plans/007-V0_1_1_WEB_FRONTEND_FOUNDATION_PLAN.md
```
ADD :
```text
deltas/0.1.1/rc.1.md
prompts/008-V0_1_2_START_PROMPT.md
```
DELETE : aucun.
Le history `beta.1` est livré séparément et MUST être appliqué/committé avant ce delta.
## Gate opérateur de release candidate
Après application du history `PASS` de `beta.1`, commit/push de `beta.1`, puis application du présent delta :
```bash
test "$(cat VERSION)" = '0.1.1-rc.1'
git cat-file -e HEAD:history/0.1.1/beta.1.md
test -f history/0.1.1/beta.1.md
test -f deltas/0.1.1/rc.1.md
test -f prompts/008-V0_1_2_START_PROMPT.md
test ! -e history/0.1.1/rc.1.md
grep -A2 '^## Statut$' history/0.1.1/beta.1.md | grep -Fx 'PASS'
grep -Fx '<!-- version: 12 -->' CHANGELOG.md
grep -Fx '## 0.1.1 (candidate)' CHANGELOG.md
grep -Fx '<!-- version: 30 -->' docs/000-README.md
grep -Fx '<!-- version: 10 -->' docs/plans/007-V0_1_1_WEB_FRONTEND_FOUNDATION_PLAN.md
grep -Fx '<!-- version: 11 -->' ROADMAP.md
grep -Fx '<!-- version: 1 -->' prompts/008-V0_1_2_START_PROMPT.md
```
Contrôle d'intégration de la RC :
```bash
python3 -B - <<'PYGATE'
from pathlib import Path
import json
import re
import shutil
import tempfile
expected = {
"alpha.1.md": "PASS",
"alpha.2.md": "FAIL",
"alpha.2.fix.1.md": "PASS",
"alpha.3.md": "PASS",
"alpha.3.fix.1.md": "FAIL",
"alpha.3.fix.2.md": "PASS",
"alpha.4.md": "PASS",
"alpha.5.md": "PASS",
"beta.1.md": "PASS",
}
histories = {path.name for path in Path("history/0.1.1").glob("*.md")}
assert histories == set(expected), histories
for name, status in expected.items():
text = Path("history/0.1.1", 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.1.1").glob("*.md")}
assert deltas == set(expected) | {"rc.1.md"}, deltas
changelog = Path("CHANGELOG.md").read_text(encoding="utf-8")
assert "## 0.1.1 (candidate)" in changelog
section = changelog.split("## 0.1.1 (candidate)", 1)[1].split("## 0.1.0", 1)[0]
for phrase in (
"quatre owners indépendants",
"TypeScript",
"@types/*",
"package JavaScript",
"Vite",
"CSS comme baseline valide",
"Sass",
"validation frontend indépendante du host",
"DEFER",
"0.1.4",
):
assert phrase in section, phrase
for forbidden in (
"alpha.2",
"alpha.3",
"alpha.4",
"alpha.5",
"beta.1",
"rc.1",
):
assert forbidden not in section, forbidden
plan = Path("docs/plans/007-V0_1_1_WEB_FRONTEND_FOUNDATION_PLAN.md").read_text(encoding="utf-8")
for phrase in (
"### beta.1 — réconciliation et preuve de préparation Tauri\n\nStatut opérateur : **PASS**.",
"### rc.1 — release candidate\n\nStatut opérateur : **à valider**.",
"prompts/008-V0_1_2_START_PROMPT.md",
"Aucune nouvelle fonctionnalité normative ne doit apparaître en RC.",
):
assert phrase in plan, phrase
prompt = Path("prompts/008-V0_1_2_START_PROMPT.md").read_text(encoding="utf-8")
for phrase in (
"archive source téléchargée depuis le tag Gitea `v0.1.1`",
"pgr-0.1.1-publish.001-report.md",
"0.1.2-alpha.1",
"ad6e44a1332eb7d6069cf1189d9433f0fbb8fac19c5aac9f4641ac45c1c556e8",
"520-JAVA_MAVEN_GRADLE.md",
"610-ANDROID.md",
"ADOPT / KEEP-LOCAL / OVERRIDE / DEFER",
"Gradle système versus Wrapper",
"Maven",
"Frontière Android obligatoire",
"réservé à `0.1.4`",
):
assert phrase in prompt, phrase
roadmap = Path("ROADMAP.md").read_text(encoding="utf-8")
for version in ("0.1.1", "0.1.2", "0.1.3", "0.1.4", "0.1.5", "0.1.6", "0.1.7"):
assert f"- `( ) {version}`" in roadmap, version
assert "- `( ) 0.1.8`" not in roadmap
assert "skeleton Tauri jusqu'au réexamen 0.1.4" in roadmap
for path, version in (
("docs/rules/530-TYPESCRIPT.md", 3),
("docs/rules/540-JAVASCRIPT_PACKAGE_ECOSYSTEM.md", 3),
("docs/rules/550-VITE.md", 2),
("docs/rules/560-CSS_SASS.md", 2),
("docs/rules/710-TAURI.md", 6),
("docs/skeletons/003-WEB_FRONTEND.md", 1),
("docs/validation/005-WEB_FRONTEND_VALIDATION.md", 1),
("docs/studies/002-TAURI_SKELETON_DECISION.md", 2),
):
lines = Path(path).read_text(encoding="utf-8").splitlines()
assert lines[1] == f"<!-- version: {version} -->", (path, lines[1])
study = Path("docs/studies/002-TAURI_SKELETON_DECISION.md").read_text(encoding="utf-8")
for phrase in (
"DEFER",
"Condition 1 — TypeScript et conventions Web contrôlées",
"Condition 2 — Vite et ownership des commandes/dev server/build outputs",
"Condition 3 — Sass/CSS et statut des artefacts générés",
"Condition 4 — validation frontend indépendante de la validation Tauri",
"Condition 5 — framework CSS classé comme décision de skeleton/projet",
"réexamen autorisé 0.1.4",
):
assert phrase in study, phrase
package_source = Path("templates/web-typescript/package.json")
tsconfig_source = Path("templates/web-typescript/tsconfig.json")
with tempfile.TemporaryDirectory(prefix="pgr-rc1-web-") as temp_name:
temp = Path(temp_name)
shutil.copy2(package_source, temp / "package.json")
shutil.copy2(tsconfig_source, temp / "tsconfig.json")
package = json.loads((temp / "package.json").read_text(encoding="utf-8"))
tsconfig = json.loads((temp / "tsconfig.json").read_text(encoding="utf-8"))
assert package == {
"name": "project-web",
"private": True,
"scripts": {"typecheck": "tsc --noEmit"},
}
assert tsconfig["compilerOptions"] == {
"strict": True,
"noEmit": True,
"noUnusedLocals": True,
"noUnusedParameters": True,
"noFallthroughCasesInSwitch": True,
}
assert not (temp / "vite.config.ts").exists()
assert not (temp / "main.scss").exists()
assert not (temp / "src-tauri").exists()
assert not Path("templates/web-vite/vite.config.ts").exists()
assert not Path("templates/web-css/main.scss").exists()
index = Path("docs/000-README.md").read_text(encoding="utf-8")
assert "../prompts/008-V0_1_2_START_PROMPT.md" in index
print("0.1.1 rc.1 integration audit: clean (9 prior histories, frozen Web foundation, candidate changelog and prompt 008 verified)")
PYGATE
```
Rejouer ensuite les preuves PGR :
```bash
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
```
Vérifier également l'hygiène texte/JSON sans prétendre remplacer les toolchains frontend :
```bash
python3 -B - <<'PYHYGIENE'
from pathlib import Path
import json
json.loads(Path("templates/web-typescript/package.json").read_text(encoding="utf-8"))
json.loads(Path("templates/web-typescript/tsconfig.json").read_text(encoding="utf-8"))
roots = (
Path("VERSION"),
Path("README.md"),
Path("RULES.md"),
Path("ROADMAP.md"),
Path("CHANGELOG.md"),
Path("docs"),
Path("deltas"),
Path("history"),
Path("prompts"),
Path("templates"),
)
files = []
for root in roots:
if root.is_file():
files.append(root)
elif root.is_dir():
files.extend(path for path in root.rglob("*") if path.is_file())
for path in files:
try:
data = path.read_bytes()
text = data.decode("utf-8")
except UnicodeDecodeError:
continue
assert b"\r" not in data, path
assert text.endswith("\n"), path
for number, line in enumerate(text.splitlines(), 1):
assert line == line.rstrip(" \t"), (path, number)
print("0.1.1 rc.1 text/JSON hygiene: clean")
PYHYGIENE
git diff --check
git add VERSION CHANGELOG.md docs/000-README.md \
docs/plans/007-V0_1_1_WEB_FRONTEND_FOUNDATION_PLAN.md \
prompts/008-V0_1_2_START_PROMPT.md \
deltas/0.1.1/rc.1.md
git diff --cached --check
git status --short
```
Le scope indexé attendu avant ajout du history de `rc.1` est exactement :
```text
M CHANGELOG.md
M VERSION
A deltas/0.1.1/rc.1.md
M docs/000-README.md
M docs/plans/007-V0_1_1_WEB_FRONTEND_FOUNDATION_PLAN.md
A prompts/008-V0_1_2_START_PROMPT.md
```
## Revue opérateur complémentaire
Confirmer que :
- le scope normatif Web est gelé ;
- aucun owner `530/540/550/560`, skeleton, template technique ou contrat de validation n'est modifié par la RC ;
- le changelog candidat décrit les capacités utiles de `0.1.1` sans recopier les tranches internes ;
- TypeScript, Vite et Sass restent des recommandations conditionnelles et non des obligations universelles ;
- le prompt `008` réévalue le profil `520` avant de créer de nouveaux artefacts Java/Gradle ;
- le prompt `008` ne transforme pas les choix Android de Games en règles Java/Gradle générales ;
- Maven reste dans l'owner `520`, mais aucun nouvel artefact Maven n'est anticipé sans corpus réel ;
- le skeleton Tauri reste `DEFER` et son réexamen reste réservé à `0.1.4` ;
- `0.1.8` n'est pas réservé ;
- aucun résultat `tsc`, Vite ou Sass n'est revendiqué alors que PGR ne contient pas de frontend concret ni de dépendances installées pour cette RC.
## Transition
### PASS
Produire `history/0.1.1/rc.1.md`, l'appliquer puis committer/pousser `rc.1`. Continuer avec `0.1.1-rel.1` pour la promotion mécanique vers la stable, la clôture roadmap/plan/changelog et la gate pré-tag.
### FAIL
Consigner le diagnostic réel dans `history/0.1.1/rc.1.md`. Corriger uniquement la release candidate dans `rc.1.fix.N` tant qu'aucun défaut normatif plus large ne justifie un REPLAN. Ne pas préparer `rel.1` tant que la RC n'a pas obtenu `PASS`.

252
deltas/0.1.1/rel.1.md Normal file
View File

@@ -0,0 +1,252 @@
<!-- file: deltas/0.1.1/rel.1.md -->
<!-- version: 1 -->
# Delta 0.1.1 rel.1 — promotion stable pré-tag
## Baseline et version
Baseline : `0.1.1-rc.1`, avec `history/0.1.1/rc.1.md` appliqué et committé. Ce delta MUST NOT être appliqué avant ce commit.
Version avant application :
```text
0.1.1-rc.1
```
Version après application :
```text
0.1.1
```
`rel.1` identifie la clôture opérationnelle ; il ne fait pas partie de la version SemVer du produit.
## Objet
Promouvoir mécaniquement la RC validée vers la stable `0.1.1` sans rouvrir le scope fonctionnel.
La tranche finalise uniquement la présentation et les métadonnées de release : version stable, roadmap terminée, changelog sans marqueur `candidate`, README/index en état stable et plan `007` historique. Aucun owner, profil, template, skeleton, validation, étude technique ou script d'audit n'est modifié.
La validation de cette tranche est **pré-tag**. Le tag `v0.1.1`, son archive source Gitea et le rapport `pgr-0.1.1-publish.001-report.md` ne sont pas déclarés existants par ce delta. Ils suivent uniquement un history `rel.1` `PASS`, le commit stable `0.1.1` et la publication réelle du tag.
## Scope
REPLACE :
```text
VERSION
README.md
ROADMAP.md
CHANGELOG.md
docs/000-README.md
docs/plans/007-V0_1_1_WEB_FRONTEND_FOUNDATION_PLAN.md
```
ADD :
```text
deltas/0.1.1/rel.1.md
```
DELETE : aucun.
Le history `rc.1` est livré séparément. Le history `rel.1` sera produit uniquement après la gate opérateur.
## Validation opérateur pré-tag
Après application sur le commit contenant `history/0.1.1/rc.1.md` :
```bash
test "$(cat VERSION)" = '0.1.1'
git cat-file -e HEAD:history/0.1.1/rc.1.md
test -f history/0.1.1/rc.1.md
test -f deltas/0.1.1/rel.1.md
test -f prompts/008-V0_1_2_START_PROMPT.md
test ! -e history/0.1.1/rel.1.md
grep -A2 '^## Statut$' history/0.1.1/rc.1.md | grep -Fx 'PASS'
grep -Fx '<!-- version: 19 -->' README.md
grep -Fx '<!-- version: 12 -->' ROADMAP.md
grep -Fx '<!-- version: 13 -->' CHANGELOG.md
grep -Fx '<!-- version: 31 -->' docs/000-README.md
grep -Fx '<!-- version: 11 -->' docs/plans/007-V0_1_1_WEB_FRONTEND_FOUNDATION_PLAN.md
grep -F -- '- `(x) 0.1.1`' ROADMAP.md
grep -Fx '## 0.1.1' CHANGELOG.md
grep -F 'fondation frontend Web stable' README.md
grep -F 'plan historique de la stable `0.1.1`' docs/000-README.md
python3 -B - <<'PYGATE'
from pathlib import Path
import re
expected = {
"alpha.1.md": "PASS",
"alpha.2.md": "FAIL",
"alpha.2.fix.1.md": "PASS",
"alpha.3.md": "PASS",
"alpha.3.fix.1.md": "FAIL",
"alpha.3.fix.2.md": "PASS",
"alpha.4.md": "PASS",
"alpha.5.md": "PASS",
"beta.1.md": "PASS",
"rc.1.md": "PASS",
}
for name, status in expected.items():
delta = Path("deltas/0.1.1", name)
history = Path("history/0.1.1", 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 = {path.name for path in Path("deltas/0.1.1").glob("*.md")} - {
path.name for path in Path("history/0.1.1").glob("*.md")
}
assert pending == {"rel.1.md"}, pending
roadmap = Path("ROADMAP.md").read_text(encoding="utf-8")
assert "- `(x) 0.1.1`" in roadmap
for version in ("0.1.2", "0.1.3", "0.1.4", "0.1.5", "0.1.6", "0.1.7"):
assert f"- `( ) {version}`" in roadmap, version
assert "- `( ) 0.1.8`" not in roadmap
assert "skeleton Tauri jusqu'au réexamen 0.1.4" in roadmap
changelog = Path("CHANGELOG.md").read_text(encoding="utf-8")
assert "## 0.1.1" in changelog.splitlines()
assert "## 0.1.1 (candidate)" not in changelog
section = changelog.split("## 0.1.1", 1)[1].split("## 0.1.0", 1)[0]
for forbidden in ("alpha.2", "alpha.3", "alpha.4", "alpha.5", "beta.1", "rc.1", "rel.1"):
assert forbidden not in section, forbidden
readme = Path("README.md").read_text(encoding="utf-8")
assert "fondation frontend Web stable" in readme
assert "plan historique de la fondation frontend Web stable `0.1.1`" in readme
index = Path("docs/000-README.md").read_text(encoding="utf-8")
assert "plan historique de la stable `0.1.1`" in index
assert "à utiliser seulement après publication et vérification post-tag de `0.1.1`" in index
plan = Path("docs/plans/007-V0_1_1_WEB_FRONTEND_FOUNDATION_PLAN.md").read_text(encoding="utf-8")
assert "### rc.1 — release candidate\n\nStatut opérateur : **PASS**." in plan
assert "history/0.1.1/rel.1.md" in plan
assert "pgr-0.1.1-publish.001-report.md" in plan
assert "commit `0.1.1` avant le tag `v0.1.1`" in plan
prompt = Path("prompts/008-V0_1_2_START_PROMPT.md").read_text(encoding="utf-8")
assert "tag Gitea `v0.1.1`" in prompt
assert "pgr-0.1.1-publish.001-report.md" in prompt
assert "0.1.2-alpha.1" in prompt
for path, version in (
("docs/rules/530-TYPESCRIPT.md", 3),
("docs/rules/540-JAVASCRIPT_PACKAGE_ECOSYSTEM.md", 3),
("docs/rules/550-VITE.md", 2),
("docs/rules/560-CSS_SASS.md", 2),
("docs/rules/710-TAURI.md", 6),
("docs/skeletons/003-WEB_FRONTEND.md", 1),
("docs/validation/005-WEB_FRONTEND_VALIDATION.md", 1),
("docs/studies/002-TAURI_SKELETON_DECISION.md", 2),
):
lines = Path(path).read_text(encoding="utf-8").splitlines()
assert lines[1] == f"<!-- version: {version} -->", (path, lines[1])
workflow = Path("docs/rules/210-WORKFLOW.md").read_text(encoding="utf-8")
assert "history rel.1 FAIL / PARTIAL / BLOCKED" in workflow
assert "premier history rel.N[/fix.M] PASS qui établit réellement la stable" in workflow
assert "commit X.Y.Z" in workflow
print("0.1.1 rel.1 stable gate audit: clean (10 prior histories, rel.1 pending, stable Web presentation and post-tag handoff coherent)")
PYGATE
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 - <<'PYHYGIENE'
from pathlib import Path
import json
json.loads(Path("templates/web-typescript/package.json").read_text(encoding="utf-8"))
json.loads(Path("templates/web-typescript/tsconfig.json").read_text(encoding="utf-8"))
roots = (
Path("VERSION"), Path("README.md"), Path("RULES.md"), Path("ROADMAP.md"), Path("CHANGELOG.md"),
Path("docs"), Path("deltas"), Path("history"), Path("prompts"), Path("templates"),
)
files = []
for root in roots:
if root.is_file():
files.append(root)
elif root.is_dir():
files.extend(path for path in root.rglob("*") if path.is_file())
for path in files:
try:
data = path.read_bytes()
text = data.decode("utf-8")
except UnicodeDecodeError:
continue
assert b"\r" not in data, path
assert text.endswith("\n"), path
for number, line in enumerate(text.splitlines(), 1):
assert line == line.rstrip(" \t"), (path, number)
print("0.1.1 rel.1 text/JSON hygiene: clean")
PYHYGIENE
git diff --check
git add VERSION README.md ROADMAP.md CHANGELOG.md docs/000-README.md \
docs/plans/007-V0_1_1_WEB_FRONTEND_FOUNDATION_PLAN.md \
deltas/0.1.1/rel.1.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.1.1/rel.1.md
M docs/000-README.md
M docs/plans/007-V0_1_1_WEB_FRONTEND_FOUNDATION_PLAN.md
```
La RC a déjà reconfirmé le dry-run structurel Web, les owners gelés et le contrat du prompt `008`. Comme `rel.1` ne modifie aucun artefact technique frontend, la promotion stable ne simule pas de nouvelle exécution `tsc`/Vite/Sass sans projet concret ; elle rejoue les tests PGR, les audits documentaires et l'hygiène des artefacts.
## Revue opérateur complémentaire
Confirmer que :
- le scope fonctionnel de `rc.1` ne change pas ;
- `0.1.1` est présenté comme stable de manière cohérente dans VERSION/README/ROADMAP/CHANGELOG/index/plan ;
- les `FAIL` historiques `alpha.2` et `alpha.3.fix.1` restent conservés avec leurs fixes `PASS` ;
- les owners Web `530/540/550/560`, le skeleton Web et la validation Web restent gelés ;
- le skeleton Tauri reste `DEFER` jusqu'au réexamen `0.1.4` ;
- la roadmap engagée `0.1.2` à `0.1.7` reste intacte sans `0.1.8` ;
- le prompt `008` reste conditionnel à une vraie publication de `v0.1.1` et à un rapport post-tag `PASS` réel ;
- aucune preuve post-tag n'est anticipée.
## Transition
### PASS
Produire séparément `history/0.1.1/rel.1.md`, l'appliquer, puis créer le commit stable sous le message exact :
```text
0.1.1
```
Après push de la branche canonique, créer et publier le tag annoté `v0.1.1`. Vérifier localement et à distance l'objet tag et son commit déréférencé. Télécharger ensuite l'archive source depuis le tag Gitea et la fournir au générateur avec les sorties Git de publication afin de produire `pgr-0.1.1-publish.001-report.md` à partir de preuves réelles.
Le prompt `008-V0_1_2_START_PROMPT.md` ne devient la reprise effective de `0.1.2` qu'après un rapport post-tag `PASS`.
### FAIL
Consigner le diagnostic réel dans `history/0.1.1/rel.1.md`, ne pas créer le tag et corriger uniquement la fermeture dans `rel.1.fix.1` avant toute publication.

235
deltas/0.1.2/alpha.1.md Normal file
View File

@@ -0,0 +1,235 @@
<!-- file: deltas/0.1.2/alpha.1.md -->
<!-- version: 1 -->
# Delta 0.1.2-alpha.1 — audit de stable et cadrage Java / Gradle
## Baseline et sources
Baseline PGR autoritaire : archive source téléchargée depuis le tag Gitea `v0.1.1`, accompagnée du rapport externe `pgr-0.1.1-publish.001-report.md` avec statut `PASS`.
SHA-256 vérifiés sur les fichiers réellement fournis :
```text
pgr-v0.1.1(1).zip caaf8f456f7f8520172ea7705fd0cf5c5bf0e942dc4a773410bcbe7fe4ce243a
pgr-0.1.1-publish.001-report(1).md 3eafc2767225526a6cba65b3b62a45a664b71a1f2fa049915ec243a196e14bb3
games-v0.3.6(1).zip ad6e44a1332eb7d6069cf1189d9433f0fbb8fac19c5aac9f4641ac45c1c556e8
```
Les archives locales PGR et Games comportent `(1)` dans leur nom, mais leurs empreintes correspondent exactement aux baselines canoniques `pgr-v0.1.1.zip` et `games-v0.3.6.zip` attendues par le rapport/prompt.
Version avant application :
```text
0.1.1
```
Version après application :
```text
0.1.2-alpha.1
```
## Objet
Exécuter `prompts/008-V0_1_2_START_PROMPT.md` : vérifier intégralement la stable `v0.1.1` et son rapport post-tag, auditer le corpus Games autoritaire sur Java/Gradle et ses preuves historiques, relire `520-JAVA_MAVEN_GRADLE.md`, `610-ANDROID.md` et la revue d'horizon, puis créer le plan `0.1.2` avant toute normalisation importante.
`alpha.1` reste un gate de cadrage. Aucune règle Java/Gradle, règle Android, validation spécialisée, template, skeleton ou audit nouveau n'est encore créé ou modifié.
## Résultat de l'audit d'intake
La stable PGR et son rapport post-tag concordent : SHA-256 attendu, CRC propre, racine unique `pgr/`, `256` fichiers, `36` répertoires en comptant la racine, aucun symlink, absence normale de `.git` et `VERSION=0.1.1`.
Les quatre modules de tests Python ont été rejoués par groupes et donnent `48/48 PASS`. Les audits Markdown sont propres : `231` fichiers pour les headers, `9` tables sur `231` fichiers et `267` liens locaux sur `231` fichiers. Les cinq templates TOML Rust/Cargo sont parsables.
Les `83` couples delta/history de `0.0.1` à `0.1.1` sont complets. La vérité `0.1.1` conserve `alpha.2 FAIL`, `alpha.2.fix.1 PASS`, `alpha.3.fix.1 FAIL`, `alpha.3.fix.2 PASS`, puis `rel.1 PASS`.
Le corpus Games fourni possède exactement le SHA canonique attendu, `502` fichiers et aucun symlink. Ses audits statiques principaux sont propres. Il exerce quatre sources Java canoniques sous `src/main/java/` et un projet Gradle multi-module en Groovy DSL avec ownership identifiable entre `settings.gradle`, root build, `gradle.properties`, modules et scripts Gradle communs.
Les histories Games montrent successivement une preuve avec Wrapper Gradle `9.6.0` + JDK 17, puis la décision durable et validée d'utiliser Gradle système `>= 9.6.0` avec le JDK courant. Les gates suivantes ont utilisé Temurin `25.0.4.1 LTS` et Gradle `9.7.1`, tandis que la glue Java restait explicitement source/target `17`. Cette trajectoire confirme la séparation build JDK / niveau Java et le caractère conditionnel du Wrapper sans généraliser les versions exactes.
Games n'exerce ni Maven, ni version catalog, ni tests Java génériques suffisants pour créer de nouveaux artefacts correspondants. Aucun `pom.xml`, Maven Wrapper, Gradle Wrapper ou `libs.versions.toml` n'est présent dans la stable `0.3.6`.
Les contraintes AGP, SDK/NDK, ABI/JNI, SDL3, manifests, APK/AAB, signing, AVD/devices et smokes restent explicitement hors scope : elles appartiennent à Android ou au produit Games et sont réservées à `0.1.3` pour la réévaluation PGR Android.
Le plan classe les choix observés avec `ADOPT / KEEP-LOCAL / OVERRIDE / DEFER` et retient une révision ciblée de `520` plutôt qu'une copie de Games ou une multiplication d'artefacts.
## Scope
REPLACE :
```text
VERSION
README.md
docs/000-README.md
```
ADD :
```text
docs/plans/008-V0_1_2_JAVA_GRADLE_REEVALUATION_PLAN.md
deltas/0.1.2/alpha.1.md
```
DELETE : aucun.
`RULES.md`, `ROADMAP.md`, `CHANGELOG.md`, `docs/rules/520-JAVA_MAVEN_GRADLE.md`, `docs/rules/610-ANDROID.md`, les autres règles, templates, skeletons, validations, scripts, studies, prompts et histories existants restent inchangés dans `alpha.1`.
Aucun `history/0.1.2/alpha.1.md` n'est anticipé avant la gate opérateur.
## Validation opérateur
Après application sur la stable `0.1.1`, depuis la racine du dépôt :
```bash
test "$(cat VERSION)" = '0.1.2-alpha.1'
test -f docs/plans/008-V0_1_2_JAVA_GRADLE_REEVALUATION_PLAN.md
test -f deltas/0.1.2/alpha.1.md
test ! -e history/0.1.2/alpha.1.md
grep -Fx '<!-- version: 20 -->' README.md
grep -Fx '<!-- version: 32 -->' docs/000-README.md
grep -F '008-V0_1_2_JAVA_GRADLE_REEVALUATION_PLAN.md' README.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
expected = {
'0.0.1': 12,
'0.0.2': 12,
'0.0.3': 10,
'0.0.4': 9,
'0.0.5': 19,
'0.1.0': 10,
'0.1.1': 11,
}
for release, count in expected.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) == count, (release, len(deltas))
assert deltas == histories, (release, sorted(deltas ^ histories))
statuses = {}
for path in Path('history/0.1.1').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[path.name] = match.group(1)
assert statuses['alpha.2.md'] == 'FAIL'
assert statuses['alpha.2.fix.1.md'] == 'PASS'
assert statuses['alpha.3.fix.1.md'] == 'FAIL'
assert statuses['alpha.3.fix.2.md'] == 'PASS'
assert statuses['rel.1.md'] == 'PASS'
roadmap = Path('ROADMAP.md').read_text(encoding='utf-8')
assert '- `(x) 0.1.1`' in roadmap
for release in range(2, 8):
assert f'- `( ) 0.1.{release}`' in roadmap, release
assert '0.1.8' not in roadmap
assert 'skeleton Tauri jusqu\'au réexamen 0.1.4' in roadmap
prompt = Path('prompts/008-V0_1_2_START_PROMPT.md').read_text(encoding='utf-8')
for phrase in (
'Version cible : `0.1.2`',
'Première tranche attendue : `0.1.2-alpha.1`',
'ad6e44a1332eb7d6069cf1189d9433f0fbb8fac19c5aac9f4641ac45c1c556e8',
'ADOPT / KEEP-LOCAL / OVERRIDE / DEFER',
'Gradle système versus Wrapper',
'Le profil `520` possède également Maven.',
'`0.1.2` MUST NOT absorber les responsabilités',
):
assert phrase in prompt, phrase
profile = Path('docs/rules/520-JAVA_MAVEN_GRADLE.md').read_text(encoding='utf-8')
for phrase in (
'JDK utilisé pour construire',
'PGR MUST NOT ajouter un Maven Wrapper uniquement par cérémonie.',
'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',
):
assert phrase in profile, phrase
android = Path('docs/rules/610-ANDROID.md').read_text(encoding='utf-8')
for phrase in (
'Matrice AGP / Gradle / JDK',
'`compileSdk`, `targetSdk` et `minSdk`',
'ABI et code natif',
'Signing et secrets',
):
assert phrase in android, phrase
plan = Path('docs/plans/008-V0_1_2_JAVA_GRADLE_REEVALUATION_PLAN.md').read_text(encoding='utf-8')
for phrase in (
'Classification initiale des décisions Games',
'`ADOPT`',
'`KEEP-LOCAL`',
'`OVERRIDE`',
'`DEFER`',
'alpha.2 — révision ciblée Java / Gradle',
'beta.1 — réconciliation et décision d\'artefacts',
'AGP 9.4.0',
'Aucun skeleton Java/Gradle ni artefact Maven nouveau n\'est prévu par défaut.',
'0.1.3 — réévaluation pratique du profil Android à partir de Games',
):
assert phrase in plan, phrase
assert Path('docs/rules/520-JAVA_MAVEN_GRADLE.md').read_text(encoding='utf-8').startswith(
'<!-- file: docs/rules/520-JAVA_MAVEN_GRADLE.md -->\n<!-- version: 2 -->'
)
assert Path('docs/rules/610-ANDROID.md').read_text(encoding='utf-8').startswith(
'<!-- file: docs/rules/610-ANDROID.md -->\n<!-- version: 2 -->'
)
print('0.1.2 alpha.1 structural audit: clean (83 prior pairs, Games classified, Android 0.1.3 boundary preserved)')
PY
git diff --check
git add VERSION README.md docs/000-README.md \
docs/plans/008-V0_1_2_JAVA_GRADLE_REEVALUATION_PLAN.md \
deltas/0.1.2/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.1.2/alpha.1.md
M docs/000-README.md
A docs/plans/008-V0_1_2_JAVA_GRADLE_REEVALUATION_PLAN.md
```
La revue opérateur doit également confirmer que :
- `alpha.1` n'a pas modifié `520-JAVA_MAVEN_GRADLE.md` avant validation du cadrage ;
- `610-ANDROID.md` reste intact et aucune responsabilité Android n'a été absorbée dans le plan Java/Gradle ;
- les versions exactes Games (`Gradle 9.6/9.7.1`, JDK 25, Java 17, AGP 9.4.0) restent des preuves ou choix locaux, pas des contraintes PGR universelles ;
- l'absence de Wrapper dans Games est classée comme choix local compatible avec une politique PGR conditionnelle, pas comme interdiction globale du Wrapper ;
- aucun nouveau template/audit/skeleton Maven ou Gradle n'est créé sans preuve supplémentaire ;
- Games reste un corpus externe non modifié et son adoption reste réservée à `0.1.5` ;
- le skeleton Tauri reste `DEFER` jusqu'à `0.1.4` ;
- aucun nouveau numéro au-delà de `0.1.7` n'est réservé.
## Transition
### PASS
Produire `history/0.1.2/alpha.1.md` à partir des résultats réellement observés. Dans la même réponse, si aucune décision nouvelle n'est ouverte, préparer séparément le delta `0.1.2-alpha.2` consacré à la révision normative ciblée de `520-JAVA_MAVEN_GRADLE.md`, sans modification de `610-ANDROID.md` et sans nouvel artefact Maven.
Après remise du history, fournir automatiquement le bloc Git exact de fermeture conformément à `docs/templates/006-OPERATOR_COMMAND_HANDOFF.md`, puis indiquer l'application du delta suivant seulement après succès du commit/push.
### FAIL
Consigner le résultat réel dans le history, puis ouvrir `0.1.2-alpha.1.fix.1` ou un REPLAN selon la cause. Un fix de `alpha.1` doit rester limité au cadrage et ne doit pas absorber la révision normative prévue pour `alpha.2`.

View File

@@ -0,0 +1,213 @@
<!-- file: deltas/0.1.2/alpha.2.fix.1.md -->
<!-- version: 1 -->
# Delta 0.1.2-alpha.2.fix.1 — récupération de contamination inter-projet
## Baseline et diagnostic
Baseline Git observée et déjà publiée sur `origin/master` :
```text
17b7ef23a18c913f986c7d57caf958d33479363d
```
Le commit précédent observé est :
```text
6e978bfed8c1ad10d1888cd3da92aeaf70338b7e
```
La gate opérateur de `0.1.2-alpha.2` avait été exécutée avec succès avant cette chaîne de commits : tests Python, audits Markdown, gate Java/Gradle et contrôles de scope étaient `PASS`. `history/0.1.2/alpha.2.md` conserve donc ce résultat réel.
La publication de la tranche a ensuite été contaminée par des fichiers provenant d'un autre projet. Les preuves Git montrent notamment :
- `6e978bf` porte les vraies modifications PGR de `alpha.2`, mais ajoute aussi `history/0.0.1/alpha.3.fix.1.md` et utilise un message de commit étranger ;
- `17b7ef2` ajoute `Cargo.toml`, `crates/knowledge-domain-lib/src/content_family.rs` et `deltas/0.0.1/alpha.3.fix.2.md` ;
- `17b7ef2` remplace `docs/plans/001-V0_0_1_FOUNDATION_PLAN.md` et `docs/validation/001-VALIDATION_MATRIX.md` par du contenu Knowledge ;
- `git diff --check 17b7ef2^ 17b7ef2` signale en plus une ligne vide finale parasite dans la matrice de validation ;
- les commits étant déjà poussés, le présent fix restaure l'état PGR par un nouveau commit et ne réécrit pas l'historique distant.
Version avant correction au niveau Git publié : état contaminé après `0.1.2-alpha.2`.
Version après application :
```text
0.1.2-alpha.2.fix.1
```
## Objet
Ramener la branche publiée à l'état PGR attendu après `alpha.2`, tout en préservant les vraies modifications Java/Maven/Gradle et leur history `PASS`.
Ce fix est exclusivement un correctif de provenance et d'hygiène Git. Il ne change aucune décision normative de `alpha.2` et n'absorbe ni le REPLAN Java/Maven/Gradle préparé pour la tranche suivante ni le scope Android réservé à `0.1.3`.
## Scope
REPLACE :
```text
VERSION
docs/plans/001-V0_0_1_FOUNDATION_PLAN.md
docs/validation/001-VALIDATION_MATRIX.md
```
ADD :
```text
deltas/0.1.2/alpha.2.fix.1.md
manifests/0.1.2/alpha.2.fix.1.delete.txt
```
DELETE :
```text
Cargo.toml
crates/knowledge-domain-lib/src/content_family.rs
deltas/0.0.1/alpha.3.fix.2.md
history/0.0.1/alpha.3.fix.1.md
```
Le manifest de suppression doit contenir exactement ces quatre chemins.
Les fichiers suivants de `alpha.2` MUST rester inchangés par le fix :
```text
deltas/0.1.2/alpha.2.md
docs/plans/008-V0_1_2_JAVA_GRADLE_REEVALUATION_PLAN.md
docs/rules/520-JAVA_MAVEN_GRADLE.md
history/0.1.2/alpha.2.md
```
`docs/rules/610-ANDROID.md` reste également inchangé.
## Restauration autoritaire
`docs/plans/001-V0_0_1_FOUNDATION_PLAN.md` et `docs/validation/001-VALIDATION_MATRIX.md` n'étaient modifiés ni par `alpha.1` ni par `alpha.2`. Leur contenu attendu est donc exactement celui de la stable `v0.1.1`.
Le fix restaure ces deux fichiers depuis cette baseline au lieu de tenter de corriger manuellement le contenu Knowledge injecté.
## Application du manifest
Après extraction du delta, appliquer explicitement le manifest de suppression :
```bash
while IFS= read -r path; do
case "$path" in
''|'#'*) continue ;;
esac
rm -f -- "$path"
done < manifests/0.1.2/alpha.2.fix.1.delete.txt
```
Les éventuels répertoires devenus vides ne sont pas des chemins suivis par Git et n'affectent pas le contenu publié.
## Validation opérateur
Le stash `pgr-0.1.2-alpha.3-before-alpha.2-recovery` doit rester intact pendant toute cette gate. Ne pas exécuter `stash pop` avant fermeture du fix.
```bash
test "$(git rev-parse HEAD)" = '17b7ef23a18c913f986c7d57caf958d33479363d'
test "$(git rev-parse origin/master)" = '17b7ef23a18c913f986c7d57caf958d33479363d'
test "$(cat VERSION)" = '0.1.2-alpha.2.fix.1'
test -f history/0.1.2/alpha.2.md
grep -A2 '^## Statut$' history/0.1.2/alpha.2.md | grep -Fx 'PASS'
test -f deltas/0.1.2/alpha.2.fix.1.md
test ! -e history/0.1.2/alpha.2.fix.1.md
test ! -e Cargo.toml
test ! -e crates/knowledge-domain-lib/src/content_family.rs
test ! -e deltas/0.0.1/alpha.3.fix.2.md
test ! -e history/0.0.1/alpha.3.fix.1.md
git diff --exit-code v0.1.1 -- \
docs/plans/001-V0_0_1_FOUNDATION_PLAN.md \
docs/validation/001-VALIDATION_MATRIX.md
grep -Fx '<!-- version: 2 -->' docs/plans/008-V0_1_2_JAVA_GRADLE_REEVALUATION_PLAN.md
grep -Fx '<!-- version: 3 -->' docs/rules/520-JAVA_MAVEN_GRADLE.md
grep -Fx '<!-- version: 2 -->' docs/rules/610-ANDROID.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
manifest = Path('manifests/0.1.2/alpha.2.fix.1.delete.txt')
paths = [line.strip() for line in manifest.read_text(encoding='utf-8').splitlines() if line.strip() and not line.lstrip().startswith('#')]
expected = [
'Cargo.toml',
'crates/knowledge-domain-lib/src/content_family.rs',
'deltas/0.0.1/alpha.3.fix.2.md',
'history/0.0.1/alpha.3.fix.1.md',
]
assert paths == expected, (paths, expected)
for path in expected:
assert not Path(path).exists(), path
history = Path('history/0.1.2/alpha.2.md').read_text(encoding='utf-8')
assert re.search(r'## Statut\s+PASS\s', history)
alpha2 = Path('deltas/0.1.2/alpha.2.md').read_text(encoding='utf-8')
assert '# Delta 0.1.2-alpha.2 — révision ciblée Java / Gradle' in alpha2
plan = Path('docs/plans/008-V0_1_2_JAVA_GRADLE_REEVALUATION_PLAN.md').read_text(encoding='utf-8')
assert plan.startswith('<!-- file: docs/plans/008-V0_1_2_JAVA_GRADLE_REEVALUATION_PLAN.md -->\n<!-- version: 2 -->')
profile = Path('docs/rules/520-JAVA_MAVEN_GRADLE.md').read_text(encoding='utf-8')
assert profile.startswith('<!-- file: docs/rules/520-JAVA_MAVEN_GRADLE.md -->\n<!-- version: 3 -->')
android = Path('docs/rules/610-ANDROID.md').read_text(encoding='utf-8')
assert android.startswith('<!-- file: docs/rules/610-ANDROID.md -->\n<!-- version: 2 -->')
for forbidden in (
'knowledge-domain-lib',
'# Matrice de validation Knowledge',
'knowledge-pgr-server',
):
assert forbidden not in Path('docs/validation/001-VALIDATION_MATRIX.md').read_text(encoding='utf-8'), forbidden
print('0.1.2 alpha.2.fix.1 recovery audit: clean (foreign Knowledge paths removed, PGR baseline restored, alpha.2 preserved)')
PYGATE
git diff --check
git add -A
git diff --cached --check
git status --short
```
Le scope indexé attendu est :
```text
D Cargo.toml
M VERSION
D crates/knowledge-domain-lib/src/content_family.rs
D deltas/0.0.1/alpha.3.fix.2.md
A deltas/0.1.2/alpha.2.fix.1.md
M docs/plans/001-V0_0_1_FOUNDATION_PLAN.md
M docs/validation/001-VALIDATION_MATRIX.md
D history/0.0.1/alpha.3.fix.1.md
A manifests/0.1.2/alpha.2.fix.1.delete.txt
```
L'ordre exact peut varier ; l'ensemble des chemins doit être identique.
## Transition
### PASS
Produire `history/0.1.2/alpha.2.fix.1.md`, commit/push sous l'identité `0.1.2-alpha.2.fix.1`, puis abandonner le stash préparé à partir de l'ancien HEAD contaminé et réémettre la tranche `alpha.3` sur la baseline corrigée.
La tranche `alpha.3` devra être régénérée ; le stash actuel sert uniquement de sauvegarde de sécurité et ne doit pas devenir la source autoritaire du nouveau delta.
### FAIL
Conserver les résultats réels dans `history/0.1.2/alpha.2.fix.1.md` et poursuivre sous `alpha.2.fix.N`. Ne pas restaurer `alpha.3` tant que l'état PGR publié n'est pas propre.

259
deltas/0.1.2/alpha.2.md Normal file
View File

@@ -0,0 +1,259 @@
<!-- file: deltas/0.1.2/alpha.2.md -->
<!-- version: 1 -->
# Delta 0.1.2-alpha.2 — révision ciblée Java / Gradle
## Baseline et version
Baseline attendue : commit opérateur de `0.1.2-alpha.1`, réalisé après application de `history/0.1.2/alpha.1.md` avec statut `PASS`.
Le hash de ce commit n'est pas anticipé.
Version avant application :
```text
0.1.2-alpha.1
```
Version après application :
```text
0.1.2-alpha.2
```
## Objet
Appliquer la révision normative ciblée décidée après l'audit Games de `alpha.1` sans transformer les choix locaux du corpus en prescriptions générales.
La tranche précise uniquement :
- la distinction entre JDK de build, niveau source et bytecode/runtime supporté ;
- la possibilité pour un JDK plus récent de cibler explicitement un niveau Java plus ancien ;
- l'ownership naturel de `settings.gradle(.kts)`, du build root, des builds de modules et de `gradle.properties` partagé ;
- la nécessité qu'une politique « Gradle système » possède une contrainte effectivement vérifiée ;
- la séparation entre configuration Gradle partagée portable et état local/machine/secrets ;
- la frontière entre règles Java/Gradle générales et overrides Android.
Les sections Maven sont relues et conservées sans nouvel artefact : Games `0.3.6` ne contient aucun projet Maven permettant de justifier une normalisation supplémentaire.
## Scope
REPLACE :
```text
VERSION
docs/plans/008-V0_1_2_JAVA_GRADLE_REEVALUATION_PLAN.md
docs/rules/520-JAVA_MAVEN_GRADLE.md
```
ADD :
```text
deltas/0.1.2/alpha.2.md
```
DELETE : aucun.
`docs/rules/610-ANDROID.md`, `RULES.md`, `ROADMAP.md`, `CHANGELOG.md`, les autres profils, templates, skeletons, validations, scripts et tests restent inchangés.
Aucun `history/0.1.2/alpha.2.md` n'est anticipé.
## Décisions Java
Le contrat existant est conservé et rendu plus explicite :
```text
JDK de build
!= niveau Java du code source
!= niveau de bytecode/runtime minimal supporté
```
Un JDK de build plus récent peut être utilisé avec une cible Java plus ancienne lorsque cette cible est déclarée explicitement par le build et réellement supportée par la toolchain.
PGR ne rend obligatoire ni `--release`, ni une toolchain Java, ni `sourceCompatibility`/`targetCompatibility` pour tous les builds. Le mécanisme concret dépend de Maven, Gradle, du plugin et du projet ; le contrat important est que la compatibilité ne soit pas une conséquence implicite du JDK actif.
Les versions Games observées restent locales : ni JDK 25 LTS ni Java 17 ne deviennent un minimum PGR.
## Décisions Gradle
### Ownership
La responsabilité est explicitée sans imposer le layout Games :
```text
settings.gradle(.kts)
composition du build
politiques globales de résolution lorsqu'elles existent
contraintes de bootstrap/version devant agir avant les projets
build root
plugins, versions et conventions réellement partagés
build de module
plugins, dépendances, sources, tâches et paramètres locaux au module
gradle.properties partagé
propriétés portables, non secrètes et réellement communes
```
Une logique transverse devenue importante peut être extraite dans un script, build logic ou plugin possédé plutôt que dupliquée. Aucun de ces mécanismes n'est rendu obligatoire.
### Gradle système et Wrapper
Le Wrapper reste conditionnel : il est recommandé lorsqu'il apporte une reproductibilité utile, mais son absence dans Games reste `KEEP-LOCAL` et n'est pas généralisée.
Lorsqu'un projet choisit un Gradle système, sa contrainte de compatibilité doit être effectivement vérifiée par le build ou par une gate exécutée par le projet/CI. Une version écrite uniquement dans la documentation ne suffit pas.
PGR ne reprend ni le minimum `9.6.0` ni l'API `GradleVersion.current()` de Games comme règle universelle. Ils constituent une implémentation valide d'une politique locale, pas la forme obligatoire de la vérification.
### Propriétés et état local
Un `gradle.properties` partagé doit rester portable et non secret. Les chemins machine, credentials, secrets et overrides développeur utilisent un mécanisme local approprié et restent hors Git.
Le version catalog reste optionnel. Groovy DSL et Kotlin DSL restent tous deux reconnus ; le choix Groovy de Games reste `KEEP-LOCAL`.
## Maven
Aucun `pom.xml`, Maven Wrapper ou projet Maven n'existe dans le corpus Games autoritaire. Les sections Maven de `520` ont donc uniquement été relues pour vérifier qu'elles restent cohérentes avec la philosophie générale : centraliser ce qui est réellement commun, ne pas imposer un Wrapper par cérémonie, préférer les gates ciblées et ne pas automatiser `clean` sans besoin.
Aucun template, skeleton, audit ou autre artefact Maven n'est ajouté.
## Frontière Android
`610-ANDROID.md` n'est pas modifié.
Les éléments suivants restent hors scope de `0.1.2` :
```text
AGP et sa matrice de compatibilité
compileSdk / targetSdk / minSdk
NDK et ABI
JNI / AAR / Prefab
applicationId / namespace
manifests / resources
APK / AAB / signing
Variant API Android
devices / AVD / smokes Android
contraintes 16 KB
SDL3 et architecture Games
```
`520` documente seulement qu'une plateforme ou un framework peut imposer un override plus étroit sans transformer cet override en minimum Java/Gradle général.
## Validation opérateur
Après application du history `PASS`, commit/push de `alpha.1`, puis application du présent delta :
```bash
test "$(cat VERSION)" = '0.1.2-alpha.2'
git cat-file -e HEAD:history/0.1.2/alpha.1.md
test -f history/0.1.2/alpha.1.md
test -f deltas/0.1.2/alpha.2.md
test ! -e history/0.1.2/alpha.2.md
grep -A2 '^## Statut$' history/0.1.2/alpha.1.md | grep -Fx 'PASS'
grep -Fx '<!-- version: 2 -->' docs/plans/008-V0_1_2_JAVA_GRADLE_REEVALUATION_PLAN.md
grep -Fx '<!-- version: 3 -->' docs/rules/520-JAVA_MAVEN_GRADLE.md
grep -Fx '<!-- version: 2 -->' docs/rules/610-ANDROID.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
history = Path('history/0.1.2/alpha.1.md').read_text(encoding='utf-8')
assert re.search(r'## Statut\s+PASS\s', history)
profile = Path('docs/rules/520-JAVA_MAVEN_GRADLE.md').read_text(encoding='utf-8')
for phrase in (
'Un JDK de build plus récent MAY compiler un projet qui cible un niveau source ou bytecode plus ancien',
'Le simple fait qu\'une compilation réussisse avec le JDK actif ne constitue pas une déclaration de compatibilité.',
'composition du build et inclusion des projets',
'plugins, dépendances, sources, tâches et paramètres propres au module',
'propriétés portables, non secrètes et réellement communes au build',
'effectivement vérifiée',
'Une version seulement écrite dans la documentation sans contrôle exécutable n\'est pas une preuve suffisante',
'Son absence dans un corpus particulier ne constitue pas une règle générale.',
):
assert phrase in profile, phrase
for phrase in (
'AGP',
'`minSdk`',
'`targetSdk`',
'NDK',
'ABI/JNI',
'packaging APK/AAB',
'device/AVD',
):
assert phrase in profile, phrase
plan = Path('docs/plans/008-V0_1_2_JAVA_GRADLE_REEVALUATION_PLAN.md').read_text(encoding='utf-8')
for phrase in (
'## Décision après `alpha.1`',
'La gate opérateur de `alpha.1` est `PASS`',
'`KEEP-LOCAL` : Groovy DSL, absence de Wrapper dans Games, JDK 25 LTS et cible Java 17',
'`OVERRIDE` : matrice AGP/Gradle/JDK et autres contraintes de plateforme Android',
'`DEFER` : version catalog, skeleton Java/Gradle, audit Python Java/Gradle et nouveaux artefacts Maven',
'`alpha.2` est donc bornée à la révision du profil `520`',
):
assert phrase in plan, phrase
android = Path('docs/rules/610-ANDROID.md').read_text(encoding='utf-8')
assert android.startswith('<!-- file: docs/rules/610-ANDROID.md -->\n<!-- version: 2 -->')
for path in (
'docs/templates',
'docs/skeletons',
'scripts',
):
assert Path(path).is_dir(), path
print('0.1.2 alpha.2 Java/Gradle audit: clean (JDK/source/bytecode explicit, Gradle ownership and system-version verification clarified, Android boundary preserved)')
PYGATE
git diff --check
git add VERSION \
docs/plans/008-V0_1_2_JAVA_GRADLE_REEVALUATION_PLAN.md \
docs/rules/520-JAVA_MAVEN_GRADLE.md \
deltas/0.1.2/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.1.2/alpha.2.md
M docs/plans/008-V0_1_2_JAVA_GRADLE_REEVALUATION_PLAN.md
M docs/rules/520-JAVA_MAVEN_GRADLE.md
```
La revue qualitative doit confirmer que :
- aucune version JDK ou Java observée dans Games n'est devenue un minimum général ;
- un Gradle système reste permis seulement avec une contrainte réellement vérifiée ;
- le Wrapper reste conditionnel et le Groovy DSL n'est pas privilégié normativement ;
- `gradle.properties` partagé ne devient pas un emplacement pour secrets ou chemins machine ;
- les sections Maven n'ont pas acquis de règle provenant d'un corpus qui n'exerce pas Maven ;
- aucune responsabilité Android n'a été déplacée hors de `610` ou démarrée prématurément dans `0.1.2` ;
- aucun template, skeleton ou audit supplémentaire n'a été créé pour matérialiser artificiellement la release.
## Transition
### PASS
Produire `history/0.1.2/alpha.2.md`, puis préparer `0.1.2-beta.1` pour la réconciliation finale du profil contre Games, `500-LANGUAGES.md`, `610-ANDROID.md` et les règles générales de validation, ainsi que la décision explicite sur l'absence ou la nécessité d'artefacts supplémentaires.
### FAIL
Consigner le diagnostic réel dans `history/0.1.2/alpha.2.md` et rester dans `alpha.2.fix.N` sauf REPLAN justifié. Le fix MUST rester borné à la révision Java/Gradle et ne doit pas absorber `beta.1` ou le scope Android `0.1.3`.

365
deltas/0.1.2/alpha.3.md Normal file
View File

@@ -0,0 +1,365 @@
<!-- file: deltas/0.1.2/alpha.3.md -->
<!-- version: 1 -->
# Delta 0.1.2-alpha.3 — REPLAN et scission Java / Maven / Gradle
## Baseline et version
Baseline attendue : commit opérateur de `0.1.2-alpha.2.fix.1`, réalisé après application de `history/0.1.2/alpha.2.fix.1.md` avec statut `PASS`. Le fix de récupération doit donc être publié avant application de la présente tranche.
Le hash de ce commit n'est pas anticipé. L'ancien stash `pgr-0.1.2-alpha.3-before-alpha.2-recovery` est uniquement une sauvegarde de l'application effectuée sur le HEAD contaminé ; il ne constitue pas une source autoritaire et doit être abandonné après publication du fix.
Version avant application :
```text
0.1.2-alpha.2.fix.1
```
Version après application :
```text
0.1.2-alpha.3
```
## Motif du REPLAN
La gate de `alpha.2` valide le contenu normatif ajouté à l'ancien profil combiné. La réconciliation préparatoire de `beta.1` révèle toutefois une ambiguïté d'ownership prévue comme déclencheur de REPLAN dans le plan actif.
`500-LANGUAGES.md` autorise un langage et son build tool dans un même profil lorsque leur séparation serait artificielle, mais indique qu'ils SHOULD être séparés lorsque plusieurs build tools interchangeables possèdent chacun des règles propres significatives.
Après `alpha.2`, Maven et Gradle possèdent chacun des contrats substantiels et indépendants : ownership du build, Wrapper, validation et outputs ; Gradle possède en plus sa politique de version système, DSL, propriétés et version catalog. Un profil unique `Java / Maven / Gradle` rend donc l'applicabilité ambiguë : un projet Java n'utilise pas nécessairement les deux build tools, et Gradle n'implique pas nécessairement Java.
La scission devient une correction d'ownership, pas une préférence de taxonomie.
## Scope
REPLACE :
```text
VERSION
RULES.md
ROADMAP.md
docs/000-README.md
docs/architecture/003-RULE_PROFILE_MODEL.md
docs/plans/008-V0_1_2_JAVA_GRADLE_REEVALUATION_PLAN.md
docs/rules/000-README.md
docs/rules/520-JAVA_MAVEN_GRADLE.md
docs/rules/610-ANDROID.md
```
ADD :
```text
docs/rules/520-JAVA.md
docs/rules/521-MAVEN.md
docs/rules/522-GRADLE.md
deltas/0.1.2/alpha.3.md
```
DELETE : aucun.
L'ancien chemin `docs/rules/520-JAVA_MAVEN_GRADLE.md` devient un bridge `SUPERSEDED` non normatif. Il est conservé uniquement parce que des prompts, plans, deltas, histories et études historiques le référencent encore ; ces snapshots ne doivent pas être réécrits a posteriori et les audits de liens doivent rester propres.
Aucun `history/0.1.2/alpha.3.md` n'est anticipé.
## Owners après scission
Le découpage courant devient :
```text
520 Java
521 Maven
522 Gradle
```
### `520-JAVA.md`
Possède uniquement les règles Java :
- politique JDK et compatibilité source/bytecode/runtime ;
- structure `src/main/java` / `src/test/java` ;
- packages, modules, imports et visibilité ;
- interfaces/API, annotations, nullabilité et exceptions ;
- tests Java ;
- composition explicite avec Maven ou Gradle selon le build réellement utilisé.
Il ne possède plus les règles de Wrapper, reactor, Gradle DSL ou outputs des build tools.
### `521-MAVEN.md`
Possède les responsabilités Maven :
- POM parent/root et héritage multi-module ;
- `dependencyManagement` / `pluginManagement` ;
- miroir technique de `VERSION` lorsque Maven l'exige ;
- Maven système versus Wrapper sans cérémonie ;
- validation ciblée puis reactor/`verify` selon le scope ;
- `target/`, état local et futurs audits réellement justifiés.
Games n'exerce toujours aucun projet Maven : la scission ne prétend donc pas avoir validé une nouvelle convention Maven par corpus ; elle isole seulement les règles déjà existantes et cohérentes.
### `522-GRADLE.md`
Possède les responsabilités Gradle validées et clarifiées en `alpha.2` :
- ownership `settings` / root / module / propriétés partagées ;
- contrainte Gradle système effectivement vérifiée ou Wrapper lorsque pertinent ;
- neutralité Groovy/Kotlin DSL ;
- version catalog optionnel ;
- validation ciblée et `clean` non systématique ;
- `.gradle/`, `build/`, état local et futurs audits réellement justifiés.
Le niveau Java reste possédé par `520-JAVA.md` lorsqu'un build Gradle construit du Java.
## Bridge historique
`520-JAVA_MAVEN_GRADLE.md` passe en révision `4` et ne contient plus de règles courantes. Il indique explicitement :
```text
SUPERSEDED
520-JAVA.md owner Java courant
521-MAVEN.md spécialisation Maven courante
522-GRADLE.md spécialisation Gradle courante
```
Il n'est plus référencé par `RULES.md`, les index de règles ou les compositions courantes. Sa seule responsabilité est la compatibilité documentaire des références historiques.
## Frontière Android
`610-ANDROID.md` change uniquement pour refléter la nouvelle composition :
```text
Android + Gradle -> 600 + 610 + 522
Android + Java -> + 520 lorsque Java est réellement présent
```
Une application Android n'applique pas `520` uniquement parce qu'elle utilise Android ou Gradle.
Aucune règle AGP, `compileSdk`, `targetSdk`, `minSdk`, NDK, ABI/JNI, manifests/resources, packaging/signing, device/AVD, 16 KB ou SDL3 n'est réévaluée dans cette tranche. Ce scope reste réservé à `0.1.3`.
## Décision d'artefacts
La scission n'autorise aucun artefact technique supplémentaire.
Restent non justifiés :
```text
skeleton Java/Gradle générique
template Maven ou Gradle générique
audit Python Java/Maven/Gradle
nouveau contrat de validation spécialisé
artefact Maven issu de Games
```
Les trois profils sont des owners normatifs nécessaires à l'applicabilité ; ils ne constituent pas une duplication fonctionnelle du build tool officiel.
## Validation opérateur
Après application du history `PASS`, commit/push de `alpha.2.fix.1`, abandon de l'ancien stash de sécurité, puis application du présent delta régénéré :
```bash
test "$(cat VERSION)" = '0.1.2-alpha.3'
git cat-file -e HEAD:history/0.1.2/alpha.2.fix.1.md
test -f history/0.1.2/alpha.2.md
test -f history/0.1.2/alpha.2.fix.1.md
test -f deltas/0.1.2/alpha.3.md
test ! -e history/0.1.2/alpha.3.md
grep -A2 '^## Statut$' history/0.1.2/alpha.2.md | grep -Fx 'PASS'
grep -A2 '^## Statut$' history/0.1.2/alpha.2.fix.1.md | grep -Fx 'PASS'
test ! -e Cargo.toml
test ! -e crates/knowledge-domain-lib/src/content_family.rs
test ! -e deltas/0.0.1/alpha.3.fix.2.md
test ! -e history/0.0.1/alpha.3.fix.1.md
grep -Fx '<!-- version: 4 -->' docs/rules/520-JAVA_MAVEN_GRADLE.md
grep -Fx '`SUPERSEDED` depuis `0.1.2-alpha.3`.' docs/rules/520-JAVA_MAVEN_GRADLE.md
grep -Fx '<!-- version: 4 -->' docs/rules/520-JAVA.md
grep -Fx '<!-- version: 1 -->' docs/rules/521-MAVEN.md
grep -Fx '<!-- version: 1 -->' docs/rules/522-GRADLE.md
grep -Fx '<!-- version: 3 -->' docs/rules/610-ANDROID.md
grep -Fx '<!-- version: 7 -->' docs/architecture/003-RULE_PROFILE_MODEL.md
grep -Fx '<!-- version: 3 -->' docs/plans/008-V0_1_2_JAVA_GRADLE_REEVALUATION_PLAN.md
grep -Fx '<!-- version: 14 -->' RULES.md
grep -Fx '<!-- version: 16 -->' docs/rules/000-README.md
grep -Fx '<!-- version: 33 -->' docs/000-README.md
grep -Fx '<!-- version: 13 -->' ROADMAP.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
history = Path('history/0.1.2/alpha.2.md').read_text(encoding='utf-8')
assert re.search(r'## Statut\s+PASS\s', history)
recovery = Path('history/0.1.2/alpha.2.fix.1.md').read_text(encoding='utf-8')
assert re.search(r'## Statut\s+PASS\s', recovery)
family = Path('docs/rules/500-LANGUAGES.md').read_text(encoding='utf-8')
for phrase in (
'Un langage et son build tool MAY partager un profil',
'Ils SHOULD être séparés lorsque plusieurs build tools interchangeables possèdent chacun des règles propres significatives.',
'Une spécialisation de build tool ne devient pas une règle du langage entier.',
):
assert phrase in family, phrase
legacy = Path('docs/rules/520-JAVA_MAVEN_GRADLE.md').read_text(encoding='utf-8')
for phrase in (
'`SUPERSEDED` depuis `0.1.2-alpha.3`.',
'Il ne constitue plus un profil sélectionnable',
'520-JAVA.md',
'521-MAVEN.md',
'522-GRADLE.md',
):
assert phrase in legacy, phrase
java = Path('docs/rules/520-JAVA.md').read_text(encoding='utf-8')
for phrase in (
'# Profil Java',
'JDK utilisé pour construire',
'niveau Java du code source',
'niveau de bytecode/runtime minimal supporté',
'Un projet Java construit avec Maven compose normalement',
'Un projet Java construit avec Gradle compose normalement',
):
assert phrase in java, phrase
assert '## Maven' not in java
assert '## Gradle' not in java
maven = Path('docs/rules/521-MAVEN.md').read_text(encoding='utf-8')
for phrase in (
'# Profil Maven',
'POM parent/root',
'PGR MUST NOT ajouter un Maven Wrapper uniquement par cérémonie.',
'./mvnw -pl <module> -am test',
'target/',
):
assert phrase in maven, phrase
gradle = Path('docs/rules/522-GRADLE.md').read_text(encoding='utf-8')
for phrase in (
'# Profil Gradle',
'composition du build et inclusion des projets',
'effectivement vérifiée',
'Groovy DSL et Kotlin DSL sont tous deux reconnus.',
'gradle clean',
):
assert phrase in gradle, phrase
for forbidden in (
'compileSdk',
'targetSdk',
'minSdk',
'NDK',
'ABI/JNI',
'APK/AAB',
'device/AVD',
'SDL3',
):
assert forbidden not in maven, forbidden
assert forbidden not in gradle, forbidden
android = Path('docs/rules/610-ANDROID.md').read_text(encoding='utf-8')
assert '520-JAVA.md' in android
assert '522-GRADLE.md' in android
assert '520-JAVA_MAVEN_GRADLE.md' not in android
architecture = Path('docs/architecture/003-RULE_PROFILE_MODEL.md').read_text(encoding='utf-8')
for phrase in (
'## Scission Java / Maven / Gradle en `0.1.2`',
'520 — Java',
'521 — Maven',
'522 — Gradle',
'GENERAL + 500 + 520 + 522 + 600 + 610',
'bridge `SUPERSEDED` non normatif',
):
assert phrase in architecture, phrase
for current in (
'RULES.md',
'docs/000-README.md',
'docs/rules/000-README.md',
'docs/rules/610-ANDROID.md',
):
assert '520-JAVA_MAVEN_GRADLE.md' not in Path(current).read_text(encoding='utf-8'), current
plan = Path('docs/plans/008-V0_1_2_JAVA_GRADLE_REEVALUATION_PLAN.md').read_text(encoding='utf-8')
for phrase in (
'## Décision après `alpha.2` et REPLAN',
'`alpha.2.fix.1` restaure l\'état PGR attendu',
'alpha.3 scission des owners Java / Maven / Gradle',
'520-JAVA.md',
'521-MAVEN.md',
'522-GRADLE.md',
'bridge documentaire non normatif',
'aucun template, skeleton, audit Java/Gradle ou nouvel artefact Maven n\'est justifié',
):
assert phrase in plan, phrase
for foreign in (
'Cargo.toml',
'crates/knowledge-domain-lib/src/content_family.rs',
'deltas/0.0.1/alpha.3.fix.2.md',
'history/0.0.1/alpha.3.fix.1.md',
):
assert not Path(foreign).exists(), foreign
print('0.1.2 alpha.3 owner split audit: clean (recovery baseline confirmed, Java/Maven/Gradle applicability separated, historical bridge preserved, Android boundary preserved)')
PYGATE
git diff --check
git add -A
git diff --cached --check
git status --short
```
Le scope indexé attendu avant ajout du history est exactement :
```text
M ROADMAP.md
M RULES.md
M VERSION
A deltas/0.1.2/alpha.3.md
M docs/000-README.md
M docs/architecture/003-RULE_PROFILE_MODEL.md
M docs/plans/008-V0_1_2_JAVA_GRADLE_REEVALUATION_PLAN.md
M docs/rules/000-README.md
M docs/rules/520-JAVA_MAVEN_GRADLE.md
A docs/rules/520-JAVA.md
A docs/rules/521-MAVEN.md
A docs/rules/522-GRADLE.md
M docs/rules/610-ANDROID.md
```
La revue qualitative doit confirmer que :
- la scission suit une différence réelle d'applicabilité, pas une préférence de taille de fichier ;
- l'ancien fichier est uniquement un bridge `SUPERSEDED` et n'apparaît plus dans les index ou compositions courantes ;
- aucune règle Java n'est perdue et aucune règle Maven/Gradle n'est remontée dans `520-JAVA.md` ;
- Maven et Gradle ne s'appliquent que lorsqu'ils sont réellement utilisés ;
- la preuve Games reste principalement une preuve Gradle/Java et ne devient pas une preuve Maven fictive ;
- aucun minimum JDK, Java ou Gradle propre à Games n'est généralisé ;
- Android ne devient pas une condition d'applicabilité de `522-GRADLE.md` et `610` conserve ses responsabilités ;
- les documents historiques ne sont pas réécrits pour masquer l'ancien owner combiné ;
- aucun template, skeleton, audit ou contrat de validation supplémentaire n'est créé.
## Transition
### PASS
Produire `history/0.1.2/alpha.3.md`, puis préparer `0.1.2-beta.1` pour la réconciliation intégrée des trois owners, la décision finale d'artefacts et les mises à jour documentaires durables nécessaires avant RC.
### FAIL
Consigner le diagnostic réel dans `history/0.1.2/alpha.3.md`, puis produire `alpha.3.fix.N` ou effectuer un nouveau REPLAN si la scission révèle une responsabilité qui ne peut pas être possédée proprement par `520`, `521` ou `522`.

275
deltas/0.1.2/beta.1.md Normal file
View File

@@ -0,0 +1,275 @@
<!-- file: deltas/0.1.2/beta.1.md -->
<!-- version: 1 -->
# Delta 0.1.2-beta.1 — réconciliation intégrée et décision finale d'artefacts
## Baseline et version
Baseline attendue : commit opérateur de `0.1.2-alpha.3`, réalisé après application de `history/0.1.2/alpha.3.md` avec statut `PASS`.
Version avant application :
```text
0.1.2-alpha.3
```
Version après application :
```text
0.1.2-beta.1
```
## Objet
Cette tranche exécute la réconciliation prévue après la scission des owners Java, Maven et Gradle. Elle ne crée aucune nouvelle règle fonctionnelle et ne modifie aucun des profils `520-JAVA.md`, `521-MAVEN.md`, `522-GRADLE.md` ou `610-ANDROID.md`.
La beta confirme que la séparation `520/521/522` résout l'ambiguïté d'applicabilité sans importer les choix locaux Games ni ouvrir le scope Android.
## Scope
REPLACE :
```text
VERSION
README.md
docs/000-README.md
docs/architecture/003-RULE_PROFILE_MODEL.md
docs/plans/008-V0_1_2_JAVA_GRADLE_REEVALUATION_PLAN.md
```
ADD :
```text
deltas/0.1.2/beta.1.md
```
DELETE : aucun.
Aucun `history/0.1.2/beta.1.md` n'est anticipé.
## Réconciliation des owners
La revue confirme les contrats suivants :
```text
520-JAVA.md Java uniquement
521-MAVEN.md Maven uniquement lorsqu'il est réellement utilisé
522-GRADLE.md Gradle uniquement lorsqu'il est réellement utilisé
```
La composition reste explicite. Un projet Java/Maven applique `520 + 521`; un projet Java/Gradle applique `520 + 522`; un projet Gradle sans Java n'applique pas `520` par simple transitivité.
L'ancien `520-JAVA_MAVEN_GRADLE.md` reste un bridge `SUPERSEDED` non normatif pour la compatibilité documentaire historique et ne redevient pas sélectionnable.
## Réconciliation contre Games
Games fournit une preuve réelle pour Java et Gradle, mais aucune preuve Maven. La beta confirme donc que :
- la séparation JDK de build / niveau source / bytecode-runtime est généralisable ;
- l'ownership `settings` / root / module / propriétés partagées est généralisable ;
- une politique Gradle système doit avoir une contrainte effectivement vérifiée ;
- le Wrapper reste un mécanisme conditionnel de reproductibilité ;
- Groovy DSL et absence de Wrapper restent des choix locaux Games ;
- JDK 25, Java 17, Gradle 9.6.0+ et Gradle 9.7.1 ne deviennent aucun minimum PGR ;
- aucun contenu Maven nouveau n'est déduit d'un corpus qui n'utilise pas Maven.
## Frontière Android
La beta ne modifie pas `610-ANDROID.md`.
Restent explicitement hors du scope `0.1.2` :
```text
AGP
compileSdk / targetSdk / minSdk
SDK / NDK
ABI / JNI
manifests / resources
APK / AAB / signing
Variant API
AVD / devices / smokes Android
contraintes 16 KB
SDL3 et architecture produit Games
```
Ces responsabilités restent réservées à `0.1.3` ou à un owner plus spécifique.
## Décision finale d'artefacts
Aucun artefact technique supplémentaire n'est justifié pour `0.1.2`.
Ne sont donc pas ajoutés :
```text
nouveau contrat docs/validation/
template Java/Maven/Gradle générique
skeleton Java/Gradle générique
audit Python Java/Maven/Gradle
artefact Maven déduit de Games
```
La raison est positive et vérifiable : les trois owners couvrent déjà les responsabilités génériques démontrées, tandis que Java, Maven et Gradle eux-mêmes possèdent les preuves exécutables de compilation/build/test. Ajouter un artefact uniquement pour remplir la release introduirait de la duplication ou une convention insuffisamment éprouvée.
## Documentation durable
La tranche actualise :
- le statut racine de la release ;
- l'index documentaire `0.1.2` ;
- le modèle architectural avec la décision beta durable ;
- le plan actif avec le `PASS` de `alpha.3` et la décision finale d'artefacts.
Aucun changement n'est requis dans `RULES.md`, `docs/rules/000-README.md` ou `ROADMAP.md`, déjà réconciliés pendant `alpha.3`.
## Validation opérateur
Après application du history `PASS` de `alpha.3`, commit/push de `alpha.3`, puis application du présent delta :
```bash
test "$(cat VERSION)" = '0.1.2-beta.1'
git cat-file -e HEAD:history/0.1.2/alpha.3.md
test -f history/0.1.2/alpha.3.md
test -f deltas/0.1.2/beta.1.md
test ! -e history/0.1.2/beta.1.md
grep -A2 '^## Statut$' history/0.1.2/alpha.3.md | grep -Fx 'PASS'
grep -Fx '<!-- version: 21 -->' README.md
grep -Fx '<!-- version: 34 -->' docs/000-README.md
grep -Fx '<!-- version: 8 -->' docs/architecture/003-RULE_PROFILE_MODEL.md
grep -Fx '<!-- version: 4 -->' docs/plans/008-V0_1_2_JAVA_GRADLE_REEVALUATION_PLAN.md
grep -Fx '<!-- version: 4 -->' docs/rules/520-JAVA.md
grep -Fx '<!-- version: 1 -->' docs/rules/521-MAVEN.md
grep -Fx '<!-- version: 1 -->' docs/rules/522-GRADLE.md
grep -Fx '<!-- version: 4 -->' docs/rules/520-JAVA_MAVEN_GRADLE.md
grep -Fx '<!-- version: 3 -->' docs/rules/610-ANDROID.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
history = Path('history/0.1.2/alpha.3.md').read_text(encoding='utf-8')
assert re.search(r'## Statut\s+PASS\s', history)
java = Path('docs/rules/520-JAVA.md').read_text(encoding='utf-8')
maven = Path('docs/rules/521-MAVEN.md').read_text(encoding='utf-8')
gradle = Path('docs/rules/522-GRADLE.md').read_text(encoding='utf-8')
legacy = Path('docs/rules/520-JAVA_MAVEN_GRADLE.md').read_text(encoding='utf-8')
android = Path('docs/rules/610-ANDROID.md').read_text(encoding='utf-8')
architecture = Path('docs/architecture/003-RULE_PROFILE_MODEL.md').read_text(encoding='utf-8')
plan = Path('docs/plans/008-V0_1_2_JAVA_GRADLE_REEVALUATION_PLAN.md').read_text(encoding='utf-8')
assert '# Profil Java' in java
assert '# Profil Maven' in maven
assert '# Profil Gradle' in gradle
assert '`SUPERSEDED` depuis `0.1.2-alpha.3`.' in legacy
assert 'Il ne constitue plus un profil sélectionnable' in legacy
for current in ('RULES.md', 'docs/000-README.md', 'docs/rules/000-README.md', 'docs/rules/610-ANDROID.md'):
assert '520-JAVA_MAVEN_GRADLE.md' not in Path(current).read_text(encoding='utf-8'), current
for local_choice in (
'JDK 25',
'source/target 17',
'Gradle 9.6.0',
'Gradle 9.7.1',
'AGP 9.4.0',
):
assert local_choice not in java, local_choice
assert local_choice not in maven, local_choice
assert local_choice not in gradle, local_choice
for android_term in (
'compileSdk',
'targetSdk',
'minSdk',
'NDK',
'ABI/JNI',
'APK/AAB',
'device/AVD',
'SDL3',
):
assert android_term not in maven, android_term
assert android_term not in gradle, android_term
assert 'Matrice AGP / Gradle / JDK' in android
assert '`compileSdk`, `targetSdk` et `minSdk`' in android
for phrase in (
'## Réconciliation beta de Java / Maven / Gradle en `0.1.2`',
'aucune preuve Maven réelle',
'Aucun nouveau contrat sous `docs/validation/`, template, skeleton ou audit Python Java/Maven/Gradle n\'est justifié.',
):
assert phrase in architecture, phrase
for phrase in (
'## Décision après `alpha.3` et réconciliation `beta.1`',
'La gate opérateur de `alpha.3` est `PASS`',
'aucun artefact technique supplémentaire',
'aucun corpus Maven',
'`0.1.3`',
):
assert phrase in plan, phrase
for foreign in (
'Cargo.toml',
'crates/knowledge-domain-lib/src/content_family.rs',
'deltas/0.0.1/alpha.3.fix.2.md',
'history/0.0.1/alpha.3.fix.1.md',
):
assert not Path(foreign).exists(), foreign
print('0.1.2 beta.1 reconciliation audit: clean (owners stable, Games-local choices not generalized, no extra artifacts justified, Android boundary preserved)')
PYGATE
git diff --check
git add README.md VERSION \
docs/000-README.md \
docs/architecture/003-RULE_PROFILE_MODEL.md \
docs/plans/008-V0_1_2_JAVA_GRADLE_REEVALUATION_PLAN.md \
deltas/0.1.2/beta.1.md
git diff --cached --check
git status --short
```
Le scope indexé attendu avant ajout du history est exactement :
```text
M README.md
M VERSION
A deltas/0.1.2/beta.1.md
M docs/000-README.md
M docs/architecture/003-RULE_PROFILE_MODEL.md
M docs/plans/008-V0_1_2_JAVA_GRADLE_REEVALUATION_PLAN.md
```
La revue qualitative doit confirmer que :
- aucun choix local Games n'est promu comme minimum générique ;
- Maven n'est pas présenté comme validé par Games ;
- les owners `520/521/522` restent indépendants et composables ;
- aucun nouveau fichier technique n'est ajouté pour satisfaire une structure théorique ;
- Android reste entièrement hors du scope fonctionnel de `0.1.2` ;
- la documentation durable reflète la scission et la décision d'artefacts sans réécrire les snapshots historiques.
## Transition
### PASS
Produire `history/0.1.2/beta.1.md`, puis préparer `0.1.2-rc.1` pour le gel de scope et la release gate complète.
### FAIL
Consigner le diagnostic réel dans `history/0.1.2/beta.1.md`, puis produire `beta.1.fix.N` ou effectuer un REPLAN uniquement si un défaut d'ownership ou de frontière ne peut pas être corrigé localement.

359
deltas/0.1.2/rc.1.md Normal file
View File

@@ -0,0 +1,359 @@
<!-- file: deltas/0.1.2/rc.1.md -->
<!-- version: 1 -->
# Delta 0.1.2-rc.1 — gel du scope et gate de release candidate
## Baseline et version
Baseline attendue : commit opérateur de `0.1.2-beta.1`, réalisé après application de `history/0.1.2/beta.1.md` avec statut `PASS`.
Le hash de ce commit n'est pas anticipé.
Version avant application :
```text
0.1.2-beta.1
```
Version après application :
```text
0.1.2-rc.1
```
## Objet et gel
La RC gèle le scope fonctionnel de `0.1.2` sur :
- `520-JAVA.md` comme owner du langage Java, de la compatibilité JDK/source/bytecode-runtime, de la structure, de l'API et des tests Java ;
- `521-MAVEN.md` comme spécialisation Maven uniquement lorsqu'un projet utilise réellement Maven ;
- `522-GRADLE.md` comme spécialisation Gradle uniquement lorsqu'un projet utilise réellement Gradle ;
- la distinction JDK de build / niveau Java source / niveau de bytecode-runtime sans généraliser les versions particulières de Games ;
- l'ownership Gradle `settings` / root / modules / propriétés partagées, avec séparation de l'état local ;
- le Wrapper comme mécanisme conditionnel de reproductibilité et Gradle système comme politique valide seulement lorsque sa contrainte est effectivement vérifiée ;
- l'ancien `520-JAVA_MAVEN_GRADLE.md` comme bridge `SUPERSEDED` non normatif afin de préserver les liens historiques ;
- la décision beta qu'aucun template, skeleton, audit Python, contrat de validation ou artefact Maven supplémentaire n'est justifié par le corpus disponible ;
- la frontière Android : AGP, SDK/NDK, ABI/JNI, manifests/resources, packaging/signing, devices/AVD, contraintes 16 KB et SDL3 restent hors des owners Java/Maven/Gradle et sont réévalués séparément en `0.1.3`.
Le changelog reçoit une entrée candidate `0.1.2` orientée utilisateurs. Le prompt `009-V0_1_3_START_PROMPT.md` est préparé pour la prochaine cible engagée Android à partir de Games.
Aucune nouvelle règle fonctionnelle n'entre dans cette RC. Les owners `520/521/522`, le bridge historique, `610-ANDROID.md`, les templates, skeletons, validations et scripts d'audit sont vérifiés mais non modifiés.
## Scope
REPLACE :
```text
VERSION
CHANGELOG.md
docs/000-README.md
docs/plans/008-V0_1_2_JAVA_GRADLE_REEVALUATION_PLAN.md
```
ADD :
```text
deltas/0.1.2/rc.1.md
prompts/009-V0_1_3_START_PROMPT.md
```
DELETE : aucun.
Le history `beta.1` est livré séparément et MUST être appliqué/committé avant ce delta.
## Gate opérateur de release candidate
Après application du history `PASS` de `beta.1`, commit/push de `beta.1`, puis application du présent delta :
```bash
test "$(cat VERSION)" = '0.1.2-rc.1'
git cat-file -e HEAD:history/0.1.2/beta.1.md
test -f history/0.1.2/beta.1.md
test -f deltas/0.1.2/rc.1.md
test -f prompts/009-V0_1_3_START_PROMPT.md
test ! -e history/0.1.2/rc.1.md
grep -A2 '^## Statut$' history/0.1.2/beta.1.md | grep -Fx 'PASS'
grep -Fx '<!-- version: 14 -->' CHANGELOG.md
grep -Fx '## 0.1.2 (candidate)' CHANGELOG.md
grep -Fx '<!-- version: 35 -->' docs/000-README.md
grep -Fx '<!-- version: 5 -->' docs/plans/008-V0_1_2_JAVA_GRADLE_REEVALUATION_PLAN.md
grep -Fx '<!-- version: 13 -->' ROADMAP.md
grep -Fx '<!-- version: 1 -->' prompts/009-V0_1_3_START_PROMPT.md
grep -Fx '<!-- version: 4 -->' docs/rules/520-JAVA.md
grep -Fx '<!-- version: 1 -->' docs/rules/521-MAVEN.md
grep -Fx '<!-- version: 1 -->' docs/rules/522-GRADLE.md
grep -Fx '<!-- version: 4 -->' docs/rules/520-JAVA_MAVEN_GRADLE.md
grep -Fx '<!-- version: 3 -->' docs/rules/610-ANDROID.md
```
Contrôle d'intégration de la RC :
```bash
python3 -B - <<'PYGATE'
from pathlib import Path
import re
expected = {
"alpha.1.md": "PASS",
"alpha.2.md": "PASS",
"alpha.2.fix.1.md": "PASS",
"alpha.3.md": "PASS",
"beta.1.md": "PASS",
}
histories = {path.name for path in Path("history/0.1.2").glob("*.md")}
assert histories == set(expected), histories
for name, status in expected.items():
text = Path("history/0.1.2", 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.1.2").glob("*.md")}
assert deltas == set(expected) | {"rc.1.md"}, deltas
changelog = Path("CHANGELOG.md").read_text(encoding="utf-8")
assert "## 0.1.2 (candidate)" in changelog
section = changelog.split("## 0.1.2 (candidate)", 1)[1].split("## 0.1.1", 1)[0]
for phrase in (
"trois owners indépendants",
"520-JAVA",
"521-MAVEN",
"522-GRADLE",
"JDK utilisé pour construire",
"Wrapper",
"Gradle système",
"SUPERSEDED",
"réévaluation pratique reste la cible distincte `0.1.3`",
):
assert phrase in section, phrase
for forbidden in (
"alpha.1",
"alpha.2",
"alpha.3",
"beta.1",
"rc.1",
):
assert forbidden not in section, forbidden
java = Path("docs/rules/520-JAVA.md").read_text(encoding="utf-8")
maven = Path("docs/rules/521-MAVEN.md").read_text(encoding="utf-8")
gradle = Path("docs/rules/522-GRADLE.md").read_text(encoding="utf-8")
legacy = Path("docs/rules/520-JAVA_MAVEN_GRADLE.md").read_text(encoding="utf-8")
android = Path("docs/rules/610-ANDROID.md").read_text(encoding="utf-8")
assert "# Profil Java" in java
assert "# Profil Maven" in maven
assert "# Profil Gradle" in gradle
assert "`SUPERSEDED` depuis `0.1.2-alpha.3`." in legacy
assert "Il ne constitue plus un profil sélectionnable" in legacy
for current in (
"RULES.md",
"docs/000-README.md",
"docs/rules/000-README.md",
"docs/rules/610-ANDROID.md",
):
assert "520-JAVA_MAVEN_GRADLE.md" not in Path(current).read_text(encoding="utf-8"), current
for local_choice in (
"JDK 25",
"source/target 17",
"Gradle 9.6.0",
"Gradle 9.7.1",
"AGP 9.4.0",
):
assert local_choice not in java, local_choice
assert local_choice not in maven, local_choice
assert local_choice not in gradle, local_choice
for android_term in (
"compileSdk",
"targetSdk",
"minSdk",
"NDK",
"ABI/JNI",
"APK/AAB",
"device/AVD",
"SDL3",
):
assert android_term not in maven, android_term
assert android_term not in gradle, android_term
for phrase in (
"Matrice AGP / Gradle / JDK",
"`compileSdk`, `targetSdk` et `minSdk`",
"ABI et code natif",
"Signing et secrets",
):
assert phrase in android, phrase
roadmap = Path("ROADMAP.md").read_text(encoding="utf-8")
assert "- `( ) 0.1.2`" in roadmap
for version in ("0.1.3", "0.1.4", "0.1.5", "0.1.6", "0.1.7"):
assert f"- `( ) {version}`" in roadmap, version
assert "- `( ) 0.1.8`" not in roadmap
assert "skeleton Tauri jusqu'au réexamen 0.1.4" in roadmap
plan = Path("docs/plans/008-V0_1_2_JAVA_GRADLE_REEVALUATION_PLAN.md").read_text(encoding="utf-8")
for phrase in (
"### beta.1 — réconciliation et décision d'artefacts",
"Statut opérateur : **PASS**.",
"### rc.1 — release candidate",
"Statut opérateur : **à valider**.",
"prompts/009-V0_1_3_START_PROMPT.md",
"Aucune nouvelle règle fonctionnelle n'entre en RC",
):
assert phrase in plan, phrase
prompt = Path("prompts/009-V0_1_3_START_PROMPT.md").read_text(encoding="utf-8")
for phrase in (
"archive source téléchargée depuis le tag Gitea `v0.1.2`",
"pgr-0.1.2-publish.001-report.md",
"0.1.3-alpha.1",
"ad6e44a1332eb7d6069cf1189d9433f0fbb8fac19c5aac9f4641ac45c1c556e8",
"610-ANDROID.md",
"520-JAVA.md",
"522-GRADLE.md",
"ADOPT / KEEP-LOCAL / OVERRIDE / DEFER",
"Android Gradle Plugin / Gradle / JDK",
"compileSdk",
"targetSdk",
"minSdk",
"NDK",
"ABI",
"JNI",
"signing",
"16 KB",
"réservé à `0.1.4`",
"adoption Games `0.1.5`",
):
assert phrase in prompt, phrase
for forbidden in (
"Cargo.toml",
"crates/knowledge-domain-lib/src/content_family.rs",
"deltas/0.0.1/alpha.3.fix.2.md",
"history/0.0.1/alpha.3.fix.1.md",
):
assert not Path(forbidden).exists(), forbidden
java_related = sorted(
str(path)
for root in (Path("docs/templates"), Path("docs/skeletons"), Path("docs/validation"), Path("scripts"))
for path in root.rglob("*")
if path.is_file() and any(word in path.name.lower() for word in ("java", "maven", "gradle"))
)
assert java_related == [], java_related
print("0.1.2 rc.1 integration audit: clean (5 prior histories, frozen Java/Maven/Gradle owners, candidate changelog and prompt 009 verified, Android boundary preserved)")
PYGATE
```
Rejouer ensuite les preuves PGR :
```bash
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
```
Vérifier également l'hygiène texte et la parsabilité des templates de baseline sans prétendre simuler une toolchain Java/Maven/Gradle absente :
```bash
python3 -B - <<'PYHYGIENE'
from pathlib import Path
import json
import tomllib
for path in sorted(Path("templates/rust-cargo").rglob("*.toml")):
tomllib.loads(path.read_text(encoding="utf-8"))
json.loads(Path("templates/web-typescript/package.json").read_text(encoding="utf-8"))
json.loads(Path("templates/web-typescript/tsconfig.json").read_text(encoding="utf-8"))
roots = (
Path("VERSION"),
Path("README.md"),
Path("RULES.md"),
Path("ROADMAP.md"),
Path("CHANGELOG.md"),
Path("docs"),
Path("deltas"),
Path("history"),
Path("prompts"),
Path("templates"),
)
files = []
for root in roots:
if root.is_file():
files.append(root)
elif root.is_dir():
files.extend(path for path in root.rglob("*") if path.is_file())
for path in files:
try:
data = path.read_bytes()
text = data.decode("utf-8")
except UnicodeDecodeError:
continue
assert b"\r" not in data, path
assert text.endswith("\n"), path
for number, line in enumerate(text.splitlines(), 1):
assert line == line.rstrip(" \t"), (path, number)
print("0.1.2 rc.1 text/template hygiene: clean")
PYHYGIENE
git diff --check
git add VERSION CHANGELOG.md docs/000-README.md \
docs/plans/008-V0_1_2_JAVA_GRADLE_REEVALUATION_PLAN.md \
prompts/009-V0_1_3_START_PROMPT.md \
deltas/0.1.2/rc.1.md
git diff --cached --check
git status --short
```
Le scope indexé attendu avant ajout du history de `rc.1` est exactement :
```text
M CHANGELOG.md
M VERSION
A deltas/0.1.2/rc.1.md
M docs/000-README.md
M docs/plans/008-V0_1_2_JAVA_GRADLE_REEVALUATION_PLAN.md
A prompts/009-V0_1_3_START_PROMPT.md
```
## Revue opérateur complémentaire
Confirmer que :
- le scope normatif Java/Maven/Gradle est gelé ;
- aucun owner `520/521/522`, bridge historique, profil Android, template, skeleton, contrat de validation ou script d'audit n'est modifié par la RC ;
- le changelog candidat décrit les capacités utiles de `0.1.2` sans recopier les tranches internes ni l'incident de chaîne de commit ;
- aucun choix local Games n'est promu comme minimum Java/Maven/Gradle générique ;
- Maven n'est pas présenté comme éprouvé par Games ;
- l'absence d'artefacts Java/Maven/Gradle supplémentaires reste une décision positive fondée sur le corpus, pas un oubli ;
- Android reste hors du scope fonctionnel de `0.1.2` et le prompt `009` ne devient exécutable qu'après publication vérifiée de `v0.1.2` ;
- le prompt `009` ne transforme pas SDL3, les jeux ou Tauri Android en règles Android générales ;
- le skeleton Tauri reste réservé à `0.1.4` et l'adoption Games à `0.1.5` ;
- `0.1.8` n'est pas réservé ;
- aucune preuve `javac`, Maven, Gradle ou Android n'est revendiquée localement alors que PGR ne contient pas d'artefact exécutable correspondant dans cette RC.
## Transition
### PASS
Produire `history/0.1.2/rc.1.md`, l'appliquer puis committer/pousser `rc.1`. Continuer avec `0.1.2-rel.1` pour la promotion mécanique vers la stable, la clôture roadmap/plan/changelog et la gate pré-tag.
### FAIL
Consigner le diagnostic réel dans `history/0.1.2/rc.1.md`. Corriger uniquement la release candidate dans `rc.1.fix.N` tant qu'aucun défaut normatif plus large ne justifie un REPLAN. Ne pas préparer `rel.1` tant que la RC n'a pas obtenu `PASS`.

288
deltas/0.1.2/rel.1.md Normal file
View File

@@ -0,0 +1,288 @@
<!-- file: deltas/0.1.2/rel.1.md -->
<!-- version: 1 -->
# Delta 0.1.2 rel.1 — promotion stable pré-tag
## Baseline et version
Baseline : `0.1.2-rc.1`, avec `history/0.1.2/rc.1.md` appliqué et committé. Ce delta MUST NOT être appliqué avant ce commit.
Version avant application :
```text
0.1.2-rc.1
```
Version après application :
```text
0.1.2
```
`rel.1` identifie la clôture opérationnelle ; il ne fait pas partie de la version SemVer du produit.
## Objet
Promouvoir mécaniquement la RC validée vers la stable `0.1.2` sans rouvrir le scope fonctionnel.
La tranche finalise uniquement la présentation et les métadonnées de release : version stable, roadmap terminée, changelog sans marqueur `candidate`, README/index en état stable et plan `008` historique. Aucun owner Java/Maven/Gradle, bridge historique, profil Android, template, skeleton, validation ou script d'audit n'est modifié.
La validation de cette tranche est **pré-tag**. Le tag `v0.1.2`, son archive source Gitea et le rapport `pgr-0.1.2-publish.001-report.md` ne sont pas déclarés existants par ce delta. Ils suivent uniquement un history `rel.1` `PASS`, le commit stable `0.1.2` et la publication réelle du tag.
## Scope
REPLACE :
```text
VERSION
README.md
ROADMAP.md
CHANGELOG.md
docs/000-README.md
docs/plans/008-V0_1_2_JAVA_GRADLE_REEVALUATION_PLAN.md
```
ADD :
```text
deltas/0.1.2/rel.1.md
```
DELETE : aucun.
Le history `rc.1` est livré séparément. Le history `rel.1` sera produit uniquement après la gate opérateur.
## Validation opérateur pré-tag
Après application sur le commit contenant `history/0.1.2/rc.1.md` :
```bash
test "$(cat VERSION)" = '0.1.2'
git cat-file -e HEAD:history/0.1.2/rc.1.md
test -f history/0.1.2/rc.1.md
test -f deltas/0.1.2/rel.1.md
test -f prompts/009-V0_1_3_START_PROMPT.md
test ! -e history/0.1.2/rel.1.md
grep -A2 '^## Statut$' history/0.1.2/rc.1.md | grep -Fx 'PASS'
grep -Fx '<!-- version: 22 -->' README.md
grep -Fx '<!-- version: 14 -->' ROADMAP.md
grep -Fx '<!-- version: 15 -->' CHANGELOG.md
grep -Fx '<!-- version: 36 -->' docs/000-README.md
grep -Fx '<!-- version: 6 -->' docs/plans/008-V0_1_2_JAVA_GRADLE_REEVALUATION_PLAN.md
grep -F -- '- `(x) 0.1.2`' ROADMAP.md
grep -Fx '## 0.1.2' CHANGELOG.md
grep -F 'avec `0.1.2` d’owners Java, Maven et Gradle séparés et composables' README.md
grep -F 'plan historique de la stable `0.1.2`' README.md docs/000-README.md
python3 -B - <<'PYGATE'
from pathlib import Path
import re
expected = {
"alpha.1.md": "PASS",
"alpha.2.md": "PASS",
"alpha.2.fix.1.md": "PASS",
"alpha.3.md": "PASS",
"beta.1.md": "PASS",
"rc.1.md": "PASS",
}
for name, status in expected.items():
delta = Path("deltas/0.1.2", name)
history = Path("history/0.1.2", 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 = {path.name for path in Path("deltas/0.1.2").glob("*.md")} - {
path.name for path in Path("history/0.1.2").glob("*.md")
}
assert pending == {"rel.1.md"}, pending
roadmap = Path("ROADMAP.md").read_text(encoding="utf-8")
assert "- `(x) 0.1.2`" in roadmap
for version in ("0.1.3", "0.1.4", "0.1.5", "0.1.6", "0.1.7"):
assert f"- `( ) {version}`" in roadmap, version
assert "- `( ) 0.1.8`" not in roadmap
assert "skeleton Tauri jusqu'au réexamen 0.1.4" in roadmap
changelog = Path("CHANGELOG.md").read_text(encoding="utf-8")
assert "## 0.1.2" in changelog.splitlines()
assert "## 0.1.2 (candidate)" not in changelog
section = changelog.split("## 0.1.2", 1)[1].split("## 0.1.1", 1)[0]
for phrase in (
"trois owners indépendants",
"520-JAVA",
"521-MAVEN",
"522-GRADLE",
"JDK utilisé pour construire",
"Wrapper",
"Gradle système",
"SUPERSEDED",
"réévaluation pratique reste la cible distincte `0.1.3`",
):
assert phrase in section, phrase
for forbidden in ("alpha.1", "alpha.2", "alpha.3", "beta.1", "rc.1", "rel.1"):
assert forbidden not in section, forbidden
readme = Path("README.md").read_text(encoding="utf-8")
assert "avec `0.1.2` d’owners Java, Maven et Gradle séparés et composables" in readme
assert "plan historique de la stable `0.1.2`" in readme
index = Path("docs/000-README.md").read_text(encoding="utf-8")
assert "plan historique de la stable `0.1.2`" in index
assert "à exécuter uniquement après publication et vérification post-tag de `v0.1.2`" in index
plan = Path("docs/plans/008-V0_1_2_JAVA_GRADLE_REEVALUATION_PLAN.md").read_text(encoding="utf-8")
assert "Plan historique de la stable `0.1.2`" in plan
assert "### rc.1 — release candidate\n\nStatut opérateur : **PASS**." in plan
assert "history/0.1.2/rel.1.md" in plan
assert "pgr-0.1.2-publish.001-report.md" in plan
assert "commit `0.1.2` avant le tag `v0.1.2`" in plan
prompt = Path("prompts/009-V0_1_3_START_PROMPT.md").read_text(encoding="utf-8")
assert "tag Gitea `v0.1.2`" in prompt
assert "pgr-0.1.2-publish.001-report.md" in prompt
assert "0.1.3-alpha.1" in prompt
assert "réservé à `0.1.4`" in prompt
assert "adoption Games `0.1.5`" in prompt
for path, version in (
("docs/rules/520-JAVA.md", 4),
("docs/rules/521-MAVEN.md", 1),
("docs/rules/522-GRADLE.md", 1),
("docs/rules/520-JAVA_MAVEN_GRADLE.md", 4),
("docs/rules/610-ANDROID.md", 3),
):
lines = Path(path).read_text(encoding="utf-8").splitlines()
assert lines[1] == f"<!-- version: {version} -->", (path, lines[1])
legacy = Path("docs/rules/520-JAVA_MAVEN_GRADLE.md").read_text(encoding="utf-8")
assert "`SUPERSEDED` depuis `0.1.2-alpha.3`." in legacy
assert "Il ne constitue plus un profil sélectionnable" in legacy
for current in ("RULES.md", "docs/000-README.md", "docs/rules/000-README.md", "docs/rules/610-ANDROID.md"):
assert "520-JAVA_MAVEN_GRADLE.md" not in Path(current).read_text(encoding="utf-8"), current
for forbidden in (
"Cargo.toml",
"crates/knowledge-domain-lib/src/content_family.rs",
"deltas/0.0.1/alpha.3.fix.2.md",
"history/0.0.1/alpha.3.fix.1.md",
):
assert not Path(forbidden).exists(), forbidden
java_related = sorted(
str(path)
for root in (Path("docs/templates"), Path("docs/skeletons"), Path("docs/validation"), Path("scripts"))
for path in root.rglob("*")
if path.is_file() and any(word in path.name.lower() for word in ("java", "maven", "gradle"))
)
assert java_related == [], java_related
workflow = Path("docs/rules/210-WORKFLOW.md").read_text(encoding="utf-8")
assert "history rel.1 FAIL / PARTIAL / BLOCKED" in workflow
assert "premier history rel.N[/fix.M] PASS qui établit réellement la stable" in workflow
assert "commit X.Y.Z" in workflow
print("0.1.2 rel.1 stable gate audit: clean (6 prior histories, rel.1 pending, stable Java/Maven/Gradle presentation and post-tag handoff coherent)")
PYGATE
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 - <<'PYHYGIENE'
from pathlib import Path
import json
import tomllib
for path in sorted(Path("templates/rust-cargo").rglob("*.toml")):
tomllib.loads(path.read_text(encoding="utf-8"))
json.loads(Path("templates/web-typescript/package.json").read_text(encoding="utf-8"))
json.loads(Path("templates/web-typescript/tsconfig.json").read_text(encoding="utf-8"))
roots = (
Path("VERSION"), Path("README.md"), Path("RULES.md"), Path("ROADMAP.md"), Path("CHANGELOG.md"),
Path("docs"), Path("deltas"), Path("history"), Path("prompts"), Path("templates"),
)
files = []
for root in roots:
if root.is_file():
files.append(root)
elif root.is_dir():
files.extend(path for path in root.rglob("*") if path.is_file())
for path in files:
try:
data = path.read_bytes()
text = data.decode("utf-8")
except UnicodeDecodeError:
continue
assert b"\r" not in data, path
assert text.endswith("\n"), path
for number, line in enumerate(text.splitlines(), 1):
assert line == line.rstrip(" \t"), (path, number)
print("0.1.2 rel.1 text/template hygiene: clean")
PYHYGIENE
git diff --check
git add VERSION README.md ROADMAP.md CHANGELOG.md docs/000-README.md \
docs/plans/008-V0_1_2_JAVA_GRADLE_REEVALUATION_PLAN.md \
deltas/0.1.2/rel.1.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.1.2/rel.1.md
M docs/000-README.md
M docs/plans/008-V0_1_2_JAVA_GRADLE_REEVALUATION_PLAN.md
```
La RC a déjà reconfirmé les owners gelés, la frontière Android, le contrat du prompt `009` et l'absence d'artefacts Java/Maven/Gradle supplémentaires. Comme `rel.1` ne modifie aucun artefact technique, la promotion stable rejoue les tests PGR, les audits documentaires et l'hygiène des templates sans simuler de toolchain Java/Maven/Gradle absente du dépôt.
## Revue opérateur complémentaire
Confirmer que :
- le scope fonctionnel de `rc.1` ne change pas ;
- `0.1.2` est présenté comme stable de manière cohérente dans VERSION/README/ROADMAP/CHANGELOG/index/plan ;
- les histories `alpha.1`, `alpha.2`, `alpha.2.fix.1`, `alpha.3`, `beta.1` et `rc.1` restent conservés avec leur statut réel `PASS` ;
- `520-JAVA`, `521-MAVEN` et `522-GRADLE` restent gelés et l'ancien owner combiné reste uniquement un bridge historique `SUPERSEDED` ;
- aucune version particulière de Games ne devient un minimum PGR ;
- le profil Android reste inchangé et `0.1.3` conserve seul sa réévaluation pratique ;
- le skeleton Tauri reste réservé au réexamen `0.1.4` et l'adoption Games à `0.1.5` ;
- la roadmap engagée `0.1.3` à `0.1.7` reste intacte sans `0.1.8` ;
- le prompt `009` reste conditionnel à une vraie publication de `v0.1.2` et à un rapport post-tag `PASS` réel ;
- aucune preuve post-tag n'est anticipée.
## Transition
### PASS
Produire séparément `history/0.1.2/rel.1.md`, l'appliquer, puis créer le commit stable sous le message exact :
```text
0.1.2
```
Après push de la branche canonique, créer et publier le tag annoté `v0.1.2`. Vérifier localement et à distance l'objet tag et son commit déréférencé. Télécharger ensuite l'archive source depuis le tag Gitea et la fournir au générateur avec les sorties Git de publication afin de produire `pgr-0.1.2-publish.001-report.md` à partir de preuves réelles.
Le prompt `009-V0_1_3_START_PROMPT.md` ne devient la reprise effective de `0.1.3` qu'après un rapport post-tag `PASS`.
### FAIL
Consigner le diagnostic réel dans `history/0.1.2/rel.1.md`, ne pas créer le tag et corriger uniquement la fermeture dans `rel.1.fix.1` avant toute publication.

247
deltas/0.1.3/alpha.1.md Normal file
View File

@@ -0,0 +1,247 @@
<!-- file: deltas/0.1.3/alpha.1.md -->
<!-- version: 1 -->
# Delta 0.1.3-alpha.1 — audit de stable et cadrage Android
## Baseline et sources
Baseline PGR autoritaire : archive source téléchargée depuis le tag Gitea `v0.1.2`, accompagnée du rapport externe `pgr-0.1.2-publish.001-report.md` avec statut `PASS`.
SHA-256 vérifiés sur les fichiers réellement fournis :
```text
pgr-v0.1.2(1).zip 0ef8facab0c6f92ca427f5f13d38d6c4a4c1cc16174a20ecdab48991bd88d0e6
pgr-0.1.2-publish.001-report.md 0f6b4e2a685a957fa647a7db009320ada0fc67948737d8344cc3773bcaeb6a9c
games-v0.3.6(2).zip ad6e44a1332eb7d6069cf1189d9433f0fbb8fac19c5aac9f4641ac45c1c556e8
```
Les archives locales PGR et Games comportent respectivement `(1)` et `(2)` dans leur nom, mais leurs empreintes correspondent exactement aux baselines canoniques `pgr-v0.1.2.zip` et `games-v0.3.6.zip` attendues par le rapport/prompt.
Version avant application :
```text
0.1.2
```
Version après application :
```text
0.1.3-alpha.1
```
## Objet
Exécuter `prompts/009-V0_1_3_START_PROMPT.md` : vérifier intégralement la stable `v0.1.2` et son rapport post-tag, auditer le corpus Games autoritaire sur Android et ses preuves historiques, relire `610-ANDROID.md`, `520-JAVA.md`, `522-GRADLE.md`, `600-PLATFORMS.md`, la validation générale et la revue d'horizon, puis créer le plan `0.1.3` avant toute normalisation Android importante.
`alpha.1` reste un gate de cadrage. Aucune règle Android, règle Java/Gradle, validation spécialisée, template, skeleton ou audit nouveau n'est encore créé ou modifié.
## Résultat de l'audit d'intake
La stable PGR et son rapport post-tag concordent : SHA-256 attendu, CRC propre, racine unique `pgr/`, `316` entrées, `276` fichiers, `40` répertoires, aucun symlink, absence normale de `.git` et `VERSION=0.1.2`.
Le rapport `publish.001` est `PASS` et confirme le commit stable `585b508578aae337f6940110d4ca47c694a052d5`, l'objet tag annoté `cea2c7a06cde844ffa7411f73bb22685a3214414` et la déréférence de `v0.1.2` vers le commit stable.
La suite PGR donne `48/48` tests `PASS`. Les audits Markdown sont propres : `250` fichiers pour les headers, `10` tables sur `250` fichiers et `307` liens locaux sur `250` fichiers. Les templates TOML Rust/Cargo et JSON Web contrôlés sont parsables.
Les `90` couples delta/history de `0.0.1` à `0.1.2` sont complets. Les sept histories `0.1.2` sont tous `PASS`, y compris `alpha.2.fix.1` qui conserve la récupération historique de contamination inter-projet.
Le corpus Games fourni possède exactement le SHA canonique attendu, `652` entrées, `502` fichiers, `150` répertoires et aucun symlink. Ses audits statiques principaux sont propres : règles Rust, exports, workspace, tableaux Markdown et layout de distribution.
Le sous-projet Android natif exerce un build Gradle multi-module sous `Android/` avec `common`, `game-reflex-poc` et `game-snake-poc`, quatre sources Java, manifests/resources, namespaces/application IDs, configuration locale ignorée et scripts Gradle communs.
La baseline Games utilise AGP `9.4.0`, Gradle système `>= 9.6.0`, JDK de build compatible `>= 17`, niveau Java source/target `17`, `compileSdk 36`, `targetSdk 36`, `minSdk 21`, NDK `28.2.13676358` et SDL3 `3.4.16`. Ces valeurs restent des décisions et preuves Games, pas des minima PGR.
Les histories Games démontrent le passage d'une preuve initiale Wrapper/JDK 17 vers un Gradle système avec minimum exécutable et JDK courant, puis des builds réels avec Temurin `25.0.4.1 LTS` + Gradle `9.7.1` tout en conservant Java `17` comme niveau source/target.
Le pipeline natif Games exerce `cargo ndk`, JNI, SDL3 et quatre ABI (`arm64-v8a`, `armeabi-v7a`, `x86_64`, `x86`). Les histories prouvent APK Debug, AAB Release, contenu natif packagé, smokes AVD x86_64 et appareil ARM64 réel, runtime API 21 ainsi qu'une preuve `PAGE_SIZE=16384` sur Android 15/API 35 x86_64.
Ces responsabilités spécialisées ne sont pas copiées dans PGR. Le plan classe les décisions avec `ADOPT / KEEP-LOCAL / OVERRIDE / DEFER`, conserve Tauri en `DEFER` jusqu'à `0.1.4`, l'adoption Games jusqu'à `0.1.5` et prévoit une vérification des exigences Android officielles courantes avant toute normalisation de contraintes évolutives telles que 16 KB.
## Scope
REPLACE :
```text
VERSION
README.md
docs/000-README.md
```
ADD :
```text
docs/plans/009-V0_1_3_ANDROID_REEVALUATION_PLAN.md
deltas/0.1.3/alpha.1.md
```
DELETE : aucun.
`RULES.md`, `ROADMAP.md`, `CHANGELOG.md`, `docs/rules/610-ANDROID.md`, `docs/rules/520-JAVA.md`, `docs/rules/522-GRADLE.md`, `docs/rules/600-PLATFORMS.md`, les autres règles, templates, skeletons, validations, scripts, studies, prompts et histories existants restent inchangés dans `alpha.1`.
Aucun `history/0.1.3/alpha.1.md` n'est anticipé avant la gate opérateur.
## Validation opérateur
Après application sur la stable `0.1.2`, depuis la racine du dépôt :
```bash
test "$(cat VERSION)" = '0.1.3-alpha.1'
test -f docs/plans/009-V0_1_3_ANDROID_REEVALUATION_PLAN.md
test -f deltas/0.1.3/alpha.1.md
test ! -e history/0.1.3/alpha.1.md
grep -Fx '<!-- version: 23 -->' README.md
grep -Fx '<!-- version: 37 -->' docs/000-README.md
grep -F '009-V0_1_3_ANDROID_REEVALUATION_PLAN.md' README.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
expected = {
'0.0.1': 12,
'0.0.2': 12,
'0.0.3': 10,
'0.0.4': 9,
'0.0.5': 19,
'0.1.0': 10,
'0.1.1': 11,
'0.1.2': 7,
}
for release, count in expected.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) == count, (release, len(deltas))
assert deltas == histories, (release, sorted(deltas ^ histories))
statuses = {}
for path in Path('history/0.1.2').glob('*.md'):
text = path.read_text(encoding='utf-8')
match = re.search(r'## Statut\s+(?:`?)(PASS|FAIL|PARTIAL|BLOCKED)', text)
assert match is not None, path
statuses[path.name] = match.group(1)
assert len(statuses) == 7, statuses
assert set(statuses.values()) == {'PASS'}, statuses
assert statuses['alpha.2.fix.1.md'] == 'PASS'
assert statuses['rel.1.md'] == 'PASS'
roadmap = Path('ROADMAP.md').read_text(encoding='utf-8')
assert '- `(x) 0.1.2`' in roadmap
for release in range(3, 8):
assert f'- `( ) 0.1.{release}`' in roadmap, release
assert '0.1.8' not in roadmap
assert 'skeleton Tauri jusqu\'au réexamen 0.1.4' in roadmap
prompt = Path('prompts/009-V0_1_3_START_PROMPT.md').read_text(encoding='utf-8')
for phrase in (
'Version cible : `0.1.3`',
'Première tranche attendue : `0.1.3-alpha.1`',
'ad6e44a1332eb7d6069cf1189d9433f0fbb8fac19c5aac9f4641ac45c1c556e8',
'ADOPT / KEEP-LOCAL / OVERRIDE / DEFER',
'structure `Android/`',
'compileSdk`, `targetSdk` et `minSdk',
'alignement mémoire/16 KB',
'skeleton Tauri, réservé à `0.1.4`',
"démarrer l'adoption Games `0.1.5`",
):
assert phrase in prompt, phrase
android = Path('docs/rules/610-ANDROID.md').read_text(encoding='utf-8')
assert android.startswith('<!-- file: docs/rules/610-ANDROID.md -->\n<!-- version: 3 -->')
for phrase in (
'Android n\'implique pas à lui seul l\'applicabilité du profil Java.',
'Matrice AGP / Gradle / JDK',
'`compileSdk`, `targetSdk` et `minSdk`',
'ABI et code natif',
'Niveaux de tests Android',
'APK, AAB et artefacts de distribution',
):
assert phrase in android, phrase
assert Path('docs/rules/520-JAVA.md').read_text(encoding='utf-8').startswith(
'<!-- file: docs/rules/520-JAVA.md -->\n<!-- version: 4 -->'
)
assert Path('docs/rules/522-GRADLE.md').read_text(encoding='utf-8').startswith(
'<!-- file: docs/rules/522-GRADLE.md -->\n<!-- version: 1 -->'
)
assert Path('docs/rules/600-PLATFORMS.md').read_text(encoding='utf-8').startswith(
'<!-- file: docs/rules/600-PLATFORMS.md -->\n<!-- version: 1 -->'
)
plan = Path('docs/plans/009-V0_1_3_ANDROID_REEVALUATION_PLAN.md').read_text(encoding='utf-8')
for phrase in (
'Classification initiale des décisions Games',
'`ADOPT`',
'`KEEP-LOCAL`',
'`OVERRIDE`',
'`DEFER`',
'alpha.2 — structure, composition et contrats Android de base',
'alpha.3 — natif, packaging, distribution et validation',
'beta.1 — réconciliation et décision d\'artefacts',
'AGP `9.4.0`',
'Gradle système `>= 9.6.0`',
'NDK `r28c`',
'PAGE_SIZE=16384',
'documentation Android officielle courante',
'0.1.4 — domaine Tauri',
'0.1.5',
):
assert phrase in plan, phrase
assert not Path('docs/validation/006-ANDROID_VALIDATION.md').exists()
assert not Path('history/0.1.3/alpha.1.md').exists()
print('0.1.3 alpha.1 structural audit: clean (90 prior pairs, Games Android classified, Tauri/adoption boundaries preserved)')
PY
git diff --check
git add VERSION README.md docs/000-README.md \
docs/plans/009-V0_1_3_ANDROID_REEVALUATION_PLAN.md \
deltas/0.1.3/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.1.3/alpha.1.md
M docs/000-README.md
A docs/plans/009-V0_1_3_ANDROID_REEVALUATION_PLAN.md
```
La revue opérateur doit également confirmer que :
- `alpha.1` n'a pas modifié `610-ANDROID.md` avant validation du cadrage ;
- les versions exactes Games (AGP/Gradle/JDK/SDK/NDK/SDL3) restent des preuves ou choix locaux, pas des contraintes PGR universelles ;
- `Android/` reste une convention de séparation multi-plateforme et n'est pas imposé artificiellement à un dépôt Android-only ;
- Java reste un owner composé seulement lorsqu'il existe réellement du code Java ;
- les quatre ABI, JNI, `cargo ndk`, SDL3, Activities et assets Games restent des responsabilités produit/framework/spécialisation ;
- aucune exigence 16 KB n'est normalisée sans vérification des sources Android officielles courantes ;
- aucun nouveau template, audit, skeleton ou contrat de validation Android n'est créé par symétrie ;
- Games reste un corpus externe non modifié et son adoption reste réservée à `0.1.5` ;
- le skeleton Tauri reste `DEFER` jusqu'à `0.1.4` ;
- aucun nouveau numéro au-delà de `0.1.7` n'est réservé.
## Transition
### PASS
Produire `history/0.1.3/alpha.1.md` à partir des résultats réellement observés. Dans la même réponse, si aucune décision nouvelle n'est ouverte, préparer séparément le delta `0.1.3-alpha.2` consacré à la structure, la composition et aux contrats Android de base définis par le plan, sans absorber encore les détails natifs/packaging de `alpha.3`.
Après remise du history, fournir automatiquement le bloc opérateur exact pour appliquer le history, committer/pusher `0.1.3-alpha.1`, puis seulement appliquer le delta suivant conformément à `docs/templates/006-OPERATOR_COMMAND_HANDOFF.md`.
### FAIL
Consigner le résultat réel dans le history, puis ouvrir `0.1.3-alpha.1.fix.1` ou un REPLAN selon la cause. Aucun changement prévu pour `alpha.2` ne doit être absorbé silencieusement dans le fix.

198
deltas/0.1.3/alpha.2.md Normal file
View File

@@ -0,0 +1,198 @@
<!-- file: deltas/0.1.3/alpha.2.md -->
<!-- version: 1 -->
# Delta 0.1.3-alpha.2 — contrats Android de base
## Baseline
Ce delta s'applique après :
```text
0.1.3-alpha.1
+ history/0.1.3/alpha.1.md PASS
+ commit/push complet de la tranche alpha.1
```
Il ne doit pas être appliqué avant l'intégration du history `alpha.1`.
## Objet
Réviser le profil Android uniquement sur les contrats de base démontrés par le corpus Games et confirmés par la documentation Android officielle courante : structure Android-only versus multi-plateforme, composition langage/build, matrice AGP/Gradle/JDK, niveaux SDK, identité applicative, versioning, configuration locale et signing.
Cette tranche ne couvre pas encore NDK/ABI/native packaging, APK/AAB, Android Lint, tests instrumentés, installation/smokes device/AVD ni exigences 16 KB ; ces responsabilités restent réservées à `alpha.3`.
## Modifications
### Version
`VERSION` devient :
```text
0.1.3-alpha.2
```
### Plan Android
`docs/plans/009-V0_1_3_ANDROID_REEVALUATION_PLAN.md` passe en révision interne `2` et enregistre :
- le `PASS` opérateur réel de `alpha.1` ;
- l'absence de fix avant `alpha.2` ;
- les sources Android officielles vérifiées le `2026-09-28` ;
- la confirmation que les valeurs Games AGP `9.4.0`, Gradle `>= 9.6.0` et JDK observé restent des preuves locales et non des minima PGR ;
- le scope exact de `alpha.2` ;
- le maintien du détail 16 KB dans `alpha.3`.
### Profil Android
`docs/rules/610-ANDROID.md` passe en révision interne `4`.
La révision :
- conserve `Android/` comme convention conditionnelle d'un dépôt multi-plateforme, mais retire `gradlew*` du layout d'exemple afin de ne plus présenter le Wrapper comme structure obligatoire ;
- rend le profil Android neutre quant au langage applicatif et applique `520-JAVA.md` uniquement lorsque du Java est réellement présent ;
- distingue le JDK qui exécute Gradle/AGP du niveau Java du code applicatif ;
- conserve la matrice AGP/Gradle/JDK sans recopier les règles générales possédées par `522-GRADLE.md` ;
- clarifie `compileSdk`, `targetSdk` et `minSdk` comme trois contrats distincts ;
- remplace l'objectif implicite « `minSdk` aussi bas que possible » par une décision de compatibilité produit explicitement justifiée ;
- introduit la séparation explicite entre `namespace` et `applicationId` ;
- conserve `VERSION`, `versionName` et `versionCode` comme contrats distincts selon le release train réellement possédé ;
- précise que `local.properties` est réservé à l'environnement local Android/AGP et ne doit pas devenir une source de configuration partagée ou un fourre-tout de propriétés produit ;
- consolide le traitement des keystores, clés et mots de passe de signing sans recopier l'interdiction générale des secrets ;
- clarifie que le manifest possède composants/permissions/capabilities tandis que les identités `namespace` / `applicationId` restent dans la configuration Android du module.
Aucun template, skeleton, audit Python ou contrat de validation Android n'est créé.
## Vérification officielle utilisée
La vérification courante effectuée avant préparation du delta couvre :
```text
Android Gradle plugin 9.4.0 release notes
Configure your build
Java versions in Android builds
Configure the app module
Sign your app
```
Elle confirme notamment la matrice AGP/Gradle/JDK, la distinction du JDK de build et du niveau Java, les responsabilités `compileSdk` / `targetSdk` / `minSdk`, la séparation `namespace` / `applicationId`, le rôle local de `local.properties` et le caractère secret des clés de signing.
Elle n'est pas utilisée pour normaliser encore la contrainte 16 KB.
## Validation opérateur
Après application du history `PASS`, commit/push de `alpha.1`, puis application du présent delta :
```bash
test "$(cat VERSION)" = '0.1.3-alpha.2'
git cat-file -e HEAD:history/0.1.3/alpha.1.md
test -f history/0.1.3/alpha.1.md
test -f deltas/0.1.3/alpha.2.md
test ! -e history/0.1.3/alpha.2.md
grep -A2 '^## Statut$' history/0.1.3/alpha.1.md | grep -Fx 'PASS'
grep -Fx '<!-- version: 2 -->' docs/plans/009-V0_1_3_ANDROID_REEVALUATION_PLAN.md
grep -Fx '<!-- version: 4 -->' docs/rules/610-ANDROID.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
history = Path('history/0.1.3/alpha.1.md').read_text(encoding='utf-8')
assert re.search(r'## Statut\s+PASS\s', history)
android = Path('docs/rules/610-ANDROID.md').read_text(encoding='utf-8')
assert android.startswith('<!-- file: docs/rules/610-ANDROID.md -->\n<!-- version: 4 -->')
for phrase in (
'Android ne sélectionne pas à lui seul le langage applicatif du projet.',
'JDK qui exécute Gradle / AGP',
'Le choix de `minSdk` MUST être justifié par le contrat produit',
'## Identité applicative et namespace',
'`applicationId` identifie l\'application installée et distribuée.',
'`local.properties` appartient à l\'environnement local du build Android/AGP',
'release / upload keystore',
'`AndroidManifest.xml` MUST déclarer uniquement les composants',
):
assert phrase in android, phrase
structure = android.split('## Structure du projet', 1)[1].split('## Langage applicatif et logique de build', 1)[0]
assert 'gradlew' not in structure
assert 'settings.gradle(.kts)' in structure
assert '<module>/' in structure
assert 'Java est le langage applicatif Android par défaut du profil PGR' not in android
assert '`minSdk` SHOULD rester aussi bas que raisonnablement supportable' not in android
plan = Path('docs/plans/009-V0_1_3_ANDROID_REEVALUATION_PLAN.md').read_text(encoding='utf-8')
for phrase in (
'## Décision après `alpha.1`',
'La gate opérateur de `alpha.1` est `PASS`',
'### Vérification Android officielle courante pour `alpha.2`',
'AGP `9.4.0` requiert actuellement au minimum Gradle `9.6.0` et JDK `17`',
'La vérification 16 KB n\'est pas absorbée ici',
'### Scope arrêté pour `alpha.2`',
):
assert phrase in plan, phrase
assert not Path('docs/validation/006-ANDROID_VALIDATION.md').exists()
assert not Path('history/0.1.3/alpha.2.md').exists()
for path in (
'docs/rules/520-JAVA.md',
'docs/rules/522-GRADLE.md',
'docs/rules/600-PLATFORMS.md',
):
assert Path(path).is_file(), path
print('0.1.3 alpha.2 Android base-contract audit: clean (language/build ownership, SDK contracts, app identity, local config and signing clarified)')
PYGATE
git diff --check
git add VERSION \
docs/plans/009-V0_1_3_ANDROID_REEVALUATION_PLAN.md \
docs/rules/610-ANDROID.md \
deltas/0.1.3/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.1.3/alpha.2.md
M docs/plans/009-V0_1_3_ANDROID_REEVALUATION_PLAN.md
M docs/rules/610-ANDROID.md
```
La revue qualitative doit confirmer que :
- aucun choix Games n'est devenu une règle Android générale par copie de valeur ;
- Android n'impose plus Java par défaut et ne confond pas JDK de build avec niveau Java applicatif ;
- l'exemple structurel ne rend ni Wrapper ni Gradle système obligatoire ;
- `minSdk` est une décision de compatibilité produit et non un concours vers la valeur la plus basse ;
- `namespace` et `applicationId` sont distingués sans imposer un schéma de nommage propriétaire ;
- `local.properties` ne devient pas une configuration partagée et les secrets de signing restent hors Git ;
- aucun contenu NDK/ABI/16 KB, Tauri ou adoption Games n'a été absorbé prématurément ;
- aucun artefact supplémentaire n'a été créé uniquement pour remplir la release.
## Transition
### PASS
Produire `history/0.1.3/alpha.2.md`, puis préparer `0.1.3-alpha.3` pour les responsabilités conditionnelles NDK/ABI/native packaging, APK/AAB, Android Lint, niveaux de tests, install/smokes device/AVD et contraintes de distribution modernes réellement applicables.
Avant toute règle 16 KB, vérifier explicitement les exigences Android officielles courantes et borner le contrat au canal de distribution et aux artefacts natifs réellement concernés.
### FAIL
Consigner le diagnostic réel dans `history/0.1.3/alpha.2.md` et rester dans `alpha.2.fix.N` sauf REPLAN justifié. Le fix MUST rester borné aux contrats Android de base et ne doit pas absorber le scope natif/distribution de `alpha.3`, Tauri `0.1.4` ou l'adoption Games `0.1.5`.

211
deltas/0.1.3/alpha.3.md Normal file
View File

@@ -0,0 +1,211 @@
<!-- file: deltas/0.1.3/alpha.3.md -->
<!-- version: 1 -->
# Delta 0.1.3-alpha.3 — natif, packaging, distribution et validation Android
## Baseline
Ce delta s'applique après :
```text
0.1.3-alpha.2
+ history/0.1.3/alpha.2.md PASS
+ commit/push complet de la tranche alpha.2
```
Il ne doit pas être appliqué avant l'intégration du history `alpha.2`.
## Objet
Réviser le profil Android uniquement sur les responsabilités conditionnelles démontrées par Games et confirmées par la documentation Android officielle courante : NDK/ABI/code natif, Android Lint, niveaux de tests, APK/AAB, installation/smokes device/AVD et compatibilité 16 KB lorsque le package ou le canal de distribution l'exigent réellement.
Cette tranche ne crée aucun owner JNI/Rust/SDL, skeleton Android, audit Python ou contrat `docs/validation/` séparé. Elle ne modifie ni Tauri `0.1.4`, ni Games `0.1.5`.
## Modifications
### Version
`VERSION` devient :
```text
0.1.3-alpha.3
```
### Plan Android
`docs/plans/009-V0_1_3_ANDROID_REEVALUATION_PLAN.md` passe en révision interne `3` et enregistre :
- le `PASS` opérateur réel de `alpha.2` ;
- l'absence de fix avant `alpha.3` ;
- les sources Android officielles vérifiées le `2026-09-28` pour native/ABI, Lint, tests, packaging, Google Play et 16 KB ;
- le caractère évolutif des exigences de canal telles que `targetSdk` et les échéances de publication ;
- la cohérence de la preuve Games 16 KB sans la transformer en gate PGR locale ;
- le scope exact de `alpha.3` ;
- le maintien de la décision finale d'artefacts supplémentaires dans `beta.1`.
### Profil Android
`docs/rules/610-ANDROID.md` passe en révision interne `5`.
La révision :
- rend NDK et ABI conditionnels à la présence de bibliothèques natives directes ou transitives ;
- refuse toute version NDK ou liste d'ABI universelle et distingue compilation native, présence dans le package et preuve runtime ;
- inclut les SDK/bibliothèques natives précompilés dans le contrat de compatibilité du package final ;
- garde JNI, Rust, SDL, `cargo ndk` et les choix Games hors du profil Android général ;
- introduit une section Android Lint qui impose une exécution explicite et ciblée lorsqu'elle est applicable, sans supposer qu'un build ordinaire l'exécute ;
- précise les frontières JVM unit / instrumented / smoke device-AVD et la sélection proportionnée des matrices ;
- distingue l'APK installable de l'AAB de distribution et interdit d'utiliser un AAB seul comme preuve runtime ;
- impose de revalider les politiques évolutives du canal de distribution au moment de la release concernée ;
- normalise la compatibilité 16 KB uniquement lorsqu'il existe du code natif et qu'elle est requise par la plateforme ou le canal ;
- demande alors une preuve adaptée sur les bibliothèques 64 bits, le package APK/AAB et, lorsque nécessaire, un environnement runtime 16 KB ;
- conserve les versions AGP/NDK et les commandes précises comme moyens de preuve/toolchain, non comme minima PGR génériques.
## Vérification officielle utilisée
La vérification courante effectuée avant préparation du delta couvre :
```text
Support 16 KB page sizes
Android ABIs
Improve your code with lint checks
Test from the command line
Build your app from the command line
Meet Google Play's target API level requirement
```
Elle confirme notamment, au `2026-09-28` :
- Google Play demande depuis le `2026-08-31` API `36+` pour les nouvelles applications et mises à jour Android ordinaires, avec des règles distinctes pour certains form factors ; cette valeur reste une politique Play datée, pas un default Android PGR ;
- les applications Google Play ciblant API `35+` doivent supporter les pages `16 KB` sur appareils 64 bits et la documentation courante annonce le `2027-02-01` comme échéance à partir de laquelle les mises à jour non compatibles ne pourront plus être publiées ;
- une application sans code natif direct ou transitif n'a pas de réalignement ELF à effectuer ; une application native doit vérifier aussi ses bibliothèques tierces précompilées ;
- les moyens officiels de preuve couvrent les segments ELF, `zipalign -P 16` pour l'APK, l'alignement déclaré dans l'AAB via `bundletool` et, lorsque pertinent, un test sur environnement 16 KB ;
- AGP `8.5.1+` et NDK `r28+` facilitent le chemin standard actuel mais ne deviennent pas des minima PGR universels ;
- Lint doit être lancé explicitement ; les tests locaux JVM et instrumentés ont des environnements et des responsabilités distincts ;
- un APK est directement installable, tandis qu'un AAB sert à la distribution et n'est pas une preuve runtime par lui-même.
## Validation opérateur
Après application du history `PASS`, commit/push de `alpha.2`, puis application du présent delta :
```bash
test "$(cat VERSION)" = '0.1.3-alpha.3'
git cat-file -e HEAD:history/0.1.3/alpha.2.md
test -f history/0.1.3/alpha.2.md
test -f deltas/0.1.3/alpha.3.md
test ! -e history/0.1.3/alpha.3.md
grep -A2 '^## Statut$' history/0.1.3/alpha.2.md | grep -Fx 'PASS'
grep -Fx '<!-- version: 3 -->' docs/plans/009-V0_1_3_ANDROID_REEVALUATION_PLAN.md
grep -Fx '<!-- version: 5 -->' docs/rules/610-ANDROID.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
history = Path('history/0.1.3/alpha.2.md').read_text(encoding='utf-8')
assert re.search(r'## Statut\s+PASS\s', history)
android = Path('docs/rules/610-ANDROID.md').read_text(encoding='utf-8')
assert android.startswith('<!-- file: docs/rules/610-ANDROID.md -->\n<!-- version: 5 -->')
for phrase in (
'## NDK, ABI et code natif',
'bibliothèques natives précompilées ou apportées par un SDK',
'compilation native',
'packaging',
'runtime',
'## Android Lint',
'PGR MUST NOT supposer qu\'un build Gradle ordinaire exécute Lint automatiquement.',
'JVM unit',
'instrumented / integration',
'smoke device / AVD',
'Un AAB n\'est pas directement une preuve d\'installation ou d\'exécution sur device.',
'## Pages mémoire 16 KB et packaging natif',
'Google Play',
'API `35` ou supérieur',
'`zipalign -P 16`',
'`bundletool`',
):
assert phrase in android, phrase
assert 'PGR ne fixe ni version NDK ni liste universelle d\'ABI.' in android
assert 'PGR MUST NOT imposer une version AGP/NDK globale uniquement pour cette raison.' in android
assert 'targetSdk` minimal' in android
plan = Path('docs/plans/009-V0_1_3_ANDROID_REEVALUATION_PLAN.md').read_text(encoding='utf-8')
for phrase in (
'## Décision après `alpha.2`',
'La gate opérateur de `alpha.2` est `PASS`',
'### Vérification Android officielle courante pour `alpha.3`',
'depuis le `2026-08-31`',
'à partir du `2027-02-01`',
'### Scope arrêté pour `alpha.3`',
'Aucun owner JNI/Rust/SDL, skeleton Android, audit Python ou contrat `docs/validation/` n\'est créé.',
):
assert phrase in plan, phrase
assert not Path('docs/validation/006-ANDROID_VALIDATION.md').exists()
assert not Path('history/0.1.3/alpha.3.md').exists()
for forbidden in (
'NDK MUST être r28',
'MUST supporter arm64-v8a, armeabi-v7a, x86_64 et x86',
'targetSdk MUST être 36',
):
assert forbidden not in android, forbidden
print('0.1.3 alpha.3 Android native/distribution audit: clean (conditional native ownership, lint/tests/package boundaries and 16 KB policy verified)')
PYGATE
git diff --check
git add VERSION \
docs/plans/009-V0_1_3_ANDROID_REEVALUATION_PLAN.md \
docs/rules/610-ANDROID.md \
deltas/0.1.3/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.1.3/alpha.3.md
M docs/plans/009-V0_1_3_ANDROID_REEVALUATION_PLAN.md
M docs/rules/610-ANDROID.md
```
La revue qualitative doit confirmer que :
- aucune valeur Games (NDK `r28c`, quatre ABI, SDL3, Rust/JNI) n'est devenue une règle Android générale ;
- une application sans code natif n'hérite d'aucune gate NDK/ABI/ELF artificielle ;
- une dépendance native précompilée est couverte par la même preuve package que le code natif du projet ;
- Android Lint, tests JVM, tests instrumentés, package, install et smoke restent des preuves distinctes et proportionnées ;
- un AAB n'est pas traité comme un artefact directement installable ;
- la règle 16 KB est conditionnelle, fondée sur la politique officielle courante et ne fige ni date ni version d'outil comme default PGR durable ;
- le profil exige de revalider les politiques de distribution évolutives plutôt que de conserver aveuglément une valeur `targetSdk` datée ;
- PGR ne prétend pas avoir reconstruit les APK/AAB Games pendant cette tranche documentaire ;
- aucun contrat Android séparé, skeleton, audit ou owner spécialisé n'a été créé uniquement pour remplir la release ;
- Tauri `0.1.4` et l'adoption Games `0.1.5` restent hors scope.
## Transition
### PASS
Produire `history/0.1.3/alpha.3.md`, puis préparer `0.1.3-beta.1` pour la réconciliation du profil Android révisé contre Games, `520-JAVA.md`, `522-GRADLE.md`, `600-PLATFORMS.md` et `400-VALIDATION.md`.
La beta doit décider explicitement si `610-ANDROID.md` et les owners existants suffisent. Si un artefact fonctionnel supplémentaire devient réellement nécessaire, déclencher un REPLAN vers une tranche alpha dédiée au lieu de l'ajouter en beta.
### FAIL
Consigner le diagnostic réel dans `history/0.1.3/alpha.3.md` et rester dans `alpha.3.fix.N` sauf REPLAN justifié. Le fix MUST rester borné au natif, packaging, distribution et validation Android et ne doit pas absorber Tauri `0.1.4` ou l'adoption Games `0.1.5`.

266
deltas/0.1.3/beta.1.md Normal file
View File

@@ -0,0 +1,266 @@
<!-- file: deltas/0.1.3/beta.1.md -->
<!-- version: 1 -->
# Delta 0.1.3-beta.1 — réconciliation Android et décision finale d'artefacts
## Baseline et version
Baseline attendue : commit opérateur de `0.1.3-alpha.3`, réalisé après application de `history/0.1.3/alpha.3.md` avec statut `PASS`.
Version avant application :
```text
0.1.3-alpha.3
```
Version après application :
```text
0.1.3-beta.1
```
## Objet
Cette tranche exécute la réconciliation prévue après les révisions Android `alpha.2` et `alpha.3`. Elle ne crée aucune nouvelle règle fonctionnelle et ne modifie pas `610-ANDROID.md`.
La beta vérifie que le profil révisé reste générique face au corpus Games, se compose correctement avec `400-VALIDATION.md`, `520-JAVA.md`, `522-GRADLE.md` et `600-PLATFORMS.md`, puis tranche explicitement la question des artefacts Android supplémentaires.
## Scope
REPLACE :
```text
VERSION
README.md
docs/000-README.md
docs/plans/009-V0_1_3_ANDROID_REEVALUATION_PLAN.md
```
ADD :
```text
deltas/0.1.3/beta.1.md
```
DELETE : aucun.
Aucun `history/0.1.3/beta.1.md` n'est anticipé.
## Réconciliation contre les owners PGR
La revue confirme la composition suivante :
```text
400-VALIDATION.md sélection et autorité générales des preuves
520-JAVA.md Java uniquement lorsqu'il est présent
522-GRADLE.md Gradle uniquement lorsqu'il est utilisé
600-PLATFORMS.md contrat commun des plateformes
610-ANDROID.md spécialisation Android
```
Le profil Android ne recopie donc pas les contrats Java/Gradle généraux et ne transforme pas la présence d'AGP ou d'un JDK de build en applicabilité automatique du profil Java.
`400-VALIDATION.md` possède déjà la validation proportionnée et les catégories de preuves. `610-ANDROID.md` ajoute uniquement les responsabilités Android nécessaires pour choisir Lint, tests, packaging, installation et smokes selon le risque.
## Réconciliation contre Games
Les choix réutilisables démontrés par Games sont intégrés comme contrats génériques sans reprendre ses valeurs concrètes.
Restent explicitement locaux à Games :
```text
chemin concret Android/
Groovy DSL
Gradle système sans Wrapper
AGP 9.4.0
Gradle 9.7.1 / contrainte système >= 9.6.0
JDK 25.0.4.1
Java source/target 17
compileSdk 36 / targetSdk 36 / minSdk 21
NDK r28c
arm64-v8a / armeabi-v7a / x86_64 / x86
cargo ndk / bridge JNI / SDL3 / staging jniLibs
modules, Activities, labels et assets Games
```
Aucune de ces valeurs n'est promue comme minimum Android PGR.
Les deux corrections `OVERRIDE` initiales sont résolues : le Wrapper n'est plus présenté comme élément structurel obligatoire et `minSdk` est un contrat produit explicitement justifié.
Le sujet 16 KB, initialement `DEFER`, a été vérifié pendant `alpha.3` puis normalisé uniquement de manière conditionnelle au code natif, au package et au canal de distribution concerné. Les versions d'outils et échéances observées restent des informations datées, pas des defaults universels.
## Décision finale d'artefacts
Aucun artefact technique supplémentaire n'est justifié pour `0.1.3`.
Ne sont donc pas créés :
```text
docs/validation/006-ANDROID_VALIDATION.md
skeleton Android
template de build Android générique
audit Python Android
owner JNI / Rust Android / SDL
```
`400 + 600 + 610`, complétés par `520` et `522` lorsqu'ils sont applicables, couvrent déjà les responsabilités réutilisables démontrées. PGR ne possède en outre aucun build Android exécutable qui fournirait aujourd'hui un sujet légitime pour un skeleton, template ou audit spécialisé.
Si un nouvel artefact fonctionnel devenait réellement nécessaire, il exigerait un REPLAN vers une tranche alpha dédiée. La beta ne doit pas ajouter opportunément du contenu fonctionnel nouveau.
## Documentation durable
La tranche actualise :
- le statut racine de la release ;
- l'index documentaire `0.1.3` ;
- le plan actif avec le `PASS` réel de `alpha.3`, la résolution des classifications et la décision finale d'artefacts.
`610-ANDROID.md` reste en révision `5`. `ROADMAP.md`, `CHANGELOG.md`, `RULES.md`, les owners `400/520/522/600`, les skeletons, templates, validations et scripts restent inchangés.
Tauri demeure strictement réservé à `0.1.4` et l'adoption Games à `0.1.5`.
## Validation opérateur
Après application du history `PASS` de `alpha.3`, commit/push de `alpha.3`, puis application du présent delta :
```bash
test "$(cat VERSION)" = '0.1.3-beta.1'
git cat-file -e HEAD:history/0.1.3/alpha.3.md
test -f history/0.1.3/alpha.3.md
test -f deltas/0.1.3/beta.1.md
test ! -e history/0.1.3/beta.1.md
grep -A2 '^## Statut$' history/0.1.3/alpha.3.md | grep -Fx 'PASS'
grep -Fx '<!-- version: 24 -->' README.md
grep -Fx '<!-- version: 38 -->' docs/000-README.md
grep -Fx '<!-- version: 4 -->' docs/plans/009-V0_1_3_ANDROID_REEVALUATION_PLAN.md
grep -Fx '<!-- version: 5 -->' docs/rules/610-ANDROID.md
grep -Fx '<!-- version: 1 -->' docs/rules/400-VALIDATION.md
grep -Fx '<!-- version: 4 -->' docs/rules/520-JAVA.md
grep -Fx '<!-- version: 1 -->' docs/rules/522-GRADLE.md
grep -Fx '<!-- version: 1 -->' docs/rules/600-PLATFORMS.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
history = Path('history/0.1.3/alpha.3.md').read_text(encoding='utf-8')
assert re.search(r'## Statut\s+PASS\s', history)
validation = Path('docs/rules/400-VALIDATION.md').read_text(encoding='utf-8')
java = Path('docs/rules/520-JAVA.md').read_text(encoding='utf-8')
gradle = Path('docs/rules/522-GRADLE.md').read_text(encoding='utf-8')
platforms = Path('docs/rules/600-PLATFORMS.md').read_text(encoding='utf-8')
android = Path('docs/rules/610-ANDROID.md').read_text(encoding='utf-8')
plan = Path('docs/plans/009-V0_1_3_ANDROID_REEVALUATION_PLAN.md').read_text(encoding='utf-8')
for phrase in (
'La validation existe pour fournir une preuve utile proportionnée au changement.',
'BUILD, PACKAGE et PUBLISH',
'## Autorité du gate opérateur',
):
assert phrase in validation, phrase
assert '# Profil Java' in java
assert '# Profil Gradle' in gradle
assert '# Règles de profils plateforme' in platforms
for phrase in (
'Android ne sélectionne pas à lui seul le langage applicatif du projet.',
'Le choix de `minSdk` MUST être justifié par le contrat produit',
'PGR ne fixe ni version NDK ni liste universelle d\'ABI.',
'PGR MUST NOT supposer qu\'un build Gradle ordinaire exécute Lint automatiquement.',
'Un AAB n\'est pas directement une preuve d\'installation ou d\'exécution sur device.',
'## Pages mémoire 16 KB et packaging natif',
'PGR MUST NOT imposer une version AGP/NDK globale uniquement pour cette raison.',
):
assert phrase in android, phrase
for forbidden in (
'targetSdk MUST être 36',
'minSdk MUST être 21',
'NDK MUST être r28',
'MUST supporter arm64-v8a, armeabi-v7a, x86_64 et x86',
'Gradle MUST être 9.7.1',
'AGP MUST être 9.4.0',
'JDK MUST être 25',
):
assert forbidden not in android, forbidden
for phrase in (
'## Décision après `alpha.3` et réconciliation `beta.1`',
'La gate opérateur de `alpha.3` est `PASS`',
'### Résolution de la classification initiale',
'### Décision finale d\'artefacts Android',
'Aucun artefact technique supplémentaire n\'est justifié pour `0.1.3`.',
'docs/validation/006-ANDROID_VALIDATION.md',
'### Frontières après réconciliation',
'Tauri 0.1.4',
'adoption Games 0.1.5',
):
assert phrase in plan, phrase
assert not Path('docs/validation/006-ANDROID_VALIDATION.md').exists()
assert not Path('history/0.1.3/beta.1.md').exists()
for forbidden_path in (
'templates/android',
'docs/skeletons/004-ANDROID.md',
'docs/rules/620-JNI.md',
):
assert not Path(forbidden_path).exists(), forbidden_path
print('0.1.3 beta.1 reconciliation audit: clean (Android profile generic, Games-local choices preserved, existing owners sufficient, no extra artifacts justified)')
PYGATE
git diff --check
git add README.md VERSION \
docs/000-README.md \
docs/plans/009-V0_1_3_ANDROID_REEVALUATION_PLAN.md \
deltas/0.1.3/beta.1.md
git diff --cached --check
git status --short
```
Le scope indexé attendu avant ajout du history est exactement :
```text
M README.md
M VERSION
A deltas/0.1.3/beta.1.md
M docs/000-README.md
M docs/plans/009-V0_1_3_ANDROID_REEVALUATION_PLAN.md
```
La revue qualitative doit confirmer que :
- aucun choix local Games n'est devenu une règle Android générale ;
- les contraintes NDK/ABI/16 KB restent conditionnelles et n'imposent aucune toolchain universelle ;
- Java et Gradle restent des profils composés uniquement lorsqu'ils sont applicables ;
- `400 + 600 + 610` expriment déjà la validation Android sans contrat séparé redondant ;
- aucun skeleton, template, audit ou owner spécialisé n'est ajouté pour satisfaire une structure théorique ;
- Tauri `0.1.4` n'est pas commencé et l'adoption Games `0.1.5` reste hors scope ;
- aucun `0.1.8` n'est réservé.
## Transition
### PASS
Produire `history/0.1.3/beta.1.md`, puis préparer `0.1.3-rc.1` pour geler le scope Android, préparer le changelog candidat et le prompt de reprise `0.1.4`, puis rejouer le release gate complet sans commencer Tauri.
### FAIL
Consigner le diagnostic réel dans `history/0.1.3/beta.1.md`, puis produire `beta.1.fix.N` ou effectuer un REPLAN uniquement si un défaut d'ownership, de généricité ou de frontière ne peut pas être corrigé localement sans nouvelle matière fonctionnelle.

312
deltas/0.1.3/rc.1.md Normal file
View File

@@ -0,0 +1,312 @@
<!-- file: deltas/0.1.3/rc.1.md -->
<!-- version: 1 -->
# Delta 0.1.3-rc.1 — gel du scope Android et gate de release candidate
## Baseline et version
Baseline attendue : commit opérateur de `0.1.3-beta.1`, réalisé après application de `history/0.1.3/beta.1.md` avec statut `PASS`.
Le hash de ce commit n'est pas anticipé.
Version avant application :
```text
0.1.3-beta.1
```
Version après application :
```text
0.1.3-rc.1
```
## Objet et gel
La RC gèle le scope fonctionnel de `0.1.3` sur :
- Android comme spécialisation de `600-PLATFORMS.md`, neutre vis-à-vis du langage applicatif et composant Java/Gradle uniquement lorsqu'ils sont réellement applicables ;
- les responsabilités distinctes de `compileSdk`, `targetSdk` et `minSdk`, avec `minSdk` justifié par le contrat produit plutôt que minimisé cérémoniellement ;
- `namespace`, `applicationId`, manifests/resources, configuration locale et signing comme responsabilités Android clairement bornées ;
- NDK, ABI et bibliothèques natives uniquement pour les projets réellement concernés, sans version NDK ni liste d'ABI universelles ;
- la séparation entre compilation native, packaging et preuve runtime ;
- Android Lint comme gate explicite, avec tests JVM, tests instrumentés et smokes device/AVD sélectionnés proportionnellement au changement ;
- la distinction APK/AAB versus preuve d'installation/exécution ;
- la compatibilité pages mémoire 16 KB comme contrat conditionnel au code natif, au package et au canal de distribution concernés, sans minimum AGP/NDK/SDK universel ;
- les choix spécifiques Games — versions d'outils, niveaux SDK, quatre ABI, Rust/JNI/SDL, modules et assets — conservés comme décisions locales ;
- la décision beta qu'aucun skeleton Android, template de build, audit Python, owner JNI/Rust/SDL ni contrat de validation Android séparé n'est justifié ;
- la frontière suivante : réexamen Tauri `0.1.4`, adoption Games `0.1.5`, adoption KSP `0.1.6`.
Le changelog reçoit une entrée candidate `0.1.3` orientée utilisateurs. Le prompt `010-V0_1_4_START_PROMPT.md` est préparé pour le réexamen Tauri après publication vérifiée de `v0.1.3`.
Aucune nouvelle règle fonctionnelle Android n'entre dans cette RC. Les owners, skeletons, templates, validations et scripts sont vérifiés mais non modifiés.
## Scope
REPLACE :
```text
VERSION
CHANGELOG.md
docs/000-README.md
docs/plans/009-V0_1_3_ANDROID_REEVALUATION_PLAN.md
```
ADD :
```text
deltas/0.1.3/rc.1.md
prompts/010-V0_1_4_START_PROMPT.md
```
DELETE : aucun.
Le history `beta.1` est livré séparément et MUST être appliqué/committé avant ce delta.
## Gate opérateur de release candidate
Après application du history `PASS` de `beta.1`, commit/push de `beta.1`, puis application du présent delta :
```bash
test "$(cat VERSION)" = '0.1.3-rc.1'
git cat-file -e HEAD:history/0.1.3/beta.1.md
test -f history/0.1.3/beta.1.md
test -f deltas/0.1.3/rc.1.md
test -f prompts/010-V0_1_4_START_PROMPT.md
test ! -e history/0.1.3/rc.1.md
grep -A2 '^## Statut$' history/0.1.3/beta.1.md | grep -Fx 'PASS'
grep -Fx '<!-- version: 16 -->' CHANGELOG.md
grep -Fx '## 0.1.3 (candidate)' CHANGELOG.md
grep -Fx '<!-- version: 39 -->' docs/000-README.md
grep -Fx '<!-- version: 5 -->' docs/plans/009-V0_1_3_ANDROID_REEVALUATION_PLAN.md
grep -Fx '<!-- version: 14 -->' ROADMAP.md
grep -Fx '<!-- version: 1 -->' prompts/010-V0_1_4_START_PROMPT.md
grep -Fx '<!-- version: 5 -->' docs/rules/610-ANDROID.md
grep -Fx '<!-- version: 6 -->' docs/rules/710-TAURI.md
grep -Fx '<!-- version: 2 -->' docs/studies/002-TAURI_SKELETON_DECISION.md
grep -Fx '<!-- version: 1 -->' docs/skeletons/003-WEB_FRONTEND.md
grep -Fx '<!-- version: 1 -->' docs/validation/005-WEB_FRONTEND_VALIDATION.md
```
Contrôle d'intégration de la RC :
```bash
python3 -B - <<'PYGATE'
from pathlib import Path
import re
expected = {
"alpha.1.md": "PASS",
"alpha.2.md": "PASS",
"alpha.3.md": "PASS",
"beta.1.md": "PASS",
}
histories = {path.name for path in Path("history/0.1.3").glob("*.md")}
assert histories == set(expected), histories
for name, status in expected.items():
text = Path("history/0.1.3", 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.1.3").glob("*.md")}
assert deltas == set(expected) | {"rc.1.md"}, deltas
changelog = Path("CHANGELOG.md").read_text(encoding="utf-8")
assert "## 0.1.3 (candidate)" in changelog
section = changelog.split("## 0.1.3 (candidate)", 1)[1].split("## 0.1.2", 1)[0]
for phrase in (
"profil Android",
"compileSdk",
"targetSdk",
"minSdk",
"namespace",
"applicationId",
"NDK",
"Android Lint",
"tests instrumentés",
"APK/AAB",
"16 KB",
"0.1.4",
"0.1.5",
):
assert phrase in section, phrase
for forbidden in (
"alpha.1",
"alpha.2",
"alpha.3",
"beta.1",
"rc.1",
):
assert forbidden not in section, forbidden
android = Path("docs/rules/610-ANDROID.md").read_text(encoding="utf-8")
for phrase in (
"Android ne sélectionne pas à lui seul le langage applicatif du projet.",
"Le choix de `minSdk` MUST être justifié par le contrat produit",
"PGR ne fixe ni version NDK ni liste universelle d'ABI.",
"PGR MUST NOT supposer qu'un build Gradle ordinaire exécute Lint automatiquement.",
"Un AAB n'est pas directement une preuve d'installation ou d'exécution sur device.",
"## Pages mémoire 16 KB et packaging natif",
"PGR MUST NOT imposer une version AGP/NDK globale uniquement pour cette raison.",
):
assert phrase in android, phrase
for forbidden in (
"targetSdk MUST être 36",
"minSdk MUST être 21",
"NDK MUST être r28",
"MUST supporter arm64-v8a, armeabi-v7a, x86_64 et x86",
"Gradle MUST être 9.7.1",
"AGP MUST être 9.4.0",
"JDK MUST être 25",
):
assert forbidden not in android, forbidden
plan = Path("docs/plans/009-V0_1_3_ANDROID_REEVALUATION_PLAN.md").read_text(encoding="utf-8")
for phrase in (
"### beta.1 — réconciliation et décision d'artefacts\n\nRelire",
"Statut opérateur : **PASS**.",
"### rc.1 — release candidate\n\nStatut opérateur : **à valider**.",
"prompts/010-V0_1_4_START_PROMPT.md",
"Aucune nouvelle fonctionnalité normative Android ne doit apparaître en RC.",
):
assert phrase in plan, phrase
prompt = Path("prompts/010-V0_1_4_START_PROMPT.md").read_text(encoding="utf-8")
for phrase in (
"archive source téléchargée depuis le tag Gitea `v0.1.3`",
"pgr-0.1.3-publish.001-report.md",
"0.1.4-alpha.1",
"2a9cabcb9f147a348dcf8d24df8bc6c5029089b6d49feb17bd4a42b4293c329a",
"ad6e44a1332eb7d6069cf1189d9433f0fbb8fac19c5aac9f4641ac45c1c556e8",
"002-TAURI_SKELETON_DECISION.md",
"710-TAURI.md",
"003-WEB_FRONTEND",
"ADOPT / KEEP-LOCAL / OVERRIDE / DEFER",
"conditions de sortie",
"créer le skeleton Tauri parce que la roadmap le mentionne",
"adoption Games `0.1.5`",
"adoption KSP `0.1.6`",
):
assert phrase in prompt, phrase
study = Path("docs/studies/002-TAURI_SKELETON_DECISION.md").read_text(encoding="utf-8")
for phrase in (
"DEFER",
"Condition 1 — TypeScript et conventions Web contrôlées",
"Condition 2 — Vite et ownership des commandes/dev server/build outputs",
"Condition 3 — Sass/CSS et statut des artefacts générés",
"Condition 4 — validation frontend indépendante de la validation Tauri",
"Condition 5 — framework CSS classé comme décision de skeleton/projet",
"réexamen autorisé 0.1.4",
"création automatique interdite",
):
assert phrase in study, phrase
roadmap = Path("ROADMAP.md").read_text(encoding="utf-8")
for version in ("0.1.3", "0.1.4", "0.1.5", "0.1.6", "0.1.7"):
assert f"- `( ) {version}`" in roadmap, version
assert "- `( ) 0.1.8`" not in roadmap
assert "skeleton Tauri jusqu'au réexamen 0.1.4" in roadmap
for forbidden_path in (
"docs/validation/006-ANDROID_VALIDATION.md",
"docs/skeletons/004-ANDROID.md",
"docs/rules/620-JNI.md",
"docs/skeletons/004-TAURI.md",
):
assert not Path(forbidden_path).exists(), forbidden_path
index = Path("docs/000-README.md").read_text(encoding="utf-8")
assert "../prompts/010-V0_1_4_START_PROMPT.md" in index
print("0.1.3 rc.1 integration audit: clean (4 prior histories, frozen Android profile, candidate changelog and prompt 010 verified)")
PYGATE
```
Rejouer ensuite les preuves PGR :
```bash
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
```
Vérifier également l'hygiène texte/templates sans simuler une toolchain Android ou Tauri absente du dépôt PGR :
```bash
python3 -B - <<'PYHYGIENE'
from pathlib import Path
import json
import tomllib
for path in sorted(Path("templates/rust-cargo").rglob("*.toml")):
tomllib.loads(path.read_text(encoding="utf-8"))
json.loads(Path("templates/web-typescript/package.json").read_text(encoding="utf-8"))
json.loads(Path("templates/web-typescript/tsconfig.json").read_text(encoding="utf-8"))
roots = (
Path("VERSION"), Path("README.md"), Path("RULES.md"), Path("ROADMAP.md"), Path("CHANGELOG.md"),
Path("docs"), Path("deltas"), Path("history"), Path("prompts"), Path("templates"),
)
files = []
for root in roots:
if root.is_file():
files.append(root)
elif root.is_dir():
files.extend(path for path in root.rglob("*") if path.is_file())
for path in files:
try:
data = path.read_bytes()
text = data.decode("utf-8")
except UnicodeDecodeError:
continue
assert b"\r" not in data, path
assert text.endswith("\n"), path
for number, line in enumerate(text.splitlines(), 1):
assert line == line.rstrip(" \t"), (path, number)
print("0.1.3 rc.1 text/template hygiene: clean")
PYHYGIENE
git diff --check
git add VERSION CHANGELOG.md docs/000-README.md \
docs/plans/009-V0_1_3_ANDROID_REEVALUATION_PLAN.md \
deltas/0.1.3/rc.1.md prompts/010-V0_1_4_START_PROMPT.md
git diff --cached --check
git status --short
```
Le scope indexé attendu avant ajout du history est exactement :
```text
M CHANGELOG.md
M VERSION
A deltas/0.1.3/rc.1.md
M docs/000-README.md
M docs/plans/009-V0_1_3_ANDROID_REEVALUATION_PLAN.md
A prompts/010-V0_1_4_START_PROMPT.md
```
La revue qualitative doit confirmer que :
- aucune règle fonctionnelle Android nouvelle n'entre en RC ;
- `610-ANDROID.md` reste en révision `5` et aucun choix Games n'est généralisé ;
- aucun artefact Android supplémentaire n'est créé ;
- le changelog candidat décrit la valeur utilisateur de `0.1.3` sans recopier la chronologie alpha/beta/RC ;
- le prompt `010` exige une future stable `v0.1.3` réellement publiée et son rapport post-tag `PASS` ;
- le `DEFER` Tauri n'est pas levé par le prompt : `0.1.4` doit le réexaminer objectivement contre les corpus courants ;
- l'adoption Games `0.1.5` et l'adoption KSP `0.1.6` ne sont pas commencées ;
- aucune preuve Android/Tauri exécutable n'est simulée dans PGR.
## Transition
### PASS
Produire séparément `history/0.1.3/rc.1.md`, puis préparer la promotion mécanique `0.1.3-rel.1` sans rouvrir le scope fonctionnel.

288
deltas/0.1.3/rel.1.md Normal file
View File

@@ -0,0 +1,288 @@
<!-- file: deltas/0.1.3/rel.1.md -->
<!-- version: 1 -->
# Delta 0.1.3 rel.1 — promotion stable pré-tag
## Baseline et version
Baseline : `0.1.3-rc.1`, avec `history/0.1.3/rc.1.md` appliqué et committé. Ce delta MUST NOT être appliqué avant ce commit.
Version avant application :
```text
0.1.3-rc.1
```
Version après application :
```text
0.1.3
```
`rel.1` identifie la clôture opérationnelle ; il ne fait pas partie de la version SemVer du produit.
## Objet
Promouvoir mécaniquement la RC validée vers la stable `0.1.3` sans rouvrir le scope fonctionnel.
La tranche finalise uniquement la présentation et les métadonnées de release : version stable, roadmap terminée, changelog sans marqueur `candidate`, README/index en état stable et plan `009` historique. Aucun owner Android/Java/Gradle/Tauri, template, skeleton, validation, étude technique ou script d'audit n'est modifié.
La validation de cette tranche est **pré-tag**. Le tag `v0.1.3`, son archive source Gitea et le rapport `pgr-0.1.3-publish.001-report.md` ne sont pas déclarés existants par ce delta. Ils suivent uniquement un history `rel.1` `PASS`, le commit stable `0.1.3` et la publication réelle du tag.
## Scope
REPLACE :
```text
VERSION
README.md
ROADMAP.md
CHANGELOG.md
docs/000-README.md
docs/plans/009-V0_1_3_ANDROID_REEVALUATION_PLAN.md
```
ADD :
```text
deltas/0.1.3/rel.1.md
```
DELETE : aucun.
Le history `rc.1` est livré séparément. Le history `rel.1` sera produit uniquement après la gate opérateur.
## Validation opérateur pré-tag
Après application sur le commit contenant `history/0.1.3/rc.1.md` :
```bash
test "$(cat VERSION)" = '0.1.3'
git cat-file -e HEAD:history/0.1.3/rc.1.md
test -f history/0.1.3/rc.1.md
test -f deltas/0.1.3/rel.1.md
test -f prompts/010-V0_1_4_START_PROMPT.md
test ! -e history/0.1.3/rel.1.md
grep -A2 '^## Statut$' history/0.1.3/rc.1.md | grep -Fx 'PASS'
grep -Fx '<!-- version: 25 -->' README.md
grep -Fx '<!-- version: 15 -->' ROADMAP.md
grep -Fx '<!-- version: 17 -->' CHANGELOG.md
grep -Fx '<!-- version: 40 -->' docs/000-README.md
grep -Fx '<!-- version: 6 -->' docs/plans/009-V0_1_3_ANDROID_REEVALUATION_PLAN.md
grep -F -- '- `(x) 0.1.3`' ROADMAP.md
grep -Fx '## 0.1.3' CHANGELOG.md
grep -F 'avec `0.1.3` d’un profil Android réévalué contre Games' README.md
grep -F 'plan historique de la stable `0.1.3`' docs/000-README.md
python3 -B - <<'PYGATE'
from pathlib import Path
import re
expected = {
"alpha.1.md": "PASS",
"alpha.2.md": "PASS",
"alpha.3.md": "PASS",
"beta.1.md": "PASS",
"rc.1.md": "PASS",
}
for name, status in expected.items():
delta = Path("deltas/0.1.3", name)
history = Path("history/0.1.3", 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 = {path.name for path in Path("deltas/0.1.3").glob("*.md")} - {
path.name for path in Path("history/0.1.3").glob("*.md")
}
assert pending == {"rel.1.md"}, pending
roadmap = Path("ROADMAP.md").read_text(encoding="utf-8")
assert "- `(x) 0.1.3`" in roadmap
for version in ("0.1.4", "0.1.5", "0.1.6", "0.1.7"):
assert f"- `( ) {version}`" in roadmap, version
assert "- `( ) 0.1.8`" not in roadmap
assert "skeleton Tauri jusqu'au réexamen 0.1.4" in roadmap
changelog = Path("CHANGELOG.md").read_text(encoding="utf-8")
assert "## 0.1.3" in changelog.splitlines()
assert "## 0.1.3 (candidate)" not in changelog
section = changelog.split("## 0.1.3", 1)[1].split("## 0.1.2", 1)[0]
for phrase in (
"profil Android",
"compileSdk",
"targetSdk",
"minSdk",
"namespace",
"applicationId",
"NDK",
"Android Lint",
"tests instrumentés",
"APK/AAB",
"16 KB",
"0.1.4",
"0.1.5",
):
assert phrase in section, phrase
for forbidden in ("alpha.1", "alpha.2", "alpha.3", "beta.1", "rc.1", "rel.1"):
assert forbidden not in section, forbidden
readme = Path("README.md").read_text(encoding="utf-8")
assert "avec `0.1.3` d’un profil Android réévalué contre Games" in readme
assert "plan historique de la stable Android `0.1.3`" in readme
index = Path("docs/000-README.md").read_text(encoding="utf-8")
assert "plan historique de la stable `0.1.3`" in index
assert "à exécuter uniquement après publication et vérification post-tag de `v0.1.3`" in index
plan = Path("docs/plans/009-V0_1_3_ANDROID_REEVALUATION_PLAN.md").read_text(encoding="utf-8")
assert "Plan 0.1.3 — réévaluation pratique Android" in plan
assert "### rc.1 — release candidate\n\nStatut opérateur : **PASS**." in plan
assert "history/0.1.3/rel.1.md" in plan
assert "pgr-0.1.3-publish.001-report.md" in plan
assert "commit `0.1.3` avant le tag `v0.1.3`" in plan
assert "plan historique de la stable `0.1.3`" in plan
prompt = Path("prompts/010-V0_1_4_START_PROMPT.md").read_text(encoding="utf-8")
for phrase in (
"tag Gitea `v0.1.3`",
"pgr-0.1.3-publish.001-report.md",
"0.1.4-alpha.1",
"002-TAURI_SKELETON_DECISION.md",
"710-TAURI.md",
"003-WEB_FRONTEND",
"ADOPT / KEEP-LOCAL / OVERRIDE / DEFER",
"adoption Games `0.1.5`",
"adoption KSP `0.1.6`",
):
assert phrase in prompt, phrase
for path, version in (
("docs/rules/400-VALIDATION.md", 1),
("docs/rules/520-JAVA.md", 4),
("docs/rules/522-GRADLE.md", 1),
("docs/rules/600-PLATFORMS.md", 1),
("docs/rules/610-ANDROID.md", 5),
("docs/rules/710-TAURI.md", 6),
("docs/studies/002-TAURI_SKELETON_DECISION.md", 2),
("docs/skeletons/003-WEB_FRONTEND.md", 1),
("docs/validation/005-WEB_FRONTEND_VALIDATION.md", 1),
):
lines = Path(path).read_text(encoding="utf-8").splitlines()
assert lines[1] == f"<!-- version: {version} -->", (path, lines[1])
android = Path("docs/rules/610-ANDROID.md").read_text(encoding="utf-8")
for phrase in (
"Android ne sélectionne pas à lui seul le langage applicatif du projet.",
"Le choix de `minSdk` MUST être justifié par le contrat produit",
"PGR ne fixe ni version NDK ni liste universelle d'ABI.",
"PGR MUST NOT supposer qu'un build Gradle ordinaire exécute Lint automatiquement.",
"Un AAB n'est pas directement une preuve d'installation ou d'exécution sur device.",
"## Pages mémoire 16 KB et packaging natif",
"PGR MUST NOT imposer une version AGP/NDK globale uniquement pour cette raison.",
):
assert phrase in android, phrase
for forbidden in (
"targetSdk MUST être 36",
"minSdk MUST être 21",
"NDK MUST être r28",
"MUST supporter arm64-v8a, armeabi-v7a, x86_64 et x86",
"Gradle MUST être 9.7.1",
"AGP MUST être 9.4.0",
"JDK MUST être 25",
):
assert forbidden not in android, forbidden
for forbidden_path in (
"docs/validation/006-ANDROID_VALIDATION.md",
"docs/skeletons/004-ANDROID.md",
"docs/rules/620-JNI.md",
"docs/skeletons/004-TAURI.md",
):
assert not Path(forbidden_path).exists(), forbidden_path
workflow = Path("docs/rules/210-WORKFLOW.md").read_text(encoding="utf-8")
assert "history rel.1 FAIL / PARTIAL / BLOCKED" in workflow
assert "premier history rel.N[/fix.M] PASS qui établit réellement la stable" in workflow
assert "commit X.Y.Z" in workflow
print("0.1.3 rel.1 stable gate audit: clean (5 prior histories, rel.1 pending, stable Android presentation and post-tag Tauri handoff coherent)")
PYGATE
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 - <<'PYHYGIENE'
from pathlib import Path
import json
import tomllib
for path in sorted(Path("templates/rust-cargo").rglob("*.toml")):
tomllib.loads(path.read_text(encoding="utf-8"))
json.loads(Path("templates/web-typescript/package.json").read_text(encoding="utf-8"))
json.loads(Path("templates/web-typescript/tsconfig.json").read_text(encoding="utf-8"))
roots = (
Path("VERSION"), Path("README.md"), Path("RULES.md"), Path("ROADMAP.md"), Path("CHANGELOG.md"),
Path("docs"), Path("deltas"), Path("history"), Path("prompts"), Path("templates"),
)
files = []
for root in roots:
if root.is_file():
files.append(root)
elif root.is_dir():
files.extend(path for path in root.rglob("*") if path.is_file())
for path in files:
try:
data = path.read_bytes()
text = data.decode("utf-8")
except UnicodeDecodeError:
continue
assert b"\r" not in data, path
assert text.endswith("\n"), path
for number, line in enumerate(text.splitlines(), 1):
assert line == line.rstrip(" \t"), (path, number)
print("0.1.3 rel.1 text/template hygiene: clean")
PYHYGIENE
git diff --check
git add VERSION README.md ROADMAP.md CHANGELOG.md docs/000-README.md \
docs/plans/009-V0_1_3_ANDROID_REEVALUATION_PLAN.md \
deltas/0.1.3/rel.1.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.1.3/rel.1.md
M docs/000-README.md
M docs/plans/009-V0_1_3_ANDROID_REEVALUATION_PLAN.md
```
La RC a déjà reconfirmé le profil Android gelé, les frontières Tauri/Games/KSP, le contrat du prompt `010` et l'absence d'artefacts Android supplémentaires. Comme `rel.1` ne modifie aucun artefact technique, la promotion stable rejoue les tests PGR, les audits documentaires et l'hygiène des templates sans simuler une toolchain Android absente du dépôt.
## Revue opérateur complémentaire
Confirmer que :
- `0.1.3` est bien présenté comme stable partout où la RC était auparavant candidate ;
- aucun changement fonctionnel Android n'est entré dans `rel.1` ;
- `0.1.4` reste le réexamen Tauri, sans création anticipée du skeleton ;
- `0.1.5` et `0.1.6` restent respectivement les adoptions Games et KSP ;
- le tag et le rapport post-tag ne sont pas anticipés dans le dépôt pré-tag.

207
deltas/0.1.4/alpha.1.md Normal file
View File

@@ -0,0 +1,207 @@
<!-- file: deltas/0.1.4/alpha.1.md -->
<!-- version: 1 -->
# Delta 0.1.4-alpha.1 — intake et cadrage du réexamen Tauri
## Objet
Ouvrir `0.1.4` conformément à `prompts/010-V0_1_4_START_PROMPT.md`, conserver une preuve locale de l'audit des baselines réellement fournies et matérialiser le plan avant toute modification normative ou création d'un skeleton Tauri.
La tranche ne crée pas `docs/skeletons/004-TAURI.md`, ne modifie pas `710-TAURI.md` et ne commence aucune adoption Games/KSP.
## Sources vérifiées avant préparation
```text
pgr-v0.1.3(1).zip
SHA-256 f3a7dffd5fe0fd3542e6b5207fda0b94bca2bd05bd5a54542d0a08d635a5d6ee
CRC PASS
pgr-0.1.3-publish.001-report.md
SHA-256 5405a1d6c216a5882c4638c07d573d50d440ce9e4e892d97f425e99054245544
status PASS
games-v0.3.6(3).zip
SHA-256 ad6e44a1332eb7d6069cf1189d9433f0fbb8fac19c5aac9f4641ac45c1c556e8
CRC PASS
khadhroony-solana-project-v0.3.19(1).zip
SHA-256 64a3813620925fa4f8914cdf74113399cfdd78ad51d60bbeff9bafbddcf4b253
CRC PASS
```
La baseline PGR correspond exactement au SHA canonique publié. La baseline Games correspond exactement à la référence `0.3.6` du prompt. KSP `0.3.19` est le corpus courant explicitement fourni et remplace, pour cette étude, la référence historique `0.3.17` sans prétendre posséder une preuve post-tag non fournie.
## Résultats d'intake
La stable PGR rejoue `48/48` tests Python et ses trois audits Markdown propres.
Games `0.3.6` rejoue ses audits Rust/workspace, Markdown tables et distribution layout propres. KSP `0.3.19` rejoue ses audits Rust/workspace et Markdown tables propres.
L'inventaire Tauri courant comporte `7` hosts : un sous Games et six sous KSP. Les sept convergent sur un host Cargo direct, `build.rs`, `tauri.conf.json`, `capabilities/`, `src/tauri.rs`, `frontend/`, TypeScript et Vite, sans `src-tauri/`.
Les choix Bootstrap/Sass/TS-RS, plugins, windows, ACL, ports, identifiers, bundle/resources et WASM ne convergent pas suffisamment pour devenir des obligations générales.
La relecture des owners Web confirme les cinq conditions historiques de sortie du `DEFER`. La vérification Tauri 2 officielle confirme que le layout standard et les commandes de commodité restent des possibilités supportées, tandis que capabilities/permissions doivent être traitées comme une surface de sécurité explicite.
## Modifications de la tranche
- `VERSION` passe à `0.1.4-alpha.1` ;
- `README.md` annonce l'ouverture du réexamen Tauri et référence son plan actif ;
- `docs/000-README.md` ajoute les points d'entrée actifs de `0.1.4` ;
- `docs/plans/010-V0_1_4_TAURI_REEVALUATION_PLAN.md` consigne audits, inventaire, classification et trajectoire ;
- le présent delta conserve le contrat de gate opérateur.
`ROADMAP.md` et `CHANGELOG.md` restent inchangés pendant cette tranche d'ouverture. Leur mise à jour est volontairement réservée aux phases de fermeture lorsque l'état réellement atteint est connu.
## Décision de tranche
```text
conditions Web historiques SATISFIED
ancien motif Web du DEFER LIFT
skeleton Tauri organisationnel ADOPT FOR MATERIALIZATION
création pendant alpha.1 NO
prochaine tranche alpha.2 — réconciliation normative 710 + étude 002
```
Cette décision autorise la matérialisation future du candidat ; elle ne présume pas que sa forme historique est correcte en bloc.
## Gate opérateur
Appliquer le delta puis exécuter depuis la racine du dépôt :
```bash
cat VERSION
test -f docs/plans/010-V0_1_4_TAURI_REEVALUATION_PLAN.md
test -f deltas/0.1.4/alpha.1.md
test ! -e history/0.1.4/alpha.1.md
test ! -e docs/skeletons/004-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
assert Path('VERSION').read_text(encoding='utf-8').strip() == '0.1.4-alpha.1'
expected = {
'0.0.1': 12,
'0.0.2': 12,
'0.0.3': 10,
'0.0.4': 9,
'0.0.5': 19,
'0.1.0': 10,
'0.1.1': 11,
'0.1.2': 7,
'0.1.3': 6,
}
for release, count in expected.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) == count, (release, len(deltas))
assert deltas == histories, (release, sorted(deltas ^ histories))
statuses = {}
for path in Path('history/0.1.3').glob('*.md'):
text = path.read_text(encoding='utf-8')
match = re.search(r'## Statut\s+(?:`?)(PASS|FAIL|PARTIAL|BLOCKED)', text)
assert match is not None, path
statuses[path.name] = match.group(1)
assert len(statuses) == 6, statuses
assert set(statuses.values()) == {'PASS'}, statuses
assert statuses['rel.1.md'] == 'PASS'
roadmap = Path('ROADMAP.md').read_text(encoding='utf-8')
assert '- `(x) 0.1.3`' in roadmap
for release in range(4, 8):
assert f'- `( ) 0.1.{release}`' in roadmap, release
assert '0.1.8' not in roadmap
prompt = Path('prompts/010-V0_1_4_START_PROMPT.md').read_text(encoding='utf-8')
for phrase in (
'Version cible : `0.1.4`',
'Première tranche attendue : `0.1.4-alpha.1`',
'ADOPT / KEEP-LOCAL / OVERRIDE / DEFER',
'conditions de sortie du report historique',
'skeleton Tauri',
'adoption Games `0.1.5`',
'adoption KSP `0.1.6`',
):
assert phrase in prompt, phrase
plan = Path('docs/plans/010-V0_1_4_TAURI_REEVALUATION_PLAN.md').read_text(encoding='utf-8')
for phrase in (
'7` hosts',
'conditions historiques de sortie SATISFIED',
'Classification initiale `alpha.1`',
'### `ADOPT`',
'### `KEEP-LOCAL`',
'### `OVERRIDE`',
'### `DEFER`',
'ADOPT FOR MATERIALIZATION',
'`alpha.2` — réconciliation normative Tauri',
'`alpha.3` — skeleton Tauri contrôlé',
'`beta.1` — réconciliation et décision d\'artefacts',
'`rc.1` — freeze et handoff',
'`rel.1` — stable',
'0.1.5',
'0.1.6',
):
assert phrase in plan, phrase
assert Path('docs/rules/710-TAURI.md').read_text(encoding='utf-8').startswith(
'<!-- file: docs/rules/710-TAURI.md -->\n<!-- version: 6 -->'
)
assert Path('docs/studies/002-TAURI_SKELETON_DECISION.md').read_text(encoding='utf-8').startswith(
'<!-- file: docs/studies/002-TAURI_SKELETON_DECISION.md -->\n<!-- version: 2 -->'
)
assert Path('docs/skeletons/003-WEB_FRONTEND.md').exists()
assert not Path('docs/skeletons/004-TAURI.md').exists()
assert not Path('history/0.1.4/alpha.1.md').exists()
print('0.1.4 alpha.1 structural audit: clean (96 prior pairs, 7 current Tauri hosts classified, no premature skeleton/adoption)')
PY
git diff --check
git add VERSION README.md docs/000-README.md \
docs/plans/010-V0_1_4_TAURI_REEVALUATION_PLAN.md \
deltas/0.1.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.1.4/alpha.1.md
M docs/000-README.md
A docs/plans/010-V0_1_4_TAURI_REEVALUATION_PLAN.md
```
## Revue opérateur attendue
La revue doit confirmer que `alpha.1` ne modifie ni `710-TAURI.md` ni l'étude historique avant validation du cadrage ; que les sept hosts réellement fournis sont utilisés comme preuves et non comme modèles à recopier ; que Bootstrap/Sass/TS-RS/WASM/plugins/windows/ports/identifiers restent correctement classifiés ; et que ni Games ni KSP ne sont adoptés pendant `0.1.4`.
Elle doit aussi confirmer que le candidat de skeleton est **autorisé à être matérialisé plus tard**, et non déjà créé par cette tranche.
## Transition
### PASS
Produire `history/0.1.4/alpha.1.md` à partir des résultats réellement observés. Dans la même réponse, préparer séparément le delta `0.1.4-alpha.2` consacré à la réconciliation normative de `710-TAURI.md` et de `002-TAURI_SKELETON_DECISION.md`, sans créer encore `004-TAURI.md`.
Après remise du history, fournir automatiquement le bloc opérateur exact pour appliquer le history, committer/pusher `0.1.4-alpha.1`, puis seulement appliquer le delta suivant conformément à `docs/templates/006-OPERATOR_COMMAND_HANDOFF.md`.
### FAIL
Consigner le résultat réel dans le history, puis ouvrir `0.1.4-alpha.1.fix.1` ou un REPLAN selon la cause. Aucun changement prévu pour `alpha.2` ne doit être absorbé silencieusement dans le fix.

View File

@@ -0,0 +1,209 @@
<!-- file: deltas/0.1.4/alpha.2.fix.1.md -->
<!-- version: 1 -->
# Delta 0.1.4-alpha.2.fix.1 — hygiène EOF et prévention automatique
## Diagnostic
La gate opérateur de `0.1.4-alpha.2` a validé les `48/48` tests Python, les trois audits Markdown et le contrôle normatif Tauri, puis a échoué sur les deux contrôles Git d'hygiène :
```text
docs/studies/002-TAURI_SKELETON_DECISION.md:299: new blank line at EOF.
```
Le même défaut a été signalé par :
```text
git diff --check
git diff --cached --check
```
`history/0.1.4/alpha.2.md` enregistre donc `FAIL`. Le contenu normatif Tauri de `alpha.2` reste conservé ; le présent fix corrige uniquement l'hygiène mécanique et la lacune de prévention qui a permis la réapparition d'un défaut déjà rencontré historiquement.
Version après application :
```text
0.1.4-alpha.2.fix.1
```
## Objet
Corriger la ligne vide surnuméraire à EOF de l'étude Tauri et faire de cette classe de défaut une propriété automatiquement contrôlée avant les futures livraisons PGR.
Le correctif introduit un audit monotâche read-only au lieu d'ajouter une vérification ad hoc dans chaque delta.
## Scope
REPLACE :
```text
VERSION
docs/rules/210-WORKFLOW.md
docs/studies/002-TAURI_SKELETON_DECISION.md
docs/validation/001-VALIDATION_MATRIX.md
```
ADD :
```text
deltas/0.1.4/alpha.2.fix.1.md
scripts/audit_text_hygiene.py
tests/test_text_hygiene.py
```
Les autres décisions de `alpha.2`, notamment `docs/rules/710-TAURI.md`, le plan `010` et `docs/000-README.md`, MUST rester inchangées.
## Correction EOF
`docs/studies/002-TAURI_SKELETON_DECISION.md` conserve son contenu et sa révision interne `3`. La seule modification de ce fichier est mécanique : sa terminaison passe de deux caractères LF successifs à exactement un LF final.
Aucune décision Tauri n'est modifiée par cette correction.
## Audit `text_hygiene`
`scripts/audit_text_hygiene.py` possède quatre propriétés mécaniques sur les fichiers texte sélectionnés :
```text
LF uniquement
aucun whitespace terminal
newline finale obligatoire
exactement une newline finale, donc aucune ligne vide supplémentaire à EOF
```
L'audit reste read-only, accepte des fichiers ou répertoires explicites et ignore les répertoires générés usuels. Il ne remplace pas un formatter, un parser Markdown ou `git diff --check`.
`tests/test_text_hygiene.py` couvre au minimum :
- fichier propre avec exactement un LF final ;
- ligne vide supplémentaire à EOF ;
- newline finale absente ;
- CRLF ;
- espace ou tabulation terminale ;
- exclusion d'un répertoire généré ;
- sélection invalide.
## Contrat de workflow
`docs/rules/210-WORKFLOW.md` passe de la révision `7` à `8` et rend explicite que le générateur doit contrôler l'hygiène mécanique avant livraison, plutôt que déléguer sa découverte à la gate opérateur.
`docs/validation/001-VALIDATION_MATRIX.md` passe de la révision `14` à `15` et ajoute `PGR-TEXT-HYGIENE-001` comme audit faible coût déclenché lorsqu'un fichier texte gouverné est modifié.
Le contrôle Git reste conservé comme filet indépendant.
## Gate opérateur
Après application puis commit/push du history `FAIL` de `alpha.2`, appliquer ce delta et exécuter :
```bash
cat VERSION
test -f history/0.1.4/alpha.2.md
grep -A2 '^## Statut$' history/0.1.4/alpha.2.md | grep -Fx 'FAIL'
test -f deltas/0.1.4/alpha.2.fix.1.md
test ! -e history/0.1.4/alpha.2.fix.1.md
test -f scripts/audit_text_hygiene.py
test -f tests/test_text_hygiene.py
python3 -B -m unittest discover -s tests -v
python3 -B scripts/audit_text_hygiene.py \
VERSION README.md RULES.md ROADMAP.md CHANGELOG.md \
docs deltas history prompts scripts tests templates .gitignore .settings
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
assert Path('VERSION').read_text(encoding='utf-8').strip() == '0.1.4-alpha.2.fix.1'
history = Path('history/0.1.4/alpha.2.md').read_text(encoding='utf-8')
assert re.search(r'## Statut\s+FAIL', history)
study_path = Path('docs/studies/002-TAURI_SKELETON_DECISION.md')
study = study_path.read_bytes()
assert study.endswith(b'\n')
assert not study.endswith(b'\n\n')
assert study_path.read_text(encoding='utf-8').startswith(
'<!-- file: docs/studies/002-TAURI_SKELETON_DECISION.md -->\n'
'<!-- version: 3 -->'
)
workflow = Path('docs/rules/210-WORKFLOW.md').read_text(encoding='utf-8')
assert workflow.startswith(
'<!-- file: docs/rules/210-WORKFLOW.md -->\n'
'<!-- version: 8 -->'
)
for phrase in (
'## Hygiène mécanique des artefacts texte',
'exactement une seule newline finale',
'scripts/audit_text_hygiene.py',
'Un générateur MUST corriger un défaut mécanique détectable avant livraison',
):
assert phrase in workflow, phrase
matrix = Path('docs/validation/001-VALIDATION_MATRIX.md').read_text(encoding='utf-8')
assert matrix.startswith(
'<!-- file: docs/validation/001-VALIDATION_MATRIX.md -->\n'
'<!-- version: 15 -->'
)
assert '`PGR-TEXT-HYGIENE-001`' in matrix
assert 'exactement une seule newline finale' in matrix
assert Path('scripts/audit_text_hygiene.py').exists()
assert Path('tests/test_text_hygiene.py').exists()
for path, version in (
('docs/rules/710-TAURI.md', '7'),
('docs/plans/010-V0_1_4_TAURI_REEVALUATION_PLAN.md', '2'),
('docs/000-README.md', '42'),
):
lines = Path(path).read_text(encoding='utf-8').splitlines()
assert lines[1] == f'<!-- version: {version} -->', (path, lines[1])
assert not Path('docs/skeletons/004-TAURI.md').exists()
assert not Path('history/0.1.4/alpha.2.fix.1.md').exists()
print(
'0.1.4 alpha.2.fix.1 hygiene audit: clean '
'(EOF corrected, reusable text hygiene audit active, Tauri decisions preserved)'
)
PY
git diff --check
git add -A
git diff --cached --check
git status --short
```
Le scope indexé attendu est :
```text
M VERSION
A deltas/0.1.4/alpha.2.fix.1.md
M docs/rules/210-WORKFLOW.md
M docs/studies/002-TAURI_SKELETON_DECISION.md
M docs/validation/001-VALIDATION_MATRIX.md
A scripts/audit_text_hygiene.py
A tests/test_text_hygiene.py
```
L'ordre d'affichage peut varier ; l'ensemble des chemins doit être identique.
## Transition
### PASS
Produire `history/0.1.4/alpha.2.fix.1.md`, commit/push sous l'identité `0.1.4-alpha.2.fix.1`, puis poursuivre avec `alpha.3` sur cette baseline propre. Les gates suivantes de `0.1.4` doivent sélectionner `PGR-TEXT-HYGIENE-001` pour les fichiers texte modifiés.
### FAIL
Enregistrer le résultat réel dans `history/0.1.4/alpha.2.fix.1.md` et poursuivre sous `alpha.2.fix.N`. Ne pas commencer `alpha.3` tant que l'hygiène texte et le scope du correctif ne sont pas `PASS`.

214
deltas/0.1.4/alpha.2.md Normal file
View File

@@ -0,0 +1,214 @@
<!-- file: deltas/0.1.4/alpha.2.md -->
<!-- version: 1 -->
# Delta 0.1.4-alpha.2 — réconciliation normative Tauri
## Objet
Réconcilier l'owner Tauri `710` et l'étude historique `002` à partir du cadrage `alpha.1` validé, sans matérialiser encore le skeleton `004-TAURI.md`.
La tranche sépare explicitement les responsabilités Tauri des choix Web déjà possédés par les owners `530/540/550/560`, précise la frontière commande / permission / capability et rend la politique de sélection des capability files visible comme décision de sécurité.
## Précondition
Le history `history/0.1.4/alpha.1.md` doit être présent avec statut `PASS` avant application de ce delta.
`alpha.1` a validé :
```text
48 / 48 tests PASS
Markdown headers: clean (266 file(s))
Markdown tables: clean (11 table(s), 266 file(s))
Markdown links: clean (343 local link(s), 266 file(s))
0.1.4 alpha.1 structural audit: clean (96 prior pairs, 7 current Tauri hosts classified, no premature skeleton/adoption)
```
## Réconciliation de `710-TAURI.md`
La révision interne passe de `6` à `7`.
La convention contrôlée est recentrée sur ce que Tauri possède réellement :
- host Cargo direct `lib + bin` recommandé pour une nouvelle baseline PGR contrôlée ;
- `src-tauri/` reste un layout Tauri supporté et n'est pas déclaré invalide ;
- `build.rs`, configuration Tauri, capabilities, assemblage Rust, hooks et packaging restent dans le scope Tauri ;
- la racine frontend est un point de composition, pas un choix possédé par `710` ;
- TypeScript, Vite, CSS/Sass, framework CSS et package manager restent possédés par leurs owners Web ;
- TS-RS devient un choix conditionnel de frontière typée plutôt qu'une obligation Tauri générale ;
- aucun template technique n'est créé.
La frontière de sécurité distingue désormais :
```text
commande enregistrée
permission ACL + scopes
capability assignant les permissions aux fenêtres/webviews
```
La tranche exige une décision explicite sur la sélection des capabilities. Elle enregistre le comportement Tauri 2 courant : si `app.security.capabilities` est absent ou vide, les capability files du répertoire `capabilities/` sont inclus par défaut ; une liste explicite permet de sélectionner ceux qui participent au build.
L'ajout d'un capability file sous auto-inclusion devient donc explicitement une modification de surface de sécurité. La revue doit également considérer le cumul des droits lorsqu'une fenêtre/webview appartient à plusieurs capabilities.
## Révision de l'étude `002`
La révision interne passe de `2` à `3`.
La décision `DEFER` de `0.0.5-alpha.9` reste conservée comme preuve historique mais n'est plus la décision active :
```text
motif Web historique LIFT
candidat organisationnel ADOPT FOR MATERIALIZATION
matérialisation pendant alpha.2 NO
matérialisation visée alpha.3
```
Le corpus courant reste `1` host Games `0.3.6` + `6` hosts KSP `0.3.19`. La future specification doit composer fondation + Rust/Cargo + Web applicable + Tauri + plateformes ciblées, sans recopier les owners.
## Mise à jour du plan et de l'index
`docs/plans/010-V0_1_4_TAURI_REEVALUATION_PLAN.md` passe en révision `2` et enregistre :
- la gate `alpha.1 PASS` ;
- les décisions normatives préparées pour `alpha.2` ;
- l'autorisation conditionnelle de matérialiser `004-TAURI.md` en `alpha.3` ;
- le point transversal découvert lors de l'utilisation de PGR avec SaseDev Knowledge : sémantique `SHOULD`, autonomie post-adoption et future séparation PGR/Knowledge ;
- l'obligation de reprendre ce point lors de la revue d'horizon de fermeture avant de générer le prompt suivant.
`docs/000-README.md` passe en révision `42` pour refléter l'état réconcilié du profil et de l'étude.
`ROADMAP.md` et `CHANGELOG.md` restent inchangés. La trajectoire publiée `0.1.5` Games / `0.1.6` KSP / `0.1.7` audits Rust n'est pas réécrite avant la revue d'horizon prévue en fermeture de `0.1.4`.
## Frontières
Cette tranche MUST NOT :
- créer `docs/skeletons/004-TAURI.md` ;
- créer un template `tauri.conf.json`, `build.rs` ou capability générique ;
- créer un contrat `docs/validation/*TAURI*` séparé ;
- modifier `RULES.md` ou `230-ADOPTION.md` pour traiter dès maintenant le point transversal `SHOULD`/autonomie ;
- modifier `ROADMAP.md` ou `CHANGELOG.md` ;
- commencer l'adoption Games ou KSP.
## Gate opérateur
Après application du history `alpha.1`, commit/push de `alpha.1`, puis application du présent delta, exécuter depuis la racine du dépôt :
```bash
cat VERSION
test -f history/0.1.4/alpha.1.md
test -f deltas/0.1.4/alpha.2.md
test ! -e history/0.1.4/alpha.2.md
test ! -e docs/skeletons/004-TAURI.md
grep -A4 '^## Statut$' history/0.1.4/alpha.1.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
assert Path('VERSION').read_text(encoding='utf-8').strip() == '0.1.4-alpha.2'
history = Path('history/0.1.4/alpha.1.md').read_text(encoding='utf-8')
assert re.search(r'## Statut\s+PASS', history)
assert {p.name for p in Path('deltas/0.1.4').glob('*.md')} == {'alpha.1.md', 'alpha.2.md'}
assert {p.name for p in Path('history/0.1.4').glob('*.md')} == {'alpha.1.md'}
rule = Path('docs/rules/710-TAURI.md').read_text(encoding='utf-8')
assert rule.startswith('<!-- file: docs/rules/710-TAURI.md -->\n<!-- version: 7 -->')
for phrase in (
'## Commandes, permissions et capabilities',
'commande enregistrée → handler natif connu du système d\'invocation',
'app.security.capabilities',
'inclut par défaut les capability files du répertoire `capabilities/`',
'droits cumulés',
'Le choix ou le renforcement de TS-RS appartient au projet ou au futur skeleton Tauri',
'host SHOULD être une crate Cargo mixte directement lisible',
):
assert phrase in rule, phrase
for phrase in (
'TypeScript et Vite sont fortement recommandés',
'Bootstrap est la baseline de présentation privilégiée',
'MUST utiliser TS-RS',
):
assert phrase not in rule, phrase
study = Path('docs/studies/002-TAURI_SKELETON_DECISION.md').read_text(encoding='utf-8')
assert study.startswith('<!-- file: docs/studies/002-TAURI_SKELETON_DECISION.md -->\n<!-- version: 3 -->')
for phrase in (
'## Réexamen décisionnel `0.1.4-alpha.2`',
'DEFER historique pour absence d\'owners Web LIFT',
'candidat organisationnel ADOPT FOR MATERIALIZATION',
'matérialisation visée alpha.3',
'Le `DEFER` de `0.0.5-alpha.9` reste conservé comme décision historique',
):
assert phrase in study, phrase
plan = Path('docs/plans/010-V0_1_4_TAURI_REEVALUATION_PLAN.md').read_text(encoding='utf-8')
assert plan.startswith('<!-- file: docs/plans/010-V0_1_4_TAURI_REEVALUATION_PLAN.md -->\n<!-- version: 2 -->')
for phrase in (
'## Gate `alpha.1` acquise',
'## Réconciliation normative préparée en `alpha.2`',
'## Point transversal découvert pendant la gate `alpha.1`',
'forte recommandation non obligatoire',
'sans rechercher automatiquement une version PGR plus récente',
'howtos, recettes et snippets pratiques vivent dans Knowledge',
'revue d\'horizon',
):
assert phrase in plan, phrase
index = Path('docs/000-README.md').read_text(encoding='utf-8')
assert index.startswith('<!-- file: docs/000-README.md -->\n<!-- version: 42 -->')
assert 'owner Tauri 2 réconcilié en `alpha.2`' in index
assert 'candidat organisationnel retenu pour matérialisation contrôlée en `alpha.3`' in index
roadmap = Path('ROADMAP.md').read_text(encoding='utf-8')
for phrase in (
'`( ) 0.1.4`',
'`( ) 0.1.5` — adoption réelle de PGR par `sasedev-games`',
'`( ) 0.1.6` — adoption réelle de PGR par `khadhroony-solana-project`',
'`( ) 0.1.7` — audits Python read-only',
):
assert phrase in roadmap, phrase
assert '0.1.8' not in roadmap
assert not Path('docs/skeletons/004-TAURI.md').exists()
assert not Path('history/0.1.4/alpha.2.md').exists()
print(
'0.1.4 alpha.2 Tauri normative audit: clean '
'(ACL boundaries explicit, Web ownership separated, historical DEFER lifted, skeleton still deferred to alpha.3)'
)
PY
git diff --check
git add VERSION \
deltas/0.1.4/alpha.2.md \
docs/000-README.md \
docs/plans/010-V0_1_4_TAURI_REEVALUATION_PLAN.md \
docs/rules/710-TAURI.md \
docs/studies/002-TAURI_SKELETON_DECISION.md
git diff --cached --check
git status --short
```
Le scope attendu du delta `alpha.2` est :
```text
M VERSION
A deltas/0.1.4/alpha.2.md
M docs/000-README.md
M docs/plans/010-V0_1_4_TAURI_REEVALUATION_PLAN.md
M docs/rules/710-TAURI.md
M docs/studies/002-TAURI_SKELETON_DECISION.md
```

202
deltas/0.1.4/alpha.3.md Normal file
View File

@@ -0,0 +1,202 @@
<!-- file: deltas/0.1.4/alpha.3.md -->
<!-- version: 1 -->
# Delta 0.1.4-alpha.3 — skeleton Tauri contrôlé
## Précondition
`0.1.4-alpha.2.fix.1` doit être committée avec son history `PASS` avant application de ce delta.
Version après application :
```text
0.1.4-alpha.3
```
## Objet
Matérialiser le skeleton Tauri 2 autorisé par les gates précédentes, sans créer de template technique universel ni absorber les owners Rust/Web/plateforme.
La tranche corrige également le contrat de packaging des archives delta/history après l'observation opérateur d'un répertoire englobant `pgr/` dans deux ZIP remis : les entrées doivent désormais être directement relatives à la racine du dépôt.
## Scope
ADD :
```text
deltas/0.1.4/alpha.3.md
docs/skeletons/004-TAURI.md
```
REPLACE :
```text
VERSION
docs/000-README.md
docs/plans/010-V0_1_4_TAURI_REEVALUATION_PLAN.md
docs/rules/210-WORKFLOW.md
docs/skeletons/000-README.md
```
Aucun template Tauri, contrat de validation Tauri séparé, changement de roadmap ou adoption Games/KSP n'appartient à cette tranche.
## Skeleton `004-TAURI`
La nouvelle specification :
- compose `001-PROJECT_GOVERNANCE_FOUNDATION`, `002-RUST_CARGO_WORKSPACE`, `003-WEB_FRONTEND` et `710-TAURI` ;
- conserve `src-tauri/` comme layout valide pour un projet existant tout en recommandant une crate Cargo directement lisible pour une nouvelle baseline contrôlée ;
- rend obligatoires les décisions de version, frontend, package manager, hooks, `devUrl`, `frontendDist`, capabilities, permissions, plugins, fenêtres, bundles et plateformes ;
- distingue recommandations de baseline et options locales ;
- garde WASM séparé par défaut ;
- définit un ordre d'initialisation ;
- définit une gate initiale séparant preuves Rust, frontend, intégration Tauri, packaging et plateforme ;
- conclut qu'aucun template Tauri technique supplémentaire n'est actuellement justifié.
## Packaging delta/history
`docs/rules/210-WORKFLOW.md` passe en révision `9` et rend explicite que :
```text
archive.delta/history.zip
├── VERSION # si présent dans le delta
├── docs/...
├── deltas/...
└── history/...
```
est valide, tandis que :
```text
archive.zip
└── pgr/
├── docs/...
└── history/...
```
est invalide pour le handoff canonique `unzip -o <archive> -d .`.
Le générateur doit vérifier la liste des entrées du ZIP avant remise.
## Gate opérateur
Après commit/push du history `PASS` de `alpha.2.fix.1`, appliquer ce delta puis exécuter :
```bash
cat VERSION
test -f history/0.1.4/alpha.2.fix.1.md
grep -A2 '^## Statut$' history/0.1.4/alpha.2.fix.1.md | grep -Fx 'PASS'
test -f deltas/0.1.4/alpha.3.md
test -f docs/skeletons/004-TAURI.md
test ! -e history/0.1.4/alpha.3.md
python3 -B -m unittest discover -s tests -v
python3 -B scripts/audit_text_hygiene.py \
VERSION README.md RULES.md ROADMAP.md CHANGELOG.md \
docs deltas history prompts scripts tests templates .gitignore .settings
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
assert Path('VERSION').read_text(encoding='utf-8').strip() == '0.1.4-alpha.3'
history = Path('history/0.1.4/alpha.2.fix.1.md').read_text(encoding='utf-8')
assert re.search(r'## Statut\s+PASS', history)
skeleton = Path('docs/skeletons/004-TAURI.md').read_text(encoding='utf-8')
assert skeleton.startswith(
'<!-- file: docs/skeletons/004-TAURI.md -->\n'
'<!-- version: 1 -->'
)
for phrase in (
'## Décisions obligatoires avant matérialisation',
'## Baseline organisationnelle recommandée',
'## Capabilities, permissions et commandes',
'## Ordre d\'initialisation',
'## Validation initiale',
'## Templates techniques',
'Aucun template Tauri technique supplémentaire n\'est requis',
'ADOPT / KEEP-LOCAL / OVERRIDE / DEFER',
):
assert phrase in skeleton, phrase
for path, version in (
('docs/rules/210-WORKFLOW.md', '9'),
('docs/skeletons/000-README.md', '7'),
('docs/000-README.md', '43'),
('docs/plans/010-V0_1_4_TAURI_REEVALUATION_PLAN.md', '3'),
('docs/rules/710-TAURI.md', '7'),
('docs/studies/002-TAURI_SKELETON_DECISION.md', '3'),
):
lines = Path(path).read_text(encoding='utf-8').splitlines()
assert lines[1] == f'<!-- version: {version} -->', (path, lines[1])
workflow = Path('docs/rules/210-WORKFLOW.md').read_text(encoding='utf-8')
for phrase in (
'Les entrées des archives delta/history MUST utiliser directement les chemins relatifs à la racine du dépôt',
'MUST NOT ajouter un répertoire englobant portant le nom du projet',
'vérifier la liste des entrées du ZIP avant remise',
):
assert phrase in workflow, phrase
index = Path('docs/skeletons/000-README.md').read_text(encoding='utf-8')
assert '[`004-TAURI.md`](004-TAURI.md)' in index
doc_index = Path('docs/000-README.md').read_text(encoding='utf-8')
assert '[`skeletons/004-TAURI.md`](skeletons/004-TAURI.md)' in doc_index
assert not Path('history/0.1.4/alpha.3.md').exists()
assert not Path('docs/templates/011-TAURI.md').exists()
assert not Path('docs/validation/006-TAURI_VALIDATION.md').exists()
print(
'0.1.4 alpha.3 skeleton audit: clean '
'(004 materialized, owners composed, no premature template/validation artifact, ZIP root contract explicit)'
)
PY
git diff --check
git add VERSION \
deltas/0.1.4/alpha.3.md \
docs/000-README.md \
docs/plans/010-V0_1_4_TAURI_REEVALUATION_PLAN.md \
docs/rules/210-WORKFLOW.md \
docs/skeletons/000-README.md \
docs/skeletons/004-TAURI.md
git diff --cached --check
git status --short
```
Le scope attendu est :
```text
M VERSION
A deltas/0.1.4/alpha.3.md
M docs/000-README.md
M docs/plans/010-V0_1_4_TAURI_REEVALUATION_PLAN.md
M docs/rules/210-WORKFLOW.md
M docs/skeletons/000-README.md
A docs/skeletons/004-TAURI.md
```
## Transition
### PASS
Produire `history/0.1.4/alpha.3.md`, commit/push sous l'identité `0.1.4-alpha.3`, puis ouvrir `beta.1` pour la réconciliation globale et la décision explicite sur les artefacts Tauri supplémentaires.
### FAIL
Enregistrer le résultat réel dans `history/0.1.4/alpha.3.md` et poursuivre sous `alpha.3.fix.N`. Ne pas ouvrir `beta.1` tant que la composition du skeleton et le scope ne sont pas propres.

189
deltas/0.1.4/beta.1.md Normal file
View File

@@ -0,0 +1,189 @@
<!-- file: deltas/0.1.4/beta.1.md -->
<!-- version: 1 -->
# Delta 0.1.4-beta.1 — réconciliation des artefacts Tauri
## Objet
Fermer la phase de conception Tauri de `0.1.4` en réconciliant les artefacts matérialisés, en vérifiant leurs owners et en décidant explicitement de ne pas créer de template technique Tauri, de contrat de validation Tauri séparé ou de dry-run factice en l'absence de lacune démontrée.
## Préconditions
- `0.1.4-alpha.3` est validée `PASS` et son history est présent ;
- `docs/skeletons/004-TAURI.md` est matérialisé ;
- `docs/rules/710-TAURI.md` reste l'owner Tauri en révision interne `7` ;
- aucun `docs/templates/011-TAURI.md` ni `docs/validation/006-TAURI_VALIDATION.md` n'existe ;
- les archives delta/history restent relatives directement à la racine du dépôt.
## Modifications
- `VERSION` passe à `0.1.4-beta.1` ;
- `docs/plans/010-V0_1_4_TAURI_REEVALUATION_PLAN.md` passe en révision `4` et enregistre la gate `alpha.3` ainsi que les décisions d'artefacts de `beta.1` ;
- `docs/studies/002-TAURI_SKELETON_DECISION.md` passe en révision `4` et ferme explicitement la décision sur template, validation séparée et dry-run ;
- `docs/000-README.md` passe en révision `44` et indexe l'état `beta.1` ;
- aucun nouvel owner, template ou contrat de validation Tauri n'est créé.
## Décision attendue
```text
004-TAURI.md KEEP
template technique Tauri générique DO NOT CREATE
006-TAURI_VALIDATION.md DO NOT CREATE
dry-run exécutable d'un faux projet NOT REQUIRED
audit statique de composition REQUIRED
```
L'absence d'artefact supplémentaire est une décision positive : un fichier nouveau n'est justifié que s'il possède une responsabilité réutilisable non déjà couverte.
## Gate opérateur
```bash
cat VERSION
test -f history/0.1.4/alpha.3.md
grep -A2 '^## Statut$' history/0.1.4/alpha.3.md | grep -Fx 'PASS'
test -f docs/skeletons/004-TAURI.md
test ! -e docs/templates/011-TAURI.md
test ! -e docs/validation/006-TAURI_VALIDATION.md
test ! -e history/0.1.4/beta.1.md
python3 -B -m unittest discover -s tests -v
python3 -B scripts/audit_text_hygiene.py \
VERSION README.md RULES.md ROADMAP.md CHANGELOG.md \
docs deltas history prompts scripts tests templates .gitignore .settings
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
assert Path('VERSION').read_text(encoding='utf-8').strip() == '0.1.4-beta.1'
history = Path('history/0.1.4/alpha.3.md').read_text(encoding='utf-8')
assert re.search(r'## Statut\s+PASS', history)
expected_deltas = {
'alpha.1.md',
'alpha.2.md',
'alpha.2.fix.1.md',
'alpha.3.md',
'beta.1.md',
}
expected_histories = {
'alpha.1.md',
'alpha.2.md',
'alpha.2.fix.1.md',
'alpha.3.md',
}
assert {p.name for p in Path('deltas/0.1.4').glob('*.md')} == expected_deltas
assert {p.name for p in Path('history/0.1.4').glob('*.md')} == expected_histories
plan = Path('docs/plans/010-V0_1_4_TAURI_REEVALUATION_PLAN.md').read_text(encoding='utf-8')
assert plan.startswith(
'<!-- file: docs/plans/010-V0_1_4_TAURI_REEVALUATION_PLAN.md -->\n'
'<!-- version: 4 -->'
)
for phrase in (
'## Gate `alpha.3` acquise',
"## Réconciliation d'artefacts préparée en `beta.1`",
'template technique Tauri générique DO NOT CREATE',
'006-TAURI_VALIDATION.md DO NOT CREATE',
"dry-run exécutable d'un faux projet NOT REQUIRED",
'audit statique de composition REQUIRED',
):
assert phrase in plan, phrase
study = Path('docs/studies/002-TAURI_SKELETON_DECISION.md').read_text(encoding='utf-8')
assert study.startswith(
'<!-- file: docs/studies/002-TAURI_SKELETON_DECISION.md -->\n'
'<!-- version: 4 -->'
)
for phrase in (
'## Réconciliation finale des artefacts `0.1.4-beta.1`',
'Décision : **DO NOT CREATE**.',
'Décision : **NOT REQUIRED** pour `0.1.4-beta.1`.',
'004-TAURI.md KEEP',
'template Tauri générique DO NOT CREATE',
'validation Tauri séparée DO NOT CREATE',
'artefact supplémentaire sans lacune réelle FORBIDDEN BY DEFAULT',
):
assert phrase in study, phrase
skeleton = Path('docs/skeletons/004-TAURI.md').read_text(encoding='utf-8')
for ref in (
'001-PROJECT_GOVERNANCE_FOUNDATION',
'002-RUST_CARGO_WORKSPACE',
'003-WEB_FRONTEND',
'710 TAURI',
):
assert ref in skeleton, ref
for path in (
'docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md',
'docs/skeletons/002-RUST_CARGO_WORKSPACE.md',
'docs/skeletons/003-WEB_FRONTEND.md',
'docs/rules/710-TAURI.md',
'docs/validation/005-WEB_FRONTEND_VALIDATION.md',
):
assert Path(path).is_file(), path
assert not Path('docs/templates/011-TAURI.md').exists()
assert not Path('docs/validation/006-TAURI_VALIDATION.md').exists()
assert not Path('history/0.1.4/beta.1.md').exists()
index = Path('docs/000-README.md').read_text(encoding='utf-8')
assert index.startswith(
'<!-- file: docs/000-README.md -->\n'
'<!-- version: 44 -->'
)
assert '`004-TAURI.md` suffit' in index
roadmap = Path('ROADMAP.md').read_text(encoding='utf-8')
for phrase in (
'`( ) 0.1.4`',
'`( ) 0.1.5` — adoption réelle de PGR par `sasedev-games`',
'`( ) 0.1.6` — adoption réelle de PGR par `khadhroony-solana-project`',
'`( ) 0.1.7` — audits Python read-only',
):
assert phrase in roadmap, phrase
assert '0.1.8' not in roadmap
print(
'0.1.4 beta.1 artifact audit: clean '
'(004 sufficient, ownership composed, no redundant template/validation contract, no fake dry-run)'
)
PY
git diff --check
git add VERSION \
deltas/0.1.4/beta.1.md \
docs/000-README.md \
docs/plans/010-V0_1_4_TAURI_REEVALUATION_PLAN.md \
docs/studies/002-TAURI_SKELETON_DECISION.md
git diff --cached --check
git status --short
```
## Scope Git attendu
```text
M VERSION
A deltas/0.1.4/beta.1.md
M docs/000-README.md
M docs/plans/010-V0_1_4_TAURI_REEVALUATION_PLAN.md
M docs/studies/002-TAURI_SKELETON_DECISION.md
```
## Suite
Si la gate est `PASS`, produire `history/0.1.4/beta.1.md`, committer/pousser la tranche puis préparer `rc.1` avec freeze Tauri, changelog candidate et revue d'horizon transversale avant génération du prochain start prompt.

203
deltas/0.1.4/rc.1.md Normal file
View File

@@ -0,0 +1,203 @@
<!-- file: deltas/0.1.4/rc.1.md -->
<!-- version: 1 -->
# Delta 0.1.4-rc.1 — freeze Tauri et revue d’horizon
## Objet
Geler le scope Tauri validé par `beta.1`, préparer le changelog candidat et exécuter la revue d’horizon transversale exigée par le plan avant de générer le prochain start prompt.
La RC ne corrige pas encore la sémantique `SHOULD`, le contrat d’autonomie ou la frontière PGR / Knowledge : elle décide explicitement qu’ils forment la prochaine release `0.1.5` et décale les adoptions Games/KSP afin qu’elles utilisent ensuite ce contrat stabilisé.
## Préconditions
- `0.1.4-beta.1` est validée `PASS` et son history est présent ;
- `710-TAURI.md` reste en révision `7` et `004-TAURI.md` en révision `1` ;
- aucun template technique Tauri ni `006-TAURI_VALIDATION.md` n’est requis ;
- les trois questions transversales enregistrées dans le plan doivent être décidées avant création du prompt suivant ;
- les archives delta/history restent relatives directement à la racine du dépôt.
## Modifications
- `VERSION` passe à `0.1.4-rc.1` ;
- `CHANGELOG.md` reçoit l’entrée `0.1.4 (candidate)` sans chronologie de tranches ;
- `ROADMAP.md` enregistre la revue d’horizon : `0.1.5` gouvernance/autonomie, `0.1.6` Games, `0.1.7` KSP, `0.1.8` audits Rust ;
- `docs/studies/004-V0_1_4_HORIZON_REVIEW.md` matérialise la décision et ses limites ;
- `prompts/011-V0_1_5_START_PROMPT.md` prépare la prochaine release à partir d’une future stable `v0.1.4` réellement publiée ;
- le plan et les index sont mis à jour pour refléter le freeze et le handoff ;
- aucun owner normatif transversal n’est encore modifié en RC.
## Gate opérateur
```bash
cat VERSION
test -f history/0.1.4/beta.1.md
grep -A2 '^## Statut$' history/0.1.4/beta.1.md | grep -Fx 'PASS'
test -f docs/studies/004-V0_1_4_HORIZON_REVIEW.md
test -f prompts/011-V0_1_5_START_PROMPT.md
test ! -e history/0.1.4/rc.1.md
grep -Fx '<!-- version: 18 -->' CHANGELOG.md
grep -Fx '<!-- version: 16 -->' ROADMAP.md
grep -Fx '<!-- version: 45 -->' docs/000-README.md
grep -Fx '<!-- version: 5 -->' docs/plans/010-V0_1_4_TAURI_REEVALUATION_PLAN.md
grep -Fx '<!-- version: 5 -->' docs/studies/000-README.md
grep -Fx '<!-- version: 1 -->' docs/studies/004-V0_1_4_HORIZON_REVIEW.md
grep -Fx '<!-- version: 1 -->' prompts/011-V0_1_5_START_PROMPT.md
python3 -B - <<'PYGATE'
from pathlib import Path
import re
assert Path('VERSION').read_text(encoding='utf-8').strip() == '0.1.4-rc.1'
expected_statuses = {
'alpha.1.md': 'PASS',
'alpha.2.md': 'FAIL',
'alpha.2.fix.1.md': 'PASS',
'alpha.3.md': 'PASS',
'beta.1.md': 'PASS',
}
for name, status in expected_statuses.items():
delta = Path('deltas/0.1.4', name)
history = Path('history/0.1.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.1.4').glob('*.md')} - {
p.name for p in Path('history/0.1.4').glob('*.md')
}
assert pending == {'rc.1.md'}, pending
for path, version in (
('docs/rules/710-TAURI.md', 7),
('docs/skeletons/004-TAURI.md', 1),
('docs/studies/002-TAURI_SKELETON_DECISION.md', 4),
('RULES.md', 14),
('docs/rules/230-ADOPTION.md', 1),
('docs/rules/400-VALIDATION.md', 1),
):
lines = Path(path).read_text(encoding='utf-8').splitlines()
assert lines[1] == f'<!-- version: {version} -->', (path, lines[1])
changelog = Path('CHANGELOG.md').read_text(encoding='utf-8')
assert '## 0.1.4 (candidate)' in changelog
section = changelog.split('## 0.1.4 (candidate)', 1)[1].split('## 0.1.3', 1)[0]
for phrase in (
'skeleton Tauri',
'commandes, permissions et capabilities',
'004-TAURI.md',
'audit réutilisable d’hygiène texte',
'0.1.5',
'0.1.8',
):
assert phrase in section, phrase
for forbidden in ('alpha.1', 'alpha.2', 'alpha.3', 'beta.1', 'rc.1', 'rel.1'):
assert forbidden not in section, forbidden
roadmap = Path('ROADMAP.md').read_text(encoding='utf-8')
for phrase in (
'`( ) 0.1.4` — domaine Tauri',
'`( ) 0.1.5` — sémantique normative et autonomie',
'`( ) 0.1.6` — adoption réelle de PGR par `sasedev-games`',
'`( ) 0.1.7` — adoption réelle de PGR par `khadhroony-solana-project`',
'`( ) 0.1.8` — audits Python read-only',
):
assert phrase in roadmap, phrase
assert '`( ) 0.1.9`' not in roadmap
assert "skeleton Tauri jusqu'au réexamen 0.1.4" not in roadmap
study = Path('docs/studies/004-V0_1_4_HORIZON_REVIEW.md').read_text(encoding='utf-8')
for phrase in (
'forte recommandation',
'MUST NOT faire échouer à lui seul une gate',
'baseline locale du projet',
'règles locales = autorité des sessions/releases suivantes',
'PGR MUST rester auto-suffisant',
'une release de gouvernance/autonomie doit précéder les adoptions Games/KSP',
'0.1.8 audits Rust/Clippy read-only',
):
assert phrase in study, phrase
prompt = Path('prompts/011-V0_1_5_START_PROMPT.md').read_text(encoding='utf-8')
for phrase in (
'tag Gitea `v0.1.4`',
'pgr-0.1.4-publish.001-report.md',
'0.1.5-alpha.1',
'004-V0_1_4_HORIZON_REVIEW.md',
'forte recommandation non obligatoire',
'ne doivent ni rechercher automatiquement « la dernière version de PGR »',
'SaseDev Knowledge',
'réservée à `0.1.6`',
'réservée à `0.1.7`',
'réservés à `0.1.8`',
):
assert phrase in prompt, phrase
plan = Path('docs/plans/010-V0_1_4_TAURI_REEVALUATION_PLAN.md').read_text(encoding='utf-8')
for phrase in (
'## Gate `beta.1` acquise',
'## Revue d’horizon préparée en `rc.1`',
'0.1.5 sémantique normative + autonomie + frontière PGR/Knowledge',
'Le prompt `011` transmet explicitement leur réexamen à `0.1.5-alpha.1`.',
):
assert phrase in plan, phrase
assert not Path('docs/templates/011-TAURI.md').exists()
assert not Path('docs/validation/006-TAURI_VALIDATION.md').exists()
assert not Path('history/0.1.4/rc.1.md').exists()
print(
'0.1.4 rc.1 integration audit: clean '
'(beta PASS, Tauri frozen, horizon reordered to governance 0.1.5 before Games/KSP, prompt 011 verified)'
)
PYGATE
python3 -B -m unittest discover -s tests -v
python3 -B scripts/audit_text_hygiene.py \
VERSION README.md RULES.md ROADMAP.md CHANGELOG.md \
docs deltas history prompts scripts tests templates .gitignore .settings
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 CHANGELOG.md ROADMAP.md \
deltas/0.1.4/rc.1.md \
docs/000-README.md \
docs/plans/010-V0_1_4_TAURI_REEVALUATION_PLAN.md \
docs/studies/000-README.md \
docs/studies/004-V0_1_4_HORIZON_REVIEW.md \
prompts/011-V0_1_5_START_PROMPT.md
git diff --cached --check
git status --short
```
## Scope Git attendu
```text
M CHANGELOG.md
M ROADMAP.md
M VERSION
A deltas/0.1.4/rc.1.md
M docs/000-README.md
M docs/plans/010-V0_1_4_TAURI_REEVALUATION_PLAN.md
M docs/studies/000-README.md
A docs/studies/004-V0_1_4_HORIZON_REVIEW.md
A prompts/011-V0_1_5_START_PROMPT.md
```
## Transition
Si la gate est `PASS`, produire `history/0.1.4/rc.1.md`, committer/pousser `0.1.4-rc.1`, puis préparer la promotion mécanique `rel.1` sans rouvrir le scope Tauri ni commencer `0.1.5`.

233
deltas/0.1.4/rel.1.md Normal file
View File

@@ -0,0 +1,233 @@
<!-- file: deltas/0.1.4/rel.1.md -->
<!-- version: 1 -->
# Delta 0.1.4 rel.1 — promotion stable pré-tag
## Baseline et version
Baseline : `0.1.4-rc.1`, avec `history/0.1.4/rc.1.md` appliqué et committé. Ce delta MUST NOT être appliqué avant ce commit.
Version avant application :
```text
0.1.4-rc.1
```
Version après application :
```text
0.1.4
```
`rel.1` identifie la clôture opérationnelle ; il ne fait pas partie de la version SemVer du produit.
## Objet
Promouvoir mécaniquement la RC validée vers la stable `0.1.4` sans rouvrir le scope Tauri et sans commencer `0.1.5`.
La tranche finalise uniquement la présentation et les métadonnées de release : version stable, roadmap terminée, changelog sans marqueur `candidate`, README/index en état stable et plan `010` historique. Aucun owner Tauri, skeleton, étude technique, audit Python ou règle normative réservée à `0.1.5` n'est modifié.
La validation de cette tranche est **pré-tag**. Le tag `v0.1.4`, son archive source Gitea et le rapport `pgr-0.1.4-publish.001-report.md` ne sont pas déclarés existants par ce delta. Ils suivent uniquement un history `rel.1` `PASS`, le commit stable `0.1.4` et la publication réelle du tag.
## Scope
REPLACE :
```text
VERSION
README.md
ROADMAP.md
CHANGELOG.md
docs/000-README.md
docs/plans/010-V0_1_4_TAURI_REEVALUATION_PLAN.md
```
ADD :
```text
deltas/0.1.4/rel.1.md
```
DELETE : aucun.
Le history `rc.1` est livré séparément. Le history `rel.1` sera produit uniquement après la gate opérateur.
## Validation opérateur pré-tag
Après application sur le commit contenant `history/0.1.4/rc.1.md` :
```bash
test "$(cat VERSION)" = '0.1.4'
git cat-file -e HEAD:history/0.1.4/rc.1.md
test -f history/0.1.4/rc.1.md
test -f deltas/0.1.4/rel.1.md
test -f prompts/011-V0_1_5_START_PROMPT.md
test ! -e history/0.1.4/rel.1.md
grep -A2 '^## Statut$' history/0.1.4/rc.1.md | grep -Fx 'PASS'
grep -Fx '<!-- version: 27 -->' README.md
grep -Fx '<!-- version: 17 -->' ROADMAP.md
grep -Fx '<!-- version: 19 -->' CHANGELOG.md
grep -Fx '<!-- version: 46 -->' docs/000-README.md
grep -Fx '<!-- version: 6 -->' docs/plans/010-V0_1_4_TAURI_REEVALUATION_PLAN.md
grep -F -- '- `(x) 0.1.4`' ROADMAP.md
grep -Fx '## 0.1.4' CHANGELOG.md
grep -F 'La stable `0.1.4` réexamine le domaine Tauri' README.md
grep -F 'plan historique de la stable `0.1.4`' docs/000-README.md
python3 -B - <<'PYGATE'
from pathlib import Path
import re
expected = {
'alpha.1.md': 'PASS',
'alpha.2.md': 'FAIL',
'alpha.2.fix.1.md': 'PASS',
'alpha.3.md': 'PASS',
'beta.1.md': 'PASS',
'rc.1.md': 'PASS',
}
for name, status in expected.items():
delta = Path('deltas/0.1.4', name)
history = Path('history/0.1.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 = {path.name for path in Path('deltas/0.1.4').glob('*.md')} - {
path.name for path in Path('history/0.1.4').glob('*.md')
}
assert pending == {'rel.1.md'}, pending
roadmap = Path('ROADMAP.md').read_text(encoding='utf-8')
assert '- `(x) 0.1.4`' in roadmap
for version in ('0.1.5', '0.1.6', '0.1.7', '0.1.8'):
assert f'- `( ) {version}`' in roadmap, version
assert '- `( ) 0.1.9`' not in roadmap
changelog = Path('CHANGELOG.md').read_text(encoding='utf-8')
assert '## 0.1.4' in changelog.splitlines()
assert '## 0.1.4 (candidate)' not in changelog
section = changelog.split('## 0.1.4', 1)[1].split('## 0.1.3', 1)[0]
for phrase in (
'skeleton Tauri',
'commandes, permissions et capabilities',
'004-TAURI.md',
'audit réutilisable d’hygiène texte',
'0.1.5',
'0.1.8',
):
assert phrase in section, phrase
for forbidden in ('alpha.1', 'alpha.2', 'alpha.3', 'beta.1', 'rc.1', 'rel.1'):
assert forbidden not in section, forbidden
readme = Path('README.md').read_text(encoding='utf-8')
for phrase in (
'La stable `0.1.4` réexamine le domaine Tauri',
'skeleton organisationnel `004-TAURI.md`',
'audit réutilisable d’hygiène texte',
'0.1.5',
'0.1.6',
'0.1.7',
):
assert phrase in readme, phrase
index = Path('docs/000-README.md').read_text(encoding='utf-8')
assert 'plan historique de la stable `0.1.4`' in index
assert 'handoff de la stable `0.1.4` vers `0.1.5-alpha.1`' in index
plan = Path('docs/plans/010-V0_1_4_TAURI_REEVALUATION_PLAN.md').read_text(encoding='utf-8')
for phrase in (
'Plan historique de la stable `0.1.4`',
'## Gate `rc.1` acquise et promotion stable',
'history/0.1.4/rel.1.md',
'pgr-0.1.4-publish.001-report.md',
'commit stable `0.1.4`',
):
assert phrase in plan, phrase
prompt = Path('prompts/011-V0_1_5_START_PROMPT.md').read_text(encoding='utf-8')
for phrase in (
'tag Gitea `v0.1.4`',
'pgr-0.1.4-publish.001-report.md',
'0.1.5-alpha.1',
'004-V0_1_4_HORIZON_REVIEW.md',
'forte recommandation non obligatoire',
'SaseDev Knowledge',
'réservée à `0.1.6`',
'réservée à `0.1.7`',
'réservés à `0.1.8`',
):
assert phrase in prompt, phrase
for path, version in (
('docs/rules/710-TAURI.md', 7),
('docs/skeletons/004-TAURI.md', 1),
('docs/studies/002-TAURI_SKELETON_DECISION.md', 4),
('docs/studies/004-V0_1_4_HORIZON_REVIEW.md', 1),
('RULES.md', 14),
('docs/rules/230-ADOPTION.md', 1),
('docs/rules/400-VALIDATION.md', 1),
):
lines = Path(path).read_text(encoding='utf-8').splitlines()
assert lines[1] == f'<!-- version: {version} -->', (path, lines[1])
assert not Path('docs/templates/011-TAURI.md').exists()
assert not Path('docs/validation/006-TAURI_VALIDATION.md').exists()
print(
'0.1.4 rel.1 stable gate audit: clean '
'(6 prior histories including expected alpha.2 FAIL/fix PASS, rel.1 pending, stable Tauri presentation and 0.1.5 handoff coherent)'
)
PYGATE
python3 -B -m unittest discover -s tests -v
python3 -B scripts/audit_text_hygiene.py \
VERSION README.md RULES.md ROADMAP.md CHANGELOG.md \
docs deltas history prompts scripts tests templates .gitignore .settings
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 \
deltas/0.1.4/rel.1.md \
docs/000-README.md \
docs/plans/010-V0_1_4_TAURI_REEVALUATION_PLAN.md
git diff --cached --check
git status --short
```
## Scope Git attendu
```text
M CHANGELOG.md
M README.md
M ROADMAP.md
M VERSION
A deltas/0.1.4/rel.1.md
M docs/000-README.md
M docs/plans/010-V0_1_4_TAURI_REEVALUATION_PLAN.md
```
## Transition après PASS
Si cette gate pré-tag est `PASS` :
1. produire `history/0.1.4/rel.1.md` avec les preuves opérateur réelles ;
2. appliquer ce history ;
3. `git add -A`, `git diff --cached --check`, puis committer **`0.1.4`** sans suffixe `rel.1` ;
4. pousser `master` ;
5. vérifier un workspace propre ;
6. créer et pousser le tag annoté `v0.1.4` ;
7. télécharger l'archive Gitea du tag et produire `pgr-0.1.4-publish.001-report.md` après vérification indépendante ;
8. seulement après `publish.001 PASS`, ouvrir la session `0.1.5` avec `prompts/011-V0_1_5_START_PROMPT.md`.

View File

@@ -1,5 +1,5 @@
<!-- file: docs/000-README.md -->
<!-- version: 17 -->
<!-- version: 46 -->
# Documentation PGR
@@ -20,6 +20,62 @@ D'autres collections telles que `ideas/`, `studies/`, `reference/` ou `formats/`
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.1.4
- [`plans/010-V0_1_4_TAURI_REEVALUATION_PLAN.md`](plans/010-V0_1_4_TAURI_REEVALUATION_PLAN.md) — plan historique de la stable `0.1.4` : réexamen Tauri, skeleton `004`, décision d’artefacts, freeze RC et revue d’horizon.
- [`rules/710-TAURI.md`](rules/710-TAURI.md) — owner Tauri 2 réconcilié en `alpha.2` : host/orchestration, frontière commandes-permissions-capabilities, sélection des capabilities, plugins, version produit et validation proportionnée, sans absorber les choix Web.
- [`skeletons/003-WEB_FRONTEND.md`](skeletons/003-WEB_FRONTEND.md) — specialization Web composable dont l'existence satisfait les prérequis historiques sans rendre Vite, TypeScript, Sass, Bootstrap ou `frontend/` universels à Tauri.
- [`skeletons/004-TAURI.md`](skeletons/004-TAURI.md) — skeleton Tauri 2 matérialisé en `alpha.3`, composant fondation, Rust/Cargo, Web et owner `710` sans template technique universel ni copie des choix Games/KSP.
- [`studies/002-TAURI_SKELETON_DECISION.md`](studies/002-TAURI_SKELETON_DECISION.md) — décision historique `DEFER`, levée du motif Web puis décision `beta.1` : `004-TAURI.md` suffit ; aucun template technique ni contrat de validation Tauri séparé n'est justifié.
- [`studies/004-V0_1_4_HORIZON_REVIEW.md`](studies/004-V0_1_4_HORIZON_REVIEW.md) — revue de fermeture `rc.1` décidant de stabiliser en `0.1.5` la sémantique `SHOULD`, l’autonomie après adoption et la frontière PGR / SaseDev Knowledge avant Games/KSP.
- [`../prompts/011-V0_1_5_START_PROMPT.md`](../prompts/011-V0_1_5_START_PROMPT.md) — handoff de la stable `0.1.4` vers `0.1.5-alpha.1`, à exécuter uniquement après publication et vérification post-tag de `v0.1.4`.
- [`../prompts/010-V0_1_4_START_PROMPT.md`](../prompts/010-V0_1_4_START_PROMPT.md) — contrat de reprise exécuté pour ouvrir `0.1.4-alpha.1` après publication vérifiée de `v0.1.3`.
## Points d'entrée de 0.1.3
- [`plans/009-V0_1_3_ANDROID_REEVALUATION_PLAN.md`](plans/009-V0_1_3_ANDROID_REEVALUATION_PLAN.md) — plan historique de la stable `0.1.3`, de l'audit Games à la stabilisation du profil Android générique et au handoff Tauri `0.1.4`.
- [`rules/610-ANDROID.md`](rules/610-ANDROID.md) — owner Android révisé : contrats SDK/identité/signing, natif/ABI, Lint, niveaux de tests, packaging/distribution et 16 KB conditionnel, sans absorber les choix propres à Games.
- [`rules/520-JAVA.md`](rules/520-JAVA.md) et [`rules/522-GRADLE.md`](rules/522-GRADLE.md) — owners composés uniquement lorsqu'un projet Android contient réellement du Java ou utilise Gradle.
- [`rules/600-PLATFORMS.md`](rules/600-PLATFORMS.md) et [`rules/400-VALIDATION.md`](rules/400-VALIDATION.md) — contrats généraux de plateforme et de preuve auxquels la spécialisation Android doit rester conforme.
- [`studies/003-V0_1_0_HORIZON_REVIEW.md`](studies/003-V0_1_0_HORIZON_REVIEW.md) — revue ayant engagé Android `0.1.3`, Tauri `0.1.4` puis l'adoption Games `0.1.5` comme scopes distincts.
- [`../prompts/009-V0_1_3_START_PROMPT.md`](../prompts/009-V0_1_3_START_PROMPT.md) — contrat de reprise exécuté pour ouvrir `0.1.3-alpha.1` après publication vérifiée de `v0.1.2`.
- [`../prompts/010-V0_1_4_START_PROMPT.md`](../prompts/010-V0_1_4_START_PROMPT.md) — prompt préparé par la RC pour le réexamen Tauri `0.1.4`, à exécuter uniquement après publication et vérification post-tag de `v0.1.3`.
## Points d'entrée de 0.1.2
- [`plans/008-V0_1_2_JAVA_GRADLE_REEVALUATION_PLAN.md`](plans/008-V0_1_2_JAVA_GRADLE_REEVALUATION_PLAN.md) — plan historique de la stable `0.1.2`, de la réévaluation Games à la scission `520/521/522`, avec frontière Android explicite.
- [`rules/520-JAVA.md`](rules/520-JAVA.md) — owner Java issu de la réévaluation du profil historique combiné ; il possède JDK, compatibilité source/bytecode, structure, API et tests Java.
- [`rules/521-MAVEN.md`](rules/521-MAVEN.md) — spécialisation Maven séparée afin que Maven ne devienne pas implicitement applicable à tout projet Java.
- [`rules/522-GRADLE.md`](rules/522-GRADLE.md) — spécialisation Gradle éprouvée contre Games, avec ownership du build, politique Wrapper/système et propriétés partagées/locales.
- [`rules/610-ANDROID.md`](rules/610-ANDROID.md) — owner de contrôle de frontière ; AGP, SDK/NDK, ABI/JNI, manifests, packaging/signing et smokes Android restent hors du scope `0.1.2`.
- [`studies/003-V0_1_0_HORIZON_REVIEW.md`](studies/003-V0_1_0_HORIZON_REVIEW.md) — revue ayant engagé `0.1.2` puis la réévaluation Android `0.1.3` comme releases distinctes.
- [`../prompts/008-V0_1_2_START_PROMPT.md`](../prompts/008-V0_1_2_START_PROMPT.md) — contrat de reprise autoritaire exécuté pour ouvrir `0.1.2-alpha.1` après publication vérifiée de `v0.1.1`.
- [`../prompts/009-V0_1_3_START_PROMPT.md`](../prompts/009-V0_1_3_START_PROMPT.md) — prompt préparé par la RC pour la réévaluation Android `0.1.3`, à exécuter uniquement après publication et vérification post-tag de `v0.1.2`.
## Points d'entrée de 0.1.1
- [`plans/007-V0_1_1_WEB_FRONTEND_FOUNDATION_PLAN.md`](plans/007-V0_1_1_WEB_FRONTEND_FOUNDATION_PLAN.md) — plan historique de la stable `0.1.1`, de l'audit des corpus à la fondation Web composable et à la préparation du futur réexamen Tauri.
- [`rules/530-TYPESCRIPT.md`](rules/530-TYPESCRIPT.md), [`rules/540-JAVASCRIPT_PACKAGE_ECOSYSTEM.md`](rules/540-JAVASCRIPT_PACKAGE_ECOSYSTEM.md), [`rules/550-VITE.md`](rules/550-VITE.md) et [`rules/560-CSS_SASS.md`](rules/560-CSS_SASS.md) — owners frontend matérialisés par `0.1.1-alpha.2`, séparant langage typé, écosystème de package, build tool et styles.
- [`templates/008-WEB_TYPESCRIPT_PACKAGE.md`](templates/008-WEB_TYPESCRIPT_PACKAGE.md) — adaptation de la baseline minimale `package.json` + `tsconfig.json` de `alpha.3`, sans package manager, versions ou bundler imposés.
- [`templates/009-WEB_VITE.md`](templates/009-WEB_VITE.md) — guide d'adaptation Vite de `alpha.4` : root, dev server, cache, outputs, assets et scripts sans imposer de layout ni de port universels.
- [`templates/010-WEB_CSS_SASS.md`](templates/010-WEB_CSS_SASS.md) — guide CSS/Sass de `alpha.5` : sources, modules Sass, packages de styles et artefacts générés sans imposer de framework CSS.
- [`validation/005-WEB_FRONTEND_VALIDATION.md`](validation/005-WEB_FRONTEND_VALIDATION.md) — validation frontend réutilisable et indépendante du host : restore, type-check, build/styles et smoke proportionné.
- [`skeletons/003-WEB_FRONTEND.md`](skeletons/003-WEB_FRONTEND.md) — specialization Web composable fondée sur les owners `530/540/550/560`, sans imposer Vite, Sass, npm, Bootstrap ou un layout unique.
- [`studies/002-TAURI_SKELETON_DECISION.md`](studies/002-TAURI_SKELETON_DECISION.md) — décision `DEFER` conservée ; `beta.1` vérifie que ses cinq prérequis Web sont désormais couverts et prépare leur réexamen objectif en `0.1.4` sans créer le skeleton Tauri.
- [`studies/003-V0_1_0_HORIZON_REVIEW.md`](studies/003-V0_1_0_HORIZON_REVIEW.md) — revue ayant engagé `0.1.1` à `0.1.7` et maintenu WASM, serveur Rust et deployment sans réservation prématurée.
- [`../prompts/007-V0_1_1_START_PROMPT.md`](../prompts/007-V0_1_1_START_PROMPT.md) — contrat de reprise autoritaire de la release `0.1.1`.
- [`../prompts/008-V0_1_2_START_PROMPT.md`](../prompts/008-V0_1_2_START_PROMPT.md) — prompt de reprise préparé pour réévaluer Java/Maven/Gradle en `0.1.2`, à utiliser seulement après publication et vérification post-tag de `0.1.1`, avec frontière Android explicite.
## Points d'entrée de 0.1.0
- [`plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md`](plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md) — plan historique de la stable `0.1.0`, depuis l’audit de `v0.0.5` jusqu’à la baseline réutilisable, la clôture/publication et la revue d’horizon.
- [`templates/006-OPERATOR_COMMAND_HANDOFF.md`](templates/006-OPERATOR_COMMAND_HANDOFF.md) — pattern de remise automatique des commandes entre history, commit/push, delta suivant, tag et vérification post-tag.
- [`rules/230-ADOPTION.md`](rules/230-ADOPTION.md) — contrat d’adoption proportionnée de PGR par un projet existant sans réécriture rétroactive de son historique.
- [`templates/007-EXISTING_PROJECT_ADOPTION.md`](templates/007-EXISTING_PROJECT_ADOPTION.md) — pattern court de baseline, mapping `ADOPT / KEEP-LOCAL / OVERRIDE / DEFER`, découpage et validation d’une migration existante.
- [`validation/004-RUST_CARGO_BASELINE_DRY_RUN.md`](validation/004-RUST_CARGO_BASELINE_DRY_RUN.md) — contrat de dry-run temporaire pour vérifier la composition d’un nouveau workspace Rust/Cargo et l’adoption non destructive d’un workspace existant.
- [`studies/003-V0_1_0_HORIZON_REVIEW.md`](studies/003-V0_1_0_HORIZON_REVIEW.md) — revue d’horizon de `beta.1` engageant `0.1.1` à `0.1.7` par domaines cohérents et laissant WASM, serveur Rust et deployment sans réservation prématurée.
- [`../prompts/007-V0_1_1_START_PROMPT.md`](../prompts/007-V0_1_1_START_PROMPT.md) — prompt de reprise préparé pour la fondation frontend Web `0.1.1`, à utiliser seulement après publication et vérification post-tag de `0.1.0`.
## 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` ;

View File

@@ -1,5 +1,5 @@
<!-- file: docs/architecture/002-GOVERNANCE_ARCHITECTURE.md -->
<!-- version: 3 -->
<!-- version: 4 -->
# Architecture de gouvernance PGR
@@ -55,6 +55,26 @@ PGR rules + templates + skeleton specifications
Une évolution ultérieure de PGR ne modifie jamais automatiquement les projets déjà créés.
## Adoption d’un projet existant
Un dépôt déjà existant ne repasse pas artificiellement par le flux d’instanciation. Son adoption part de sa baseline réelle et compare les owners PGR applicables avec les contrats locaux avant toute migration. Le mapping utilise la classification `ADOPT / KEEP-LOCAL / OVERRIDE / DEFER`.
Le flux conceptuel est :
```text
baseline autoritaire du projet
↓
inventaire + owners PGR applicables
↓
ADOPT / KEEP-LOCAL / OVERRIDE / DEFER
↓
migration progressive + validation
↓
projet autonome avec historique préservé
```
Le contrat normatif appartient à [`../rules/230-ADOPTION.md`](../rules/230-ADOPTION.md). Un skeleton MAY servir de référence de comparaison, mais l’adoption ne prétend pas que le projet existant a été créé depuis ce skeleton et ne réécrit pas rétroactivement ses snapshots historiques.
## Hiérarchie
Les règles générales sont raffinées par les scopes plus spécifiques. Un choix spécialisé, par exemple une contrainte Tauri Android, ne devient pas automatiquement une règle Android ou Java générale.

View File

@@ -1,5 +1,5 @@
<!-- file: docs/architecture/003-RULE_PROFILE_MODEL.md -->
<!-- version: 5 -->
<!-- version: 8 -->
# Modèle de profils de règles PGR
@@ -204,6 +204,53 @@ Aucune contradiction non résolue de même niveau n'a été identifiée entre le
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.
## Scission Java / Maven / Gradle en `0.1.2`
La réévaluation pratique de `0.1.2` confirme que le profil historique combiné `520 — Java / Maven / Gradle` ne constitue plus le meilleur owner courant. Maven et Gradle sont deux build tools interchangeables possédant chacun des règles propres significatives ; les rendre tous deux applicables par l'intermédiaire d'un unique profil Java crée une ambiguïté de sélection contraire au contrat de [`../rules/500-LANGUAGES.md`](../rules/500-LANGUAGES.md).
Le découpage courant devient :
```text
520 — Java
521 — Maven
522 — Gradle
```
Les spécialisations de build restent dans la famille `500` et se composent explicitement avec le langage réellement utilisé. Par exemple :
```text
GENERAL + 500 + 520 + 521
Java + Maven
GENERAL + 500 + 520 + 522
Java + Gradle
GENERAL + 500 + 520 + 522 + 600 + 610
Java + Gradle + Android
```
Un projet Gradle sans Java n'applique pas `520` uniquement parce qu'il utilise `522`. De même, Maven et Gradle ne sont jamais rendus applicables l'un par l'autre. Les contraintes Android restent possédées par `610` et raffinent `522`, ainsi que `520` uniquement lorsque Java est réellement présent.
Cette scission remplace l'owner courant combiné sans réécrire les documents historiques qui décrivent fidèlement l'état `0.0.2` à `0.1.1`. L'ancien chemin `520-JAVA_MAVEN_GRADLE.md` reste un bridge `SUPERSEDED` non normatif afin de préserver leurs liens.
## Réconciliation beta de Java / Maven / Gradle en `0.1.2`
La réconciliation `beta.1` confirme la scission introduite en `alpha.3` sans ajouter de quatrième owner ou d'artefact technique générique. Les owners courants restent :
```text
520 — Java
521 — Maven
522 — Gradle
```
Le corpus Games apporte une preuve pratique pour Java et Gradle, mais aucune preuve Maven réelle. Cette asymétrie ne remet pas en cause `521-MAVEN.md` : elle interdit seulement de présenter Games comme validation d'une convention Maven nouvelle ou de créer un artefact Maven à partir d'un corpus qui n'en possède pas.
La revue confirme également que les décisions locales Games ne deviennent pas des minima généraux : ni JDK 25, ni cible Java 17, ni Gradle 9.6.0+, ni Groovy DSL, ni absence de Wrapper ne sont imposés par les profils courants. Seuls les principes réutilisables démontrés sont conservés : séparation JDK/source/bytecode, ownership du build, contrainte système effectivement vérifiée et Wrapper conditionnel.
Aucun nouveau contrat sous `docs/validation/`, template, skeleton ou audit Python Java/Maven/Gradle n'est justifié. Les toolchains officielles restent propriétaires des preuves exécutables lorsque des artefacts Java/Maven/Gradle réels existent.
Enfin, Android reste un raffinement de plateforme : `610-ANDROID.md` possède AGP, SDK/NDK, ABI/JNI, manifests/resources, packaging/signing et smokes. La réconciliation `0.1.2` ne constitue pas le démarrage de `0.1.3`.
## 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.
@@ -214,6 +261,38 @@ La famille `800 — architecture` reste réservée : aucune règle nouvelle n'en
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é.
## Owners frontend matérialisés en `0.1.1`
L'audit Games/KSP et la revue opérateur de `0.1.1-alpha.1` justifient quatre owners distincts dans la famille `500` :
```text
530 — TypeScript
540 — JavaScript package ecosystem
550 — Vite
560 — CSS / Sass
```
Cette séparation évite un profil monolithique « Web moderne » : TypeScript, Vite et Sass sont des recommandations fortes pour les nouveaux frontends contrôlés lorsqu'ils apportent une valeur proportionnée, mais chacun reste sélectionnable indépendamment. Le package manager est également indépendant et PGR n'impose pas npm.
Une composition complète peut par exemple être :
```text
GENERAL
+ 500
+ 530 TypeScript
+ 540 JavaScript package ecosystem
+ 550 Vite
+ 560 CSS / Sass
```
Un frontend minimal peut n'en sélectionner qu'une partie. Un host Tauri qui utilise cette stack ajoute ensuite `700 + 710` sans transférer à Tauri l'ownership des règles frontend :
```text
GENERAL + 500 + 510 + 530 + 540 + 550 + 560 + 700 + 710
```
WASM et serveur Web Rust restent des responsabilités séparées et ne sont pas activés par cette composition.
## 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.

View File

@@ -0,0 +1,310 @@
<!-- file: docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md -->
<!-- version: 10 -->
# Plan 0.1.0 — première baseline PGR réutilisable
## Statut et sources
Plan actif créé pendant `0.1.0-alpha.1` conformément à `prompts/006-V0_1_0_START_PROMPT.md` après audit indépendant de la stable taggée `v0.0.5` et de son rapport post-tag.
Sources autoritaires de reprise :
```text
pgr-v0.0.5.zip 1fb72bafb24b5a0f3406561b96caa8245142a5f099e692842d9ef1ba44f41b49
pgr-0.0.5-publish.001-report.md a6727fd1f3122dbb19eb79d6b904ebaed2bbfc360ed4a34cc1299cb2166efd96
```
Le rapport `publish.001` est `PASS` et porte sur cette même archive. L'absence de `.git` dans l'archive du tag est normale et n'est pas une validation manquante.
Deux corpus récents ont également été fournis pour préparer l'adoption future sans devenir des dépendances de la baseline `0.1.0` :
```text
games-v0.3.6.zip ad6e44a1332eb7d6069cf1189d9433f0fbb8fac19c5aac9f4641ac45c1c556e8
khadhroony-solana-project-v0.3.16.zip db3cc1b3fc3fb07ee864b02e2a7346c673d4cf63b33e8e872aca6c6458856ca0
```
Games `0.3.6` conserve explicitement `0.3.7` comme future release d'alignement PGR. KSP `0.3.16` reste principalement un corpus Rust/Cargo avec six applications Tauri ; aucune migration de Games ou KSP n'appartient à `0.1.0`.
## Audit de la stable `v0.0.5`
### Intégrité et chaîne historique
L'archive stable contient `225` entrées sous une racine unique `pgr/`, soit `194` fichiers et `31` répertoires. Son CRC est propre, aucun lien symbolique n'est présent et `.git` est absent comme attendu pour une archive de tag Gitea.
Les `62` couples delta/history des releases `0.0.1` à `0.0.5` sont complets :
```text
0.0.1 12 / 12
0.0.2 12 / 12
0.0.3 10 / 10
0.0.4 9 / 9
0.0.5 19 / 19
```
La vérité opérateur de `0.0.5` est conservée, notamment les `FAIL` intermédiaires et la fermeture finale `rel.001.fix.1` en `PASS`. Aucun ancien delta/history ne sera renommé rétroactivement lorsque la nouvelle convention `rel.N` sera introduite.
### Tests et audits
La stable passe :
```text
python3 -B -m unittest discover -s tests -v
48 tests PASS
Markdown header audit: clean (171 file(s))
Markdown table audit: clean (8 table(s), 171 file(s))
Markdown link audit: clean (161 local link(s), 171 file(s))
```
Les audits PGR restent monotâches et read-only : trois audits Markdown, six audits de style Rust, un audit Rust de façade/export completeness, plus leur helper commun. Aucun audit ne devient un wrapper de build.
### Règles, profils, templates et skeletons
La hiérarchie normative est cohérente et possède un owner explicite pour gouvernance, workflow, skeletons, documentation, validation, langages/écosystèmes, plateformes et frameworks.
Profils techniques déjà matérialisés :
```text
510 Rust / Cargo
520 Java / Maven / Gradle
610 Android
710 Tauri 2
```
La baseline possède cinq templates techniques Rust/Cargo sous `templates/rust-cargo/`, deux skeleton specifications concrètes — fondation de gouvernance et workspace Rust/Cargo — et les contrats de validation associés.
Le profil Rust/Cargo est suffisamment avancé pour servir rapidement de référence à Games et KSP. Les profils Java/Gradle et Android existent déjà normativement ; leur future release `0.1.x` devra donc d'abord réévaluer leur complétude pratique, leurs templates, skeletons et audits nécessaires au cas Games au lieu de recréer les profils depuis zéro.
Le profil Tauri `710` existe également, mais le skeleton Tauri contrôlé reste volontairement `DEFER` : il attend des owners Web suffisants pour TypeScript, Vite, Sass/CSS, sorties frontend et validation frontend indépendante.
## Défauts de gouvernance à corriger en 0.1.0
L'audit ne révèle pas de défaut bloquant de la stable, mais deux conventions doivent être corrigées avant de diffuser PGR plus largement.
### Clôture stable `rel.N`
L'expérience réelle de `0.0.5` montre que la convention actuelle `rel.001` mélange inutilement padding historique et identité de tranche. La convention future doit utiliser :
```text
rel.1
rel.1.fix.1
rel.2
...
```
Les anciens fichiers `rel.001*` restent immuables.
Le nom de tranche et le message du commit qui matérialise finalement la stable doivent être distingués. Par défaut PGR :
```text
rel.1 FAIL -> commit de tranche X.Y.Z-rel.1
rel.1.fix.1 FAIL -> commit de tranche X.Y.Z-rel.1.fix.1
première tranche qui obtient le PASS stable
-> commit final X.Y.Z
```
Le tag `vX.Y.Z` n'est créé qu'après ce commit final stable.
### Commandes opérateur et publication
Après production d'un history constaté, le générateur doit remettre spontanément les commandes exactes à exécuter entre l'application de ce history et le delta suivant. Le défaut PGR retenu est :
```bash
git add -A
git diff --cached --check
git status --short
git commit -m "<message attendu>"
git push origin <branche>
```
Le bloc doit être adapté au projet et au statut réel de la tranche ; il ne doit pas inventer une branche ou un remote lorsqu'ils ne sont pas établis.
Pour la dernière clôture pré-tag, le handoff opérateur doit en plus fournir le bloc de tag/vérification approprié et indiquer explicitement les preuves/artefacts à remettre pour générer la vérification post-tag, notamment l'archive issue du tag et les preuves Git réellement disponibles. Un tag annoté doit être vérifié sans confondre l'objet tag avec son commit déréférencé.
Après `publish.* PASS`, la consigne manuelle de nouvelle session reste produite automatiquement selon `docs/templates/003-NEW_SESSION_PROMPT.md`.
## Mission de `0.1.0`
`0.1.0` doit transformer la fondation `0.0.x` en baseline réellement réutilisable **sans absorber les domaines technologiques futurs**.
La release doit :
1. corriger la sémantique de clôture `rel.N` et des commits stables ;
2. rendre obligatoire le handoff automatique des commandes opérateur après chaque history et lors de la publication ;
3. formaliser une adoption proportionnée de PGR par un projet existant, distincte de l'instanciation d'un nouveau projet ;
4. vérifier que la fondation et le skeleton Rust/Cargo peuvent servir de baseline réutilisable sans dépendre de choix KSP/Games ;
5. effectuer avant RC une revue d'horizon qui engage uniquement les prochaines releases `0.1.x` suffisamment décidées.
`0.1.0` ne crée pas de profil Web, WASM, serveur Rust/Actix, Java, Android ou Tauri supplémentaire. Ces domaines seront traités séparément dans la série `0.1.x` lorsque leur release dédiée sera engagée.
## Direction acquise pour la série `0.1.x`
La série `0.1.x` doit rester composée de releases concrètes indépendantes, en pratique une release/session par domaine cohérent. Il est explicitement exclu de regrouper Web, serveur Rust, Java/Android, Tauri et WASM dans `0.1.0` ou dans une unique grosse release suivante.
La revue d'horizon de `0.1.0` devra ordonner et, seulement lorsque le scope est suffisamment décidé, numéroter les axes suivants :
- owners Web contrôlés : TypeScript, Vite, Sass/CSS, package manager/build outputs et validation frontend ;
- serveur Web Rust — Actix Web ou autre framework seulement à partir d'un besoin et d'un corpus réels, notamment pour les trajectoires HTTP/3 ;
- réévaluation pratique du profil Java/Gradle existant pour Games ;
- réévaluation pratique du profil Android existant pour Games ;
- WASM comme domaine séparé si l'adoption Games démontre qu'un owner PGR apporte une valeur immédiate ;
- levée du `DEFER` Tauri seulement après matérialisation des owners Web nécessaires ;
- adoption de PGR par Games dès que le sous-ensemble requis est réellement prêt ;
- adoption de PGR par KSP ensuite, avec une pression principalement Rust/Cargo + Tauri et sans attendre les profils non pertinents pour KSP.
Les numéros exacts `0.1.1`, `0.1.2`, etc. ne sont pas réservés dans `alpha.1`. Cette attribution appartient à la revue d'horizon lorsque l'ordre réel est suffisamment décidé.
Après cette vague d'adoption `0.1.x`, les axes plus larges — projets documentaires/spécifications tels que `saselang-bible`, généricité hors logiciel et autres familles technologiques — restent candidats pour une trajectoire `0.2.x`/`0.3.x` à décider ultérieurement, sans réservation artificielle aujourd'hui.
Deux horizons supplémentaires sont acquis comme **candidats différés**, sans numéro réservé :
- après application réelle de PGR à Games puis KSP, une release `0.1.x` non prioritaire pourra introduire des audits Python read-only reproduisant uniquement le sous-ensemble des conventions Rust/Clippy vérifiable statiquement sans Cargo ni `rustc`; ces audits devront utiliser les options PGR existantes, documenter explicitement les lints `FULL / LIMITED / UNSUPPORTED` et MUST NOT être présentés comme équivalents à `cargo clippy`, qui reste la validation autoritaire ;
- à plus long terme, une série dédiée au déploiement et à l'exploitation devra être étudiée, potentiellement dans un horizon `0.4.x` ou `0.5.x` mais sans réservation actuelle : reverse proxies tels que Nginx/Apache, bases PostgreSQL/MySQL ou autres, conteneurs Docker/Compose, hébergement Linux/services, environnements et secrets, migrations/backup, health/observabilité et skeletons/audits de déploiement composables.
Ces horizons ne modifient pas la mission de `0.1.0` et ne doivent pas être absorbés par les tranches courantes.
## Trajectoire prévisionnelle de `0.1.0`
### alpha.1 — audit de stable et plan
Statut opérateur : **PASS**.
La stable `v0.0.5`, son rapport post-tag, les owners normatifs, profils, templates, skeletons, audits, chaîne delta/history et décisions différées ont été vérifiés. Le cadrage a été consigné sans changement normatif ni migration externe.
### alpha.2 — clôture stable et identité `rel.N`
Statut opérateur : **FAIL**.
Le contenu normatif prévu a été matérialisé et le contrôle structurel spécifique a confirmé `rel.N` sans padding, la conservation des historiques `rel.001*` et l'identité explicite du commit stable. La gate livrée contenait toutefois des commandes `grep -F` entourées de quotes simples alors que certains motifs contenaient eux-mêmes des apostrophes (`n'utilise`, `l'exploitation`). Le shell a donc mal interprété plusieurs contrôles textuels.
Le défaut appartient à la gate opérateur, pas aux owners `200-GOVERNANCE` / `210-WORKFLOW`. Le delta `alpha.2.md` reste immuable.
### alpha.2.fix.1 — correction de la gate `rel.N`
Statut opérateur : **PASS**.
Le fix a conservé `200-GOVERNANCE.md`, `210-WORKFLOW.md` et le delta historique `alpha.2.md` inchangés. La preuve Python corrigée a reconfirmé la convention `rel.N`, le `FAIL` historique de `alpha.2`, les anciens artefacts `rel.001*` et l'indépendance de `publish.001`.
La validation a exécuté `48/48` tests et les trois audits Markdown sans diagnostic. Aucun nouveau fix ni REPLAN n'est requis.
### alpha.3 — handoff automatique des commandes opérateur
Statut opérateur : **FAIL**.
Le contenu prévu a été matérialisé : `210-WORKFLOW.md` possède le contrat normatif de remise automatique et `006-OPERATOR_COMMAND_HANDOFF.md` fournit la forme de rendu pour tranche ordinaire, échec + fix, clôture stable, tag et preuves `publish.*`. Les `48` tests et les trois audits Markdown sont restés propres.
La gate spécifique n'a toutefois pas pu s'exécuter jusqu'au bout : le littéral Python `'## Fermeture d'une tranche non stable'` utilisait des quotes simples autour d'un texte contenant l'apostrophe de `d'une`, provoquant `SyntaxError: unterminated string literal`. Le défaut appartient à la gate ; aucun défaut normatif du workflow ou du template n'est établi.
### alpha.3.fix.1 — correction de la gate du handoff opérateur
Statut opérateur : **PASS**.
Le fix a conservé `210-WORKFLOW.md`, `006-OPERATOR_COMMAND_HANDOFF.md`, l'index documentaire et le delta historique `alpha.3.md` inchangés. La gate corrigée a reconfirmé le `FAIL` historique de `alpha.3`, le contenu normatif du handoff et le pattern opérateur.
La validation a exécuté `48/48` tests et les trois audits Markdown sans diagnostic. Aucun nouveau fix ni REPLAN n'est requis.
### alpha.4 — adoption d'un projet existant
Statut opérateur : **PASS**.
Le nouvel owner `230-ADOPTION.md` et le pattern `007-EXISTING_PROJECT_ADOPTION.md` ont été validés avec le mapping `ADOPT / KEEP-LOCAL / OVERRIDE / DEFER`, la migration progressive et la préservation de l’historique. Les `48` tests et les trois audits Markdown sont propres.
Games et KSP restent des futurs consommateurs : aucune migration externe ni activation de profils non applicables n’a été introduite.
### alpha.5 — baseline réutilisable et dry-run de composition
Statut opérateur : **PASS**.
La fondation `001`, le skeleton Rust/Cargo `002`, les templates Rust/Cargo et la validation minimale ont été réconciliés. Les deux chemins du contrat `004-RUST_CARGO_BASELINE_DRY_RUN.md` ont été exécutés avec Cargo :
```text
NEW PASS — metadata/fmt/check/clippy sur instanciation temporaire
ADOPTION PASS — workspace synthétique valide et choix KEEP-LOCAL / DEFER préservés
```
Les `48/48` tests PGR et les trois audits Markdown sont restés propres. Games et KSP n'ont pas été utilisés comme fixtures et aucun profil technologique supplémentaire n'a été absorbé par la tranche.
### beta.1 — réconciliation finale et revue d'horizon
Statut opérateur : **PASS**.
La gate opérateur a confirmé la revue d'horizon, la roadmap `0.1.1` à `0.1.7`, le maintien des domaines différés sans numéro, le prompt `007` et les `48/48` tests PGR avec les trois audits Markdown propres.
La revue d'horizon est matérialisée dans `003-V0_1_0_HORIZON_REVIEW.md`. Elle engage une séquence par domaines cohérents :
```text
0.1.1 Web frontend
0.1.2 Java / Gradle
0.1.3 Android
0.1.4 Tauri contrôlé, sous condition de readiness Web
0.1.5 adoption Games
0.1.6 adoption KSP
0.1.7 audits Rust/Clippy statiques Python-only
```
WASM, serveur Rust et deployment restent non numérotés. Le prompt `007-V0_1_1_START_PROMPT.md` est préparé pour la cible suivante mais ne devient exécutable qu'après publication de `v0.1.0` et vérification post-tag `PASS`.
### rc.1 — release candidate
Statut opérateur : **PASS**.
La gate opérateur a confirmé le scope gelé, les huit histories antérieurs avec leurs statuts réels, les deux dry-runs Rust/Cargo via la toolchain réelle, le contrat d’adoption, la convention `rel.N`, le handoff opérateur, la roadmap et le prompt `007`. Les `48/48` tests et les trois audits Markdown sont propres. Aucun owner ni domaine technique nouveau n’est entré dans la RC.
### rel.1 — promotion stable
Première utilisation de la convention corrigée `rel.1`. La promotion est strictement mécanique : `VERSION = 0.1.0`, `ROADMAP.md` marque `0.1.0` terminée, le `CHANGELOG` perd son marqueur `candidate`, README/index décrivent la baseline comme stable et le présent plan devient historique. Aucun owner, profil, template, skeleton ou script technique n’est modifié.
Le résultat opérateur de cette tranche appartient à `history/0.1.0/rel.1.md`, créé seulement après exécution de la gate. Si `rel.1` échoue, son history est conservé et un `rel.1.fix.N` corrige uniquement la fermeture ; la première tranche qui établit réellement la stable est incluse dans le commit `0.1.0` avant le tag `v0.1.0`. La vérification post-tag reste séparée et doit produire `pgr-0.1.0-publish.001-report.md` uniquement à partir de l’archive et des preuves réellement publiées.
## Stratégie de validation
Chaque tranche documentaire rejoue au minimum :
```text
python3 -B -m unittest discover -s tests -v
python3 -B scripts/audit_markdown_headers.py ...
python3 -B scripts/audit_markdown_tables.py ...
python3 -B scripts/audit_markdown_links.py ...
```
Les scripts d'audit restent read-only et ne déclenchent aucun build. Les changements de workflow doivent recevoir des contrôles structurels ciblés qui vérifient la nomenclature future sans imposer de renommer les snapshots historiques.
Le dry-run de composition `alpha.5` doit privilégier les parsers/outils officiels lorsque disponibles. Une prévalidation générateur ne remplace pas le gate opérateur.
## Déclencheurs de REPLAN
REPLAN est requis si :
- `0.1.0` commence à absorber Web, Android, WASM, Actix ou le skeleton Tauri au lieu de les laisser à des releases `0.1.x` distinctes ;
- la convention de commit stable ne peut pas être définie sans ambiguïté avec les histories `FAIL`/fix ;
- le handoff automatique dépend de valeurs Git qui ne peuvent pas être établies de manière sûre ;
- l'adoption d'un projet existant exige de modifier rétroactivement son historique ;
- le dry-run révèle que la fondation ou le skeleton Rust/Cargo n'est pas réellement autonome ;
- la revue d'horizon transforme des candidats en numéros réservés sans scope suffisamment décidé.
## Clôture et transition
- documentation durable du workflow : `alpha.2` à `alpha.4` ;
- preuve de réutilisabilité : `alpha.5` ;
- réconciliation documentaire et revue d'horizon : `beta.1` ;
- `CHANGELOG` candidate et release gate : `rc.1` ;
- promotion stable et nouveau contrat `rel.1` : `rel.1` ;
- tag/post-tag : après le commit stable `0.1.0`, avec handoff opérateur automatique ;
- prompt suivant : créé uniquement si `beta.1` a réellement engagé la prochaine cible `0.1.x`.
## Revue d'horizon
État : **validée `PASS` par la gate opérateur de `beta.1`**.
Décision proposée par la revue :
- engager `0.1.1` Web frontend ;
- engager séparément `0.1.2` Java/Gradle et `0.1.3` Android ;
- engager `0.1.4` comme release de domaine Tauri, avec obligation de reconfirmer la readiness Web avant toute matérialisation de skeleton ;
- engager `0.1.5` pour l'adoption Games puis `0.1.6` pour l'adoption KSP ;
- engager `0.1.7` pour les audits Rust/Clippy statiques Python-only après retour réel des deux adoptions ;
- conserver WASM et serveur Rust comme candidats sans numéro ;
- conserver `saselang-bible` et la généricité hors logiciel pour une trajectoire ultérieure ;
- conserver deployment/operations comme horizon majeur ultérieur sans réserver aujourd'hui `0.4.x` ou `0.5.x`.
La revue complète et ses critères de réouverture sont possédés par `../studies/003-V0_1_0_HORIZON_REVIEW.md`.

View File

@@ -0,0 +1,506 @@
<!-- file: docs/plans/007-V0_1_1_WEB_FRONTEND_FOUNDATION_PLAN.md -->
<!-- version: 11 -->
# Plan 0.1.1 — fondation frontend Web contrôlée
## Statut et sources
Plan actif créé pendant `0.1.1-alpha.1` conformément à `prompts/007-V0_1_1_START_PROMPT.md`, après audit indépendant de la stable taggée `v0.1.0`, de son rapport post-tag et du corpus Games réellement fourni.
Sources autoritaires de reprise PGR :
```text
pgr-v0.1.0.zip bc8f3a8117d04afc1280344eceaaac8c6a4724ca94c285a6234fe42c1023b2be
pgr-0.1.0-publish.001-report.md a64dc4a5a81e1776b641894d8493eec3ef315932fffb2881e52ff4147eb8b6a5
```
Le rapport `publish.001` est `PASS`, porte sur cette même archive et confirme le commit stable `2ed8742f3b26695bcd2d1efc07eebf0cb88ff51d`. Le tag annoté `v0.1.0` possède l'objet tag `372650ea9fe313e7d5389ed43cacb6faa5f18f74` et se déréférence vers ce commit stable. L'absence de `.git` dans l'archive du tag est normale.
Corpus principal réellement fourni pour instruire le domaine Web :
```text
games-v0.3.6(1).zip ad6e44a1332eb7d6069cf1189d9433f0fbb8fac19c5aac9f4641ac45c1c556e8
```
Le nom local comporte `(1)`, mais son SHA-256 correspond exactement à la baseline canonique `games-v0.3.6.zip` enregistrée dans le prompt `007`. L'archive Games est donc le corpus autoritaire attendu pour cette étude.
Un corpus secondaire récent a également été fourni :
```text
khadhroony-solana-project-v0.3.17.zip 2a9cabcb9f147a348dcf8d24df8bc6c5029089b6d49feb17bd4a42b4293c329a
```
KSP `0.3.17` ne devient ni une baseline requise de `0.1.1`, ni une cible de migration. Il sert uniquement à corroborer, lorsque cela évite de généraliser un choix Games accidentel, les responsabilités frontend déjà observées derrière Tauri. Toute adoption KSP reste réservée à `0.1.6`.
## Audit de la stable `v0.1.0`
### Intégrité de l'archive et preuve post-tag
L'archive stable contient `254` entrées sous une racine unique `pgr/`, soit `221` fichiers et `33` répertoires. Son CRC est propre, aucun lien symbolique n'est présent et `.git` est absent comme attendu pour une archive de tag Gitea.
`VERSION` vaut exactement `0.1.0`. `CHANGELOG.md` contient l'entrée stable `0.1.0`, `ROADMAP.md` marque `0.1.0` terminé et engage `0.1.1` à `0.1.7` sans réserver `0.1.8`.
La convention de clôture introduite par `0.1.0` est cohérente :
```text
tranche de clôture rel.1
history rel.1 PASS
commit stable 0.1.0
tag v0.1.0
publish.001 preuve externe post-tag PASS
```
Aucun ancien artefact `rel.001*` n'est renommé rétroactivement.
### Tests, audits et hygiène
Les quatre suites Python présentes donnent :
```text
48 / 48 tests PASS
```
Les audits documentaires donnent :
```text
Markdown header audit: clean (198 file(s))
Markdown table audit: clean (8 table(s), 198 file(s))
Markdown link audit: clean (193 local link(s), 198 file(s))
```
Les cinq templates Rust/Cargo TOML sont parsables. Aucun répertoire de sortie courant tel que `target/`, `build/`, `builds/`, `dist/`, `node_modules/` ou `__pycache__/` n'est embarqué dans la stable.
Les scripts d'audit restent des contrôles read-only. Aucun audit PGR ne devient un générateur, un formateur ou un wrapper de build.
### Chaîne delta/history et vérité opérateur
Les `72` deltas publiés disposent tous d'un history correspondant :
```text
0.0.1 12 / 12
0.0.2 12 / 12
0.0.3 10 / 10
0.0.4 9 / 9
0.0.5 19 / 19
0.1.0 10 / 10
```
Pour `0.1.0`, la vérité opérateur reste explicitement conservée :
```text
alpha.1 PASS
alpha.2 FAIL
alpha.2.fix.1 PASS
alpha.3 FAIL
alpha.3.fix.1 PASS
alpha.4 PASS
alpha.5 PASS
beta.1 PASS
rc.1 PASS
rel.1 PASS
```
Les `FAIL` ne sont donc ni écrasés ni requalifiés après coup.
### Règles, profils, templates et skeletons
La hiérarchie normative courante reste cohérente : gouvernance, workflow, skeletons, adoption, documentation, validation, langages/écosystèmes, plateformes et frameworks possèdent des owners explicites.
Profils techniques déjà matérialisés :
```text
510 Rust / Cargo
520 Java / Maven / Gradle
610 Android
710 Tauri 2
```
La stable possède :
- cinq templates techniques Rust/Cargo sous `templates/rust-cargo/` ;
- deux skeleton specifications concrètes, gouvernance locale et workspace Rust/Cargo ;
- les templates documentaires de reprise, handoff opérateur et adoption d'un projet existant ;
- les contrats de validation Rust/Cargo et les audits Markdown/Rust monotâches.
Aucun owner Web générique n'existe encore. Il serait incorrect de faire porter TypeScript, Vite ou Sass/CSS par `710-TAURI.md` uniquement parce qu'un host Tauri utilise une WebView.
## Décisions différées vérifiées
`docs/studies/002-TAURI_SKELETON_DECISION.md` conserve correctement le skeleton Tauri en `DEFER`. Ses conditions de sortie exigent notamment :
```text
TypeScript et conventions Web contrôlées
Vite et ownership du dev server / build outputs
Sass/CSS et statut des artefacts générés
validation frontend indépendante de Tauri
choix d'un framework CSS classé comme décision de skeleton, pas comme règle Tauri
```
`docs/studies/003-V0_1_0_HORIZON_REVIEW.md` et `ROADMAP.md` engagent `0.1.1` pour cette fondation frontend, puis `0.1.2` Java/Gradle, `0.1.3` Android, `0.1.4` réexamen Tauri, `0.1.5` adoption Games, `0.1.6` adoption KSP et `0.1.7` audits Rust/Clippy statiques Python.
Les sujets suivants restent volontairement hors de cette release :
- WASM, sans numéro réservé ;
- serveur Web Rust / Actix Web ou alternative, sans numéro réservé et sans corpus d'implémentation suffisant ;
- deployment & operations, horizon futur sans numéro précis réservé ;
- création du skeleton Tauri contrôlé, réservée à un réexamen objectif en `0.1.4`.
La réussite de `0.1.1` devra produire les owners nécessaires à ce réexamen, mais ne lèvera pas automatiquement le `DEFER`.
## Audit du corpus Games `0.3.6`
### Intégrité et portée
L'archive fournie contient `652` entrées sous une racine unique `games/`, soit `502` fichiers et `150` répertoires. Son CRC est propre et aucun lien symbolique n'est présent.
Games n'est pas supposé conforme à PGR à ce stade. Les observations suivantes décrivent un corpus d'implémentation réel servant à décider ce qui mérite d'être généralisé ; elles ne transforment pas ses choix locaux en norme.
### Frontends exercés
Trois packages frontend sont présents :
```text
Web/game-snake-poc/
Web/game-realtime-webtransport-browser-smoke/
crates/apps/game-snake-poc-tauri/
```
Ils exercent tous :
- un `package.json` privé ;
- TypeScript ;
- Vite ;
- un `frontend/` distinct des configurations/outils du host ;
- un build de production combinant `tsc` et `vite build` lorsque la chaîne frontend elle-même est validée ;
- `cacheDir` et `outDir` placés sous `../builds/sasedev-games/...`, donc hors de l'arborescence source ;
- une séparation entre sources versionnées et sorties générées.
Les deux hosts navigateur directs utilisent en plus un mode `preview`. Le host Tauri ajoute des paramètres propres à son environnement de développement ; ces paramètres ne sont pas des règles Vite universelles.
### Styles et assets
`Web/game-snake-poc` exerce réellement Sass via `sass-embedded`, Bootstrap et une politique explicite de sorties CSS/assets. Le smoke WebTransport n'a besoin ni de Sass ni de Bootstrap. Le host Tauri Snake utilise Vite et la copie d'assets, mais son manifest actuel n'impose pas Sass.
La preuve Games indique donc :
```text
CSS responsabilité frontend générale
Sass capacité optionnelle, pas obligation universelle
framework CSS (Bootstrap) choix de présentation/skeleton ou projet, pas règle Web universelle
copie d'assets besoin Vite réel, mais configuration dépendante du projet
```
Un owner Sass/CSS doit expliquer les sources et artefacts générés sans exiger un préprocesseur sur les frontends qui n'en ont pas besoin.
### Package manager, manifest et lockfiles
Les packages exercés utilisent des commandes npm, mais le corpus ne justifie pas de rendre npm obligatoire dans PGR.
La racine Games ignore explicitement :
```text
**/node_modules/
**/dist/
package-lock.json
pnpm-lock.yaml
yarn.lock
```
Aucun lockfile Node n'est versionné dans l'archive. Cette politique est un choix Games actuel, pas une preuve qu'un lockfile frontend doit toujours être ignoré.
`alpha.3` retient une politique fondée sur le rôle :
- une application privée ou déployable `SHOULD` versionner le lockfile produit par son package manager afin de figer l'arbre réellement résolu ;
- une bibliothèque publiée `MAY` versionner un lockfile pour stabiliser l'environnement contributeur/CI, mais le manifest et ses contraintes restent le contrat de résolution des consommateurs ;
- un exemple, template ou fixture sans résolution de dépendances réelle `MAY` ne pas posséder de lockfile ;
- un même package `SHOULD NOT` conserver simultanément plusieurs lockfiles de package managers concurrents, sauf migration explicitement temporaire ;
- lorsqu'un lockfile est versionné, CI `SHOULD` utiliser le mode gelé/immutable/clean-install équivalent du package manager sélectionné plutôt qu'une résolution permissive.
L'absence actuelle de lockfiles dans Games devient donc une décision à réexaminer pendant l'adoption `0.1.5` : les packages applicatifs pourront `ADOPT` la recommandation en versionnant leur lockfile, ou documenter un `OVERRIDE` s'ils conservent volontairement une autre politique.
Le corpus Games exerce également déjà des dépendances de déclarations TypeScript :
```text
Web/game-snake-poc @types/bootstrap + @types/node
Web/game-realtime-webtransport-browser-smoke @types/node
crates/apps/game-snake-poc-tauri @types/node
```
KSP `0.3.17` corrobore la même pratique sur ses applications Tauri, qui utilisent `@types/bootstrap` et `@types/node` en `devDependencies`. Cette répétition justifie une règle générique de découverte des déclarations nécessaires, mais ne justifie pas d'imposer ces deux packages à tous les frontends.
La règle retenue est donc : vérifier d'abord les types embarqués par le package, puis rechercher un `@types/...` seulement lorsqu'il est réellement nécessaire. Pour une application privée, ces déclarations de développement appartiennent normalement à `devDependencies`; une bibliothèque publiée doit en revanche conserver disponibles aux consommateurs les types requis par ses déclarations publiques.
### Relation avec WASM et host
Deux packages Games chaînent actuellement des commandes WASM avant Vite. Cela prouve une intégration locale, mais ne justifie pas de faire du WASM une responsabilité du futur owner Vite ou TypeScript.
La frontière à conserver est :
```text
validation frontend propre TypeScript / Vite / CSS / assets / outputs
validation du host Tauri, navigateur spécialisé ou autre host
validation WASM owner futur séparé si sa valeur est démontrée
```
Un frontend doit pouvoir être validé autant que possible indépendamment du host qui l'embarque. Les commandes de génération WASM observées restent donc hors scope normatif de `0.1.1`.
## Corroboration secondaire KSP `0.3.17`
KSP contient six applications Tauri possédant chacune un frontend Vite/TypeScript. Les six manifests exercent également `sass-embedded` et Bootstrap.
Cette répétition confirme que les owners TypeScript/Vite/Sass/CSS sont bien transversaux à plusieurs hosts et ne doivent pas être absorbés par le profil Tauri. Elle ne suffit toujours pas à rendre Sass ou Bootstrap obligatoires pour tous les frontends : le corpus Games contient déjà des contre-exemples utiles.
Aucune autre règle KSP n'est importée dans `0.1.1-alpha.1`.
## Décisions de revue après `alpha.1`
La gate opérateur de `alpha.1` est `PASS` : `48/48` tests, audits Markdown propres et scope Git conforme. Aucun fix de cadrage n'est nécessaire.
La revue ajoute trois préférences explicites à traduire avec la force normative `SHOULD` :
- **TypeScript** : fortement recommandé pour les frontends contrôlés, mais non obligatoire. Sa valeur attendue est le type-check statique avant exécution/génération du JavaScript et la possibilité de partager des contrats typés avec d'autres écosystèmes ; lorsqu'une frontière Rust existe, des générateurs comme TS-RS peuvent éviter la duplication manuelle des DTO.
- **Vite** : fortement recommandé comme build tool/dev server des frontends contrôlés lorsque ses capacités correspondent au besoin, mais non obligatoire. Une alternative justifiée reste valide.
- **Sass** : fortement recommandé pour les chaînes de styles non triviales, en particulier lorsqu'une dépendance installée via l'écosystème de packages expose un entrypoint Sass/SCSS, des variables, maps, mixins ou autres points de configuration permettant d'adapter la bibliothèque sans modifier ses sources. Sass reste optionnel pour un frontend simple.
Bootstrap constitue un exemple réel de dépendance offrant une chaîne Sass personnalisable ; il ne devient pas pour autant une dépendance PGR universelle. Pour du nouveau code Sass, `@use` / `@forward` est préféré lorsque compatible ; `@import` reste toléré pour les bibliothèques existantes qui l'exigent encore.
`alpha.2` matérialise donc quatre owners séparés dans la famille `500` :
```text
530 TypeScript
540 JavaScript package ecosystem
550 Vite
560 CSS / Sass
```
Cette granularité conserve l'indépendance d'applicabilité : un projet peut utiliser TypeScript sans Vite, Vite avec JavaScript, CSS sans Sass, ou un package manager sans aucune des trois autres briques.
### Classification initiale des choix Games
| Choix Games | Classification pour l'adoption future | Motif |
|--------------------------------------------|-------------------------------------------------|----------------------------------------------------------------|
| TypeScript pour les frontends durables | `ADOPT` | déjà exercé et conforme à la préférence PGR `SHOULD` |
| Vite comme build tool/dev server | `ADOPT` | déjà exercé ; reste remplaçable par une alternative justifiée |
| `package.json` comme manifest frontend | `ADOPT` | owner générique nécessaire |
| npm comme package manager concret | `KEEP-LOCAL` | PGR ne rend pas npm universel |
| absence/versionnement des lockfiles Games | `DEFER` jusqu'à l'adoption `0.1.5` | choisir alors `ADOPT` ou `OVERRIDE` selon le rôle du package |
| Sass dans `game-snake-poc` | `ADOPT` lorsque la chaîne de styles le justifie | capacité recommandée, applicabilité conditionnelle |
| Bootstrap | `KEEP-LOCAL` | choix de présentation/skeleton, pas règle Web universelle |
| `frontend/` comme layout | `KEEP-LOCAL` / candidat skeleton | ne pas transformer un layout observé en règle de langage/build |
| ports, aliases et plugins Vite | `KEEP-LOCAL` | valeurs propres au host/projet |
| commandes/génération WASM dans les scripts | `DEFER` | futur owner WASM séparé |
Aucun `OVERRIDE` n'est nécessaire à ce stade : Games n'est pas encore gouverné par ces nouveaux profils et sera réellement mappé pendant `0.1.5`.
## Mission de `0.1.1`
`0.1.1` doit produire la première fondation frontend Web contrôlée de PGR à partir des responsabilités réellement exercées, sans créer un catalogue théorique de technologies Web.
La release doit pouvoir répondre de manière générique à ces questions :
1. qui possède la configuration TypeScript et quelles options relèvent du langage/outillage plutôt que du host ;
2. qui possède Vite, son dev server, son build, son cache et ses sorties ;
3. comment distinguer CSS, Sass optionnel et framework CSS optionnel ;
4. comment choisir et documenter un package manager sans imposer npm ;
5. comment traiter le manifest et le lockfile selon leur rôle ;
6. quelles sorties sont sources, générées, ignorées ou publiables ;
7. comment valider le frontend indépendamment de Tauri, WASM ou d'un backend ;
8. quels templates, skeletons ou audits read-only apportent une preuve réellement réutilisable.
## Frontières d'ownership à décider
`alpha.1` ne fixe volontairement ni numéros de profils ni découpage définitif. Les faits indiquent plusieurs responsabilités possibles, mais `alpha.2` doit choisir la frontière la plus générale où chaque règle est vraie.
Les axes à distinguer sont au minimum :
```text
TypeScript langage / toolchain frontend
manifest + package manager écosystème de package et scripts
Vite bundler / dev server / build outputs
CSS source frontend standard
Sass préprocesseur optionnel
framework CSS choix de skeleton/projet si applicable
frontend host navigateur direct, Tauri ou autre, hors owner générique
```
Le découpage final MUST éviter :
- un profil monolithique « Web moderne » qui rendrait toutes les briques obligatoires ;
- un owner Tauri qui posséderait des règles TypeScript/Vite génériques ;
- un owner TypeScript qui posséderait des règles de bundler ;
- une politique npm codée en dur alors que le contrat doit rester compatible avec un autre package manager choisi explicitement ;
- une règle universelle de lockfile dérivée du seul choix historique de Games ;
- l'import implicite de WASM ou d'un serveur Rust.
## Artefacts candidats
Les artefacts suivants sont candidats, pas des livrables déjà décidés :
- un ou plusieurs profils normatifs dans les familles existantes lorsque leur owner est démontré ;
- guides/templates minimaux pour `package.json`, `tsconfig.json` et `vite.config.ts` seulement si les valeurs génériques peuvent être séparées des décisions locales ;
- contrat CSS/Sass expliquant source, génération et outputs sans imposer Sass ;
- skeleton frontend Web seulement si la composition devient suffisamment générique et indépendante de Tauri/WASM ;
- validations frontend sélectionnées selon les capacités réelles : parsing du manifest, TypeScript, build Vite, Sass/CSS, smoke navigateur si la promesse de la tranche l'exige ;
- audits Python uniquement pour des propriétés statiques génériques et certaines, en restant monotâches et read-only.
Aucun de ces artefacts n'est créé par `alpha.1`.
## Trajectoire prévisionnelle de `0.1.1`
### alpha.1 — audit de stable, corpus et plan
Auditer `v0.1.0`, `publish.001`, Games `0.3.6`, les décisions Tauri/horizon, puis créer le présent plan. Aucun changement normatif Web n'appartient à cette tranche.
### alpha.2 — frontières d'ownership Web
Statut opérateur : **FAIL**.
La tranche a matérialisé les quatre owners `530 / 540 / 550 / 560`, leurs frontières indépendantes et les recommandations `SHOULD` TypeScript/Vite/Sass. Les `48` tests et les trois audits Markdown sont restés propres et le scope Git observé correspond au delta.
La gate spécifique n'a toutefois pas pu atteindre son message final : le littéral Python `'Le profil s'applique uniquement lorsqu'un projet utilise réellement Vite.'` utilise des quotes simples autour d'un texte contenant l'apostrophe de `s'applique`, provoquant un `SyntaxError`. Aucun défaut normatif des profils livrés n'est établi.
### alpha.2.fix.1 — correction de la gate d'ownership Web
Statut opérateur : **PASS**.
Le correctif a conservé le `FAIL` historique de `alpha.2`, reconfirmé les quatre owners `530/540/550/560`, les recommandations `SHOULD`, la classification Games et le `DEFER` Tauri. Les `48/48` tests et les trois audits Markdown sont propres ; le scope du fix est resté limité à `VERSION`, au plan et au delta de correction.
### alpha.3 — TypeScript et écosystème de package
Statut opérateur : **PASS**.
La tranche a matérialisé un type-check indépendant sous le script canonique `typecheck`, un `tsconfig` strict sans émission comme baseline minimale, un `package.json` privé minimal pour les applications contrôlées et une politique de lockfile fondée sur le rôle de l'artefact et la reproductibilité, jamais sur une préférence npm.
La gate spécifique atteint son message final, les `48/48` tests et les trois audits Markdown sont propres, et le scope Git correspond exactement au delta. Vite est resté réservé à `alpha.4` et CSS/Sass à `alpha.5`.
La revue opérateur après PASS relève toutefois une précision appartenant exactement au scope de la tranche : le manifest réel doit rechercher et déclarer les types externes nécessaires (`@types/node`, `@types/bootstrap` ou équivalent) lorsque les dépendances utilisées ne fournissent pas déjà leurs propres déclarations. Le delta livré reste immuable ; cette précision est portée par un fix local.
### alpha.3.fix.1 — déclarations de types externes
Statut opérateur : **FAIL**.
Le correctif a livré la règle `types embarqués → @types si nécessaire`, la classification conditionnelle de `@types/node` / `@types/bootstrap`, la distinction application privée / bibliothèque publiée et l'intégration IDE attendue. Les `48/48` tests et les trois audits Markdown sont propres, et le scope Git correspond au delta.
La gate spécifique n'a toutefois pas atteint son message final : le littéral Python `'qualité TypeScript et à l'expérience IDE'` utilise des quotes simples autour d'un texte contenant l'apostrophe de `l'expérience`, provoquant un `SyntaxError`. Aucun défaut normatif du correctif n'est établi.
### alpha.3.fix.2 — correction de la gate des déclarations de types
Statut opérateur : **PASS**.
La gate corrigée atteint son message final, reconfirme le `FAIL` historique de `alpha.3.fix.1`, les règles de découverte des types externes et la séparation application/bibliothèque. Les `48/48` tests et les trois audits Markdown passent, et le scope Git reste limité à `VERSION`, au plan et au delta de correction.
Aucune règle TypeScript/package ni aucun template n'a été modifié par le fix. La trajectoire reprend donc normalement avec Vite.
### alpha.4 — Vite, dev server et outputs
Statut opérateur : **PASS**.
La tranche a matérialisé le contrat Vite sans créer de `vite.config.ts` universel artificiel. Les sources, cache, outputs et assets ont des statuts explicites ; le dev server reste borné ; les paramètres `root`, `base`, ports, aliases et plugins restent des décisions locales.
La gate spécifique a atteint son message final, les `48/48` tests et les trois audits Markdown sont propres, et le scope Git correspond exactement aux six chemins annoncés. TypeScript/package n'a pas été rouvert et CSS/Sass est resté réservé à `alpha.5`.
### alpha.5 — CSS/Sass et validation frontend
Statut opérateur : **PASS**.
La gate spécifique Web frontend a atteint son message final, les `48/48` tests et les trois audits Markdown sont propres, et le scope Git correspond exactement au delta. Le skeleton `003-WEB_FRONTEND.md` compose désormais les owners `530/540/550/560` sans ownership caché ni valeur universelle arbitraire.
La tranche retient les décisions suivantes :
- CSS reste une baseline valide sans préprocesseur ;
- Sass reste optionnel mais **SHOULD** être préféré lorsque la chaîne de styles est non triviale ou lorsqu'un package expose une API Sass utile ;
- le nouveau code Sass contrôlé privilégie `@use` / `@forward`, tandis que `@import` reste uniquement une voie de compatibilité pour les dépendances qui l'exigent encore ;
- les sources `.css` / `.scss` / `.sass` intentionnelles sont versionnées, mais les CSS compilées, minifiées, sourcemaps et copies présentes dans un output de build sont générées et ne doivent pas devenir un second source ;
- un package de styles doit être consommé via son entrypoint public/documenté plutôt que par des chemins internes arbitraires ;
- Bootstrap, Tailwind CSS ou une autre bibliothèque restent des choix de projet/skeleton, jamais une obligation de `560` ;
- lorsqu'un frontend utilise Vite + Sass, `sass-embedded` est un choix de développement recommandé lorsque compatible, mais le profil Sass ne dépend pas de Vite ;
- la validation frontend distingue restore reproductible, type-check, build/compilation des styles et smoke navigateur seulement lorsque celui-ci apporte une preuve supplémentaire ;
- un PASS frontend ne vaut pas PASS du host, et un host Tauri ne doit pas posséder les validations TypeScript/Vite/Sass génériques.
Les owners `530/540/550/560` sont désormais assez complets pour composer un skeleton Web sans ownership caché. La tranche crée donc `003-WEB_FRONTEND.md` comme specialization contrôlée : TypeScript et Vite y restent des `SHOULD`, Sass reste conditionnel, le package manager et le framework CSS restent des décisions explicites, et aucun layout `frontend/`, `vite.config.ts`, `main.scss`, port ou package concret n'est imposé.
Le skeleton ne lève pas le `DEFER` Tauri. `beta.1` devra encore réconcilier les cinq conditions de sortie de l'étude `002` et conclure factuellement si `0.1.4` peut réexaminer le candidat Tauri.
### beta.1 — réconciliation et preuve de préparation Tauri
Statut opérateur : **PASS**.
La gate opérateur confirme le dry-run structurel du skeleton Web, la couverture des cinq prérequis Web du futur réexamen Tauri, les `48/48` tests et les trois audits Markdown propres. Le `DEFER` Tauri reste explicitement réservé à `0.1.4` et aucun owner Web n'a été modifié pendant cette réconciliation.
Les cinq conditions de sortie de `002-TAURI_SKELETON_DECISION.md` sont désormais rattachées aux artefacts matérialisés suivants :
```text
1. TypeScript contrôlé 530 + 008 + templates web-typescript
2. Vite/dev server/build outputs 550 + 009
3. CSS/Sass + statut des artefacts générés 560 + 010
4. validation frontend indépendante du host validation 005
5. framework CSS classé comme choix local 560 + skeleton 003
```
La tranche exécute aussi un dry-run structurel du skeleton Web : copie des templates JSON génériques dans un répertoire temporaire, parsing réel de ces artefacts, contrôle des références vers les owners/guides/validation et vérification de l'absence de `vite.config.ts`, `main.scss`, host Tauri ou dépendance frontend arbitraire injectés par PGR.
Ce dry-run ne prétend pas remplacer `tsc`, Vite ou Sass : le dépôt PGR ne possède volontairement ni versions de dépendances frontend ni configuration de projet concrète. Une instanciation réelle doit toujours exécuter les toolchains officielles sélectionnées conformément à `005-WEB_FRONTEND_VALIDATION.md`.
Si les cinq conditions sont matériellement couvertes, `beta.1` peut conclure que `0.1.4` dispose désormais des prérequis PGR nécessaires pour réexaminer le candidat Tauri. Cette conclusion MUST NOT lever le `DEFER`, créer le skeleton Tauri, figer `frontend/`, Bootstrap, Sass ou Vite comme obligations Tauri, ni remplacer la réévaluation du corpus courant exigée par l'étude `002`.
Si une responsabilité Web nécessaire reste sans owner clair, effectuer un REPLAN avant RC plutôt que masquer la lacune.
### rc.1 — release candidate
Statut opérateur : **PASS**.
La gate opérateur a confirmé les neuf histories antérieurs avec leurs statuts réels, le scope Web gelé, le changelog candidat, le prompt `008`, le dry-run structurel du skeleton Web, les `48/48` tests, les trois audits Markdown et l'hygiène texte/JSON. Aucun owner, template technique, skeleton, validation ou étude technique n'a été modifié pendant la RC.
Le prompt `008-V0_1_2_START_PROMPT.md` conserve la séparation Java/Gradle générique versus Android : le profil `520` sera réévalué à partir du corpus Games, tandis qu'AGP, SDK Android, JNI/ABI et packaging APK/AAB restent hors scope et réservés à `0.1.3`.
### rel.1 — promotion stable
Première clôture stable de `0.1.1`. La promotion est strictement mécanique : `VERSION = 0.1.1`, `ROADMAP.md` marque `0.1.1` terminée, le `CHANGELOG` perd son marqueur `candidate`, README/index décrivent la fondation frontend Web comme stable et le présent plan devient historique. Aucun owner, profil, template, skeleton, validation, étude ou script technique n'est modifié.
Le résultat opérateur de cette tranche appartient à `history/0.1.1/rel.1.md`, créé seulement après exécution de la gate. Si `rel.1` échoue, son history est conservé et un `rel.1.fix.N` corrige uniquement la fermeture ; la première tranche qui établit réellement la stable est incluse dans le commit `0.1.1` avant le tag `v0.1.1`.
La vérification post-tag reste séparée : `pgr-0.1.1-publish.001-report.md` ne peut être produit qu'à partir de l'archive du tag réellement publiée et des preuves Git observées. Le prompt `008` ne devient le point de départ effectif de `0.1.2` qu'après cette preuve post-tag `PASS`.
## Stratégie de validation
Chaque tranche conserve les gates PGR de base applicables :
```text
python3 -B -m unittest discover -s tests -v
python3 -B scripts/audit_markdown_headers.py ...
python3 -B scripts/audit_markdown_tables.py ...
python3 -B scripts/audit_markdown_links.py ...
```
Lorsqu'un artefact frontend réel est ajouté, la gate doit utiliser l'outil propriétaire lorsque disponible et pertinent au scope. Un audit Python peut prévalider une propriété statique précise, mais ne doit pas prétendre remplacer TypeScript, Vite, Sass ou le package manager.
Le choix des commandes Node/package manager doit être rendu explicite par le projet ou le fixture de validation. PGR ne doit pas utiliser `npm install` comme commande universelle simplement parce que Games l'utilise actuellement.
Les smokes navigateur ne sont requis que lorsqu'une tranche ou la release prétend supporter un comportement observable que le build statique ne suffit pas à prouver. Ils doivent être placés avant RC lorsque nécessaires, puis rejoués au release gate selon la matrice finale.
## Déclencheurs de REPLAN
Le plan MUST être révisé avant de continuer si :
- le découpage TypeScript/package/Vite/styles ne peut pas conserver un owner unique par règle ;
- `0.1.1` devrait absorber WASM, Tauri ou un serveur Rust pour être cohérent ;
- la politique de package manager/lockfile nécessite plusieurs catégories de projet non prévues ;
- un skeleton frontend ne peut être générique sans décisions propres à Games/KSP ;
- une tranche prévue dépasse nettement l'unité cohérente et indépendamment validable visée par PGR ;
- les validations réelles montrent qu'un outil ou une target supplémentaire est nécessaire pour soutenir une règle normative ;
- le périmètre total ne peut plus raisonnablement être clôturé dans la session/release prévue.
Un REPLAN peut scinder une tranche ou, si nécessaire, réexaminer la trajectoire conformément à la règle de revue d'horizon. Il ne doit pas artificiellement remplir la release avec des owners non prouvés.
## Clôture et transition
La release est prête pour RC lorsque :
- les owners Web retenus ont des frontières explicites et non redondantes ;
- TypeScript, package manager/manifest, Vite, CSS/Sass et outputs ont une politique contrôlée proportionnée ;
- la validation frontend est distinguée de la validation du host ;
- WASM, serveur Rust et Tauri n'ont pas été absorbés par proximité ;
- les choix Games non génériques restent classifiés comme locaux ou différés ;
- les conditions Tauri peuvent être réévaluées objectivement en `0.1.4` sans que `0.1.1` décide leur issue à l'avance.
Après publication `0.1.1` et `publish.001 PASS`, la reprise normale est `0.1.2` — réévaluation Java/Maven/Gradle — sauf REPLAN explicite de l'horizon fondé sur les résultats réels de la release.

View File

@@ -0,0 +1,467 @@
<!-- file: docs/plans/008-V0_1_2_JAVA_GRADLE_REEVALUATION_PLAN.md -->
<!-- version: 6 -->
# Plan 0.1.2 — réévaluation Java / Maven / Gradle
## Statut et sources
Plan historique de la stable `0.1.2`, créé pendant `0.1.2-alpha.1` conformément à `prompts/008-V0_1_2_START_PROMPT.md`, après audit indépendant de la stable taggée `v0.1.1`, de son rapport post-tag `PASS` et du corpus Games autoritaire réellement fourni.
Sources autoritaires de reprise PGR :
```text
pgr-v0.1.1(1).zip caaf8f456f7f8520172ea7705fd0cf5c5bf0e942dc4a773410bcbe7fe4ce243a
pgr-0.1.1-publish.001-report(1).md 3eafc2767225526a6cba65b3b62a45a664b71a1f2fa049915ec243a196e14bb3
```
Les noms locaux comportent `(1)`, mais l'archive PGR possède exactement le SHA-256 canonique enregistré par le rapport `publish.001`. Le rapport est `PASS`, porte sur cette même archive et confirme le commit stable `4893a04f4945f7cdc62d1294626a597353023a94`. Le tag annoté `v0.1.1` possède l'objet tag `09a3fe1501449a02a7edbbe9e897246b5434e15c` et se déréférence vers ce commit stable.
Corpus principal réellement fourni pour instruire Java/Gradle :
```text
games-v0.3.6(1).zip ad6e44a1332eb7d6069cf1189d9433f0fbb8fac19c5aac9f4641ac45c1c556e8
```
Le nom local comporte `(1)`, mais son SHA-256 correspond exactement à la baseline canonique `games-v0.3.6.zip` attendue par le prompt `008`. Games est donc le corpus autoritaire prévu pour cette réévaluation.
## Audit de la stable `v0.1.1`
### Intégrité de l'archive et preuve post-tag
L'archive stable contient `292` entrées sous une racine unique `pgr/`, soit `256` fichiers et `36` répertoires en comptant la racine. Son CRC est propre, aucun lien symbolique n'est présent et `.git` est absent comme attendu pour une archive de tag Gitea.
`VERSION` vaut exactement `0.1.1`. `CHANGELOG.md` contient l'entrée stable `0.1.1`, `ROADMAP.md` marque `0.1.1` terminé et conserve `0.1.2` à `0.1.7` engagés sans réserver `0.1.8`.
La publication observée suit le workflow courant :
```text
tranche de clôture rel.1
history rel.1 PASS
commit stable 0.1.1
tag v0.1.1
publish.001 preuve externe post-tag PASS
```
Le SHA de l'objet tag annoté reste distinct du commit stable ; la référence déréférencée pointe bien sur le même commit que `HEAD` et `origin/master` observés dans le rapport.
### Tests, audits et hygiène
Les quatre modules de tests Python de la stable ont été rejoués par groupes dans l'environnement d'analyse :
```text
48 / 48 tests PASS
```
Les audits documentaires donnent exactement :
```text
Markdown header audit: clean (231 file(s))
Markdown table audit: clean (9 table(s), 231 file(s))
Markdown link audit: clean (267 local link(s), 231 file(s))
```
Les cinq templates TOML Rust/Cargo restent parsables. Aucun symlink ni output courant tel que `target/`, `node_modules/`, `dist/` ou `__pycache__/` n'est embarqué dans la stable.
### Chaîne delta/history et vérité opérateur
Les `83` deltas publiés de `0.0.1` à `0.1.1` disposent tous d'un history portant la même identité.
Pour `0.1.1`, la vérité opérateur est conservée :
```text
alpha.1 PASS
alpha.2 FAIL
alpha.2.fix.1 PASS
alpha.3 PASS
alpha.3.fix.1 FAIL
alpha.3.fix.2 PASS
alpha.4 PASS
alpha.5 PASS
beta.1 PASS
rc.1 PASS
rel.1 PASS
```
Les `FAIL` ne sont ni écrasés ni réécrits après leurs corrections.
### État des owners et décisions différées
La stable possède notamment :
```text
510 Rust / Cargo
520 Java / Maven / Gradle
530 TypeScript
540 JavaScript package ecosystem
550 Vite
560 CSS / Sass
610 Android
710 Tauri 2
```
La fondation Web `0.1.1` est stable et son skeleton est indépendant du host. Le skeleton Tauri reste `DEFER` jusqu'au réexamen réservé à `0.1.4` ; `0.1.2` n'a donc aucune raison de rouvrir cette décision.
Le profil `520-JAVA_MAVEN_GRADLE.md` est l'owner à réévaluer. Le profil `610-ANDROID.md` reste l'owner des contraintes Android et sert ici uniquement à contrôler la frontière de responsabilité, pas à démarrer `0.1.3`.
## Audit du corpus Games `0.3.6`
### Intégrité et portée
L'archive Games contient `652` entrées sous une racine unique `games/`, soit `502` fichiers et `150` répertoires. Son CRC est propre et aucun lien symbolique n'est présent.
La version produit est portée par `Cargo.toml` et vaut `0.3.6`. L'absence d'un fichier racine `VERSION` dans ce corpus n'est pas interprétée comme un défaut PGR : Games n'est pas encore dans sa release d'adoption `0.3.7` / PGR `0.1.5`.
Les audits statiques rejoués sur l'archive donnent :
```text
General Rust rule audit: clean
Rust export completeness audit: 0 candidate(s)
games.sasedev workspace audit: clean
Markdown table audit: clean (6 table(s), 319 file(s))
Distribution layout audit: clean (55 required path(s), 11 forbidden path(s) absent)
```
Ces contrôles attestent l'intégrité structurelle du corpus utilisé pour l'étude ; ils ne remplacent pas les validations Gradle/Android historiques déjà consignées par Games.
### Structure Java observée
Le corpus contient quatre sources Java, toutes sous la convention `src/main/java/` :
```text
Android/common/src/main/java/com/sasedev/games/common/NativeBridge.java
Android/common/src/main/java/com/sasedev/games/common/SaseGameActivity.java
Android/game-reflex-poc/src/main/java/com/sasedev/games/reflex/ReflexActivity.java
Android/game-snake-poc/src/main/java/com/sasedev/games/snake/SnakeActivity.java
```
Les déclarations de package correspondent à leurs chemins. Les imports présents sont explicites ; aucun wildcard import n'est observé. La visibilité est bornée par la responsabilité des classes et les classes finales qui n'ont pas vocation à être étendues le sont effectivement.
Le corpus n'exerce pas de suite Java générique sous `src/test/java/`. Il ne fournit donc pas une preuve suffisante pour renforcer ou spécialiser les règles de tests Java du profil `520` au-delà de ce qui existe déjà.
Les responsabilités `Activity`, JNI, SDL3 et API Android rencontrées dans ces sources restent des responsabilités Android ou produit. Leur présence ne transforme pas ces contrats en règles Java générales.
### Build Gradle observé
Le projet Android est un build Gradle multi-module en Groovy DSL comprenant :
```text
:common
:game-reflex-poc
:game-snake-poc
```
L'ownership est réparti de manière identifiable :
- `settings.gradle` possède la composition des modules, la résolution des plugins/dépendances et le contrôle du minimum Gradle ;
- le `build.gradle` root possède les versions des plugins appliqués aux sous-projets ;
- `gradle.properties` porte des propriétés partagées non secrètes du build ;
- chaque `build.gradle` de module porte sa configuration locale et ses dépendances ;
- les scripts sous `Android/gradle/` portent une logique de build commune devenue suffisamment importante pour ne pas être dupliquée dans chaque module.
Cette répartition corrobore le principe PGR de centraliser ce qui est réellement commun sans imposer un layout ou une abstraction identique à tous les projets Gradle.
### JDK, niveau Java et compatibilité
L'historique Games fournit une preuve particulièrement utile pour la distinction déjà exigée par `520`.
Une première preuve `0.3.3-0-pre.2` a utilisé un Gradle Wrapper `9.6.0` et Temurin `17` via `JAVA_HOME`. Cette combinaison a ensuite été volontairement remplacée par un contrat moins restrictif : Gradle système `>= 9.6.0` et JDK courant de l'environnement.
Les gates `0-pre.3` à `0-pre.5` ont validé :
```text
JDK de build Temurin 25.0.4.1 LTS
Gradle exécuté 9.7.1
niveau Java source/target 17
```
La preuve démontre qu'un JDK de build plus récent peut exécuter la toolchain tout en produisant un code Java ciblant un niveau plus ancien explicitement déclaré. Elle ne justifie ni d'imposer Java 17 à PGR, ni d'imposer JDK 25, ni de transformer une contrainte Android en règle Java générale.
### Gradle système versus Wrapper
La trajectoire Games est utile précisément parce qu'elle a exercé les deux politiques :
1. wrapper exact introduit pour une preuve bornée et reproductible ;
2. retrait du wrapper lorsque la décision durable est devenue « Gradle système compatible, minimum vérifié » ;
3. contrôle de `GradleVersion.current()` contre `9.6.0` dans `settings.gradle` ;
4. validation réelle avec Gradle `9.7.1`.
Cette trajectoire confirme qu'un Wrapper est un moyen de reproductibilité, pas une obligation cérémonielle, et qu'un Gradle système peut être une politique durable lorsque sa contrainte est explicitement vérifiée.
Le minimum exact `9.6.0` est toutefois lié à la stack Android observée et reste hors de toute règle Gradle générale.
### DSL, dépendances et versions
Games utilise uniquement le Groovy DSL pour son projet Gradle natif. Ce choix ne fournit aucune preuve permettant de rendre Groovy obligatoire ou de déprécier Kotlin DSL dans PGR.
Aucun version catalog n'est présent. Les versions de plugins réellement partagées sont centralisées au root ; les repositories sont possédés au niveau `settings.gradle`. Cette organisation confirme la valeur de l'ownership partagé mais ne justifie pas d'imposer `libs.versions.toml`, `RepositoriesMode.FAIL_ON_PROJECT_REPOS` ou un repository particulier à tous les builds Gradle.
Aucun projet Maven, `pom.xml` ou Maven Wrapper n'est présent. Games n'autorise donc aucun nouvel artefact Maven dans `0.1.2` ; les règles Maven existantes seront seulement relues pour cohérence avec le contrat général du profil.
### Outputs, état local et validation
La stable Games ignore explicitement les caches et outputs Gradle :
```text
/Android/.gradle/
/Android/**/build/
```
`local.properties` reste également hors Git. Cette pratique corrobore la séparation PGR entre configuration partagée versionnée, état machine local et outputs générés.
Les gates historiques utilisent directement les tâches Gradle pertinentes (`assembleDebug`, `bundleRelease`, etc.) et n'emploient `clean` que lorsqu'une phase de stabilisation a réellement besoin de reconstruire depuis un état nettoyé. Cela confirme le principe PGR : tâches ciblées pendant le développement, gates plus larges lorsque le scope ou la phase le justifie, et aucun `clean` systématique comme pseudo-preuve.
## Frontière Android obligatoire
Les éléments suivants sont observés dans Games mais appartiennent explicitement à `610-ANDROID.md`, à une spécialisation Android/Rust/JNI ou au produit Games :
```text
AGP 9.4.0
compileSdk / targetSdk / minSdk
NDK et ABI Android
AAR SDL3 et Prefab
JNI et bibliothèques natives
applicationId / namespace / manifests / resources
APK / AAB / signing
Variant API Android
AVD, devices et smokes Android
contraintes 16 KB
choix SDL3 et architecture des jeux
```
Aucun de ces éléments ne doit devenir une règle Java/Gradle générale pendant `0.1.2`.
Une contrainte Gradle ou JDK plus étroite imposée par AGP constitue un raffinement de plateforme. `0.1.2` peut documenter cette frontière dans `520`, mais ne réécrit pas le profil Android et ne commence pas `0.1.3`.
## Classification initiale des décisions Games
La classification suivante guide les tranches normatives ; elle ne constitue pas encore une adoption de Games, réservée à `0.1.5`.
| Décision observée | Classification | Traitement `0.1.2` |
|--------------------------------------------------------------------------------|----------------------------------|--------------------------------------------------------------------------------------------|
| Séparer JDK de build et niveau Java produit | `ADOPT` | conserver et clarifier dans `520` |
| Utiliser la structure Java canonique `src/main/java` et des packages cohérents | `ADOPT` | conserver les règles existantes, sans importer les responsabilités Android |
| Centraliser la configuration Gradle réellement commune | `ADOPT` | préciser les owners `settings` / root / sous-projets sans imposer le layout Games |
| Gradle système avec contrainte minimale effectivement vérifiée | `ADOPT` comme politique possible | renforcer le contrat de vérifiabilité, sans imposer `9.6.0` |
| Absence durable de Gradle Wrapper dans Games | `KEEP-LOCAL` | conserver le Wrapper comme option PGR de reproductibilité, pas comme obligation |
| Groovy DSL | `KEEP-LOCAL` | maintenir Groovy et Kotlin DSL comme choix valides ; ne pas copier la préférence Games |
| JDK 25 LTS de build et source/target 17 | `KEEP-LOCAL` | ne généraliser que leur séparation conceptuelle |
| Matrice AGP/Gradle/JDK plus étroite | `OVERRIDE` de plateforme | reste possédée par `610` / Android, hors normalisation `520` |
| Version catalog | `DEFER` | aucun besoin démontré ; rester optionnel |
| Nouveaux templates/audits Maven | `DEFER` | aucun corpus Maven réel fourni |
| Skeleton Java/Gradle générique | `DEFER` | Games n'exerce qu'un build Gradle Android ; preuve insuffisante pour un skeleton générique |
| Audit Python Java/Gradle | `DEFER` | aucune propriété générique non mieux contrôlée par Java/Gradle n'est encore démontrée |
## Réévaluation du profil `520`
Le profil existant est globalement cohérent avec les preuves Games : il distingue déjà JDK de build et niveau Java, rend les Wrappers conditionnels, reconnaît Gradle système, accepte Groovy/Kotlin DSL, déconseille `clean` systématique et ignore les outputs/caches.
La release doit donc privilégier une correction ciblée plutôt qu'une réécriture. Les points à instruire en priorité sont :
1. préciser que la compatibilité Java ne se résume pas au JDK actif et qu'un JDK de build plus récent peut cibler un niveau produit plus ancien explicitement déclaré ;
2. rendre explicite qu'une politique « Gradle système » doit posséder une contrainte vérifiable par le build ou la gate, pas seulement une version écrite dans une documentation ;
3. préciser les responsabilités naturelles de `settings.gradle(.kts)`, du root build et des sous-projets sans transformer les APIs modernes observées dans Games en obligations universelles ;
4. distinguer `gradle.properties` partagé et portable des propriétés locales, chemins machine, secrets ou overrides utilisateur ;
5. conserver la neutralité Groovy/Kotlin DSL et le caractère conditionnel du Wrapper/version catalog ;
6. relire les sections Maven pour cohérence, sans créer de nouvel artefact Maven faute de corpus ;
7. vérifier qu'aucune règle Java/Gradle n'absorbe AGP, SDK, NDK, ABI/JNI, packaging ou smokes Android.
Le regroupement actuel Java/Maven/Gradle dans un seul owner est également relu au regard de `500-LANGUAGES.md`. Une scission documentaire ne sera effectuée que si elle réduit réellement les responsabilités ambiguës. En l'absence de corpus Maven, `0.1.2` ne créera pas artificiellement un nouvel owner Maven uniquement pour satisfaire une préférence de découpage.
## Décision après `alpha.1`
La gate opérateur de `alpha.1` est `PASS` : `48/48` tests Python, audits Markdown propres, audit structurel propre et scope Git conforme. Aucun `alpha.1.fix.N` ni REPLAN n'est requis.
La revue confirme la classification initiale sans l'élargir :
- `ADOPT` : distinction JDK de build / niveau source / bytecode-runtime, ownership Gradle explicite et politique Gradle système seulement si sa contrainte est effectivement vérifiée ;
- `KEEP-LOCAL` : Groovy DSL, absence de Wrapper dans Games, JDK 25 LTS et cible Java 17 ;
- `OVERRIDE` : matrice AGP/Gradle/JDK et autres contraintes de plateforme Android ;
- `DEFER` : version catalog, skeleton Java/Gradle, audit Python Java/Gradle et nouveaux artefacts Maven.
`alpha.2` est donc bornée à la révision du profil `520`. Le profil `610-ANDROID.md` reste inchangé et aucun template, skeleton, audit ou artefact Maven n'est ajouté.
## Décision après `alpha.2` et REPLAN
La gate opérateur de `alpha.2` est `PASS` : `48/48` tests Python, audits Markdown propres, gate Java/Gradle propre, frontière Android préservée et scope Git conforme. Le contenu normatif ajouté dans la tranche n'exige aucun fix fonctionnel.
Après cette gate, une contamination inter-projet a toutefois affecté la chaîne de commit/push : des fichiers Knowledge ont été ajoutés et deux documents PGR ont été écrasés. `alpha.2.fix.1` restaure l'état PGR attendu sans modifier les décisions Java/Maven/Gradle de `alpha.2`, conserve son history `PASS` et devient la baseline obligatoire avant réémission de `alpha.3`. L'ancienne application locale de `alpha.3` sur le HEAD contaminé n'est pas réutilisée comme source autoritaire.
La préparation de `beta.1` a toutefois exécuté la réconciliation explicitement prévue contre `500-LANGUAGES.md` et `docs/architecture/003-RULE_PROFILE_MODEL.md`. Cette lecture révèle une ambiguïté d'ownership distincte du contenu validé en `alpha.2` :
- `500-LANGUAGES.md` autorise un langage et son build tool dans un même profil lorsque leur séparation serait artificielle ;
- le même contrat indique qu'ils SHOULD être séparés lorsque plusieurs build tools interchangeables possèdent chacun des règles propres significatives ;
- `520-JAVA_MAVEN_GRADLE.md` contient désormais des contrats Maven et Gradle indépendants et substantiels : ownership du build, Wrapper, validation et outputs pour chacun, plus une politique Gradle système/DSL/propriétés qui n'appartient pas à Maven ;
- l'applicabilité d'un profil unique `Java / Maven / Gradle` devient donc ambiguë pour un projet Java qui n'utilise qu'un seul de ces build tools, et plus encore pour un projet Gradle qui ne contient pas nécessairement de Java.
Le déclencheur de REPLAN prévu par le présent plan est donc atteint : la scission réduit une ambiguïté normative réelle et ne constitue pas une multiplication décorative de fichiers.
La trajectoire devient :
```text
alpha.3 scission des owners Java / Maven / Gradle
beta.1 réconciliation intégrée après scission et décision finale d'artefacts
rc.1 gel et release gate
rel.1 promotion stable
```
La scission retenue est :
```text
520-JAVA.md
521-MAVEN.md
522-GRADLE.md
```
`520-JAVA_MAVEN_GRADLE.md` devient `SUPERSEDED` et reste uniquement comme bridge documentaire non normatif afin de préserver les liens des prompts, plans, deltas, histories et études historiques. Les documents historiques antérieurs ne sont pas réécrits : ils restent la preuve fidèle du modèle réellement publié à leur époque.
La décision d'artefacts techniques ne change pas : aucun template, skeleton, audit Java/Gradle ou nouvel artefact Maven n'est justifié par Games. Les nouveaux fichiers `521` et `522` sont des owners normatifs rendus nécessaires par l'applicabilité, pas des artefacts techniques ajoutés pour remplir la release.
Le scope Android reste inchangé et réservé à `0.1.3`. La scission ne modifie que les références nécessaires dans `610-ANDROID.md` afin qu'Android compose explicitement Gradle et Java uniquement lorsqu'ils sont réellement applicables.
## Décision après `alpha.3` et réconciliation `beta.1`
La gate opérateur de `alpha.3` est `PASS` : `48/48` tests Python, audits Markdown propres, gate de scission propre, bridge historique préservé, frontière Android maintenue et scope Git conforme. Aucun `alpha.3.fix.N` ni nouveau REPLAN n'est requis.
La réconciliation beta rejoue les trois owners contre Games, `500-LANGUAGES.md`, `610-ANDROID.md` et les règles générales de validation. Elle confirme :
- `520-JAVA.md` reste applicable au langage Java indépendamment du build tool ;
- `521-MAVEN.md` ne devient applicable que lorsqu'un projet utilise Maven et n'est pas présenté comme éprouvé par Games, qui ne fournit aucun corpus Maven ;
- `522-GRADLE.md` ne devient applicable que lorsqu'un projet utilise Gradle et conserve uniquement les principes génériques démontrés ;
- JDK 25, cible Java 17, Gradle 9.6.0+, Gradle 9.7.1, Groovy DSL et absence de Wrapper restent des décisions locales/corpus et non des minima PGR ;
- AGP, SDK/NDK, ABI/JNI, manifests/resources, packaging/signing, device/AVD, contraintes 16 KB et SDL3 restent possédés hors des owners Java/Maven/Gradle et réservés à la réévaluation Android `0.1.3` ;
- l'ancien `520-JAVA_MAVEN_GRADLE.md` reste uniquement un bridge historique `SUPERSEDED`.
La décision finale d'artefacts pour `0.1.2` est donc **aucun artefact technique supplémentaire** : aucun nouveau contrat de validation, template, skeleton, audit Python Java/Maven/Gradle ou artefact Maven n'apporte une valeur démontrée par le corpus disponible. Les owners `520/521/522` suffisent et les toolchains officielles restent propriétaires des preuves exécutables.
La beta n'ouvre aucune nouvelle règle fonctionnelle ; elle consolide l'état durable avant `rc.1`.
## Mission de `0.1.2`
La release doit produire un profil Java/Maven/Gradle mieux éprouvé par une implémentation réelle tout en restant générique.
Elle MUST :
- conserver les choix Java/Gradle qui sont déjà correctement généralisés ;
- corriger les ambiguïtés ou lacunes démontrées par Games et par la réconciliation des owners ;
- séparer Java, Maven et Gradle lorsque leur applicabilité et leurs responsabilités divergent réellement ;
- classer les contraintes Android comme overrides de plateforme plutôt que règles générales ;
- utiliser Java/Gradle eux-mêmes comme autorité lorsqu'une validation exécutable est nécessaire ;
- conserver Maven cohérent sans inventer de template, audit ou skeleton en l'absence de corpus Maven ;
- ne créer un nouvel artefact Java/Gradle que s'il évite une duplication réelle ou matérialise un contrat absent du profil actuel.
Elle MUST NOT :
- modifier Games ;
- démarrer l'adoption Games `0.1.5` ;
- réécrire `610-ANDROID.md` ou commencer `0.1.3` ;
- créer ou réexaminer le skeleton Tauri avant `0.1.4` ;
- rouvrir les owners Web `530` à `560` sans défaut transversal démontré ;
- introduire Maven, Kotlin DSL, version catalog, Wrapper ou plugin par simple possibilité écosystème.
## Artefacts retenus après REPLAN
Owners normatifs nécessaires :
```text
docs/rules/520-JAVA.md langage Java et compatibilité JDK/source/bytecode
docs/rules/521-MAVEN.md spécialisation Maven
docs/rules/522-GRADLE.md spécialisation Gradle
```
Le profil combiné historique `docs/rules/520-JAVA_MAVEN_GRADLE.md` est superseded par ces trois owners. Son chemin est conservé comme bridge documentaire non normatif pour éviter de casser les liens historiques ; il n'est plus indexé comme owner courant.
Artefacts techniques explicitement non justifiés à ce stade :
```text
docs/validation/... aucun nouveau contrat : 400 + profils spécialisés suffisent
docs/templates/... aucun fichier générique suffisamment éprouvé hors Android
scripts/audit_*.py aucune propriété générique non mieux contrôlée par Java/Maven/Gradle
docs/skeletons/... aucun skeleton Java/Gradle générique justifié par le seul corpus Games
artefacts Maven aucun corpus Maven réel fourni
```
Cette décision est rejouée et confirmée dans `beta.1` après validation opérateur de la scission.
## Trajectoire prévisionnelle de `0.1.2`
### alpha.1 — audit de stable, corpus et plan
Vérifier `v0.1.1`, son rapport `publish.001`, le corpus Games, la frontière Android et la classification initiale. Créer le présent plan sans modifier encore `520` ou `610`.
### alpha.2 — révision ciblée Java / Gradle
Réviser `520-JAVA_MAVEN_GRADLE.md` uniquement sur les points réellement démontrés : compatibilité JDK/source/bytecode, ownership Gradle, contrainte système vérifiable, Wrapper conditionnel, DSL, propriétés partagées/locales, validation et outputs.
Relire les sections Maven pour cohérence sans ajouter d'artefact Maven. Conserver toutes les contraintes Android dans leur owner actuel.
Statut opérateur : **PASS**.
### alpha.3 — REPLAN et scission des owners
Scinder le profil combiné en `520-JAVA.md`, `521-MAVEN.md` et `522-GRADLE.md` afin d'aligner l'applicabilité avec `500-LANGUAGES.md` et le modèle de profils. Conserver le contenu normatif validé, convertir l'ancien chemin en bridge `SUPERSEDED` non normatif et mettre à jour uniquement les références courantes nécessaires.
Ne pas modifier les documents historiques qui décrivent fidèlement l'ancien owner combiné. Ne pas ajouter de template, skeleton, audit ou artefact Maven/Android.
Statut opérateur : **PASS**.
### beta.1 — réconciliation et décision d'artefacts
Relire les trois owners issus de la scission contre Games, `500-LANGUAGES.md`, `610-ANDROID.md` et les règles générales de validation. Vérifier qu'aucun choix local Games ou contrainte Android n'est devenu un `MUST` général et que Maven/Gradle ne deviennent applicables que lorsqu'ils sont réellement utilisés.
À ce stade seulement, décider si un contrat de validation, template ou audit générique supplémentaire apporte une valeur réelle. S'il n'en apporte pas, consigner explicitement qu'aucun artefact supplémentaire n'est nécessaire plutôt que créer une tranche décorative.
La beta met également à jour les index/documentation durable nécessaires à la release et prépare la clôture sans ouvrir `0.1.3` prématurément.
Statut opérateur : **PASS**.
### rc.1 — release candidate
Statut opérateur : **PASS**.
La gate RC a confirmé les cinq histories antérieurs `PASS`, le scope Java/Maven/Gradle gelé, le changelog candidat, le prompt `009`, les `48/48` tests, les trois audits Markdown et l'hygiène texte/templates. Aucun owner, profil Android, template, skeleton, validation ou script n'a été modifié pendant la RC.
Le prompt `009-V0_1_3_START_PROMPT.md` conserve la frontière de release : la réévaluation Android démarre en `0.1.3` seulement depuis une stable `v0.1.2` réellement taggée et son rapport post-tag `PASS`; Tauri reste réservé à `0.1.4` et l'adoption Games à `0.1.5`.
### rel.1 — promotion stable
Première clôture stable de `0.1.2`. La promotion est strictement mécanique : `VERSION = 0.1.2`, `ROADMAP.md` marque `0.1.2` terminée, le `CHANGELOG` perd son marqueur `candidate`, README/index décrivent la réévaluation Java/Maven/Gradle comme stable et le présent plan devient historique. Aucun owner, profil Android, template, skeleton, validation ou script technique n'est modifié.
Le résultat opérateur de cette tranche appartient à `history/0.1.2/rel.1.md`, créé seulement après exécution de la gate. Si `rel.1` échoue, son history est conservé et un `rel.1.fix.N` corrige uniquement la fermeture ; la première tranche qui établit réellement la stable est incluse dans le commit `0.1.2` avant le tag `v0.1.2`.
La vérification post-tag reste séparée : `pgr-0.1.2-publish.001-report.md` ne peut être produit qu'à partir de l'archive du tag réellement publiée et des preuves Git observées. Le prompt `009` ne devient le point de départ effectif de `0.1.3` qu'après cette preuve post-tag `PASS`.
## Stratégie de validation
`alpha.1` reste documentaire et structurel : tests Python PGR, audits Markdown, contrôle des couples delta/history, vérification du prompt `008`, de l'ancien owner `520`, de `610`, du plan et du scope Git. `alpha.3` ajoute une validation structurelle de la scission et des références courantes, sans simuler une toolchain Java/Maven/Gradle absente de PGR.
Lorsqu'une tranche modifie uniquement des règles PGR et ne contient aucun projet Java/Gradle exécutable, PGR ne doit pas simuler un build Java. Les preuves Games historiques peuvent justifier une décision, mais elles ne deviennent pas une gate opérateur PGR locale.
Si une tranche ultérieure ajoute un artefact Gradle exécutable réel, sa validation doit utiliser Java/Gradle officiels en plus des audits PGR applicables. Un audit Python ne remplacera ni `javac`, ni Gradle, ni Maven.
La validation reste proportionnée : aucune commande `clean` systématique et aucune gate Android uniquement parce que Games a servi de corpus d'étude.
## Déclencheurs de REPLAN
Un REPLAN est requis notamment si :
- la révision montre que `520` doit être scindé en plusieurs owners pour éviter une ambiguïté normative réelle ;
- un besoin Maven réel apparaît et exige un corpus ou une preuve absente de la baseline actuelle ;
- une modification supposée générique dépend en réalité d'AGP, du SDK/NDK, de JNI ou du packaging Android ;
- un template/audit candidat exige de copier une structure Games plutôt que de matérialiser un contrat réutilisable ;
- la release ne peut pas rester bornée sans absorber une responsabilité explicitement réservée à `0.1.3` ou `0.1.4`.
Un REPLAN ne sert pas à ajouter des artefacts pour remplir la release ; il sert à corriger son découpage lorsque les owners réels l'exigent.
## Clôture et transition
La réconciliation documentaire durable, le `CHANGELOG`, la mise à jour de `ROADMAP` et la fermeture du plan sont achevés par `rel.1`. La publication du tag et sa vérification post-tag restent séparées de cette clôture pré-tag.
La roadmap possède déjà un horizon suffisant jusqu'à `0.1.7`. Aucune nouvelle revue d'horizon n'est requise par défaut pendant `0.1.2`.
La prochaine release engagée après publication vérifiée de `0.1.2` reste :
```text
0.1.3 — réévaluation pratique du profil Android à partir de Games
```
Le prompt de démarrage de `0.1.3` ne doit être préparé que dans une tranche où la clôture `0.1.2` est suffisamment déterminée, puis exécuté seulement après stable taggée et preuve post-tag applicable.

View File

@@ -0,0 +1,617 @@
<!-- file: docs/plans/009-V0_1_3_ANDROID_REEVALUATION_PLAN.md -->
<!-- version: 6 -->
# Plan 0.1.3 — réévaluation pratique Android
## Statut et sources
Plan actif de `0.1.3`, créé pendant `0.1.3-alpha.1` conformément à `prompts/009-V0_1_3_START_PROMPT.md`, après audit indépendant de la stable taggée `v0.1.2`, de son rapport post-tag `PASS` et du corpus Games autoritaire réellement fourni.
Sources autoritaires de reprise PGR réellement fournies :
```text
pgr-v0.1.2(1).zip 0ef8facab0c6f92ca427f5f13d38d6c4a4c1cc16174a20ecdab48991bd88d0e6
pgr-0.1.2-publish.001-report.md 0f6b4e2a685a957fa647a7db009320ada0fc67948737d8344cc3773bcaeb6a9c
```
Le nom local de l'archive PGR comporte `(1)`, mais son SHA-256 correspond exactement à l'archive canonique `pgr-v0.1.2.zip` enregistrée par le rapport `publish.001`. Le rapport est `PASS`, porte sur cette même archive et confirme le commit stable `585b508578aae337f6940110d4ca47c694a052d5`. Le tag annoté `v0.1.2` possède l'objet tag `cea2c7a06cde844ffa7411f73bb22685a3214414` et se déréférence vers ce commit stable.
Corpus principal réellement fourni pour instruire Android :
```text
games-v0.3.6(2).zip ad6e44a1332eb7d6069cf1189d9433f0fbb8fac19c5aac9f4641ac45c1c556e8
```
Le nom local comporte `(2)`, mais son SHA-256 correspond exactement à la baseline canonique `games-v0.3.6.zip` prévue par le prompt `009` et par le rapport de publication `0.1.2`. Games est donc le corpus Android autoritaire de cette réévaluation.
## Audit de la stable `v0.1.2`
### Intégrité de l'archive et preuve post-tag
L'archive stable contient `316` entrées sous une racine unique `pgr/`, soit `276` fichiers et `40` répertoires. Son CRC est propre, aucun lien symbolique n'est présent et `.git` est absent comme attendu pour une archive de tag Gitea.
`VERSION` vaut exactement `0.1.2`. `CHANGELOG.md` contient l'entrée stable `0.1.2`, `ROADMAP.md` marque `0.1.2` terminé et conserve `0.1.3` à `0.1.7` engagés sans réserver `0.1.8`.
La publication observée suit le workflow courant :
```text
tranche de clôture rel.1
history rel.1 PASS
commit stable 0.1.2
tag v0.1.2
publish.001 preuve externe post-tag PASS
```
Le SHA de l'objet tag annoté reste distinct du commit stable ; la référence distante déréférencée pointe sur le même commit que `HEAD` et `origin/master` observés dans le rapport.
### Tests, audits et hygiène
La suite Python de la stable a été rejouée dans l'environnement d'analyse :
```text
48 / 48 tests PASS
```
Les audits documentaires donnent :
```text
Markdown header audit: clean (250 file(s))
Markdown table audit: clean (10 table(s), 250 file(s))
Markdown link audit: clean (307 local link(s), 250 file(s))
```
Les cinq templates TOML Rust/Cargo et les deux fichiers JSON Web contrôlés restent parsables.
### Chaîne delta/history et vérité opérateur
Les `90` deltas publiés de `0.0.1` à `0.1.2` disposent tous d'un history portant la même identité.
Pour `0.1.2`, la vérité opérateur est :
```text
alpha.1 PASS
alpha.2 PASS
alpha.2.fix.1 PASS
alpha.3 PASS
beta.1 PASS
rc.1 PASS
rel.1 PASS
```
La récupération de contamination inter-projet de `alpha.2.fix.1` reste conservée historiquement ; aucun des quatre chemins Knowledge accidentels n'est présent dans la stable publiée.
### Owners applicables avant réévaluation
La stable `0.1.2` possède des owners désormais séparés et composables :
```text
520 Java
521 Maven
522 Gradle
600 plateformes
610 Android
710 Tauri 2
```
`610-ANDROID.md` est en révision interne `3`. Il compose déjà `522-GRADLE.md` lorsqu'un projet Android utilise Gradle et `520-JAVA.md` lorsqu'il contient du Java ; Android n'implique donc pas à lui seul l'applicabilité du profil Java.
La présente release réévalue les responsabilités Android elles-mêmes. Elle ne rouvre Java/Maven/Gradle que si un défaut transversal réellement démontré l'exige.
## Audit du corpus Games `0.3.6`
### Intégrité et portée
L'archive Games contient `652` entrées sous une racine unique `games/`, soit `502` fichiers et `150` répertoires. Son CRC est propre et aucun lien symbolique n'est présent.
La version produit du workspace est `0.3.6` dans `Cargo.toml`. Games n'a pas encore effectué son adoption PGR réservée à `0.1.5` ; l'absence d'un fichier racine PGR `VERSION` n'est donc pas interprétée comme un défaut de la baseline.
Les audits statiques rejoués sur l'archive donnent :
```text
General Rust rule audit: clean
Rust export completeness audit: 0 candidate(s)
games.sasedev workspace audit: clean
Markdown table audit: clean (6 table(s), 319 file(s))
Distribution layout audit: clean (55 required path(s), 11 forbidden path(s) absent)
```
Ces contrôles attestent l'intégrité structurelle du corpus. Ils ne remplacent pas les preuves Gradle/Android historiques consignées par Games.
### Structure Android observée
Le sous-projet Android natif contient `20` fichiers versionnés sous `Android/` et forme un build Gradle multi-module séparé du workspace Cargo :
```text
Android/
├── common/
├── game-reflex-poc/
├── game-snake-poc/
├── gradle/
├── libs/
├── build.gradle
├── gradle.properties
├── settings.gradle
└── .gitignore
```
Le choix `Android/` répond ici à une architecture réellement multi-plateforme. Il ne prouve pas qu'un dépôt exclusivement Android devrait ajouter artificiellement ce niveau.
Les modules exercent deux responsabilités différentes :
```text
common Android Library partagée
game-*-poc applications Android indépendantes
```
Les noms exacts `common`, `game-reflex-poc` et `game-snake-poc` restent des décisions produit Games.
### Composition Java et Gradle
Le corpus contient quatre sources Java sous `src/main/java/` :
```text
Android/common/src/main/java/com/sasedev/games/common/NativeBridge.java
Android/common/src/main/java/com/sasedev/games/common/SaseGameActivity.java
Android/game-reflex-poc/src/main/java/com/sasedev/games/reflex/ReflexActivity.java
Android/game-snake-poc/src/main/java/com/sasedev/games/snake/SnakeActivity.java
```
Java est donc réellement applicable à Games, mais son usage est une composition du projet Android et non une propriété universelle d'Android.
Le build Android utilise Gradle en Groovy DSL. L'ownership observé est cohérent avec `522-GRADLE.md` :
- `settings.gradle` possède modules, repositories et contrainte minimale Gradle ;
- le `build.gradle` root possède la version AGP partagée ;
- `gradle.properties` possède des propriétés partagées non secrètes ;
- les modules possèdent leur configuration Android et leurs dépendances ;
- les scripts sous `Android/gradle/` possèdent la logique commune d'assets et de build natif devenue trop importante pour être dupliquée.
### Matrice AGP / Gradle / JDK et niveau Java
La baseline courante déclare ou documente :
```text
AGP 9.4.0
Gradle >= 9.6.0
JDK de build >= 17, non épinglé par le projet
niveau Java source/target 17
```
L'histoire Games exerce deux politiques successives : une preuve initiale avec Wrapper Gradle `9.6.0` et JDK `17`, puis une décision durable utilisant Gradle système avec minimum exécutable `>= 9.6.0` et le JDK courant de l'environnement.
Les gates ultérieures ont réellement utilisé Temurin `25.0.4.1 LTS` et Gradle `9.7.1` tout en conservant `source/target 17` pour la glue Java.
Cette trajectoire confirme la séparation entre JDK de build et niveau Java. Les valeurs exactes restent des preuves Games et ne deviennent pas des minima PGR universels.
### SDK Android et compatibilité produit
Les modules exercent :
```text
compileSdk 36
targetSdk 36
minSdk 21
```
`compileSdk`, `targetSdk` et `minSdk` remplissent des responsabilités distinctes dans le corpus. Games ne fournit aucune raison de coupler mécaniquement leur évolution.
Le `minSdk 21` est lié au contrat produit/toolchain de Games, notamment au support SDL3 retenu. Sa preuve historique inclut l'installation et le démarrage de Snake sur un AVD Android 5.0/API 21 x86.
Ces valeurs ne sont donc pas copiées comme defaults PGR ; elles servent à éprouver la nécessité de justifier les niveaux selon build, distribution, dépendances et compatibilité utilisateur.
### NDK, ABI, JNI et frontière native
Games exerce réellement un pipeline natif Rust/SDL3 :
```text
NDK 28.2.13676358 / r28c
cargo-ndk build Rust Android
JNI bridge Java/Rust spécifique Games
SDL3 AAR externe non vendorizé
```
Les applications déclarent quatre ABI :
```text
arm64-v8a
armeabi-v7a
x86_64
x86
```
Les preuves historiques montrent le build et le packaging des quatre ABI, mais cette liste répond au produit Games et à sa toolchain Rust/SDL3. PGR ne doit pas en déduire une liste universelle d'ABI Android.
La responsabilité Android générique porte sur la déclaration et la preuve des ABI supportées lorsqu'un projet possède du natif. Les détails JNI, `cargo ndk`, extraction SDL3, noms de bibliothèques, features Rust et staging généré restent des responsabilités de spécialisation ou du produit tant qu'aucun owner séparé n'est justifié.
### Manifests, resources, namespaces et identités applicatives
Les deux applications possèdent chacune :
```text
src/main/AndroidManifest.xml
src/main/res/values/strings.xml
namespace
applicationId
```
Les manifests déclarent les Activities launcher réellement utilisées et aucune permission Android additionnelle n'est observée dans ces deux fichiers.
Les `namespace` et `applicationId` sont propres à chaque application. Leur forme concrète `com.sasedev.games.*`, les Activities et les labels appartiennent au produit Games ; la séparation de responsabilité entre namespace de code, identité applicative, manifest et resources est en revanche réutilisable.
### Version applicative
Les deux applications Games utilisent actuellement :
```text
versionCode 2
versionName 0.2.0
```
alors que le workspace global vaut `0.3.6`.
Cette différence est légitime dans ce corpus : les applications Android ont leur propre identité de version produit. Elle confirme le caractère conditionnel de la règle PGR actuelle qui ne synchronise `VERSION` et `versionName` que lorsque l'application appartient réellement au même release train.
`versionCode` reste un compteur Android distinct dont la monotonie appartient à l'application publiée concernée.
### Configuration locale, outputs et signing
`Android/.gitignore` exclut explicitement :
```text
.gradle/
**/build/
local.properties
libs/*.aar
**/src/main/jniLibs/
```
La baseline ne versionne ni `local.properties`, ni keystore, ni credentials de signing. Les AAR SDL3 sont également exclus et apportés localement.
Les builds `bundleRelease` historiques ne nécessitent aucun secret versionné ; sans configuration de signature externe ils produisent des AAB de validation qui ne sont pas présentés comme artefacts directement publiables sur un store.
Cette pratique corrobore la séparation entre configuration partagée, état machine local, outputs générés, dépendances locales non vendorizées et secrets de release.
### Packaging APK / AAB et preuves runtime
Les histories `0.3.3` fournissent des preuves opérateur successives :
- APK Debug Snake puis Snake/Reflex construits et inspectés ;
- AAB Release Snake/Reflex produits ;
- contenu natif vérifié sous `lib/<abi>/` dans les APK et `base/lib/<abi>/` dans les AAB ;
- installation et démarrage sur AVD x86_64 ;
- installation et démarrage sur appareil ARM64 réel ;
- preuve API 21/x86 pour le minimum supporté ;
- preuve Android 15/API 35 x86_64 avec `PAGE_SIZE=16384` ;
- répétition large en beta puis RC après stabilisation.
Ces preuves montrent qu'un build natif ou une cross-compilation ne suffit pas à prouver à lui seul le package final ou le comportement runtime.
### Contrainte 16 KB observée
Games a vérifié pour ses bibliothèques natives 64 bits `arm64-v8a` et `x86_64` des segments ELF `LOAD` alignés au moins à `2**14`, puis un `zipalign -P 16` réussi sur les APK. Un AVD `ps16k` a fourni une preuve runtime avec `getconf PAGE_SIZE=16384`.
Cette preuve est importante, mais elle reste liée à un besoin de distribution Android réel et à la présence de bibliothèques natives. `0.1.3` doit vérifier la forme générique et actuelle de cette exigence auprès des sources Android officielles avant d'en faire une règle normative PGR. Elle ne doit pas devenir une gate universelle pour un projet Android sans code natif ou sans canal de distribution concerné.
## Classification initiale des décisions Games
La classification initiale guide la réévaluation ; elle n'est pas une adoption de Games.
| Observation ou décision | Classification | Traitement prévu |
|---------------------------------------------------------------------------------|----------------|-------------------------------------------------------------------------------------------------------------------------------------------------|
| Dépôt multi-plateforme avec zone Android distincte | `ADOPT` | conserver un contrat conditionnel : racine Android dédiée lorsque l'architecture en a réellement besoin, sans l'imposer à un dépôt Android-only |
| Composition Android + Gradle + Java seulement lorsqu'applicables | `ADOPT` | maintenir la composition explicite `600 + 610 + 522 [+ 520]` |
| Matrice AGP / Gradle / JDK explicitement compatible | `ADOPT` | conserver le principe et vérifier que la contrainte choisie reste la moins restrictive réellement démontrée |
| Séparation JDK de build / niveau Java | `ADOPT` | réutiliser les owners `520/522`, sans copier les versions Games |
| Distinction `compileSdk` / `targetSdk` / `minSdk` | `ADOPT` | conserver trois contrats séparés et justifier leurs changements selon leur responsabilité |
| `VERSION` distinct du `versionName` de produits indépendants | `ADOPT` | conserver la synchronisation uniquement lorsqu'un même release train la justifie |
| État local, outputs Gradle et secrets hors Git | `ADOPT` | consolider `local.properties`, caches, build outputs et signing au bon owner |
| ABI déclarées et prouvées lorsqu'il existe du code natif | `ADOPT` | garder le contrat conditionnel sans liste universelle |
| APK/AAB, install et smoke sélectionnés selon le risque | `ADOPT` | intégrer à la validation Android proportionnée, sans full matrix systématique |
| Chemin exact `Android/` de Games | `KEEP-LOCAL` | preuve d'un layout multi-plateforme valide, pas layout obligatoire de tout dépôt Android |
| Groovy DSL | `KEEP-LOCAL` | `522-GRADLE.md` reste neutre Groovy/Kotlin DSL |
| Gradle système `>= 9.6.0` sans Wrapper | `KEEP-LOCAL` | choix Games compatible avec `522`; ne pas interdire ni imposer le Wrapper |
| AGP `9.4.0`, Gradle `9.7.1`, JDK `25.0.4.1`, Java `17` | `KEEP-LOCAL` | valeurs de preuve, jamais minima PGR génériques |
| SDK `36/36/21`, NDK `r28c`, SDL3 `3.4.16` | `KEEP-LOCAL` | contraintes Games/framework/produit |
| Quatre ABI et cibles Rust correspondantes | `KEEP-LOCAL` | matrice produit/toolchain, pas contrat Android universel |
| `cargo ndk`, bridge JNI, extraction SDL3 et staging `jniLibs` | `KEEP-LOCAL` | spécialisation Rust/SDL/JNI hors du profil Android général |
| Modules `common` / `game-*`, Activities, labels et assets | `KEEP-LOCAL` | architecture produit Games |
| Exemple PGR de layout contenant systématiquement `gradlew*` | `OVERRIDE` | réviser l'exemple pour ne pas présenter le Wrapper comme élément structurel obligatoire |
| Formulation PGR poussant `minSdk` « aussi bas que raisonnablement supportable » | `OVERRIDE` | réexaminer vers un choix de compatibilité produit explicitement justifié, sans préférence artificielle vers le minimum le plus bas |
| Détail normatif 16 KB / page size | `DEFER` | vérifier les exigences Android/distribution officielles courantes avant normalisation ciblée |
| Création d'un owner JNI/Rust Android | `DEFER` | aucun owner nouveau sans besoin générique démontré ; Games reste un corpus spécialisé |
| Skeleton ou contrat de validation Android dédié | `DEFER` | décider seulement après révision de `610` et analyse des lacunes restantes |
| Skeleton Tauri | `DEFER` | réservé à `0.1.4` |
| Adoption réelle de Games | `DEFER` | réservée à `0.1.5` |
## Décision après `alpha.1`
La gate opérateur de `alpha.1` est `PASS`. Les `48/48` tests Python, les trois audits Markdown, l'audit structurel de la tranche et les contrôles Git sont propres ; aucun `alpha.1.fix.N` n'est requis.
`alpha.2` peut donc appliquer les décisions déjà classifiées `ADOPT` / `OVERRIDE` pour les contrats Android de base, sans ouvrir le natif, le packaging de distribution ou les smokes réservés à `alpha.3`.
### Vérification Android officielle courante pour `alpha.2`
La documentation Android officielle courante a été vérifiée le `2026-09-28` sur les responsabilités touchées par cette tranche :
```text
https://developer.android.com/build/releases/agp-9-4-0-release-notes
https://developer.android.com/build
https://developer.android.com/build/jdks
https://developer.android.com/build/configure-app-module
https://developer.android.com/studio/publish/app-signing
```
Cette vérification confirme notamment :
- AGP possède une matrice de compatibilité explicite avec Gradle et le JDK de build ; AGP `9.4.0` requiert actuellement au minimum Gradle `9.6.0` et JDK `17`, ce qui confirme la cohérence du corpus Games sans transformer ces valeurs en minima PGR ;
- le JDK qui exécute Gradle/AGP est distinct du niveau de langage ou bytecode du code Java ; cette séparation reste nécessaire même lorsqu'un projet Android ne contient aucun source Java ;
- `compileSdk`, `targetSdk` et `minSdk` ont des responsabilités distinctes : APIs disponibles à la compilation, comportements/runtime ciblés et plus ancien niveau Android réellement supporté ;
- `namespace` et `applicationId` sont deux propriétés distinctes ; les garder identiques est le cas courant, mais leur divergence peut être volontaire et doit rester explicite ;
- `local.properties` est réservé aux propriétés locales de l'environnement Android/AGP et doit rester hors du contrôle de version ; des propriétés locales propres au projet doivent utiliser un mécanisme séparé ;
- les clés et mots de passe de signing sont des secrets ; le debug keystore généré par les outils reste un état local et ne constitue pas une identité de release à versionner.
La vérification 16 KB n'est pas absorbée ici : elle reste explicitement réservée à `alpha.3`, avec sa propre confrontation aux exigences de distribution officielles courantes.
### Scope arrêté pour `alpha.2`
La tranche révise uniquement `610-ANDROID.md` pour :
1. retirer du layout d'exemple toute présentation implicite du Wrapper comme élément obligatoire ;
2. rendre Android neutre quant au langage applicatif et composer `520-JAVA.md` seulement lorsque du Java est réellement présent ;
3. séparer clairement JDK de build AGP/Gradle et niveau Java du code ;
4. reformuler `minSdk` comme contrat produit explicite, sans objectif artificiel de valeur la plus basse ;
5. expliciter la séparation `namespace` / `applicationId` ;
6. consolider le rôle de `local.properties`, des propriétés partagées et du signing sans recopier les owners généraux.
Aucun template, skeleton, audit Python ou contrat `docs/validation/` n'est créé par cette tranche.
## Décision après `alpha.2`
La gate opérateur de `alpha.2` est `PASS`. Les `48/48` tests Python, les trois audits Markdown, l'audit Android de base et les contrôles Git sont propres ; aucun `alpha.2.fix.N` n'est requis.
`alpha.3` peut donc traiter le natif, le packaging, la distribution et la validation Android sans rouvrir les contrats de base validés en `alpha.2`.
### Vérification Android officielle courante pour `alpha.3`
La documentation Android officielle courante a été vérifiée le `2026-09-28` sur les responsabilités touchées par cette tranche :
```text
https://developer.android.com/guide/practices/page-sizes
https://developer.android.com/ndk/guides/abis
https://developer.android.com/studio/write/lint
https://developer.android.com/studio/test/command-line
https://developer.android.com/build/building-cmdline
https://developer.android.com/google/play/requirements/target-sdk
```
Cette vérification confirme notamment :
- les politiques de distribution sont évolutives : depuis le `2026-08-31`, Google Play demande pour les applications Android ordinaires nouvelles ou mises à jour un `targetSdk` Android 16 / API `36` ou supérieur, mais cette valeur appartient au canal Play courant et ne devient pas un default PGR universel ;
- Android 15 introduit les devices configurés avec pages mémoire `16 KB` ; une application composée uniquement de code Java/Kotlin est déjà compatible du point de vue de l'alignement natif, tandis que toute bibliothèque native directe ou transitive impose de vérifier le package réellement livré ;
- pour Google Play, les applications ciblant Android 15 / API `35` ou supérieur doivent supporter les pages `16 KB` sur les appareils 64 bits ; la documentation courante annonce qu'à partir du `2027-02-01`, les mises à jour non compatibles ne pourront plus être publiées ;
- pour une application native concernée, la preuve officielle couvre les segments ELF des bibliothèques 64 bits, l'alignement ZIP de l'APK et, pour un AAB, la configuration d'alignement du bundle ; les dépendances natives précompilées font partie du même contrat ;
- AGP `8.5.1+` et NDK `r28+` rendent aujourd'hui le chemin 16 KB standard plus direct, mais PGR n'en déduit pas de minimum global : le projet doit choisir une toolchain compatible avec ses contraintes et prouver l'artefact final ;
- Android Lint n'est pas exécuté automatiquement par un build ordinaire : lorsqu'il est applicable, il doit être appelé explicitement sur le module/variant pertinent ;
- les tests JVM locaux et les tests instrumentés constituent des niveaux distincts ; l'instrumentation s'exécute sur device/émulateur et ne remplace pas à elle seule l'installation/smoke d'un package final lorsque le packaging ou le runtime sont dans le scope ;
- l'APK reste l'artefact installable adapté aux smokes directs, tandis que l'AAB est un artefact de distribution qui entraîne la génération d'APK par le canal ; un AAB seul ne constitue donc pas une preuve runtime.
La preuve Games `PAGE_SIZE=16384`, `align 2**14` et `zipalign -P 16` est cohérente avec ces exigences actuelles. Elle reste une preuve historique du corpus et n'est pas rejouée dans PGR, qui ne possède aucun build Android exécutable.
### Scope arrêté pour `alpha.3`
La tranche révise uniquement `610-ANDROID.md` pour :
1. rendre NDK et ABI strictement conditionnels à la présence de code natif et séparer sélection de toolchain, ABI déclarées et preuve du package ;
2. inclure les bibliothèques natives précompilées ou transitives dans les preuves de compatibilité ;
3. clarifier le rôle d'Android Lint comme gate explicite et ciblée, non implicite au build ;
4. préciser la frontière entre tests JVM, tests instrumentés et smokes device/AVD ;
5. distinguer APK installable et AAB de distribution sans imposer un full packaging à chaque tranche ;
6. normaliser le contrat 16 KB de manière conditionnelle au code natif et au canal de distribution, avec revalidation obligatoire des politiques évolutives ;
7. conserver les détails JNI, Rust, SDL3, `cargo ndk`, les quatre ABI Games et les commandes spécifiques Games hors du profil Android général.
Aucun owner JNI/Rust/SDL, skeleton Android, audit Python ou contrat `docs/validation/` n'est créé. La décision finale sur l'absence d'artefact supplémentaire reste réservée à `beta.1` après réconciliation.
## Décision après `alpha.3` et réconciliation `beta.1`
La gate opérateur de `alpha.3` est `PASS`. Les `48/48` tests Python, les trois audits Markdown, l'audit Android natif/distribution et les contrôles Git sont propres ; aucun `alpha.3.fix.N` n'est requis.
La réconciliation beta relit le profil Android révisé contre le corpus Games, [`400-VALIDATION.md`](../rules/400-VALIDATION.md), [`520-JAVA.md`](../rules/520-JAVA.md), [`522-GRADLE.md`](../rules/522-GRADLE.md), [`600-PLATFORMS.md`](../rules/600-PLATFORMS.md) et la revue d'horizon. Elle ne rouvre aucun contrat fonctionnel déjà validé en `alpha.2` / `alpha.3`.
### Résolution de la classification initiale
Les décisions `ADOPT` sont couvertes par les owners existants : structure Android conditionnelle, composition de profils, compatibilité AGP/Gradle/JDK, séparation des niveaux SDK, versioning Android, configuration locale/signing, ABI conditionnelles et validation package/runtime proportionnée.
Les décisions `KEEP-LOCAL` restent locales à Games : chemin concret `Android/`, Groovy DSL, Gradle système sans Wrapper, versions AGP/Gradle/JDK/Java, niveaux SDK, NDK `r28c`, quatre ABI, `cargo ndk`, bridge JNI, SDL3, modules, Activities, labels et assets. Aucune de ces valeurs ou stacks n'est devenue un `MUST` Android général.
Les deux `OVERRIDE` initiaux sont résolus par `alpha.2` : l'exemple structurel ne présente plus `gradlew*` comme élément obligatoire et `minSdk` est désormais un contrat produit explicitement justifié plutôt qu'une course vers la valeur la plus basse.
Le `DEFER` 16 KB a été levé en `alpha.3` après vérification des sources Android officielles courantes, sous forme d'un contrat conditionnel au code natif, au package et au canal de distribution ; aucune version d'outil ni échéance datée n'est transformée en default PGR universel.
Les autres `DEFER` restent bornés : aucun owner JNI/Rust Android n'est justifié, Tauri reste réservé à `0.1.4` et l'adoption Games à `0.1.5`.
### Décision finale d'artefacts Android
Aucun artefact technique supplémentaire n'est justifié pour `0.1.3`.
Ne sont donc pas ajoutés :
```text
docs/validation/006-ANDROID_VALIDATION.md
skeleton Android
template de build Android générique
audit Python Android
owner JNI / Rust Android / SDL
```
La raison est positive et vérifiable :
- `400-VALIDATION.md` possède déjà la sélection proportionnée des preuves, les catégories `LINT`, `TEST`, `PACKAGE` et `SMOKE`, ainsi que l'autorité du gate opérateur ;
- `600-PLATFORMS.md` possède la composition et la validation spécialisées des plateformes sans rendre chaque smoke obligatoire ;
- `520-JAVA.md` et `522-GRADLE.md` restent composés uniquement lorsqu'ils sont applicables et évitent de recopier leurs contrats dans Android ;
- `610-ANDROID.md` possède désormais les responsabilités spécifiques de SDK, identité applicative, signing, NDK/ABI, Android Lint, niveaux de tests, packaging APK/AAB, distribution et 16 KB ;
- PGR ne contient aucun build Android exécutable qui justifierait aujourd'hui un skeleton, template ou audit spécialisé supplémentaire.
Créer un artefact seulement pour refléter la structure de Games ou pour dupliquer `400 + 610` augmenterait la maintenance sans apporter de nouvelle preuve. Si un futur corpus démontre une lacune réutilisable, elle devra être traitée dans une tranche qui possède réellement ce scope.
### Frontières après réconciliation
La beta confirme donc :
```text
Android générique 600 + 610
Gradle si utilisé + 522
Java si présent + 520
validation générale 400
JNI / Rust / SDL hors 610
Tauri 0.1.4
adoption Games 0.1.5
```
La prochaine tranche peut être `rc.1` si la gate opérateur de `beta.1` confirme cette réconciliation. La RC devra geler le scope Android et préparer le prompt de reprise `0.1.4` sans commencer le réexamen Tauri.
## Réévaluation initiale de `610-ANDROID.md`
Le profil courant contient déjà une part importante des contrats démontrés par Games : structure conditionnelle, matrice AGP/Gradle/JDK, niveaux SDK séparés, version Android, configuration locale, signing, modules, dépendances, ABI conditionnelles, niveaux de tests, validation proportionnée, manifests/resources et artefacts APK/AAB.
`0.1.3` ne doit donc pas réécrire ce profil pour produire du volume. La révision doit se concentrer sur les écarts réellement démontrés :
1. rendre les exemples de structure neutres vis-à-vis du choix Wrapper/système déjà possédé par `522-GRADLE.md` ;
2. confirmer qu'Android reste neutre quant au langage applicatif et n'active `520-JAVA.md` que lorsque Java est réellement présent ;
3. rendre la politique `minSdk` explicitement orientée contrat produit/compatibilité plutôt que « minimum le plus bas » comme objectif en soi ;
4. clarifier ownership Android versus build tool pour AGP, Gradle, JDK et propriétés locales ;
5. mieux séparer NDK/ABI/package Android des détails JNI/Rust/SDL spécifiques ;
6. intégrer uniquement les contraintes de distribution modernes réellement vérifiées et applicables, notamment 16 KB si les sources officielles courantes le justifient ;
7. déterminer si le profil suffit à exprimer la validation Android ou si un contrat `docs/validation/` apporte une réduction réelle de duplication.
## Mission de `0.1.3`
La release doit produire un profil Android pratiquement éprouvé contre Games tout en restant utilisable par un projet Android qui ne ressemble pas à Games.
Elle MUST :
- conserver Android comme spécialisation de `600-PLATFORMS.md` ;
- composer explicitement `522-GRADLE.md` et `520-JAVA.md` uniquement lorsqu'ils sont réellement applicables ;
- distinguer build tool, SDK Android, compatibilité utilisateur et contraintes de distribution ;
- traiter NDK et ABI uniquement pour les projets natifs ;
- séparer les responsabilités Android des détails JNI, Rust, SDL, Tauri et produit ;
- conserver manifests, resources, application identity, configuration locale, signing, packaging et validation chez le bon owner ;
- sélectionner Android Lint, tests, package, install et smokes proportionnellement au changement ;
- vérifier toute contrainte de distribution évolutive contre une source Android officielle courante avant de la figer dans PGR ;
- ne créer un template, skeleton, audit ou contrat de validation supplémentaire que s'il matérialise un contrat réutilisable absent et démontré.
Elle MUST NOT :
- modifier ou adopter Games ;
- transformer SDL3, `cargo ndk`, les Activities Games ou leur architecture produit en règles Android générales ;
- rouvrir Java/Maven/Gradle `0.1.2` sans défaut transversal démontré ;
- réexaminer ou créer le skeleton Tauri avant `0.1.4` ;
- absorber les contraintes Tauri Android dans `610` sans preuve indépendante ;
- démarrer l'adoption Games `0.1.5` ;
- créer un owner WASM, serveur Rust, JNI ou deployment par proximité ;
- réserver une release au-delà de `0.1.7` sans nouvelle revue d'horizon justifiée.
## Artefacts candidats
Owner normatif principal :
```text
docs/rules/610-ANDROID.md
```
Artefacts à décider, non promis par le plan :
```text
docs/validation/006-ANDROID_VALIDATION.md seulement si 400 + 610 ne suffisent pas à éviter une duplication réelle
docs/skeletons/... aucun skeleton Android par défaut
scripts/audit_*.py aucun audit Android par symétrie
templates/android/... aucun template de build sans sujet générique réellement éprouvé
```
Un skeleton Android n'est pas justifié par le seul fait que Games possède un projet Android. Il ne devient candidat que si la révision révèle un ensemble minimal, stable et réutilisable de décisions qu'un projet nouveau ne peut pas simplement obtenir des outils Android officiels et des owners PGR existants.
## Trajectoire prévisionnelle de `0.1.3`
### alpha.1 — audit de stable, corpus et plan
Vérifier `v0.1.2`, son rapport `publish.001`, le corpus Games, ses preuves Android historiques, les owners `520`, `522`, `600`, `610` et la revue d'horizon. Créer le présent plan et la classification initiale sans modifier encore `610-ANDROID.md`.
### alpha.2 — structure, composition et contrats Android de base
Réviser `610-ANDROID.md` sur les points démontrés par le corpus : structure Android-only versus multi-plateforme, composition avec Gradle/Java, matrice AGP/Gradle/JDK sans duplication de `522`, responsabilités `compileSdk`/`targetSdk`/`minSdk`, versioning Android, namespaces/application IDs, manifests/resources, configuration locale et signing.
Les valeurs exactes Games restent des exemples de preuve, pas des defaults PGR.
### alpha.3 — natif, packaging, distribution et validation
Réviser les responsabilités conditionnelles NDK/ABI/native packaging, APK/AAB, Android Lint, tests JVM/instrumentés, install/smoke device/AVD et contraintes de distribution applicables.
Avant toute règle évolutive telle que 16 KB, confronter la preuve Games à la documentation Android officielle courante et rédiger le contrat de manière conditionnelle au canal de distribution et au type d'artefact réellement concernés.
Ne pas créer d'owner JNI/Rust/SDL. Si un contrat de validation séparé apparaît réellement nécessaire, déclencher un REPLAN avant la beta plutôt que l'ajouter opportunément.
### beta.1 — réconciliation et décision d'artefacts
Relire le profil Android révisé contre Games, `520-JAVA.md`, `522-GRADLE.md`, `600-PLATFORMS.md`, `400-VALIDATION.md` et la revue d'horizon.
Vérifier qu'aucun choix Games n'est devenu un `MUST` général, que les contraintes natives restent conditionnelles, et que le futur réexamen Tauri dispose d'une frontière Android stable sans avoir été commencé.
Décider explicitement qu'aucun artefact supplémentaire n'est nécessaire si `610` et les owners existants suffisent. Un artefact nouveau qui exigerait du contenu fonctionnel supplémentaire entraîne un REPLAN vers une tranche alpha dédiée.
Statut opérateur : **PASS**.
La gate beta confirme `48/48` tests Python, les trois audits Markdown, la réconciliation des owners et l'absence d'artefact Android supplémentaire justifié. Aucun fix ni REPLAN n'est requis.
### rc.1 — release candidate
Statut opérateur : **PASS**.
La gate RC a confirmé les quatre histories antérieurs `PASS`, le profil Android gelé en révision `5`, le changelog candidat, le prompt `010`, les `48/48` tests, les trois audits Markdown et l'hygiène texte/templates. Aucun owner Android/Java/Gradle/Tauri, template, skeleton, validation, étude technique ou script n'a été modifié pendant la RC.
Le prompt `010-V0_1_4_START_PROMPT.md` conserve la frontière de release : le réexamen Tauri démarre en `0.1.4` seulement depuis une stable `v0.1.3` réellement taggée et son rapport post-tag `PASS`; l'adoption Games reste `0.1.5` et l'adoption KSP `0.1.6`.
### rel.1 — promotion stable
Première clôture stable de `0.1.3`. La promotion est strictement mécanique : `VERSION = 0.1.3`, `ROADMAP.md` marque `0.1.3` terminée, le `CHANGELOG` perd son marqueur `candidate`, README/index décrivent la réévaluation Android comme stable et le présent plan devient historique. Aucun owner Android/Java/Gradle/Tauri, template, skeleton, validation, étude technique ou script n'est modifié.
Le résultat opérateur de cette tranche appartient à `history/0.1.3/rel.1.md`, créé seulement après exécution de la gate. Si `rel.1` échoue, son history est conservé et un `rel.1.fix.N` corrige uniquement la fermeture ; la première tranche qui établit réellement la stable est incluse dans le commit `0.1.3` avant le tag `v0.1.3`.
La vérification post-tag reste séparée : `pgr-0.1.3-publish.001-report.md` ne peut être produit qu'à partir de l'archive du tag réellement publiée et des preuves Git observées. Le prompt `010` ne devient le point de départ effectif de `0.1.4` qu'après cette preuve post-tag `PASS`.
## Stratégie de validation
`alpha.1` reste documentaire et structurel : tests Python PGR, audits Markdown, contrôle des couples delta/history, vérification du prompt `009`, des owners `520/522/600/610`, du plan et du scope Git.
PGR lui-même ne contient aucun projet Android exécutable. Une modification de `610-ANDROID.md` ne doit donc pas simuler un build AGP/Gradle/SDK absent du dépôt PGR.
Les preuves Games historiques servent à démontrer des responsabilités et des frontières ; elles ne deviennent pas une gate PGR locale et ne doivent pas être présentées comme si les APK/AAB avaient été reconstruits pendant `0.1.3`.
Lorsqu'une propriété relève d'un build Android réel, les outils officiels restent autoritaires : Gradle/AGP, Android Lint, SDK/NDK, outils de packaging, installation et device/AVD selon le contrat à prouver. Un audit Python read-only ne remplace aucun de ces outils.
La validation reste proportionnée : pas de `clean` systématique, pas de full matrix ABI/device pour un changement documentaire, pas de signing release pour une tranche qui ne valide pas la distribution signée.
## Déclencheurs de REPLAN
Un REPLAN est requis notamment si :
- la révision montre qu'une responsabilité aujourd'hui dans `610` appartient en réalité à un owner séparé nécessaire immédiatement ;
- un contrat de validation Android séparé apporte une valeur concrète que `400 + 610` ne peuvent pas exprimer sans duplication ;
- un skeleton Android réellement réutilisable devient nécessaire et peut être démontré sans copier Games ;
- une contrainte supposée Android générale dépend en réalité de SDL, Rust, JNI, Tauri ou d'un canal de distribution particulier ;
- une exigence Android officielle courante contredit une règle `610` existante ;
- la release ne peut pas rester bornée sans absorber le scope Tauri `0.1.4` ou l'adoption Games `0.1.5`.
Un REPLAN ne sert pas à ajouter des artefacts pour remplir la release ; il corrige le découpage lorsqu'une responsabilité réelle l'exige.
## Clôture et transition
La roadmap possède déjà un horizon suffisant jusqu'à `0.1.7`. Aucune nouvelle release n'est réservée par `0.1.3-alpha.1`.
Le présent document devient le plan historique de la stable `0.1.3`. La publication du tag et sa vérification post-tag restent séparées de cette clôture pré-tag.
La prochaine release après publication vérifiée de `0.1.3` reste :
```text
0.1.4 — domaine Tauri : réexamen du DEFER et matérialisation du skeleton contrôlé seulement si les conditions de sortie sont réellement satisfaites
```
L'adoption réelle de Games reste ensuite réservée à `0.1.5`, afin qu'elle puisse comparer son état local avec une stable Android et une stable Tauri réellement publiées.

View File

@@ -0,0 +1,433 @@
<!-- file: docs/plans/010-V0_1_4_TAURI_REEVALUATION_PLAN.md -->
<!-- version: 6 -->
# Plan 0.1.4 — réexamen Tauri et skeleton contrôlé
## Statut et sources
Plan historique de la stable `0.1.4`, créé pendant `0.1.4-alpha.1` conformément à `prompts/010-V0_1_4_START_PROMPT.md`, après audit indépendant de la stable taggée `v0.1.3`, de son rapport post-tag `PASS` et des corpus Games/KSP réellement fournis.
Sources autoritaires de reprise PGR réellement fournies :
```text
pgr-v0.1.3(1).zip f3a7dffd5fe0fd3542e6b5207fda0b94bca2bd05bd5a54542d0a08d635a5d6ee
pgr-0.1.3-publish.001-report.md 5405a1d6c216a5882c4638c07d573d50d440ce9e4e892d97f425e99054245544
```
Le nom local de l'archive PGR comporte `(1)`, mais son SHA-256 correspond exactement à l'archive canonique `pgr-v0.1.3.zip` enregistrée par le rapport `publish.001`. Le rapport est `PASS`, porte sur cette même archive et confirme le commit stable `fe80dbbb737390a7ea99df27d979bd59ccfb86e3`. Le tag annoté `v0.1.3` possède l'objet tag `9b3667f622ab6ef86c1301f8cfa2301b561a0124` et se déréférence vers ce commit stable.
Corpus externes réellement fournis pour instruire Tauri :
```text
games-v0.3.6(3).zip ad6e44a1332eb7d6069cf1189d9433f0fbb8fac19c5aac9f4641ac45c1c556e8
khadhroony-solana-project-v0.3.19(1).zip 64a3813620925fa4f8914cdf74113399cfdd78ad51d60bbeff9bafbddcf4b253
```
Le SHA-256 Games correspond exactement à la baseline canonique `games-v0.3.6.zip` déjà enregistrée par le prompt de reprise. KSP `0.3.19` est plus récent que la référence historique `0.3.17` citée par le prompt ; il est donc le corpus KSP courant de cette session. L'archive KSP fournie ne possède pas de rapport post-tag associé dans les sources de cette reprise : elle est utilisée comme corpus autoritaire fourni, sans lui attribuer de preuve Git absente.
## Audit de la stable `v0.1.3`
### Intégrité et publication
L'archive PGR contient `332` entrées sous une racine unique `pgr/`, soit `290` fichiers et `42` répertoires. Son CRC est propre, aucun lien symbolique n'est présent et `.git` est absent comme attendu pour une archive de tag Gitea.
`VERSION` vaut exactement `0.1.3`. Le rapport post-tag confirme la cohérence de la stable, la présence du prompt `010`, la clôture de `0.1.3` par `rel.1` et le maintien de `0.1.4` à `0.1.7` sans réservation supplémentaire.
### Gates rejouées
La suite Python et les audits documentaires ont été rejoués directement depuis l'archive extraite :
```text
48 / 48 tests PASS
Markdown header audit: clean (264 file(s))
Markdown table audit: clean (11 table(s), 264 file(s))
Markdown link audit: clean (337 local link(s), 264 file(s))
```
La stable fournie est donc une base saine pour ouvrir `0.1.4-alpha.1`.
## Préconditions PGR du réexamen
Le report historique de `docs/studies/002-TAURI_SKELETON_DECISION.md` demandait cinq familles de responsabilités avant tout nouveau jugement sur un skeleton Tauri :
1. TypeScript et conventions Web contrôlées ;
2. Vite et ownership des commandes, du dev server et des outputs ;
3. Sass/CSS et statut des artefacts générés ;
4. validation frontend indépendante de la validation Tauri ;
5. framework CSS classé comme décision de skeleton/projet et non comme règle Tauri.
La préparation effectuée en `0.1.1-beta.1` avait déjà constaté ces cinq conditions couvertes. La relecture de la stable `0.1.3` confirme qu'elles le restent au travers des owners `530/540/550/560`, de `005-WEB_FRONTEND_VALIDATION.md` et de `003-WEB_FRONTEND.md`.
Conclusion `alpha.1` :
```text
conditions historiques de sortie SATISFIED
réexamen du candidat autorisé
création automatique interdite
ancien motif Web du DEFER levé
jugement sur le skeleton à instruire par le corpus courant
```
Le `DEFER` historique n'est donc pas reconduit par inertie. Son motif bloquant Web est levé, mais cette levée ne suffit pas à elle seule à créer le skeleton.
## Audit du corpus Tauri courant
### Intégrité des archives
Les trois archives PGR, Games et KSP sont CRC-propres et ne contiennent aucun lien symbolique.
Games `0.3.6` contient `652` entrées sous `games/`, soit `502` fichiers et `150` répertoires. Ses audits statiques rejoués sont propres :
```text
General Rust rule audit: clean
Rust export completeness audit: 0 candidate(s)
games.sasedev workspace audit: clean
Markdown table audit: clean (6 table(s), 317 file(s))
Distribution layout audit: clean (55 required path(s), 11 forbidden path(s) absent)
```
KSP `0.3.19` contient `2369` entrées sous `khadhroony-solana-project/`, soit `2146` fichiers et `223` répertoires. Ses audits statiques rejoués sont propres :
```text
General Rust rule audit: clean
Rust export completeness audit: 0 candidate(s)
KSP workspace Rust rule audit: clean
Markdown table audit: clean (353 table(s), 1029 file(s))
```
Ces audits attestent la cohérence structurelle des corpus fournis. Ils ne constituent pas une adoption PGR de Games ou KSP.
### Inventaire des hosts actuels
Games `0.3.6` possède désormais un seul host Tauri courant :
```text
crates/apps/game-snake-poc-tauri
```
KSP `0.3.19` possède six hosts Tauri courants :
```text
crates/ksp-app-backfill-desk
crates/ksp-app-config-desk
crates/ksp-app-raw-transaction-ingest-desk
crates/ksp-app-solprices-desk
crates/ksp-app-store-desk
crates/ksp-app-wallet-desk
```
Le corpus courant contient donc `7` hosts, contre `8` dans l'étude historique `0.0.5` : Games est passé de deux hosts observés à un seul. Le réexamen ne doit donc pas recopier mécaniquement l'inventaire historique.
### Convergences structurelles observées
Les sept hosts actuels convergent sur une ossature directe à la racine de la crate :
```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 de ces sept hosts n'utilise `src-tauri/`. Tous sont des crates Cargo mixtes `lib + bin`, utilisent un frontend privé TypeScript/Vite et raccordent le dev/build frontend au host Tauri.
Cette convergence justifie une convention organisationnelle PGR pour les nouveaux projets contrôlés. Elle ne démontre pas que `src-tauri/` serait invalide ou non supporté par Tauri, ni que toute application Tauri existante devrait migrer.
### Divergences significatives
KSP exerce communément Bootstrap, Sass et TS-RS dans ses desks actuels. Games ne les exerce pas comme bloc équivalent dans son host courant et possède en plus une chaîne WASM spécifique au jeu.
Les corpus divergent également sur les plugins, fenêtres, identifiers, ports de dev server, ressources/bundles et détails de capabilities. Le Store Desk KSP possède notamment un contrat de commandes/permissions plus riche que les autres hosts.
Ces divergences empêchent de transformer le bloc historique `frontend/ + Vite + TypeScript + Sass + Bootstrap + TS-RS` en baseline Tauri universelle.
## Vérification officielle Tauri 2 courante
La documentation Tauri 2 officielle a été réexaminée pendant `alpha.1` sur les points susceptibles d'avoir évolué.
Constats retenus :
- la structure documentée par Tauri présente `src-tauri/` comme layout typique/scaffold, tandis que la configuration Tauri et le projet Rust restent les éléments fonctionnels déterminants ; PGR peut donc conserver une convention différente pour ses projets contrôlés sans déclarer le layout standard invalide ;
- les capabilities et permissions sont une frontière de sécurité active ; l'enregistrement d'une commande native et l'autorisation de son appel depuis le frontend ne doivent pas être confondus ;
- lorsque la sélection explicite des capabilities n'est pas configurée, les fichiers de capability du répertoire de capabilities peuvent être activés automatiquement selon la configuration Tauri courante ; un skeleton contrôlé doit donc rendre cette surface visible et revue ;
- le CLI Tauri supporte plusieurs launchers/package managers et possède toujours des commandes de commodité, dont l'ajout de plugins et les workflows mobiles ; PGR n'a aucune raison d'imposer npm ni `cargo tauri add` ;
- les templates mobiles Tauri évoluent avec l'écosystème plateforme ; les versions Gradle/Kotlin/SDK observées dans une release Tauri ne doivent pas devenir des constantes PGR universelles.
Références officielles vérifiées le `2026-09-29` :
- <https://v2.tauri.app/start/project-structure/>
- <https://v2.tauri.app/security/capabilities/>
- <https://v2.tauri.app/security/permissions/>
- <https://v2.tauri.app/reference/cli/>
- <https://v2.tauri.app/blog/tauri-2-12-0/>
## Classification initiale `alpha.1`
### `ADOPT`
Sont retenus pour le candidat organisationnel PGR :
- composition explicite avec `001-PROJECT_GOVERNANCE_FOUNDATION`, `002-RUST_CARGO_WORKSPACE`, `003-WEB_FRONTEND` et `710-TAURI` au lieu de dupliquer leurs règles ;
- host Cargo direct `lib + bin` sans couche `src-tauri/` ajoutée uniquement pour reproduire un scaffold, pour les nouveaux projets que PGR contrôle entièrement ;
- `build.rs`, `tauri.conf.json`, `capabilities/` et `src/tauri.rs` comme surface Tauri visible de cette convention ;
- `frontend/` comme layout recommandé du skeleton contrôlé, sans en faire une obligation Tauri universelle ;
- TypeScript + Vite comme baseline Web recommandée du skeleton lorsque le projet ne possède pas déjà un autre choix frontend motivé ;
- validation frontend indépendante avant preuve d'intégration Tauri lorsque la modification touche les deux surfaces ;
- revue explicite des capabilities, permissions, commandes natives et plugins comme surface de sécurité ;
- ajout manuel/revu des plugins comme voie canonique du skeleton contrôlé, tout en autorisant les commandes de commodité lorsqu'elles apportent une valeur réelle et que leurs modifications sont relues ;
- WASM séparé du host Tauri par défaut ;
- composition des owners Android/iOS applicables pour les cibles mobiles au lieu de transférer ces responsabilités à `710`.
### `KEEP-LOCAL`
Restent des décisions de projet ou de produit :
- ports `devUrl`, identifiers, titres et dimensions de fenêtres ;
- CSP, icônes, bundle targets, resources et chemins spécifiques imposés par un produit ;
- Bootstrap et Sass lorsque réellement utiles ;
- TS-RS uniquement lorsqu'une frontière DTO Rust/TypeScript possédée par le host existe, conformément au profil strict ;
- plugins concrets tels que tracing, filesystem ou autres ;
- chaîne WASM Games et ses scripts ;
- fenêtres auxiliaires, splash screens et ACL spécifiques comme celles exercées par certains desks KSP ;
- versions concrètes Tauri, Vite, TypeScript, Bootstrap, Sass, plugins et toolchains plateforme.
### `OVERRIDE`
Le candidat historique est corrigé sur les points suivants :
- le bloc `frontend/ + Vite + TypeScript + Sass + Bootstrap + TS-RS` n'est plus traité comme une seule baseline indivisible ; seuls les éléments justifiés par le skeleton et les owners applicables sont sélectionnés ;
- l'absence de champ `version` dans des `tauri.conf.json` observés n'annule pas la politique PGR `CANONICAL / MIRROR-EXACT / MIRROR-STABLE` ; la stratégie de version reste explicite ;
- une capability présente dans le dépôt n'est pas considérée comme suffisamment sûre par sa seule existence : sélection, fenêtres/webviews, permissions et commandes doivent être revues comme un contrat de sécurité ;
- l'absence de `src-tauri/` devient une convention organisationnelle des nouvelles baselines PGR contrôlées, pas une règle prétendant que Tauri exige cette absence.
### `DEFER`
Restent différés faute de besoin démontré :
- template technique Tauri copiable contenant `tauri.conf.json`, `build.rs` ou des capabilities génériques ;
- contrat de validation Tauri séparé de `400-VALIDATION.md`, `005-WEB_FRONTEND_VALIDATION.md` et `710-TAURI.md` ;
- framework CSS universel ;
- catalogue de plugins, fenêtres ou permissions par défaut ;
- owner serveur Rust, deployment/operations ou iOS créé par proximité ;
- valeurs Android/Gradle/Kotlin/SDK/ABI dérivées des templates Tauri courants ;
- migration ou adoption de Games/KSP, réservées respectivement à `0.1.5` et `0.1.6`.
## Décision de cadrage `alpha.1`
Le corpus courant démontre une convergence suffisante pour retenir **un skeleton Tauri organisationnel comme candidat à matérialiser pendant `0.1.4`**, sous réserve de la réconciliation normative préalable de `710-TAURI.md` et de l'étude historique.
La décision est donc :
```text
ancien DEFER pour absence d'owners Web LIFT
candidat de skeleton organisationnel ADOPT FOR MATERIALIZATION
création dans alpha.1 NO
normalisation des choix locaux NO
```
`alpha.1` ne crée volontairement pas `docs/skeletons/004-TAURI.md`. La tranche suivante doit d'abord consolider le contrat Tauri actuel, notamment la frontière commandes/capabilities/permissions et la formulation des conventions organisationnelles face aux possibilités officiellement supportées.
## Gate `alpha.1` acquise
La gate opérateur exécutée le `2026-09-29` est `PASS` : `48/48` tests Python, `266` fichiers Markdown propres, `343` liens locaux propres, audit structurel `96` couples antérieurs / `7` hosts Tauri propre et scope Git exactement conforme au delta.
Le history `history/0.1.4/alpha.1.md` enregistre cette preuve. Aucun `alpha.1.fix.N` n'est requis.
## Réconciliation normative préparée en `alpha.2`
La tranche `alpha.2` resserre le profil `710` sur les responsabilités Tauri réellement possédées : host, orchestration, configuration, ACL/capabilities, plugins, intégration frontend et packaging. Elle retire du profil Tauri le choix direct de la stack Web déjà possédée par les owners `530/540/550/560` et par `003-WEB_FRONTEND.md`.
Décisions préparées pour la gate :
```text
710-TAURI.md version 7
002-TAURI_SKELETON_DECISION.md version 3
commande / permission / capability séparées
sélection des capabilities décision de sécurité explicite
src-tauri/ supporté, non imposé
host Cargo direct SHOULD pour nouvelle baseline contrôlée
TypeScript / Vite / Sass / Bootstrap owners Web / skeleton, pas owner Tauri
TS-RS conditionnel à la frontière typée réelle
template Tauri DEFER
validation Tauri séparée DEFER
004-TAURI.md toujours absent pendant alpha.2
```
La décision historique `DEFER` de `0.0.5-alpha.9` reste conservée comme preuve historique, mais son motif Web est levé. L'étude révisée autorise donc `alpha.3` à matérialiser la specification `004-TAURI.md` si la présente gate reste propre.
## Gates `alpha.2` et `alpha.2.fix.1` acquises
`alpha.2` a validé la réconciliation normative Tauri mais a été enregistrée `FAIL` à cause d'une ligne vide surnuméraire à EOF. `alpha.2.fix.1` a corrigé ce défaut et ajouté `PGR-TEXT-HYGIENE-001` ; sa gate opérateur est `PASS` avec `55/55` tests, audit texte propre sur `297` fichiers et audits Markdown propres.
Après cette gate, un défaut distinct de livraison a été identifié : deux archives remises contenaient un répertoire englobant `pgr/` au lieu d'entrées directement relatives à la racine. Le contenu du dépôt validé n'est pas affecté, mais `alpha.3` durcit `210-WORKFLOW.md` afin d'interdire ce packaging et impose au générateur de vérifier la liste des entrées avant remise.
## Matérialisation préparée en `alpha.3`
`alpha.3` matérialise `docs/skeletons/004-TAURI.md` comme specification organisationnelle. Elle compose les skeletons `001/002/003` et l'owner `710`, rend explicites versions, frontend, package manager, capabilities, permissions, plugins, fenêtres, bundles et cibles plateforme, puis définit un ordre d'initialisation et une validation proportionnée.
Aucun template technique Tauri n'est créé : `tauri.conf.json`, les manifests, capability files et sources Tauri restent trop dépendants des décisions du projet pour justifier une baseline copiable universelle à ce stade. Cette décision sera réexaminée en `beta.1` conformément au plan.
## Gate `alpha.3` acquise
La gate opérateur de `alpha.3` est `PASS` : `55/55` tests, audit d'hygiène texte propre sur `300` fichiers, audits Markdown propres, audit structurel du skeleton propre et scope Git conforme. `docs/skeletons/004-TAURI.md` est donc la specification Tauri active pour la suite de `0.1.4`.
Aucun template technique Tauri ni contrat `006-TAURI_VALIDATION.md` n'a été créé. Le contrat ZIP racine est désormais explicite dans `210-WORKFLOW.md`.
## Réconciliation d'artefacts préparée en `beta.1`
Le réexamen de l'ensemble `710 + 004 + 003 + 005` ne met en évidence aucune responsabilité Tauri sans owner :
```text
host / orchestration / ACL / plugins 710-TAURI.md
instanciation et décisions de composition 004-TAURI.md
frontend 003-WEB_FRONTEND.md + owners Web
validation frontend 005-WEB_FRONTEND_VALIDATION.md
validation Rust / plateforme owners correspondants
workflow de gate 400-VALIDATION.md + matrice 001
```
Décisions préparées pour la gate `beta.1` :
```text
004-TAURI.md KEEP
template technique Tauri générique DO NOT CREATE
006-TAURI_VALIDATION.md DO NOT CREATE
catalogue plugins/capabilities DO NOT CREATE
dry-run exécutable d'un faux projet NOT REQUIRED
audit statique de composition REQUIRED
```
Un template technique créerait nécessairement des identifiants, hooks frontend, capabilities, plugins, fenêtres, bundle targets ou valeurs de plateforme arbitraires. Le skeleton possède précisément ces décisions afin de les laisser au projet destinataire.
Un contrat de validation Tauri séparé dupliquerait `710`, `004`, `005` et les owners Rust/plateforme. Une nouvelle famille de validation ne sera justifiée que lorsqu'une preuve Tauri répétitive non correctement possédée par ces documents apparaîtra dans un corpus réel.
Le dry-run exécutable d'un projet factice n'est pas requis pour valider une specification qui ne fournit volontairement aucun scaffold technique. La preuve pertinente en `beta.1` est une vérification statique de composition : références existantes, ownership non dupliqué, décisions visibles, absence de placeholders et absence d'artefacts créés par symétrie.
## Gate `beta.1` acquise
La gate opérateur de `beta.1` est `PASS` : `55/55` tests, audit d’hygiène texte propre sur `302` fichiers, audits Markdown propres, audit structurel d’artefacts propre et scope Git conforme. `004-TAURI.md` est confirmé suffisant ; aucun template technique Tauri, contrat `006-TAURI_VALIDATION.md` ou dry-run factice n’est ajouté.
## Revue d’horizon préparée en `rc.1`
La revue exigée par le point transversal est matérialisée dans `docs/studies/004-V0_1_4_HORIZON_REVIEW.md`. Elle conclut qu’une release de gouvernance/autonomie doit précéder les adoptions Games/KSP afin de ne pas propager une sémantique `SHOULD` ambiguë ni une relation implicite d’upstream avec PGR.
Trajectoire décidée :
```text
0.1.5 sémantique normative + autonomie + frontière PGR/Knowledge
0.1.6 adoption Games
0.1.7 adoption KSP
0.1.8 audits Rust/Clippy read-only
```
La RC ne modifie pas encore les owners normatifs concernés : `RULES.md`, `230-ADOPTION.md`, `400-VALIDATION.md`, le skeleton de fondation et les templates de reprise restent gelés pour `0.1.4`. Le prompt `011` transmet explicitement leur réexamen à `0.1.5-alpha.1`.
## Gate `rc.1` acquise et promotion stable
La gate opérateur de `rc.1` est `PASS` : `55/55` tests, audit d’hygiène texte propre sur `306` fichiers, audits Markdown propres, audit d’intégration RC propre et scope Git conforme. La trajectoire `0.1.5` à `0.1.8` et le prompt `011` sont donc gelés pour la clôture.
`rel.1` effectue uniquement la promotion mécanique vers `0.1.4` : version stable, roadmap terminée, changelog sans marqueur `candidate`, README/index en état stable et présent plan classé historique. Aucun owner Tauri, skeleton, étude technique, audit ou contrat de la future `0.1.5` n’est modifié.
Le history `history/0.1.4/rel.1.md` sera créé uniquement après la gate pré-tag. Après son `PASS`, le commit stable `0.1.4`, le tag annoté `v0.1.4`, l’archive Gitea et le rapport externe `pgr-0.1.4-publish.001-report.md` pourront être produits conformément au workflow.
## Point transversal découvert pendant la gate `alpha.1`
L'utilisation de PGR pour initialiser SaseDev Knowledge a fait apparaître trois questions de gouvernance qui dépassent le domaine Tauri :
1. `SHOULD / SHOULD NOT` doit exprimer une forte recommandation non obligatoire, distincte d'un `MUST`, sans transformer automatiquement son écart en échec de gate ou en `OVERRIDE` ;
2. une adoption/instanciation PGR doit produire un projet autonome dont les sessions suivantes utilisent ses propres règles comme autorité, sans rechercher automatiquement une version PGR plus récente ;
3. lorsque SaseDev Knowledge sera suffisamment fonctionnel, PGR devra pouvoir rester concentré sur les contrats de gouvernance réutilisables tandis que howtos, recettes et snippets pratiques vivent dans Knowledge, sans rendre PGR dépendant de Knowledge pour comprendre une règle.
Ces constats ne constituent pas un défaut du cadrage Tauri `alpha.1` et ne sont donc pas absorbés dans `alpha.2`. Ils MUST être repris dans la revue d'horizon de fermeture de `0.1.4` avant de générer le prompt de la release suivante, afin de décider explicitement si la trajectoire `0.1.5+` doit être réordonnée avant les adoptions Games/KSP.
## Trajectoire de `0.1.4`
### `alpha.1` — intake, audit et décision de cadrage
Objectifs :
- auditer la stable `v0.1.3` et le rapport post-tag `PASS` ;
- auditer les corpus Games/KSP fournis et inventorier leurs hosts Tauri actuels ;
- rejouer les audits statiques disponibles ;
- vérifier les préconditions historiques du report ;
- confronter le corpus à la documentation Tauri 2 courante ;
- classifier `ADOPT / KEEP-LOCAL / OVERRIDE / DEFER` ;
- décider si le skeleton reste un candidat justifié, sans le créer.
Sortie attendue : présent plan et cadrage validé par la gate opérateur.
### `alpha.2` — réconciliation normative Tauri
Réexaminer `docs/rules/710-TAURI.md` et `docs/studies/002-TAURI_SKELETON_DECISION.md` à partir du cadrage validé.
La tranche doit notamment :
- distinguer clairement commande enregistrée, permission et capability ;
- rendre explicite la politique de sélection/revue des capability files ;
- conserver `src-tauri/` comme possibilité supportée et l'absence de `src-tauri/` comme convention organisationnelle PGR contrôlée ;
- maintenir TypeScript/Vite/frontend/Sass/Bootstrap/TS-RS dans leurs owners appropriés ;
- conserver une validation proportionnée plutôt qu'un `tauri build` systématique ;
- ne créer encore aucun template ou owner par symétrie.
### `alpha.3` — skeleton Tauri contrôlé
Si `alpha.2` confirme l'absence de défaut bloquant, créer `docs/skeletons/004-TAURI.md` comme specification organisationnelle composable.
Le skeleton devra :
- composer la fondation, Rust/Cargo, Web et Tauri sans recopier les règles ;
- séparer décisions obligatoires, recommandations de baseline et options ;
- rendre visibles versions, package manager, frontend, capabilities, plugins, fenêtres/bundle et cibles plateforme ;
- définir un ordre d'initialisation et une gate initiale proportionnée ;
- ne créer de template technique supplémentaire que si un besoin non couvert est démontré pendant l'instanciation de la specification.
### `beta.1` — réconciliation et décision d'artefacts
Rejouer le plan contre l'ensemble des artefacts `0.1.4`, rechercher doublons et ownership caché, puis décider explicitement :
- si un template technique Tauri apporte une valeur nette ;
- si un contrat de validation Tauri séparé est nécessaire ;
- si la documentation Tauri et les skeletons existants suffisent ;
- si un dry-run local de la specification est nécessaire et réalisable avec les toolchains présentes.
Par défaut, l'absence de lacune démontrée signifie **ne pas créer** d'artefact supplémentaire.
### `rc.1` — freeze et handoff
Effectuer la gate RC, geler le scope de `0.1.4` et préparer le `CHANGELOG.md` candidate. Avant de générer le prompt de la release suivante, effectuer une revue d'horizon qui traite explicitement le point transversal découvert après `alpha.1`.
Si cette revue confirme la trajectoire existante, le prompt suivant ouvre `0.1.5` pour l'adoption Games. Si elle démontre qu'une release de gouvernance/autonomie doit précéder les adoptions, le roadmap et les numéros suivants sont réordonnés explicitement à ce moment-là plutôt que contournés silencieusement.
### `rel.1` — stable
Promouvoir `0.1.4`, finaliser `README.md`, `ROADMAP.md`, `CHANGELOG.md` et les index concernés, puis suivre le workflow commit stable, tag annoté et rapport post-tag externe.
## Frontières de release
`0.1.4` ne migre ni Games ni KSP et ne modifie pas leurs archives. Les observations de ces corpus servent uniquement à éprouver les abstractions PGR.
La release ne rouvre pas Android `0.1.3` en l'absence de défaut transversal démontré. Les détails générés des projets Android/iOS Tauri restent composés avec leurs owners de plateforme lorsqu'ils sont applicables.
La revue d’horizon de fermeture confirme que le besoin transversal est prioritaire et réordonne explicitement la trajectoire : `0.1.5` gouvernance/autonomie, `0.1.6` Games, `0.1.7` KSP et `0.1.8` audits Rust. Aucun numéro au-delà de `0.1.8` n’est réservé. Le `CHANGELOG.md` candidat et le `ROADMAP.md` sont mis à jour en RC parce qu’ils décrivent désormais une décision de fermeture acquise, pas une hypothèse prématurée.
## Gate de sortie du plan
Le passage de `alpha.1` à `alpha.2` exige :
- intégrité de la baseline PGR et correspondance avec `publish.001 PASS` confirmées ;
- corpus Games/KSP identifiés par leurs SHA-256 réels ;
- inventaire des sept hosts courants vérifié ;
- conditions historiques de sortie explicitement confirmées couvertes ;
- classification `ADOPT / KEEP-LOCAL / OVERRIDE / DEFER` relue ;
- aucune matérialisation prématurée de `004-TAURI.md` ;
- aucune adoption Games/KSP commencée ;
- audits PGR de la tranche propres.
Un `FAIL` sur une de ces propriétés ouvre un `alpha.1.fix.N` ou un REPLAN ; il ne doit pas être absorbé silencieusement par `alpha.2`.

View File

@@ -1,5 +1,5 @@
<!-- file: docs/rules/000-README.md -->
<!-- version: 13 -->
<!-- version: 16 -->
# Index des règles PGR
@@ -14,11 +14,18 @@ Les règles générales actuellement nécessaires restent dans `RULES.md`. La fa
- [`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, 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.
- [`230-ADOPTION.md`](230-ADOPTION.md) — contrat d’adoption PGR pour un dépôt existant, classification `ADOPT / KEEP-LOCAL / OVERRIDE / DEFER` et migration incrémentale.
- [`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.
- [`520-JAVA.md`](520-JAVA.md) — profil Java et règles réutilisables propres au langage.
- [`521-MAVEN.md`](521-MAVEN.md) — spécialisation Maven, applicable uniquement aux projets qui utilisent Maven.
- [`522-GRADLE.md`](522-GRADLE.md) — spécialisation Gradle, applicable uniquement aux projets qui utilisent Gradle.
- [`530-TYPESCRIPT.md`](530-TYPESCRIPT.md) — profil TypeScript, recommandation pour les frontends contrôlés, type-check et frontières typées.
- [`540-JAVASCRIPT_PACKAGE_ECOSYSTEM.md`](540-JAVASCRIPT_PACKAGE_ECOSYSTEM.md) — package manager, `package.json`, dépendances, scripts et responsabilité du lockfile.
- [`550-VITE.md`](550-VITE.md) — profil Vite, build tool/dev server recommandé et ownership de son cache et de ses outputs.
- [`560-CSS_SASS.md`](560-CSS_SASS.md) — profil CSS/Sass, styles sources, prétraitement conditionnel et intégration de dépendances de styles.
- [`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.

View File

@@ -1,5 +1,5 @@
<!-- file: docs/rules/200-GOVERNANCE.md -->
<!-- version: 4 -->
<!-- version: 5 -->
# Governance rules
@@ -77,6 +77,8 @@ vX.Y.Z
`rel.N` MAY identifier une livraison ou un artefact de clôture, mais MUST NOT être traité comme une version produit SemVer.
Pour les nouvelles releases gouvernées par cette convention, `N` commence à `1` et sa représentation canonique n'utilise pas de zéro de padding : `rel.1`, `rel.2`, etc. Les formes historiques déjà publiées telles que `rel.001` restent des snapshots immuables et MUST NOT être renommées rétroactivement.
Avant `1.0.0`, PGR recommande la convention suivante lorsqu'elle correspond au projet :
- `X = 0` indique que le contrat public durable n'est pas encore stabilisé ;
@@ -126,6 +128,16 @@ La promotion stable MUST néanmoins exécuter son propre gate proportionné pour
Le tag stable canonique est `vX.Y.Z`.
La clôture opérationnelle `rel.N[/fix.M]` n'est pas une prerelease SemVer et MAY intervenir alors que `VERSION` porte déjà `X.Y.Z`. En l'absence d'une convention locale explicitement documentée, PGR impose la distinction suivante pour le message du commit de clôture :
```text
rel.1 FAIL / PARTIAL / BLOCKED -> X.Y.Z-rel.1
rel.1.fix.1 FAIL / PARTIAL / BLOCKED -> X.Y.Z-rel.1.fix.1
première tranche de clôture PASS -> X.Y.Z
```
Le commit nommé `X.Y.Z` MUST inclure le history qui établit effectivement le `PASS` stable. Le tag `vX.Y.Z` MUST être créé seulement après ce commit. Une clôture échouée MUST rester identifiable par son nom de tranche et MUST NOT être présentée comme le commit stable final.
La vérification d'une publication ou d'une archive produite après le tag est une preuve distincte de la validation pré-tag.
## Correctifs de tranche

View File

@@ -1,5 +1,5 @@
<!-- file: docs/rules/210-WORKFLOW.md -->
<!-- version: 5 -->
<!-- version: 9 -->
# Workflow artifact rules
@@ -86,6 +86,8 @@ alpha.3.md
alpha.3.fix.1.md
beta.1.md
rc.1.md
rel.1.md
rel.1.fix.1.md
```
Un delta MUST :
@@ -147,6 +149,8 @@ L'archive delta contient uniquement les fichiers à ajouter ou remplacer pour la
L'archive history contient uniquement le ou les fichiers history à appliquer pour clôturer l'état validé, sauf besoin explicitement documenté.
Les entrées des archives delta/history MUST utiliser directement les chemins relatifs à la racine du dépôt. Elles MUST NOT ajouter un répertoire englobant portant le nom du projet, par exemple `pgr/`, lorsque l'application canonique attend `unzip -o <archive> -d .`. Le générateur MUST vérifier la liste des entrées du ZIP avant remise afin qu'un chemin annoncé comme `docs/...`, `history/...` ou `VERSION` soit réellement présent à ce niveau dans l'archive.
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 :
@@ -161,6 +165,16 @@ Les deux archives restent séparées. Cette optimisation de flux n'autorise jama
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.
## Hygiène mécanique des artefacts texte
Les fichiers texte de gouvernance ajoutés ou remplacés MUST être livrés avec des fins de ligne LF, sans whitespace terminal et avec exactement une seule newline finale. Une ligne vide supplémentaire à EOF constitue un défaut de livraison même si le contenu sémantique du document est inchangé.
Avant remise d'un delta ou d'un history, le générateur MUST contrôler cette propriété sur les fichiers texte concernés. Le dépôt PGR fournit `scripts/audit_text_hygiene.py` comme audit read-only monotâche réutilisable ; il contrôle les CR, le whitespace terminal, l'absence de newline finale et les lignes vides terminales surnuméraires.
`git diff --check` et `git diff --cached --check` restent obligatoires lorsqu'ils sont sélectionnés par la gate Git applicable. Ils constituent un filet indépendant et ne remplacent pas l'audit d'hygiène lorsque celui-ci est disponible dans le projet.
Un générateur MUST corriger un défaut mécanique détectable avant livraison plutôt que compter sur la gate opérateur pour le découvrir. Si la gate opérateur détecte malgré tout ce défaut, le résultat réel reste `FAIL` et la correction suit le workflow `.fix.N`.
## Commit de tranche
Le commit d'une tranche doit représenter l'état complet de cette tranche, y compris son history.
@@ -174,9 +188,63 @@ current delta changes
doivent être présents, alors que le delta suivant MUST rester absent.
Le message de commit MAY suivre les conventions du projet. PGR n'impose pas Conventional Commits, GitFlow ou une topologie universelle de branches.
Pour une tranche alpha, beta, RC ou autre tranche qui n'établit pas la stable, le message de commit MAY suivre les conventions du projet tant que l'état et la tranche restent identifiables. PGR n'impose pas Conventional Commits, GitFlow ou une topologie universelle de branches.
L'important est que l'état et la tranche restent identifiables et que le repository ne mélange pas deux tranches non clôturées.
La clôture stable `rel.N[/fix.M]` possède une règle plus stricte afin de distinguer une tentative de fermeture de l'identité stable réellement obtenue. En l'absence d'un mapping local explicitement documenté :
```text
history rel.1 FAIL / PARTIAL / BLOCKED
-> commit X.Y.Z-rel.1
history rel.1.fix.1 FAIL / PARTIAL / BLOCKED
-> commit X.Y.Z-rel.1.fix.1
premier history rel.N[/fix.M] PASS qui établit réellement la stable
-> commit X.Y.Z
```
Le suffixe opérationnel n'est donc conservé dans le message du commit que tant que la clôture n'a pas obtenu le `PASS` stable. Le commit `X.Y.Z` MUST contenir le delta de clôture concerné et son history `PASS`; il MUST précéder le tag canonique `vX.Y.Z`.
Un projet qui possède une convention de message différente MAY utiliser un mapping équivalent, mais il MUST conserver sans ambiguïté la distinction entre tentative de clôture échouée et commit stable final.
Le repository ne doit jamais mélanger deux tranches non clôturées dans un même commit.
## Remise automatique des commandes opérateur
Après production d'un history destiné à être appliqué par l'opérateur, le générateur MUST remettre spontanément les commandes nécessaires pour fermer cette tranche. Il ne doit pas attendre une demande séparée du type « je commit avec quel message ? ».
Lorsque les valeurs Git sont établies par le projet ou par les sorties opérateur de la session, le bloc remis MUST utiliser les valeurs réelles : archive history, message de commit, remote et branche. Le générateur MUST NOT inventer un remote, une branche ou une politique de tag non établis. Une valeur encore inconnue doit être signalée explicitement ou résolue par une commande de découverte sûre avant la commande qui en dépend.
Pour une livraison ZIP et une tranche non stable, le handoff couvre normalement dans cet ordre :
```text
apply history archive
↓
git add / staged whitespace check / status
↓
commit avec le message attendu
↓
push de la branche courante
↓
apply du delta suivant ou du fix déjà livré
```
Lorsqu'un history `FAIL`, `PARTIAL` ou `BLOCKED` conduit à un `.fix.N`, le bloc de commandes ferme d'abord la tranche constatée sous son identité propre puis autorise seulement l'application du correctif. Lorsqu'un history `PASS` conduit à la tranche planifiée suivante, le même ordre s'applique.
Pour la première clôture `rel.N[/fix.M]` qui établit réellement la stable, le bloc MUST utiliser le message de commit stable `X.Y.Z`, puis fournir séparément les commandes de tag et de vérification applicables. Le tag MUST NOT être créé avant le commit stable et son push lorsque le projet exige que la branche canonique distante porte d'abord ce commit.
Le handoff de publication MUST également indiquer exactement ce que l'opérateur doit remettre au générateur pour produire la preuve post-tag applicable. Pour une archive source générée par la forge à partir du tag, cela inclut normalement :
- le ZIP téléchargé depuis le tag canonique ;
- le SHA du commit stable local observé avant ou pendant le tag ;
- le commit déréférencé localement par le tag ;
- la référence distante du tag ;
- pour un tag annoté, le commit distant déréférencé `refs/tags/vX.Y.Z^{}` afin de ne pas confondre l'objet tag avec son commit ;
- toute autre preuve explicitement requise par la politique locale de publication.
Le rapport `publish.*` est produit seulement à partir des artefacts et preuves réellement disponibles après publication. Il MUST NOT être prérempli avec un `PASS` futur.
[`../templates/006-OPERATOR_COMMAND_HANDOFF.md`](../templates/006-OPERATOR_COMMAND_HANDOFF.md) fournit le pattern de rendu des blocs de commandes. Il complète le présent contrat sans devenir une seconde source normative.
## Manifest de suppression
@@ -327,9 +395,11 @@ published source archive
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.
Un identifiant opérationnel tel que `rel.1` ou `publish.001` MAY être utilisé pour distinguer une clôture ou une vérification de publication sans devenir une nouvelle version SemVer produit. La famille `rel.N` utilise la représentation sans zéro de padding définie par la gouvernance ; les anciennes formes `rel.001*` déjà publiées restent historiques et immuables.
`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.
`rel.1` est la première tranche de clôture stable pré-tag d'une nouvelle release utilisant cette convention. Si elle échoue, `rel.1.fix.N` corrige uniquement cette fermeture. La première de ces tranches qui obtient réellement `PASS` est incluse dans le commit stable `X.Y.Z`, puis seulement le tag `vX.Y.Z` est créé.
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. La présente règle ne renomme pas `publish.001`; son identité reste indépendante de la correction `rel.001` -> `rel.1`.
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.

127
docs/rules/230-ADOPTION.md Normal file
View File

@@ -0,0 +1,127 @@
<!-- file: docs/rules/230-ADOPTION.md -->
<!-- version: 1 -->
# Existing project adoption rules
## Scope
Ce document définit le contrat transversal d’adoption de PGR par un projet **déjà existant**. Il couvre la reprise d’une baseline réelle, l’inventaire des owners applicables, la comparaison avec les contrats locaux, la classification des décisions d’adoption, la migration progressive, les exceptions et la validation de l’état obtenu.
L’adoption d’un dépôt existant est distincte de l’instanciation d’un nouveau projet par skeleton. Les skeleton specifications restent possédées par [`220-SKELETONS.md`](220-SKELETONS.md) ; l’adoption peut les utiliser comme référence de composition sans prétendre recréer rétroactivement le projet.
Les règles de workflow et de validation restent respectivement possédées par [`210-WORKFLOW.md`](210-WORKFLOW.md) et [`400-VALIDATION.md`](400-VALIDATION.md).
## Principe
PGR s’adapte au besoin réel du projet existant ; il ne cherche pas à effacer l’histoire du dépôt ni à imposer toute la bibliothèque de profils disponible.
Une adoption MUST partir d’une baseline autoritaire réellement observée : commit, tag, archive de release ou autre état explicitement accepté par le projet. Le travail d’adoption MUST distinguer ce qui existe déjà de ce que PGR propose d’ajouter ou de modifier.
Une migration réussie produit un projet autonome gouverné localement. Le projet destinataire ne devient pas dépendant runtime ou build du dépôt PGR.
## Audit initial de la baseline
Avant de modifier le projet, l’adoption MUST établir au minimum :
- la baseline autoritaire et son niveau de confiance ;
- les règles, conventions, outils, fichiers de gouvernance et validations déjà présents ;
- les langages, plateformes, frameworks et autres profils réellement applicables ;
- les contraintes locales qui ne doivent pas être remplacées par une règle générique ;
- les incohérences ou dettes qui nécessitent une décision au lieu d’une conversion automatique.
L’audit SHOULD réutiliser les outils du projet et les audits PGR applicables lorsqu’ils sont disponibles. Il MUST NOT interpréter l’absence d’un artefact PGR comme un défaut en soi tant qu’aucune règle applicable ne l’exige.
## Mapping des owners applicables
L’adoption MUST sélectionner les owners PGR à partir du scope réel du dépôt. Elle MUST NOT activer tous les profils PGR par défaut.
Chaque owner ou contrat candidat à l’adoption doit être comparé avec l’état local avant décision. Un profil non applicable reste hors scope ; une technologie envisagée mais non encore présente MAY rester `DEFER`.
Les owners PGR servent de référence normative pour ce qui est réellement adopté. Les règles propres au projet restent locales et ne deviennent pas automatiquement des règles générales PGR.
## Classification des décisions
Le mapping d’adoption utilise les quatre classifications suivantes :
```text
ADOPT
KEEP-LOCAL
OVERRIDE
DEFER
```
### ADOPT
`ADOPT` signifie que le projet retient le contrat PGR applicable et migre son état local lorsque nécessaire.
L’adoption MAY être immédiate ou découpée en plusieurs tranches si le changement est trop large pour être validé proprement en une fois.
### KEEP-LOCAL
`KEEP-LOCAL` signifie qu’un contrat local existant reste préférable ou nécessaire et qu’il n’entre pas en contradiction avec une obligation PGR réellement adoptée.
Cette classification ne crée pas une exception : elle reconnaît qu’un choix local demeure hors du besoin de normalisation ou qu’un owner PGR ne possède pas ce détail.
### OVERRIDE
`OVERRIDE` signifie qu’une règle PGR applicable est volontairement remplacée ou raffinée dans un scope local.
L’override MUST identifier la règle concernée, le scope, la raison et le contrat local retenu. Il ne doit pas être utilisé pour masquer une migration incomplète ou faire disparaître une violation non résolue.
### DEFER
`DEFER` signifie qu’une décision applicable est volontairement différée parce qu’un prérequis, un owner, une preuve ou une priorité manque encore.
Le report SHOULD indiquer ce qui permettrait de reprendre la décision. `DEFER` MUST NOT être présenté comme une adoption accomplie.
## Migration progressive
L’adoption SHOULD privilégier des tranches cohérentes et validables. Une migration massive n’est justifiée que si elle apporte moins de risque et de coût qu’une progression incrémentale.
Une tranche d’adoption SHOULD :
1. identifier le sous-ensemble de décisions concerné ;
2. modifier uniquement les owners locaux, configurations, templates ou structures nécessaires ;
3. appliquer une validation proportionnée aux contrats réellement modifiés ;
4. enregistrer les décisions durables chez leurs owners locaux ;
5. laisser les domaines non concernés inchangés.
L’adoption d’un profil ne force pas l’adoption simultanée des profils voisins. Par exemple, un dépôt Rust utilisant Tauri peut adopter les règles Rust/Cargo disponibles tout en différant les owners Web encore insuffisants.
## Préservation de l’historique
PGR MUST NOT demander de réécrire des commits, tags, histories, changelogs ou autres snapshots historiques uniquement pour donner l’apparence d’une conformité rétroactive.
Les conventions nouvelles s’appliquent à partir du point d’adoption explicitement établi. Les artefacts historiques restent interprétés selon leur contexte d’origine, sauf correction exceptionnelle justifiée par une erreur factuelle ou un risque réel.
Une adoption MAY documenter des écarts hérités comme dette, exception temporaire ou contexte historique sans modifier les snapshots qui les ont produits.
## Relation avec les skeletons et templates
Un skeleton PGR MAY servir de checklist de comparaison pour un projet existant. Il ne doit pas être appliqué comme si le dépôt était vide.
Lorsqu’un template PGR est pertinent, l’adoption MUST comparer sa responsabilité et ses valeurs avec le fichier local avant remplacement. Un fichier local fonctionnel ne doit pas être écrasé uniquement pour obtenir une copie identique au template PGR.
Une différence locale MAY être conservée si elle relève d’une décision du projet, d’un `KEEP-LOCAL` ou d’un `OVERRIDE` valide.
## Validation de l’adoption
Chaque étape d’adoption MUST sélectionner des preuves proportionnées selon [`400-VALIDATION.md`](400-VALIDATION.md).
La validation SHOULD d’abord prouver que le projet reste fonctionnel dans son environnement réel, puis que les nouveaux contrats de gouvernance ou de structure sont respectés. Un audit PGR read-only ne remplace pas une toolchain ou un smoke autoritaire lorsqu’un contrat appartient à cette toolchain ou à cet environnement.
Une adoption n’est terminée que lorsque les décisions de son scope sont classifiées, les changements retenus sont appliqués, les validations requises sont acquises et les `DEFER` restants sont explicitement hors du scope déclaré.
## Résultat attendu
Une adoption PGR réussie laisse :
- un projet autonome ;
- uniquement les owners PGR réellement applicables ;
- les choix locaux légitimes préservés ;
- les overrides explicites ;
- les domaines différés clairement identifiés ;
- un historique non falsifié ;
- une validation proportionnée au changement réellement effectué.
[`../templates/007-EXISTING_PROJECT_ADOPTION.md`](../templates/007-EXISTING_PROJECT_ADOPTION.md) fournit un pattern documentaire court pour préparer et suivre ce mapping sans imposer un format de migration unique.

200
docs/rules/520-JAVA.md Normal file
View File

@@ -0,0 +1,200 @@
<!-- file: docs/rules/520-JAVA.md -->
<!-- version: 4 -->
# Profil Java
## Rôle
Ce document possède les règles réutilisables propres au langage Java.
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.
Maven et Gradle sont des spécialisations de build distinctes possédées respectivement par [`521-MAVEN.md`](521-MAVEN.md) et [`522-GRADLE.md`](522-GRADLE.md). Un projet Java n'applique que le profil du build tool qu'il utilise réellement.
Android n'est pas défini ici. Une contrainte AGP, SDK Android, `minSdk`, `targetSdk`, `versionCode`, NDK, ABI/JNI, `applicationId`, `namespace`, manifest/resources, signing, packaging APK/AAB, device/AVD ou smoke Android appartient au profil plateforme [`610-ANDROID.md`](610-ANDROID.md) ou à un owner spécialisé et peut raffiner localement les règles Java applicables.
Une compatibilité JDK plus étroite imposée par une plateforme, un framework ou un build tool reste un override de ce scope plus spécifique. Elle MUST NOT être remontée comme minimum Java général uniquement parce qu'un projet l'exerce.
## 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.
Un JDK de build plus récent MAY compiler un projet qui cible un niveau source ou bytecode plus ancien lorsque le build exprime explicitement cette cible et que la toolchain choisie la supporte. Le simple fait qu'une compilation réussisse avec le JDK actif ne constitue pas une déclaration de compatibilité.
Selon le build, ce contrat peut être matérialisé par une option de release, une toolchain, des niveaux source/target ou un mécanisme équivalent. PGR ne généralise pas un mécanisme particulier à tous les builds Java.
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.
## Composition avec les build tools
Un projet Java construit avec Maven compose normalement :
```text
GENERAL
+ 500 languages / ecosystems
+ 520 Java
+ 521 Maven
```
Un projet Java construit avec Gradle compose normalement :
```text
GENERAL
+ 500 languages / ecosystems
+ 520 Java
+ 522 Gradle
```
Une plateforme ou un framework applicable se compose ensuite au-dessus de ces owners. Le choix d'un build tool ne rend pas l'autre profil applicable.

View File

@@ -1,316 +1,24 @@
<!-- file: docs/rules/520-JAVA_MAVEN_GRADLE.md -->
<!-- version: 2 -->
<!-- version: 4 -->
# Profil Java / Maven / Gradle
# Profil Java / Maven / Gradle — superseded
## Rôle
## Statut
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.
`SUPERSEDED` depuis `0.1.2-alpha.3`.
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.
Ce chemin est conservé uniquement afin de ne pas casser les liens contenus dans les plans, prompts, deltas, histories et études historiques qui décrivent fidèlement l'ancien owner combiné.
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.
Il ne constitue plus un profil sélectionnable et ne possède plus de règles normatives courantes.
## Politique JDK et compatibilité Java
Les owners applicables sont désormais :
Pour un projet Java général suivant le profil PGR :
- [`520-JAVA.md`](520-JAVA.md) pour le langage Java ;
- [`521-MAVEN.md`](521-MAVEN.md) pour Maven lorsqu'un projet utilise Maven ;
- [`522-GRADLE.md`](522-GRADLE.md) pour Gradle lorsqu'un projet utilise Gradle.
- 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.
Les contraintes Android restent possédées par [`610-ANDROID.md`](610-ANDROID.md).
PGR MUST distinguer :
## Compatibilité documentaire
```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.
Un document historique qui référence ce chemin conserve ainsi une cible lisible sans être réécrit a posteriori. Pour toute décision nouvelle, les trois owners ci-dessus remplacent l'ancien profil combiné.

84
docs/rules/521-MAVEN.md Normal file
View File

@@ -0,0 +1,84 @@
<!-- file: docs/rules/521-MAVEN.md -->
<!-- version: 1 -->
# Profil Maven
## Rôle
Ce document possède les règles réutilisables propres au build tool Maven.
Il complète [`500-LANGUAGES.md`](500-LANGUAGES.md) et, lorsqu'il construit du code Java, [`520-JAVA.md`](520-JAVA.md). Maven n'est pas une règle implicite de tous les projets Java : ce profil s'applique uniquement lorsqu'un projet utilise réellement Maven.
Les contraintes imposées par une plateforme ou un framework plus spécifique restent possédées par ce scope plus spécifique et MAY raffiner localement le présent profil.
## 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 de langage ou de bytecode lorsqu'il appartient au build concerné ;
- `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 ou vérifiée selon les besoins du projet
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.
## Outputs, état local et Git
Les sorties Maven usuelles sous `target/` ne sont pas versionnées.
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 locaux contenant chemins machine, credentials, secrets 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).
PGR lui-même ne possède actuellement aucun projet Maven exécutable à compiler. Aucune commande Maven n'est donc ajoutée aux gates documentaires de PGR uniquement pour exercer le présent profil.
Aucun audit Maven n'est créé uniquement pour matérialiser un outil. Lorsqu'un skeleton ou projet réel fournira un sujet stable, un audit monotâche MAY vérifier une propriété objectivement structurelle non mieux contrôlée par Maven lui-même, par exemple la cohérence `VERSION`/POM ou un héritage de politique. Il reste read-only et ne lance jamais Maven à la place de ses gates propres.

118
docs/rules/522-GRADLE.md Normal file
View File

@@ -0,0 +1,118 @@
<!-- file: docs/rules/522-GRADLE.md -->
<!-- version: 1 -->
# Profil Gradle
## Rôle
Ce document possède les règles réutilisables propres au build tool Gradle.
Il complète [`500-LANGUAGES.md`](500-LANGUAGES.md) et, lorsqu'il construit du code Java, [`520-JAVA.md`](520-JAVA.md). Gradle n'est pas une règle implicite de tous les projets Java : ce profil s'applique uniquement lorsqu'un projet utilise réellement Gradle.
Android n'est pas défini ici. Toute contrainte propre à la plateforme Android appartient à [`610-ANDROID.md`](610-ANDROID.md) ou à un owner spécialisé et MAY raffiner localement le présent profil.
## Ownership du build
Un projet Gradle SHOULD centraliser la configuration commune lorsqu'elle est réellement partagée, sans déplacer au root une responsabilité qui appartient à un module particulier.
Selon le DSL retenu, les propriétaires naturels sont typiquement :
```text
settings.gradle / settings.gradle.kts
-> composition du build et inclusion des projets
-> politique de résolution des plugins/dépendances lorsqu'elle est réellement globale
-> contraintes de bootstrap ou de version Gradle lorsqu'elles doivent s'appliquer avant la configuration des projets
build.gradle / build.gradle.kts root
-> plugins, versions ou conventions réellement partagés
-> configuration transverse qui ne doit pas être recopiée dans chaque sous-projet
build.gradle / build.gradle.kts de module
-> plugins, dépendances, sources, tâches et paramètres propres au module
gradle.properties partagé
-> propriétés portables, non secrètes et réellement communes au build
```
Cette répartition décrit des responsabilités, pas un layout obligatoire. Un build simple MAY légitimement porter moins de fichiers, et une logique transverse devenue importante MAY être extraite dans un script, build logic ou plugin clairement possédé plutôt que dupliquée.
Les sous-projets SHOULD NOT recopier sans nécessité :
- la compatibilité de langage lorsqu'elle est commune ;
- les repositories ;
- les versions de plugins ;
- les contraintes de dépendances ;
- les configurations de tests communes.
Les chemins machine, credentials, secrets et overrides propres à un développeur MUST NOT être introduits dans un `gradle.properties` partagé. Ils doivent utiliser un mécanisme local approprié, par exemple propriétés utilisateur Gradle, variables d'environnement ou fichier local explicitement ignoré lorsque la toolchain en possède un.
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. Son absence dans un corpus particulier ne constitue pas une règle générale.
Un projet contrôlé MAY utiliser un Gradle système si sa contrainte de compatibilité est **effectivement vérifiée** par le build ou par une gate exécutée par le projet/CI. Une version seulement écrite dans la documentation sans contrôle exécutable n'est pas une preuve suffisante de compatibilité.
La vérification peut être portée par `settings.gradle(.kts)`, par une logique de bootstrap ou par une gate dédiée adaptée au projet. PGR n'impose pas l'API Gradle exacte utilisée pour cette vérification.
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.
Lorsqu'un projet Gradle construit du Java, la déclaration du niveau source/bytecode reste gouvernée par [`520-JAVA.md`](520-JAVA.md). Gradle peut matérialiser ce contrat via ses mécanismes officiels, mais n'en devient pas le propriétaire normatif.
## Outputs, état local et Git
Les caches et sorties Gradle usuels sous `.gradle/` et `build/` ne sont pas versionnés.
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, secrets ou overrides développeur restent hors Git. Cette règle s'applique également aux propriétés Gradle locales : une propriété partagée doit rester portable et non secrète. 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).
PGR lui-même ne possède actuellement aucun projet Gradle exécutable à compiler. Aucune commande Gradle n'est donc ajoutée aux gates documentaires de PGR uniquement pour exercer le présent profil.
De même, aucun audit Gradle n'est créé uniquement pour matérialiser un outil. Lorsqu'un skeleton ou projet réel fournira un sujet stable, un audit monotâche MAY vérifier une propriété objectivement structurelle non mieux contrôlée par Gradle lui-même, par exemple une contrainte de version déclarée. Il reste read-only et ne lance jamais Gradle à la place de ses gates propres.

View File

@@ -0,0 +1,102 @@
<!-- file: docs/rules/530-TYPESCRIPT.md -->
<!-- version: 3 -->
# Profil TypeScript
## Rôle et applicabilité
Ce profil possède les règles réutilisables propres à TypeScript lorsqu'un projet sélectionne TypeScript pour du code frontend ou un autre package JavaScript typé.
Il complète [`500-LANGUAGES.md`](500-LANGUAGES.md). Il ne possède ni le package manager, ni `package.json`, ni le bundler/dev server, ni la chaîne CSS/Sass, ni le host natif ou navigateur.
Le profil s'applique lorsqu'une partie du source contrôlé est écrite en TypeScript ou lorsque la validation du projet inclut explicitement la toolchain TypeScript.
## Recommandation pour les projets contrôlés
Pour un frontend que l'organisation contrôle, TypeScript **SHOULD** être préféré à du JavaScript non typé dès que le frontend porte une logique durable non triviale.
Cette préférence n'est pas une obligation universelle. Du JavaScript direct MAY rester approprié pour un artefact très petit, un script isolé, une contrainte externe ou un environnement où l'introduction de TypeScript n'apporte pas une valeur proportionnée.
La justification de la recommandation est fonctionnelle : TypeScript ajoute une vérification statique avant exécution et permet de détecter une partie des incohérences de types pendant la validation plutôt qu'au runtime.
## Frontières typées avec d'autres écosystèmes
TypeScript facilite également les frontières où des types doivent être partagés avec un autre langage ou runtime.
Lorsqu'un projet Rust expose des DTO, structures ou énumérations destinés au frontend et qu'un générateur de bindings tel que TS-RS est applicable, la génération de déclarations TypeScript depuis la source de vérité Rust SHOULD être préférée à la duplication manuelle des mêmes contrats.
Cette recommandation ne transforme pas TS-RS en dépendance générale de TypeScript. L'owner Rust, le framework ou le sous-système qui possède la frontière décide si cette génération est requise. Le profil Tauri peut notamment renforcer ce contrat dans son propre scope.
## Déclarations de types externes et intégration IDE
Les dépendances TypeScript ne nécessitent pas toutes un package `@types/*` séparé. Avant d'ajouter une déclaration externe, le projet MUST déterminer si le package consommé fournit déjà ses propres fichiers de déclaration TypeScript. Une déclaration déjà fournie par le package ne doit pas être doublée arbitrairement par un package `@types/*`.
Lorsqu'une dépendance utilisée par du code TypeScript ne fournit pas de déclarations suffisantes, le projet **SHOULD** rechercher une source de types maintenue et compatible, typiquement le package `@types/<nom>` publié depuis DefinitelyTyped lorsqu'il existe. Cette dépendance améliore le contrôle statique, la compréhension des API par le language service TypeScript et, par conséquent, les diagnostics, la navigation et la complétion dans les IDE compatibles.
Pour une application privée ou de l'outillage local, les packages de déclarations qui ne sont nécessaires qu'au développement **SHOULD** normalement être placés dans `devDependencies`. Exemples d'applicabilité :
```text
@types/node code, configuration ou outillage TypeScript utilisant réellement des API/globales Node
@types/bootstrap code TypeScript utilisant les API JavaScript Bootstrap lorsque Bootstrap ne fournit pas lui-même les déclarations requises
```
Ces exemples ne sont pas des dépendances PGR universelles. Un frontend navigateur qui n'analyse aucun code Node MUST NOT ajouter `@types/node` uniquement par habitude. Un projet qui ne consomme que le CSS/Sass de Bootstrap n'a pas besoin de `@types/bootstrap` pour cette seule raison.
Lorsqu'un `tsconfig.json` utilise explicitement `compilerOptions.types`, les packages de déclarations globales nécessaires au contexte analysé doivent être sélectionnés de manière cohérente avec cette liste. Les types importés depuis un module restent gouvernés par la résolution de modules applicable.
Pour une bibliothèque publiée, la classification diffère : si les déclarations publiques produites par la bibliothèque référencent un package de types externe requis par les consommateurs, ce package MUST rester disponible à ces consommateurs. Il ne doit donc pas être caché en `devDependencies` par simple convention d'application ; sa classification dans `dependencies`, `peerDependencies` ou une autre relation appropriée doit suivre le contrat de publication réel.
Les versions des déclarations externes SHOULD rester compatibles avec le package runtime concerné et avec la version TypeScript sélectionnée. PGR MUST NOT inventer une version `@types/*` dans un template générique sans dépendance réelle à typer.
## Configuration et validation
`tsconfig.json`, les options de compilation/type-check, les fichiers inclus/exclus et la commande TypeScript canonique appartiennent à ce profil.
Pour un nouveau package TypeScript contrôlé, la baseline PGR `SHOULD` activer au minimum :
```text
strict = true
noEmit = true
```
`strict` exprime la volonté d'utiliser le contrôle de types renforcé de TypeScript. `noEmit` sépare le type-check de la production des artefacts JavaScript lorsque cette production appartient à un bundler ou à un autre outil.
Pour une baseline stricte, PGR `SHOULD` également activer les contrôles simples suivants sauf incompatibilité documentée :
```text
noUnusedLocals = true
noUnusedParameters = true
noFallthroughCasesInSwitch = true
```
Les choix `target`, `module`, `moduleResolution`, `lib`, `types`, `jsx`, chemins/aliases, `include` et `exclude` dépendent du runtime, du bundler, du framework et du layout réel. PGR MUST NOT les figer dans le profil TypeScript générique uniquement parce qu'ils apparaissent dans Games.
Le package `SHOULD` exposer une validation TypeScript indépendante sous un script canonique :
```text
typecheck
```
Lorsque le compilateur local est installé dans le package, le pattern recommandé est :
```text
tsc --noEmit
```
Un build Vite, Tauri ou autre ne remplace pas automatiquement cette preuve ciblée lorsqu'une propriété de typage doit être validée indépendamment.
Le modèle minimal [`../../templates/web-typescript/tsconfig.json`](../../templates/web-typescript/tsconfig.json) active uniquement les options génériques ci-dessus. Le guide [`../templates/008-WEB_TYPESCRIPT_PACKAGE.md`](../templates/008-WEB_TYPESCRIPT_PACKAGE.md) liste les décisions à compléter avant adoption réelle.
## Ce que le profil n'impose pas
Ce profil ne rend obligatoire :
- ni Vite ;
- ni npm ou un autre package manager particulier ;
- ni Sass ou un framework CSS ;
- ni TS-RS pour un projet qui ne partage aucun contrat avec Rust ;
- ni un framework frontend particulier ;
- ni WASM ;
- ni Tauri.
Les choix correspondants restent possédés par leurs owners applicables.

View File

@@ -0,0 +1,78 @@
<!-- file: docs/rules/540-JAVASCRIPT_PACKAGE_ECOSYSTEM.md -->
<!-- version: 3 -->
# Profil écosystème de packages JavaScript
## Rôle et applicabilité
Ce profil possède le contrat réutilisable d'un package JavaScript/TypeScript utilisant un manifest `package.json` et un package manager compatible avec cet écosystème.
Il complète [`500-LANGUAGES.md`](500-LANGUAGES.md) et reste indépendant du choix entre JavaScript et TypeScript, du bundler, du framework frontend, de Sass et du host.
## Package manager
PGR MUST NOT imposer npm uniquement parce qu'il est utilisé par un corpus source.
Le projet MUST sélectionner explicitement le package manager qu'il utilise lorsque plusieurs outils sont possibles. npm, pnpm, yarn, Bun ou une autre solution compatible MAY être retenus si le besoin et la toolchain du projet le justifient.
Les commandes opérateur et CI doivent utiliser le package manager réellement sélectionné par le projet ; un exemple PGR ne doit pas transformer sa propre syntaxe en obligation universelle.
## Manifest et scripts
`package.json` appartient à cet owner lorsqu'il décrit le package frontend ou JavaScript/TypeScript concerné.
Pour une application locale/non publiée, `private: true` **SHOULD** être utilisé afin d'exprimer explicitement que le package n'est pas destiné à être publié par erreur. Un package destiné à un registry doit au contraire définir les métadonnées et versions nécessaires à sa publication réelle.
Le projet MUST sélectionner explicitement son package manager. Cette sélection peut être rendue machine-readable dans le manifest lorsque la toolchain retenue le permet, ou être possédée par la configuration/CI/documentation locale. PGR ne fixe ni le nom ni la version du package manager dans son template générique.
Les scripts du manifest doivent représenter des responsabilités utiles du package. Un script MAY orchestrer plusieurs outils, mais sa présence ne transfère pas l'ownership de TypeScript, Vite, Sass, WASM ou Tauri vers le package manager.
Pour un package TypeScript, le nom `typecheck` **SHOULD** désigner la vérification TypeScript indépendante. `dev`, `build` et `preview` restent disponibles pour les owners qui possèdent réellement ces comportements ; leur simple présence dans un exemple ne les rend pas obligatoires.
Les champs de version restent classifiés selon la gouvernance PGR et le rôle du package ; un package privé appartenant au même release train et un package publié indépendamment n'ont pas nécessairement la même politique.
## Dépendances et sorties téléchargées
Les dépendances téléchargées telles que `node_modules/` sont des artefacts reproductibles et SHOULD rester hors du source control.
Un package tiers peut exposer des entrypoints JavaScript, CSS, Sass ou d'autres assets. Leur utilisation active les owners correspondants selon le besoin réel du projet ; elle ne fait pas du package manager le propriétaire de leur configuration.
## Dépendances de développement et packages de déclarations
Le manifest réel doit distinguer les dépendances runtime des outils et déclarations nécessaires uniquement au développement. Pour une application TypeScript privée, le compilateur TypeScript, les outils de build et les packages de déclarations externes nécessaires au type-check **SHOULD** normalement être déclarés dans `devDependencies`.
Avant d'ajouter un package `@types/*`, le projet MUST vérifier si la dépendance runtime fournit déjà ses propres types. Si les types sont embarqués, un package `@types/*` redondant SHOULD NOT être ajouté. Si les types sont absents, un package `@types/<nom>` maintenu et compatible **SHOULD** être recherché et ajouté lorsqu'il améliore réellement l'analyse du code consommateur.
Des exemples comme `@types/node` et `@types/bootstrap` sont donc conditionnels :
- `@types/node` est pertinent lorsque le package analyse du code/config/outillage TypeScript qui utilise l'environnement Node ;
- `@types/bootstrap` est pertinent lorsque le code TypeScript consomme les API JavaScript Bootstrap et que les déclarations ne sont pas fournies par le package runtime ;
- aucun des deux ne doit être injecté dans tous les frontends par défaut.
Le template PGR générique conserve volontairement un `package.json` sans `devDependencies` préremplies : il ne connaît ni les dépendances runtime du projet, ni la version TypeScript, ni l'environnement Node éventuel. L'instanciation réelle du template doit ajouter TypeScript et les packages de déclarations effectivement requis avec des versions explicitement décidées.
Pour une bibliothèque publiée, une dépendance de déclarations exposée par les `.d.ts` publics peut être nécessaire chez le consommateur. Dans ce cas, la classer uniquement en `devDependencies` est insuffisant ; le manifest publié doit rendre cette dépendance disponible selon son contrat réel.
## Lockfile
La politique du lockfile MUST être explicitement décidée selon le rôle du package, la reproductibilité recherchée, les contraintes de publication et le package manager sélectionné.
Pour une application privée, un frontend déployable ou un outil livré comme unité exécutable, le lockfile produit par le package manager sélectionné **SHOULD** être versionné afin de conserver l'arbre effectivement résolu entre développeurs, CI et livraisons.
Pour une bibliothèque publiée, un lockfile **MAY** être versionné afin de stabiliser l'environnement de développement et de CI. Il ne remplace toutefois pas les contraintes du manifest qui pilotent la résolution chez les consommateurs.
Un exemple, un template ou une fixture qui ne résout aucune dépendance réelle **MAY** ne pas embarquer de lockfile.
Un package **SHOULD NOT** conserver simultanément plusieurs lockfiles concurrents (`package-lock.json`, `pnpm-lock.yaml`, `yarn.lock` ou équivalent), sauf migration explicitement temporaire entre package managers.
Lorsqu'un lockfile est versionné, la CI **SHOULD** utiliser le mode de résolution gelé, immutable ou clean-install fourni par le package manager sélectionné. Le nom exact de cette commande reste local à l'outil ; PGR MUST NOT transformer `npm ci` en commande universelle.
L'absence actuelle de lockfiles dans Games reste historique. Lors de l'adoption `0.1.5`, chaque package concerné devra soit `ADOPT` cette recommandation, soit documenter un `OVERRIDE` si une autre politique reste préférable.
## Validation
Le parsing du manifest, l'installation/résolution de dépendances, le respect du lockfile et les scripts du package manager sont des preuves distinctes. Leur sélection reste proportionnée au scope conformément à [`400-VALIDATION.md`](400-VALIDATION.md).
Une validation statique PGR peut vérifier qu'un `package.json` template est du JSON valide et que les champs génériques attendus sont présents. Elle ne remplace pas l'installation/résolution réalisée par le package manager sélectionné.
Le modèle minimal [`../../templates/web-typescript/package.json`](../../templates/web-typescript/package.json) représente une application TypeScript privée sans choisir de package manager ni de versions de dépendances. Son adaptation est documentée par [`../templates/008-WEB_TYPESCRIPT_PACKAGE.md`](../templates/008-WEB_TYPESCRIPT_PACKAGE.md).

124
docs/rules/550-VITE.md Normal file
View File

@@ -0,0 +1,124 @@
<!-- file: docs/rules/550-VITE.md -->
<!-- version: 2 -->
# Profil Vite
## Rôle et applicabilité
Ce profil possède les règles réutilisables propres à Vite lorsqu'il est sélectionné comme build tool et dev server d'un frontend.
Vite est traité comme une spécialisation de build de l'écosystème frontend au sein de la famille [`500-LANGUAGES.md`](500-LANGUAGES.md), pas comme le propriétaire de TypeScript, Sass/CSS, du package manager, du framework UI ou du host Tauri.
Le profil s'applique uniquement lorsqu'un projet utilise réellement Vite.
## Recommandation pour les projets contrôlés
Pour un frontend moderne que l'organisation contrôle et dont les besoins sont compatibles, Vite **SHOULD** être le build tool/dev server privilégié.
Cette recommandation n'est pas une obligation. Un autre bundler, dev server ou build tool MAY être choisi lorsque ses capacités, les contraintes d'un framework, l'environnement cible ou le coût de migration le justifient mieux.
Le simple fait qu'un projet Web existe ne rend donc pas ce profil applicable automatiquement.
## Ownership
Lorsque Vite est sélectionné, cet owner possède notamment :
- `vite.config.ts` ou une configuration Vite équivalente ;
- la racine frontend présentée à Vite ;
- le dev server et son contrat de lancement ;
- le cache Vite ;
- les outputs du build Vite ;
- la copie/transformation d'assets configurée par Vite ou ses plugins ;
- les paramètres Vite nécessaires à l'intégration avec un host, sans posséder le host lui-même.
Le manifest et le package manager restent possédés par [`540-JAVASCRIPT_PACKAGE_ECOSYSTEM.md`](540-JAVASCRIPT_PACKAGE_ECOSYSTEM.md). Lorsque Vite est sélectionné, le manifest réel **SHOULD** normalement déclarer Vite comme dépendance de développement avec une version décidée par le projet et MAY exposer les scripts `dev`, `build` et `preview` correspondant au workflow réel.
Un script Vite n'absorbe pas l'ownership du type-check TypeScript, de Sass, d'une génération WASM ou du host.
## Configuration et décisions locales
PGR ne fournit pas de `vite.config.ts` universel à ce stade. Une configuration copiable qui figerait arbitrairement le layout source, les chemins de build, le port, le `base`, les aliases ou les plugins transformerait des décisions locales en règles génériques.
Le projet qui sélectionne Vite doit donc décider explicitement, lorsqu'ils sont pertinents :
```text
root
base
publicDir
cacheDir
build.outDir
build.assetsDir
build.emptyOutDir
server.host
server.port
server.strictPort
preview.host / preview.port / preview.strictPort
aliases
plugins
```
Le guide [`../templates/009-WEB_VITE.md`](../templates/009-WEB_VITE.md) décrit comment adapter ces choix sans imposer de valeurs universelles.
## Sources, cache et outputs
Les sources frontend versionnées, le cache de développement et les outputs de production sont des catégories différentes.
Le cache Vite est un artefact reproductible. Il **SHOULD** rester hors Git. Pour les projets contrôlés, `cacheDir` **SHOULD** être externalisé hors de l'arborescence source lorsque cela reste simple et compatible avec la toolchain ; sinon le chemin retenu MUST être ignoré explicitement.
Le contenu de `build.outDir` est un output généré. Il **SHOULD** rester hors Git et **SHOULD** être externalisé hors de l'arborescence source lorsque cela reste raisonnable. Un projet qui conserve `dist/` ou un autre `outDir` interne MUST l'ignorer explicitement sauf artefact publié exceptionnellement et gouverné comme tel.
`build.emptyOutDir = true` ne doit être activé explicitement que lorsque le répertoire ciblé est dédié aux outputs Vite et que sa suppression complète avant build est sûre. Il MUST NOT pointer vers un répertoire partagé contenant des artefacts appartenant à d'autres owners.
Le nom exact de `outDir` et de `cacheDir` reste local au projet.
## Assets et `publicDir`
Un asset source importé/référencé par le frontend reste un source versionné selon la politique du projet. Sa copie, transformation ou version hashée dans `build.outDir` est générée et ne doit pas être traitée comme un second source.
`publicDir` est une capacité optionnelle. Lorsqu'elle est utilisée, son contenu source est servi/copied tel quel par Vite ; les copies produites dans `outDir` restent des outputs générés. Un projet MAY définir `publicDir: false` lorsqu'il n'a pas besoin de cette voie d'assets statiques.
Un plugin de copie statique MAY être utilisé lorsqu'il répond à un besoin réel. Il ne change pas l'ownership du fichier source copié et ne rend pas ce plugin obligatoire pour les autres projets.
Le découpage final des assets (`assets/`, `js/`, `css/`, `fonts/`, images ou autre) reste local tant qu'aucune contrainte commune ne le justifie.
## `root` et `base`
`root` désigne la racine frontend comprise par Vite. PGR MUST NOT imposer le nom `frontend/` à tous les projets uniquement parce que Games l'utilise. Si les sources ne résident pas à la racine du package, le projet **SHOULD** rendre cette frontière explicite dans sa configuration.
`base` dépend du mode de déploiement ou d'embarquement. PGR MUST NOT imposer `./`, `/` ou un chemin de sous-répertoire universel. Un host embarqué, un site servi à la racine et un déploiement sous sous-chemin peuvent légitimement demander des valeurs différentes.
## Dev server
Le dev server **SHOULD** rester limité à la machine locale/loopback lorsqu'aucun accès externe n'est requis.
L'écoute sur toutes les interfaces ou l'exposition au LAN **MAY** être activée pour un besoin explicite de test, de device ou d'intégration. Elle doit alors être traitée comme une décision réseau réelle et non comme un défaut PGR.
Les ports sont locaux au projet. Lorsqu'aucun consommateur ne dépend d'un port fixe, Vite MAY conserver son comportement normal de sélection. Lorsqu'un host, un smoke ou une autre intégration dépend d'une URL déterministe, le projet **SHOULD** configurer explicitement `server.port` avec `server.strictPort = true` afin d'échouer plutôt que de dériver silencieusement vers un autre port.
`server.allowedHosts = true` et `server.cors = true` **SHOULD NOT** être utilisés comme raccourcis génériques. Une ouverture réseau ou CORS large doit être justifiée et bornée selon le besoin réel.
Les réglages HMR/WebSocket, proxy, TLS et file-system allowlists restent locaux à l'intégration qui les exige.
## Preview
`vite preview` MAY servir de smoke local du build de production lorsqu'il apporte une preuve utile.
Il MUST NOT être présenté comme serveur de production. Le déploiement/serving de production appartient à l'owner de deployment/operations ou au host concerné, hors scope de `0.1.1`.
Un port de preview fixe MAY être utilisé lorsqu'un smoke automatisé en dépend ; dans ce cas `preview.strictPort = true` est recommandé pour obtenir une failure déterministe.
## Validation
Une validation Vite ciblée prouve le contrat de build/dev tool de Vite ; elle ne remplace pas automatiquement :
- le type-check TypeScript ;
- une compilation Sass spécifique lorsqu'elle est indépendante ;
- le smoke navigateur requis par un comportement observable ;
- la validation du host Tauri ;
- une génération WASM possédée par un autre owner.
Pour un projet réel ayant sélectionné Vite, le build de production via le package manager choisi **SHOULD** faire partie de la gate lorsqu'un changement touche Vite, ses entrées ou ses outputs.
Le script `typecheck` TypeScript **SHOULD** rester exécutable indépendamment. Une CI MAY exécuter `typecheck` puis `build` comme deux preuves distinctes plutôt que d'enfouir la première dans un script spécifique à un package manager.
Le guide [`../templates/009-WEB_VITE.md`](../templates/009-WEB_VITE.md) complète ce profil.

View File

@@ -0,0 +1,70 @@
<!-- file: docs/rules/560-CSS_SASS.md -->
<!-- version: 2 -->
# Profil CSS et Sass
## Rôle et applicabilité
Ce profil possède les règles réutilisables de la chaîne de styles frontend : sources CSS, prétraitement Sass lorsqu'il est sélectionné, dépendances de styles, points d'entrée publics et classification des artefacts générés.
Il complète [`500-LANGUAGES.md`](500-LANGUAGES.md). Il ne rend aucun framework CSS particulier obligatoire et ne possède ni TypeScript, ni Vite, ni le package manager, ni le host.
Le profil s'applique à un projet qui possède réellement des sources CSS/Sass ou une chaîne de styles correspondante. La présence d'un frontend sans styles n'oblige pas à créer des fichiers CSS/Sass artificiels.
## CSS comme baseline
Un frontend Web peut utiliser directement CSS sans préprocesseur. Sass n'est donc jamais requis par la simple présence de fichiers CSS.
Les styles sources intentionnels **SHOULD** être versionnés. Les CSS produits uniquement par compilation à partir de sources Sass, les variantes minifiées, les sourcemaps et les copies placées dans un output de build sont des artefacts générés et **SHOULD** rester hors du source control, sauf besoin explicite de distribution ou publication gouverné comme tel.
Un artefact généré MUST NOT être modifié manuellement comme s'il constituait un second source. La correction appartient au source ou à la configuration qui le produit.
PGR MUST NOT imposer un nom de répertoire universel tel que `css/`, `styles/` ou `sass/`. Le layout appartient au projet ou au skeleton qui le compose.
## Recommandation Sass pour les projets contrôlés
Pour un frontend contrôlé dont la chaîne de styles est non triviale, Sass **SHOULD** être préféré lorsqu'il apporte une valeur claire de composition, factorisation ou configuration.
Cette recommandation est particulièrement forte lorsqu'une dépendance installée par le package manager expose un entrypoint Sass/SCSS, des variables configurables, maps, mixins, fonctions ou modules permettant de personnaliser la bibliothèque à la compilation sans modifier ses sources.
Bootstrap constitue un exemple concret de cette catégorie : ses sources Sass permettent de sélectionner des parties de la bibliothèque et de configurer des variables. Cette observation n'en fait pas une dépendance PGR universelle.
Un frontend petit, un smoke minimal ou un projet dont les besoins sont couverts proprement par CSS MAY rester sans Sass.
## Implémentation Sass et intégration au build
Le profil Sass ne dépend d'aucun bundler particulier.
Lorsqu'un projet utilise Vite et sélectionne Sass, il MAY utiliser `sass` ou `sass-embedded` selon la compatibilité de sa toolchain. Pour une nouvelle baseline contrôlée compatible, `sass-embedded` **SHOULD** être préféré lorsque son intégration est supportée et apporte un gain proportionné ; ce choix reste une `devDependency` du projet réel et n'est pas prérempli dans un template PGR générique.
Un autre bundler ou une compilation Sass autonome MAY utiliser l'implémentation officielle adaptée à son environnement. PGR MUST NOT installer un plugin Vite spécifique uniquement pour activer Sass lorsque Vite prend déjà en charge le préprocesseur sélectionné.
## Modules Sass et compatibilité
Pour du nouveau code contrôlé, le système de modules Sass moderne (`@use` / `@forward`) **SHOULD** être préféré lorsque les dépendances et la toolchain le permettent.
L'ancien `@import` Sass est déprécié dans Dart Sass. Il MAY toutefois rester nécessaire à titre de compatibilité lorsqu'une bibliothèque tierce, une version existante ou sa documentation l'impose encore. PGR ne doit pas forcer une migration syntaxique qui casse une dépendance supportée.
Lorsqu'une bibliothèque expose une API Sass publique et configurable, le projet **SHOULD** suivre cette API documentée. Avec le système de modules, une configuration par `@use ... with (...)` ou un entrypoint réexporté via `@forward` est préférable lorsqu'elle est réellement supportée.
PGR **SHOULD NOT** dépendre de chemins internes non documentés sous `node_modules` ou d'une arborescence privée d'un package si celui-ci expose un entrypoint Sass public. Une compatibilité historique MAY justifier temporairement un chemin interne, mais cette dépendance doit rester explicite et révisable.
## Frameworks CSS et packages de styles
Bootstrap, Tailwind CSS ou une autre bibliothèque de présentation restent des décisions de skeleton/projet ou d'un futur owner spécifique si un contrat réutilisable distinct apparaît.
Le profil CSS/Sass possède uniquement la façon de traiter leurs sources/styles lorsqu'elles passent par CSS ou Sass ; il ne choisit pas la bibliothèque à la place du projet.
Un package npm apportant uniquement des styles n'impose pas l'ajout de déclarations `@types/*`. Les déclarations TypeScript sont requises seulement lorsque des API JavaScript/TypeScript réellement consommées en ont besoin, conformément à [`530-TYPESCRIPT.md`](530-TYPESCRIPT.md) et [`540-JAVASCRIPT_PACKAGE_ECOSYSTEM.md`](540-JAVASCRIPT_PACKAGE_ECOSYSTEM.md).
## Validation des styles
La validation doit prouver la chaîne réellement utilisée sans dupliquer artificiellement la même propriété.
Lorsque Sass est compilé à l'intérieur du build Vite et qu'aucune compilation Sass indépendante n'existe, un build Vite réussi peut constituer la preuve de compilation des styles. PGR SHOULD NOT imposer en plus une seconde compilation Sass identique uniquement pour ajouter une commande à la gate.
Lorsqu'une compilation Sass autonome, un linter CSS/Sass ou une autre transformation possède un contrat distinct, sa commande officielle MAY être ajoutée comme preuve séparée.
Une validation de styles ne remplace ni le type-check TypeScript, ni le build frontend complet, ni un smoke navigateur nécessaire à un comportement observable, ni la validation du host.
Le contrat de validation frontend indépendant du host est décrit dans [`../validation/005-WEB_FRONTEND_VALIDATION.md`](../validation/005-WEB_FRONTEND_VALIDATION.md). Le guide [`../templates/010-WEB_CSS_SASS.md`](../templates/010-WEB_CSS_SASS.md) décrit l'adaptation pratique sans imposer de layout ou framework CSS universel.

View File

@@ -1,5 +1,5 @@
<!-- file: docs/rules/610-ANDROID.md -->
<!-- version: 2 -->
<!-- version: 5 -->
# Profil Android
@@ -7,15 +7,15 @@
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).
Il complète [`600-PLATFORMS.md`](600-PLATFORMS.md), [`522-GRADLE.md`](522-GRADLE.md) lorsqu'un projet Android utilise Gradle et [`520-JAVA.md`](520-JAVA.md) lorsqu'il contient du code Java. Android n'implique pas à lui seul l'applicabilité du profil Java.
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.
Une contrainte Android plus spécifique MAY raffiner les règles générales Gradle et, lorsque Java est applicable, les règles JDK/Java 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.
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 de build Android.
Dans un dépôt multi-plateforme où une zone Android distincte est nécessaire, PGR SHOULD utiliser la racine :
@@ -33,23 +33,25 @@ project/
├── crates/
├── Web/
└── Android/
├── settings.gradle
├── build.gradle
├── settings.gradle(.kts)
├── build.gradle(.kts)
├── gradle.properties
├── gradlew
├── gradlew.bat
└── gradle/
└── <module>/
```
Cet exemple décrit une frontière de plateforme, pas une liste obligatoire de fichiers Gradle. Wrapper, version catalog, plugins de convention, modules et autres éléments de build restent gouvernés par la composition réellement choisie et par [`522-GRADLE.md`](522-GRADLE.md).
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.
Android ne sélectionne pas à lui seul le langage applicatif du projet. Les profils langage s'appliquent uniquement aux langages réellement présents.
Kotlin MAY être utilisé lorsqu'une API, un framework ou une intégration l'exige réellement.
Lorsqu'un projet Android contient du Java, [`520-JAVA.md`](520-JAVA.md) possède les règles Java correspondantes. La présence d'AGP, d'un JDK de build ou d'un script Gradle ne suffit pas à rendre le profil Java applicable au code produit.
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.
Un autre langage applicatif MAY être utilisé lorsqu'il correspond à la stack réelle du projet. Le profil Android possède uniquement les contraintes imposées par la plateforme et ne transforme pas un choix de langage local en règle Android générale.
Groovy DSL ou Kotlin DSL MAY être utilisés par Gradle comme langage de configuration conformément à [`522-GRADLE.md`](522-GRADLE.md). Leur présence dans le build ne détermine pas le langage applicatif.
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.
@@ -57,7 +59,7 @@ Les annotations fonctionnelles Android ou de frameworks restent autorisées lors
## Matrice AGP / Gradle / JDK
Un projet Android MUST exprimer une chaîne de build compatible.
Un projet Android qui utilise AGP MUST exprimer une chaîne de build compatible.
La matrice conceptuelle est :
@@ -66,9 +68,11 @@ Android Gradle Plugin
↕
Gradle
↕
JDK LTS
JDK de build
```
La version AGP retenue peut également contraindre les niveaux Android SDK supportés par la chaîne de build. Cette compatibilité appartient au scope Android ; les règles Gradle générales restent possédées par [`522-GRADLE.md`](522-GRADLE.md).
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 :
@@ -80,27 +84,47 @@ version exacte / pin
latest compatible
```
Le projet choisit la forme la moins restrictive qui reste réellement compatible avec sa stack.
Le projet choisit la forme la moins restrictive qui reste réellement compatible avec sa stack et effectivement vérifiable.
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.
Le JDK utilisé pour exécuter Gradle/AGP est une contrainte de build Android même lorsqu'aucun code source Java n'existe. Lorsqu'un projet contient du Java, le niveau Java du code source et du bytecode reste un contrat distinct possédé par [`520-JAVA.md`](520-JAVA.md).
Lorsque le Gradle Wrapper est retenu, ses fichiers requis sont versionnés et sa version doit satisfaire la matrice réelle AGP/Gradle/JDK.
PGR MUST NOT confondre :
```text
JDK qui exécute Gradle / AGP
≠
niveau Java du code applicatif
```
Le choix Wrapper ou Gradle système, ainsi que la manière de vérifier la contrainte Gradle, restent possédés par [`522-GRADLE.md`](522-GRADLE.md). Une matrice Android plus étroite MAY raffiner cette contrainte dans le seul scope Android.
## `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.
`compileSdk` définit le niveau d'API Android disponible lors de la compilation. Il doit être compatible avec la version AGP réellement utilisée et MAY évoluer sans entraîner mécaniquement une hausse de `targetSdk` ou `minSdk`.
`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é.
`targetSdk` déclare le niveau Android pour lequel l'application a été adaptée et testée du point de vue des comportements de plateforme. 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.
`minSdk` définit le plus ancien niveau d'API Android que le produit choisit réellement de supporter. Il participe notamment à l'éligibilité d'installation sur les appareils plus anciens.
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.
Le choix de `minSdk` MUST être justifié par le contrat produit et ses contraintes réelles : population visée, capacités nécessaires, dépendances, sécurité, coût de maintenance et preuves de compatibilité. PGR ne privilégie ni le niveau le plus bas possible ni une hausse de confort sans justification.
Une hausse de `minSdk` est un changement de compatibilité utilisateur et MUST être explicitement justifiée.
Une hausse de `minSdk` retire explicitement des appareils auparavant éligibles ; elle constitue donc un changement de compatibilité utilisateur et MUST être traitée comme tel.
## Identité applicative et namespace
Pour un module application Android, `applicationId` et `namespace` sont deux contrats distincts.
`applicationId` identifie l'application installée et distribuée. Pour une application déjà publiée, le modifier ne constitue pas un simple renommage de code : il crée une identité applicative différente du point de vue de la plateforme et des canaux de distribution.
`namespace` possède l'espace de noms utilisé par le code et les ressources générées du module. Il MAY évoluer indépendamment de `applicationId` lorsque le projet a une raison réelle de dissocier identité distribuée et organisation du code.
PGR SHOULD conserver `namespace` et `applicationId` alignés lorsque cela suffit, mais MUST NOT les confondre ni dériver implicitement l'identité distribuée d'un renommage de namespace. Toute divergence ou modification d'`applicationId` doit être explicite dans la configuration Android concernée.
Les valeurs concrètes telles que `com.example.product` appartiennent au projet ; PGR n'impose aucun domaine ou préfixe universel.
## `VERSION`, `versionName` et `versionCode`
@@ -135,15 +159,15 @@ lorsqu'un projet ou skeleton réel fournit des fichiers à contrôler. Cet audit
## 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.
`local.properties` appartient à l'environnement local du build Android/AGP, notamment pour des chemins machine tels que l'emplacement du SDK. Il SHOULD rester hors Git.
PGR MUST NOT utiliser `local.properties` comme source normative de configuration partagée du projet.
PGR MUST NOT utiliser `local.properties` comme source normative de configuration partagée ni comme fourre-tout pour des propriétés locales propres au produit. La documentation Android réserve ce fichier aux propriétés locales comprises par la toolchain Android ; une propriété locale spécifique au projet doit utiliser un mécanisme séparé et explicitement possédé.
Si l'outil ou l'IDE régénère intégralement ce fichier, aucun fichier exemple n'est nécessaire.
Les propriétés Gradle partagées, portables et non secrètes restent gouvernées par [`522-GRADLE.md`](522-GRADLE.md). Les chemins machine, credentials, secrets et overrides développeur restent locaux, via variables d'environnement, propriétés utilisateur ou fichier explicitement ignoré selon le besoin réel.
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.
Si l'outil ou l'IDE régénère intégralement un état local, aucun fichier exemple n'est nécessaire. Lorsqu'une valeur 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.
Un fichier local tel que `keystore.properties` ou une variante `*.local.properties` MAY exister lorsqu'il possède une responsabilité claire, mais il MUST rester hors Git lorsqu'il contient des secrets ou valeurs propres à la machine.
## Signing et secrets
@@ -152,7 +176,7 @@ L'interdiction générale de versionner ou distribuer des secrets reste posséd
Dans le scope Android, les éléments suivants sont notamment des secrets ou artefacts privés soumis à cette interdiction :
```text
release keystore
release / upload keystore
private signing key
passwords
credentials
@@ -168,7 +192,9 @@ RELEASE_KEY_ALIAS
mais MUST NOT contenir leurs valeurs privées.
Le debug keystore généré automatiquement est local.
Le debug keystore généré par les outils Android est un état local de développement et ne doit pas être promu comme identité de signing de release.
Les clés de release ou d'upload appartiennent à une frontière de sécurité durable de l'application publiée. Leur stockage, sauvegarde, rotation ou délégation au canal de distribution doit être décidé explicitement par le projet sans introduire la matière secrète dans Git.
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.
@@ -203,25 +229,44 @@ Une BOM ou un mécanisme officiel de gestion de versions MAY être utilisé lors
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
## NDK, ABI et code natif
Un projet Android purement Java peut ne posséder aucune règle ABI spécifique.
Un projet Android sans bibliothèque native directe ou transitive n'a pas besoin de NDK ni de matrice ABI propre au produit.
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.
Dès qu'un projet contient du code natif via NDK, C/C++, Rust, un SDK précompilé ou une autre frontière native, la toolchain native réellement nécessaire et les ABI réellement supportées MUST être explicites.
Exemples possibles :
PGR ne fixe ni version NDK ni liste universelle d'ABI. La version NDK MAY être épinglée lorsqu'une reproductibilité, une dépendance ou une exigence de packaging le justifie ; elle ne doit pas être copiée depuis un autre projet par défaut.
Les mécanismes tels que `abiFilters` MAY exprimer la matrice voulue lorsque Gradle/AGP les utilise. La configuration choisie doit refléter le contrat produit et le canal de distribution plutôt qu'une liste maximale par principe.
Une ABI annoncée comme supportée doit disposer d'une preuve adaptée à la propriété annoncée. Il faut distinguer au minimum :
```text
arm64-v8a
armeabi-v7a
x86_64
compilation native
→ la bibliothèque est produite pour l'ABI
packaging
→ la bibliothèque et ses dépendances natives sont présentes dans l'artefact Android attendu
runtime
→ le package pertinent s'installe et exécute le chemin critique sur un environnement représentant l'ABI / API concernée
```
PGR ne fixe pas une liste universelle d'ABI.
Une cross-compilation native seule ne prouve donc ni l'intégration dans l'APK/AAB, ni le lifecycle Android, ni l'exécution sur device/AVD.
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 bibliothèques natives précompilées ou apportées par un SDK font partie du package final et MUST respecter les mêmes contraintes de compatibilité que les bibliothèques produites par le projet.
Les règles JNI elles-mêmes appartiennent à un profil spécialisé et restent hors de ce document.
Les règles JNI, Rust, SDL, `cargo ndk` ou toute autre chaîne native spécialisée appartiennent à leurs owners/projets respectifs et restent hors de ce document tant qu'un profil générique séparé n'est pas justifié.
## Android Lint
Android Lint est une analyse statique Android distincte de la compilation et des tests.
Lorsqu'un changement touche du code, des resources, un manifest, une configuration Android ou une dépendance susceptible d'être analysée par Lint, la gate SHOULD exécuter la tâche Lint du module et du variant pertinents.
PGR MUST NOT supposer qu'un build Gradle ordinaire exécute Lint automatiquement. Les commandes exactes (`lint`, `lintDebug`, `lintRelease` ou équivalent) appartiennent au projet et à sa stratégie Wrapper/Gradle système.
Une baseline Lint MAY être versionnée lorsqu'elle sert réellement à isoler la dette existante des nouvelles régressions. Elle ne doit pas servir à masquer silencieusement de nouveaux diagnostics applicables.
## Niveaux de tests Android
@@ -229,20 +274,22 @@ PGR distingue au moins trois niveaux de preuve Android lorsqu'ils sont applicabl
```text
JVM unit
→ logique ne nécessitant pas le runtime Android
→ logique exécutée sur la JVM hôte sans runtime Android réel
instrumented / integration
→ comportement nécessitant le framework Android
→ test exécuté sur device ou émulateur avec le framework Android
smoke device / AVD
→ application ou package réel dans un environnement Android
→ application ou package réel installé et chemin critique exécuté 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 JVM MUST NOT être enregistré comme preuve d'un comportement réel d'`Activity`, de lifecycle, de package ou de device.
Un test instrumenté ne remplace pas automatiquement un smoke du package final.
Un test instrumenté prouve le comportement couvert par son runner et son environnement, mais ne remplace pas automatiquement un smoke du package final lorsque la tranche modifie packaging, signing, native libraries, manifest de lancement ou installation.
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.
Les tâches de tests SHOULD être ciblées par module/variant lorsque cela suffit. Une matrice instrumentée ou multi-device large n'est requise que lorsqu'elle couvre un risque réellement modifié ou une phase de release qui l'exige.
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, d'une ABI ou d'un comportement qui ne peut pas être suffisamment prouvé par AVD.
## Ordre de validation Android
@@ -274,10 +321,12 @@ Les commandes exactes appartiennent à la matrice du projet ou du skeleton qui p
## Manifest et ressources
`AndroidManifest.xml` MUST déclarer uniquement les permissions et capabilities réellement nécessaires.
`AndroidManifest.xml` MUST déclarer uniquement les composants, permissions et capabilities de plateforme réellement nécessaires au module.
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.
`applicationId` et `namespace` restent possédés par la configuration Android du module ; PGR SHOULD éviter de créer des sources de vérité concurrentes ou des copies divergentes de ces identités dans des fichiers séparés.
`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.
@@ -290,20 +339,54 @@ PGR distingue les rôles des principaux artefacts :
```text
APK debug
→ développement et smokes ordinaires
→ développement, installation directe et smokes ordinaires
APK release
→ validation d'un package release installable lorsque nécessaire
AAB
→ artefact de distribution lorsque le canal cible l'exige
→ artefact de distribution lorsque le canal cible l'exige ; le canal génère ensuite les APK servis aux appareils
```
La phase de release et le scope modifié déterminent l'artefact nécessaire.
La phase de release, le canal de distribution 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.
Un AAB n'est pas directement une preuve d'installation ou d'exécution sur device. Lorsqu'une propriété runtime ou de packaging doit être prouvée, la gate doit aussi utiliser un APK approprié ou les APK dérivés du bundle selon le canal et le risque concerné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é.
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, manifest, code natif 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 ou composants qui entrent dans l'artefact ont changé.
Les exigences telles que le niveau `targetSdk` minimal, le format de publication ou les délais de compatibilité appartiennent au canal de distribution et évoluent indépendamment de PGR. Un projet publié MUST vérifier la politique officielle courante de son canal avant une release concernée ; PGR ne transforme pas une valeur datée de Google Play en default Android universel.
## Pages mémoire 16 KB et packaging natif
Android supporte des appareils configurés avec des pages mémoire de `16 KB`. Cette responsabilité est conditionnelle : un projet sans bibliothèque native directe ou transitive n'a pas de segments ELF à réaligner, même s'il SHOULD tester les comportements importants sur les environnements Android qu'il prétend supporter.
Lorsqu'une application contient du natif et que la plateforme ou le canal de distribution exige la compatibilité `16 KB`, le package final MUST être compatible. La preuve doit couvrir les bibliothèques natives du projet ainsi que les dépendances natives précompilées réellement embarquées.
Pour Google Play, la politique officielle courante vérifiée pendant `0.1.3` impose le support `16 KB` sur appareils 64 bits aux applications ciblant Android 15 / API `35` ou supérieur. Cette politique est évolutive : le projet MUST la revalider auprès de la documentation officielle au moment où elle devient une gate de release.
Une preuve de compatibilité native `16 KB` SHOULD couvrir, selon l'artefact réellement distribué :
```text
ELF 64 bits
→ segments LOAD des bibliothèques embarquées compatibles avec l'alignement 16 KB
APK
→ alignement ZIP des bibliothèques natives vérifié sur le package final
AAB
→ configuration d'alignement du bundle vérifiée lorsque ce bundle est l'artefact de distribution
runtime
→ smoke sur device/AVD 16 KB lorsque le comportement runtime ou la distribution concernée le justifie
```
Les outils Android officiels peuvent notamment contrôler les segments ELF, `zipalign -P 16` pour un APK et l'alignement déclaré par `bundletool` pour un AAB. Ces commandes sont des moyens de preuve, pas des noms de fichiers ou chemins machine à figer dans PGR.
Une toolchain récente peut fournir cette compatibilité par défaut, mais PGR MUST NOT imposer une version AGP/NDK globale uniquement pour cette raison. La toolchain retenue doit satisfaire la politique courante du canal et toutes les bibliothèques natives précompilées doivent être compatibles elles aussi.
Un mode de compatibilité de plateforme ou le simple fait que l'application démarre sur un appareil 16 KB ne remplace pas la preuve de conformité du package natif lorsque le canal de distribution l'exige.
## Validation et futurs audits PGR

View File

@@ -1,5 +1,5 @@
<!-- file: docs/rules/710-TAURI.md -->
<!-- version: 5 -->
<!-- version: 7 -->
# Profil Tauri 2
@@ -29,7 +29,9 @@ PGR MUST NOT imposer universellement Vite, TypeScript, Sass, Bootstrap, Tailwind
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.
Les owners frontend matérialisés par `0.1.1` sont [`530-TYPESCRIPT.md`](530-TYPESCRIPT.md), [`540-JAVASCRIPT_PACKAGE_ECOSYSTEM.md`](540-JAVASCRIPT_PACKAGE_ECOSYSTEM.md), [`550-VITE.md`](550-VITE.md) et [`560-CSS_SASS.md`](560-CSS_SASS.md). Ils s'appliquent uniquement lorsque les technologies correspondantes sont réellement sélectionnées.
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 profils Web applicables, pas au présent owner Tauri.
## WASM
@@ -52,25 +54,25 @@ Les éléments suivants appartiennent néanmoins au scope Tauri lorsqu'ils exist
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
## Convention organisationnelle 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 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, le présent owner définit seulement la convention propre au host et à l'intégration Tauri. La sélection de TypeScript, Vite, CSS/Sass, d'un framework CSS ou d'un package manager reste possédée par les owners Web et par la skeleton specification applicable.
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 :
Le host SHOULD être une crate Cargo mixte directement lisible, sans couche `src-tauri/` ajoutée uniquement pour reproduire `create-tauri-app`. Cette recommandation est une convention d'organisation PGR pour les nouveaux projets contrôlés ; elle ne signifie ni que `src-tauri/` est invalide, ni qu'un projet existant doit migrer pour être acceptable.
La surface Tauri recommandée reste visible à la racine de la crate :
```text
<tauri-crate>/
├── Cargo.toml
├── build.rs
├── package.json
├── tsconfig.json
├── tauri.conf.json
├── capabilities/
├── src/
└── frontend/
└── <frontend-root>/
```
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.
`<frontend-root>/` représente la racine frontend réellement retenue. Une skeleton PGR MAY choisir `frontend/` comme convention stable, mais `710-TAURI.md` ne transforme pas ce nom en obligation universelle. De même, `package.json`, `tsconfig.json`, `vite.config.ts` ou des sources Sass n'existent que si les owners correspondants sont réellement sélectionnés.
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 :
@@ -84,11 +86,9 @@ Dans le host Rust, le package mixte `lib + bin` constitue l'exception framework
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/`.
Lorsque le frontend sélectionné est TypeScript et que des DTO, structures ou énumérations Rust doivent être partagés, la frontière typée suit [`530-TYPESCRIPT.md`](530-TYPESCRIPT.md). Un générateur tel que TS-RS MAY être retenu comme source de bindings ; le contrat Rust reste alors la source de vérité et les bindings entièrement reproductibles SHOULD rester hors Git. Le choix ou le renforcement de TS-RS appartient au projet ou au futur skeleton Tauri, pas au profil Tauri universel.
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.
L'intégration d'un plugin SHOULD préférer des étapes explicites ou, si une commande de commodité est utilisée, une revue complète de ses modifications. `cargo tauri add` MAY être utilisé lorsqu'il apporte une valeur réelle ; il n'est pas une voie canonique imposée.
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.
@@ -148,15 +148,32 @@ Cette classification évite de réécrire `package.json` et `tauri.conf.json` à
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
## Commandes, permissions et capabilities
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.
Tauri distingue trois responsabilités qui ne doivent pas être confondues :
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.
```text
commande enregistrée → handler natif connu du système d'invocation
permission → privilège ACL, avec allow/deny et scopes éventuels
capability → attribution de permissions à des fenêtres/webviews et, le cas échéant, à des origines ou plateformes
```
Déclarer un wrapper `#[tauri::command]` ou enregistrer un handler dans l'application n'est donc pas une preuve suffisante de moindre privilège. Le comportement par défaut des commandes applicatives dépend du mécanisme Tauri réellement utilisé ; lorsqu'une commande ou une opération doit être restreinte, le projet MUST matérialiser et valider la politique correspondante au niveau approprié au lieu de supposer que l'enregistrement du handler constitue une ACL.
Les permissions possèdent les commandes et scopes qu'elles autorisent ou refusent. Les capabilities associent ensuite ces permissions aux fenêtres/webviews concernées. Lorsqu'une fenêtre ou webview appartient à plusieurs capabilities, sa surface effective résulte de leur composition ; la revue MUST donc considérer les droits cumulés, pas chaque fichier isolément.
Les capability files intentionnels sont du source de sécurité et SHOULD être versionnés. Pour une nouvelle baseline contrôlée, le projet MUST décider explicitement comment les capabilities sont sélectionnées :
- sélection explicite dans `app.security.capabilities` ; ou
- inclusion automatique des fichiers du répertoire `capabilities/` selon le comportement supporté par la version Tauri retenue.
Avec Tauri 2 courant, une configuration `app.security.capabilities` absente ou vide inclut par défaut les capability files du répertoire `capabilities/`, tandis qu'une liste explicite permet de sélectionner les capabilities utilisées. Si le projet conserve l'inclusion automatique, ajouter un nouveau capability file MUST être traité comme une modification de la surface de sécurité. Une sélection explicite SHOULD être préférée dès que plusieurs capabilities, fenêtres ou niveaux de privilège rendent l'auto-inclusion moins lisible.
Le projet SHOULD accorder uniquement les permissions et scopes 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é.
Toute permission distante, origine distante ou extension de scope sensible MUST être explicitement justifiée et validée comme frontière de sécurité.
## Plugins

View File

@@ -1,5 +1,5 @@
<!-- file: docs/skeletons/000-README.md -->
<!-- version: 4 -->
<!-- version: 7 -->
# Index des skeleton specifications PGR
@@ -19,11 +19,15 @@ Une specification peut se composer avec une fondation plus générale, mais la c
- [`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.
- [`003-WEB_FRONTEND.md`](003-WEB_FRONTEND.md) — specialization composable d'un frontend Web contrôlé fondée sur les owners `530/540/550/560`, avec TypeScript/Vite recommandés, Sass conditionnel et validation indépendante du host.
- [`004-TAURI.md`](004-TAURI.md) — specialization Tauri 2 contrôlée composant fondation, Rust/Cargo, frontend et owner `710`, avec décisions explicites sur layout, capabilities, plugins, versions, packaging et validation proportionnée.
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.
Pour un projet existant, ces specifications servent de références de comparaison et non de recettes à recopier aveuglément. Le chemin canonique passe alors par [`../rules/230-ADOPTION.md`](../rules/230-ADOPTION.md) et son mapping `ADOPT / KEEP-LOCAL / OVERRIDE / DEFER`.
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).
Les familles Java/Android, 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.
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.
Le skeleton Web `003` est matérialisé en `0.1.1-alpha.5` parce que les owners `530/540/550/560`, les guides d'adaptation et la validation frontend indépendante du host permettent désormais une composition sans ownership caché. Il ne fixe ni npm, ni Vite/Sass comme obligations, ni Bootstrap, ni un layout `frontend/` universel.
Le skeleton Tauri avait été différé en `0.0.5-alpha.9` tant que les owners Web nécessaires n'existaient pas. `0.1.4-alpha.1` a confirmé les conditions de sortie, `alpha.2` a réconcilié l'owner `710`, puis `alpha.3` matérialise `004-TAURI.md` comme specification de composition sans reprendre l'ownership Web. L'étude historique et la levée du `DEFER` restent enregistrées dans [`../studies/002-TAURI_SKELETON_DECISION.md`](../studies/002-TAURI_SKELETON_DECISION.md).
Aucun fichier placeholder ne doit être ajouté pour réserver un skeleton futur.

View File

@@ -1,5 +1,5 @@
<!-- file: docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md -->
<!-- version: 3 -->
<!-- version: 4 -->
# Skeleton — Project governance foundation
@@ -17,6 +17,8 @@ Appliquer cette fondation lorsqu'un dépôt ou release unit veut utiliser PGR co
Elle MAY servir de fondation à un skeleton spécialisé, qui ajoute ensuite uniquement les profils, templates, décisions et validations propres à son scope.
Pour un projet déjà existant, cette specification devient une checklist de comparaison : l’adoption MUST suivre [`../rules/230-ADOPTION.md`](../rules/230-ADOPTION.md), classifier les décisions applicables et préserver les choix locaux légitimes. Le pattern [`../templates/007-EXISTING_PROJECT_ADOPTION.md`](../templates/007-EXISTING_PROJECT_ADOPTION.md) peut matérialiser cette comparaison. Il ne faut pas réinstancier le dépôt comme s’il était vide.
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

View File

@@ -1,5 +1,5 @@
<!-- file: docs/skeletons/002-RUST_CARGO_WORKSPACE.md -->
<!-- version: 5 -->
<!-- version: 6 -->
# Skeleton — Rust/Cargo workspace
@@ -29,6 +29,8 @@ La composition normale est :
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.
Pour un projet Rust/Cargo existant, ne pas appliquer ce skeleton comme une réinitialisation. Utiliser [`../rules/230-ADOPTION.md`](../rules/230-ADOPTION.md), comparer le workspace réel avec la présente specification et classifier chaque écart utile en `ADOPT / KEEP-LOCAL / OVERRIDE / DEFER`. Les manifests ou fichiers d’outillage déjà fonctionnels ne sont remplacés que si la décision `ADOPT` le justifie réellement.
## 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 :
@@ -176,7 +178,7 @@ 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.
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. Le contrat réutilisable de cette preuve, ainsi que le dry-run distinct d’un projet existant, est documenté dans [`../validation/004-RUST_CARGO_BASELINE_DRY_RUN.md`](../validation/004-RUST_CARGO_BASELINE_DRY_RUN.md).
Une prévalidation PGR ou générateur ne remplace jamais la gate opérateur autoritaire du projet destinataire.

View File

@@ -0,0 +1,143 @@
<!-- file: docs/skeletons/003-WEB_FRONTEND.md -->
<!-- version: 1 -->
# Skeleton — Web frontend
## Objectif
Cette specification décrit une specialization composable pour créer une baseline frontend Web contrôlée sans confondre langage, package ecosystem, build tool, styles et host.
Elle se compose avec [`001-PROJECT_GOVERNANCE_FOUNDATION.md`](001-PROJECT_GOVERNANCE_FOUNDATION.md), sélectionne les owners Web réellement applicables de la famille `500` et utilise les templates/guides `008`, `009` et `010` lorsqu'ils correspondent aux choix du projet.
Le contrat transversal des skeletons reste possédé par [`../rules/220-SKELETONS.md`](../rules/220-SKELETONS.md).
## Applicabilité
Appliquer cette specialization lorsqu'un projet ou sous-projet possède un frontend Web autonome ou embarqué dont la baseline frontend est contrôlée par le projet.
Elle peut servir de fondation frontend à un host plus spécifique, par exemple Tauri, sans rendre ce host applicable par elle-même.
Pour un projet existant, cette specification sert de référence de comparaison : l'adoption suit [`../rules/230-ADOPTION.md`](../rules/230-ADOPTION.md) et classe les choix existants `ADOPT / KEEP-LOCAL / OVERRIDE / DEFER` plutôt que de réécrire son layout.
Ne pas appliquer ce skeleton à un backend sans frontend, à une page statique qui n'a besoin d'aucune de ces responsabilités, ni uniquement parce que Vite/TypeScript sont recommandés ailleurs.
## Owners sélectionnables
La composition de référence d'un frontend moderne contrôlé est :
```text
GENERAL
+ 500 language / ecosystem family
+ 530 TypeScript
+ 540 JavaScript package ecosystem
+ 550 Vite
+ 560 CSS / Sass
```
La sélection reste factuelle :
- `530` est sélectionné lorsque TypeScript est utilisé ; TypeScript **SHOULD** être préféré pour une baseline durable lorsqu'il est compatible avec le besoin ;
- `540` est sélectionné lorsqu'un `package.json`, un package manager ou des dépendances JavaScript sont réellement utilisés ;
- `550` est sélectionné uniquement si Vite est choisi ; Vite **SHOULD** être préféré pour les frontends compatibles, sans être obligatoire ;
- `560` est sélectionné si le frontend possède une chaîne CSS/Sass ; CSS seul reste valide et Sass reste optionnel, bien que recommandé pour une chaîne non triviale ou un package exposant une API Sass utile.
Le skeleton ne transforme pas une recommandation `SHOULD` en `MUST`.
## Fondation et fichiers de départ
Lorsque TypeScript + package ecosystem sont sélectionnés, le projet MAY partir des templates :
```text
templates/web-typescript/package.json
templates/web-typescript/tsconfig.json
```
Le guide [`../templates/008-WEB_TYPESCRIPT_PACKAGE.md`](../templates/008-WEB_TYPESCRIPT_PACKAGE.md) possède leur adaptation.
PGR ne fournit pas de `vite.config.ts` universel. Si Vite est sélectionné, créer ou adapter la configuration réelle à partir des décisions décrites dans [`../templates/009-WEB_VITE.md`](../templates/009-WEB_VITE.md).
PGR ne fournit pas non plus de `main.scss` ou de thème universel. Si CSS/Sass est sélectionné, organiser les sources selon les besoins réels et suivre [`../templates/010-WEB_CSS_SASS.md`](../templates/010-WEB_CSS_SASS.md).
Le nom `frontend/` est une convention possible, pas un chemin imposé par ce skeleton.
## Décisions destinataire avant matérialisation
Résoudre explicitement au minimum :
1. la racine et le scope exacts du frontend ;
2. TypeScript ou JavaScript, avec justification si une nouvelle baseline durable n'adopte pas la recommandation TypeScript ;
3. le package manager réel et la politique de lockfile adaptée au rôle du package ;
4. les versions réelles de TypeScript et des dépendances, ainsi que les déclarations `@types/*` réellement nécessaires ;
5. Vite ou un build tool alternatif, avec ses chemins `root`, cache, outputs, `base`, ports, plugins et assets lorsqu'ils s'appliquent ;
6. CSS seul ou Sass, puis l'implémentation Sass réelle si sélectionnée ;
7. le framework CSS éventuel : aucun, Bootstrap, Tailwind CSS ou autre ; ce choix reste local au projet ;
8. les entrypoints de styles publics des dépendances et les overrides réellement nécessaires ;
9. les scripts de package réellement utiles (`typecheck`, `dev`, `build`, `preview` ou équivalents) ;
10. la gate frontend indépendante du host et les éventuels smokes navigateur utiles ;
11. les prérequis produits par d'autres owners, s'il en existe, sans les faire absorber par le frontend.
Aucune décision ouverte ne doit être remplacée silencieusement par une valeur observée dans Games ou KSP.
## Dépendances et manifest
Le package réel **SHOULD** rester privé lorsqu'il représente une application non publiée, conformément à `540`.
Les dépendances de développement telles que TypeScript, Vite, Sass ou packages de déclarations sont ajoutées uniquement si les choix du projet les rendent nécessaires. Le skeleton MUST NOT préremplir `@types/node`, `@types/bootstrap`, `sass-embedded`, Vite ou Bootstrap sans besoin réel ni version décidée.
Lorsqu'une dépendance fournit déjà ses propres types, ne pas ajouter un package `@types/*` redondant.
## Styles
CSS source et Sass source sont des entrées versionnées. Les CSS compilées/minifiées, sourcemaps et copies dans l'output sont générées sauf contrat de distribution explicite.
Pour du nouveau Sass contrôlé, `@use` / `@forward` sont préférés lorsque les dépendances le permettent. Une compatibilité `@import` peut être conservée pour un package existant qui l'exige encore.
Le choix d'un framework CSS ne rend ni Bootstrap, ni Tailwind CSS, ni un thème spécifique normatif pour les autres projets.
## Build et outputs
Lorsque Vite est sélectionné, le cache et `build.outDir` restent générés et hors Git. Les chemins exacts restent locaux.
`build.emptyOutDir = true` n'est utilisé que sur un output dédié. `vite preview` reste un smoke/prévisualisation locale et ne devient pas un serveur de production.
Un autre build tool possède ses propres décisions project-specific tant qu'aucun owner PGR dédié n'existe.
## Validation initiale
La validation suit [`../validation/005-WEB_FRONTEND_VALIDATION.md`](../validation/005-WEB_FRONTEND_VALIDATION.md).
Selon les profils sélectionnés, elle doit pouvoir prouver indépendamment du host, autant que possible :
```text
restore reproductible
TypeScript typecheck
compilation/transformation des styles
build frontend de production
smoke navigateur seulement si nécessaire
```
La commande concrète appartient au package manager et aux outils réellement sélectionnés.
Le host reçoit ensuite sa propre gate d'intégration. Un PASS frontend ne constitue pas un PASS Tauri ou plateforme.
Une instanciation temporaire MAY être utilisée pour un dry-run de cette specialization. Elle doit employer les toolchains officielles réelles plutôt qu'un audit Python simulant TypeScript/Vite/Sass.
## Composition avec un host
Un host peut composer ce skeleton comme fondation frontend, puis ajouter son propre profil/skeleton.
Cette composition ne transfère jamais au host l'ownership de TypeScript, du package manager, de Vite ou de Sass/CSS.
Le skeleton Tauri reste `DEFER` pendant `0.1.1`. La présence du présent skeleton Web satisfait une pièce de préparation mais ne décide pas à elle seule la promotion du candidat Tauri.
## Hors scope
Cette specification ne possède pas :
- Tauri ou un autre host natif ;
- WASM ou ses bindings/générations ;
- backend/serveur Web ;
- deployment/operations ;
- choix de framework UI/CSS universel ;
- configuration de sécurité propre à un host ;
- service worker/PWA tant qu'un owner distinct n'est pas justifié.

217
docs/skeletons/004-TAURI.md Normal file
View File

@@ -0,0 +1,217 @@
<!-- file: docs/skeletons/004-TAURI.md -->
<!-- version: 1 -->
# Skeleton — Tauri 2
## Objectif
Cette specification décrit une baseline organisationnelle composable pour une application Tauri 2 contrôlée par le projet, sans transformer les choix observés dans Games ou KSP en obligations universelles.
Elle compose les responsabilités déjà possédées par :
- [`001-PROJECT_GOVERNANCE_FOUNDATION.md`](001-PROJECT_GOVERNANCE_FOUNDATION.md) pour la gouvernance locale ;
- [`002-RUST_CARGO_WORKSPACE.md`](002-RUST_CARGO_WORKSPACE.md) pour le workspace et le host Rust/Cargo ;
- [`003-WEB_FRONTEND.md`](003-WEB_FRONTEND.md) lorsque le frontend Web est gouverné par cette baseline ;
- [`../rules/710-TAURI.md`](../rules/710-TAURI.md) pour l'intégration Tauri elle-même.
Le contrat transversal des skeletons reste possédé par [`../rules/220-SKELETONS.md`](../rules/220-SKELETONS.md). Le présent document sélectionne et ordonne des décisions ; il ne recopie pas les règles de ces owners.
## Applicabilité
Appliquer ce skeleton à un nouveau host Tauri 2 dont le projet contrôle l'organisation du dépôt et souhaite une baseline PGR composable.
Pour un projet Tauri existant, cette specification sert d'abord de référence de comparaison. L'adoption suit [`../rules/230-ADOPTION.md`](../rules/230-ADOPTION.md) et classe les écarts `ADOPT / KEEP-LOCAL / OVERRIDE / DEFER` au lieu de migrer mécaniquement vers le layout proposé.
Ne pas appliquer ce skeleton uniquement parce qu'un frontend Web existe, parce qu'une application desktop est envisagée ou parce que Tauri apparaît dans un autre projet. La présence effective d'un host Tauri 2 est la condition d'applicabilité.
## Composition de référence
Pour une nouvelle baseline contrôlée, l'ordre de composition est :
```text
001 PROJECT_GOVERNANCE_FOUNDATION
↓
002 RUST_CARGO_WORKSPACE
↓
003 WEB_FRONTEND si le frontend est gouverné ici
↓
710 TAURI owner framework
↓
004 TAURI présente specification d'instanciation
↓
profils plateforme Android/iOS/autres uniquement s'ils sont ciblés
```
Cette composition ne transfère aucun ownership. TypeScript, package manager, Vite, CSS/Sass et framework CSS restent possédés par leurs owners Web ; Cargo/Rust reste possédé par `510`; Android reste possédé par `610` lorsqu'il s'applique.
## Décisions obligatoires avant matérialisation
Le projet doit résoudre explicitement au minimum :
1. l'identité du host, sa place dans le workspace et les noms distincts de ses cibles `lib` et `bin` ;
2. la version de Tauri 2 réellement retenue et sa stratégie de mise à jour ;
3. la racine frontend et les owners Web réellement sélectionnés ;
4. le package manager frontend lorsqu'un package JavaScript existe ;
5. les commandes de développement et de build reliant Tauri au frontend ;
6. la stratégie `devUrl` / `frontendDist` cohérente avec la chaîne frontend ;
7. les capabilities réellement nécessaires et leur mode de sélection ;
8. les permissions, commandes natives et scopes associés ;
9. les plugins réellement requis et leurs modifications de configuration/ACL ;
10. les fenêtres/webviews réellement nécessaires et leur répartition de privilèges ;
11. la politique de version pour `tauri.conf.json` et le frontend conformément aux règles de gouvernance ;
12. les ressources, icônes, bundle targets et cibles plateforme réellement distribuées ;
13. la gate initiale capable de prouver les surfaces effectivement matérialisées.
Une décision encore inconnue reste une entrée ouverte ; elle ne doit pas être remplacée par une valeur copiée depuis Games, KSP ou un scaffold Tauri.
## Baseline organisationnelle recommandée
Pour un nouveau projet contrôlé, le host **SHOULD** rester une crate Cargo directement lisible et la surface Tauri **SHOULD** être visible à la racine de cette crate :
```text
<tauri-crate>/
├── Cargo.toml
├── build.rs
├── tauri.conf.json
├── capabilities/
├── src/
│ ├── lib.rs
│ ├── main.rs
│ └── tauri.rs
└── frontend/
```
`frontend/` est la convention de cette baseline PGR lorsque le projet n'a pas déjà une autre racine frontend motivée. Un projet existant ou une contrainte externe peut conserver `src-tauri/`, une autre racine frontend ou une autre disposition supportée par la toolchain ; cet écart n'est pas à lui seul une raison de réécriture.
Le package Tauri contrôlé **SHOULD** utiliser une paire `lib + bin` conforme à `710-TAURI.md` : bibliothèque applicative/façade, launcher mince et module `src/tauri.rs` pour l'assemblage Tauri et les wrappers d'invocation.
## Frontend
Lorsque le projet ne possède pas déjà une stack frontend imposée ou motivée, la baseline Web de `003-WEB_FRONTEND.md` **SHOULD** être utilisée : TypeScript et Vite sont alors les choix recommandés, sans devenir des obligations Tauri universelles.
Le package manager est une décision du projet. npm, pnpm, yarn, Bun ou un autre outil supporté peuvent être retenus selon l'environnement et les contraintes réelles.
Sass et un framework CSS restent optionnels. Bootstrap, Tailwind CSS ou un autre framework ne sont jamais ajoutés par ce skeleton uniquement parce qu'ils existent dans un corpus historique.
WASM reste une unité séparée par défaut. Une chaîne WASM n'est intégrée dans le host que si l'architecture du produit l'exige explicitement.
## Capabilities, permissions et commandes
La baseline doit rendre visibles les trois niveaux distincts définis par `710-TAURI.md` :
```text
commande native enregistrée
permission ACL
capability attribuée à une fenêtre/webview
```
Pour une baseline simple à une capability, le projet peut conserver le comportement d'inclusion automatique supporté par sa version Tauri si cette décision est explicite et relue.
Dès que plusieurs capabilities, fenêtres/webviews ou niveaux de privilège apparaissent, une sélection explicite via `app.security.capabilities` **SHOULD** être préférée pour rendre la surface effective plus lisible.
Chaque ajout de plugin, permission, scope, origine distante ou capability doit être revu comme une modification de sécurité. Une commande enregistrée n'implique pas automatiquement qu'elle doit être accessible depuis toutes les fenêtres.
## Plugins
Aucun plugin n'est ajouté par défaut.
Lorsqu'un plugin est nécessaire, choisir sa version compatible, ajouter seulement les dépendances et bindings réellement utilisés, puis revoir les changements Rust, frontend, configuration et ACL associés.
Une commande de commodité comme `cargo tauri add` peut être utilisée si elle apporte une valeur réelle, mais la voie de validation reste la revue des fichiers effectivement modifiés. Le skeleton n'exige pas cette commande.
## Versions et métadonnées produit
`VERSION` reste la version canonique lorsque le projet adopte ce contrat de gouvernance.
La version du package Cargo du host suit la politique du workspace. `tauri.conf.json > version` et une éventuelle `package.json > version` doivent être classés explicitement, par exemple `MIRROR-STABLE` ou `MIRROR-EXACT`, selon le contrat de distribution réel.
Les identifiers d'application, noms de produit, bundle identifiers, publisher metadata et numéros plateforme sont des décisions produit/plateforme ; le skeleton ne fournit aucune identité fictive.
## Ordre d'initialisation
Une instanciation neuve suit normalement cet ordre :
1. appliquer la fondation locale et décider la version/unité de release ;
2. matérialiser ou adapter le workspace Rust/Cargo ;
3. créer le host Tauri et ses cibles `lib + bin` ;
4. sélectionner puis matérialiser la baseline frontend ;
5. raccorder `beforeDevCommand`, `beforeBuildCommand`, `devUrl` et `frontendDist` selon les outils réellement choisis ;
6. créer `tauri.conf.json` avec uniquement les propriétés utiles ;
7. créer les capability files et décider leur sélection ;
8. ajouter uniquement les commandes et plugins nécessaires ;
9. configurer fenêtres, ressources et bundle targets réellement requis ;
10. composer les profils plateforme applicables ;
11. exécuter la gate initiale proportionnée.
L'ordre peut être adapté lorsqu'une toolchain officielle crée certaines pièces automatiquement. Les fichiers générés doivent alors être relus et adaptés aux owners locaux avant d'être considérés comme baseline.
## Validation initiale
La gate minimale dépend des surfaces réellement créées. Elle **SHOULD** séparer les preuves :
```text
Rust/Cargo
→ fmt/check/clippy/tests sélectionnés par le projet
frontend
→ restore/typecheck/build/styles selon 003 et 005-WEB_FRONTEND_VALIDATION
Tauri integration
→ lancement Tauri ou smoke équivalent quand hooks/config/IPC/capabilities sont concernés
packaging
→ tauri build uniquement lorsqu'un artefact packagé doit réellement être prouvé
plateforme mobile
→ gates Android/iOS applicables en plus de Tauri
```
Une nouvelle baseline qui possède `beforeDevCommand`, `beforeBuildCommand`, `devUrl`, `frontendDist`, des commands ou des capabilities doit au minimum exercer une commande Tauri supportée qui charge réellement cette configuration ; un simple `cargo check` ne prouve pas cette intégration.
Le projet doit également vérifier :
```text
CHECK aucun placeholder ou identifiant fictif provenant de PGR/Games/KSP
CHECK noms lib/bin non ambigus après normalisation Cargo
CHECK frontend root et outputs cohérents avec tauri.conf.json
CHECK capabilities intentionnelles et surface cumulée relue
CHECK plugins présents uniquement s'ils sont utilisés
CHECK artefacts générés exclus ou classifiés selon leur rôle réel
CHECK secrets/signing credentials hors Git
REVIEW fenêtres, bundles, ressources et targets réellement nécessaires
```
## Templates techniques
Aucun template Tauri technique supplémentaire n'est requis pour matérialiser cette specification.
Le host dépend trop des décisions de nommage, de frontend, de capabilities, de plugins, de fenêtres, de plateformes et de versions pour qu'un `tauri.conf.json`, `Cargo.toml`, capability file ou `src/tauri.rs` universel apporte actuellement plus de valeur qu'il ne créerait de placeholders et de defaults arbitraires.
Les templates Rust/Cargo et Web existants restent utilisables pour leurs responsabilités propres. Un futur template Tauri ne sera justifié que si un besoin répétitif non correctement possédé par ces artefacts est démontré.
## Projet existant
Pour un projet existant :
- conserver son layout supporté lorsqu'une migration n'apporte pas de valeur démontrée ;
- comparer les owners et décisions plutôt que les noms de fichiers ;
- inventorier capabilities, plugins, commandes, hooks, fenêtres, bundles et plateformes ;
- classer les écarts selon `ADOPT / KEEP-LOCAL / OVERRIDE / DEFER` ;
- introduire les changements par tranches validables plutôt qu'en remplaçant le scaffold complet.
L'objectif est l'autonomie locale du projet, pas sa ressemblance visuelle avec le skeleton PGR.
## Hors scope
Cette specification ne possède pas :
- un framework frontend ou CSS universel ;
- un package manager universel ;
- une version exacte de Tauri/CLI/plugin ;
- un port de développement universel ;
- un catalogue de plugins ;
- une configuration de fenêtres ou bundles universelle ;
- une chaîne WASM implicite ;
- les règles Android/iOS ;
- un CI/CD ou deployment universel ;
- un template technique Tauri par symétrie.

View File

@@ -1,5 +1,5 @@
<!-- file: docs/studies/000-README.md -->
<!-- version: 2 -->
<!-- version: 5 -->
# Index des études PGR
@@ -10,4 +10,6 @@ Une étude peut comparer des projets sources, des technologies ou plusieurs opti
## É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.
- [`002-TAURI_SKELETON_DECISION.md`](002-TAURI_SKELETON_DECISION.md) — décision historique `DEFER` du skeleton Tauri, complétée en `0.1.1-beta.1` par la preuve que ses cinq prérequis Web disposent désormais d'owners PGR, sans lever le report avant `0.1.4`.
- [`003-V0_1_0_HORIZON_REVIEW.md`](003-V0_1_0_HORIZON_REVIEW.md) — revue d'horizon `0.1.0-beta.1` engageant les prochaines releases `0.1.x` suffisamment décidées et conservant les autres axes sans numéro.
- [`004-V0_1_4_HORIZON_REVIEW.md`](004-V0_1_4_HORIZON_REVIEW.md) — revue de fermeture `0.1.4` clarifiant le besoin d’une release `0.1.5` dédiée à la sémantique normative, à l’autonomie des projets et à la frontière PGR / SaseDev Knowledge avant les adoptions Games/KSP.

View File

@@ -1,15 +1,15 @@
<!-- file: docs/studies/002-TAURI_SKELETON_DECISION.md -->
<!-- version: 1 -->
<!-- version: 4 -->
# 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.
Cette étude conserve la décision historique `0.0.5-alpha.9` sur la matérialisation d'un skeleton Tauri pour les nouveaux projets que l'organisation contrôle, puis son réexamen formel pendant `0.1.4`.
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é
## Corpus historique et état observé `0.0.5`
Le corpus de réconciliation reste celui de `0.0.5` :
@@ -78,7 +78,7 @@ Références vérifiées le `2026-09-25` :
- <https://v2.tauri.app/plugin/file-system/>
- <https://v2.tauri.app/learn/security/using-plugin-permissions/>
## Décision
## Décision historique `0.0.5-alpha.9`
Décision `alpha.9` :
@@ -139,3 +139,219 @@ Cette décision ne :
- intègre pas WASM dans le host ;
- migre KSP ou Games vers PGR ;
- modifie pas les règles Tauri déjà stabilisées.
## Réexamen de préparation 0.1.1-beta.1
Le `DEFER` décidé en `0.0.5-alpha.9` reste la décision active pendant `0.1.1`. La présente révision n'autorise ni création ni adoption d'un skeleton Tauri ; elle vérifie uniquement si les responsabilités Web dont l'absence motivait le report possèdent désormais des owners PGR suffisants pour que `0.1.4` puisse réexaminer le candidat sur des bases concrètes.
### Condition 1 — TypeScript et conventions Web contrôlées
Couverture disponible :
```text
docs/rules/530-TYPESCRIPT.md
docs/templates/008-WEB_TYPESCRIPT_PACKAGE.md
templates/web-typescript/tsconfig.json
templates/web-typescript/package.json
docs/skeletons/003-WEB_FRONTEND.md
```
Le langage/type-check, les déclarations externes, le manifest minimal et les décisions laissées au projet ont désormais des owners explicites. TypeScript reste une recommandation `SHOULD`, pas une obligation Tauri universelle.
État de préparation : **couvert**.
### Condition 2 — Vite et ownership des commandes/dev server/build outputs
Couverture disponible :
```text
docs/rules/550-VITE.md
docs/templates/009-WEB_VITE.md
docs/validation/005-WEB_FRONTEND_VALIDATION.md
```
Le dev server, le cache, `build.outDir`, `publicDir`, les scripts et la frontière source/généré sont possédés sans imposer de `vite.config.ts`, layout, port ou `base` universel.
État de préparation : **couvert**.
### Condition 3 — Sass/CSS et statut des artefacts générés
Couverture disponible :
```text
docs/rules/560-CSS_SASS.md
docs/templates/010-WEB_CSS_SASS.md
docs/validation/005-WEB_FRONTEND_VALIDATION.md
```
CSS seul reste valide ; Sass est optionnel mais recommandé lorsque utile. Sources, compilation, outputs, entrypoints de packages et compatibilité `@import` sont distingués sans imposer Bootstrap ni un `main.scss` générique.
État de préparation : **couvert**.
### Condition 4 — validation frontend indépendante de la validation Tauri
Couverture disponible :
```text
docs/validation/005-WEB_FRONTEND_VALIDATION.md
docs/validation/001-VALIDATION_MATRIX.md
docs/skeletons/003-WEB_FRONTEND.md
```
Restore, type-check, styles, build et smoke navigateur sont classifiés indépendamment du host. Un `PASS` frontend ne vaut explicitement pas `PASS` Tauri.
État de préparation : **couvert**.
### Condition 5 — framework CSS classé comme décision de skeleton/projet
Couverture disponible :
```text
docs/rules/560-CSS_SASS.md
docs/templates/010-WEB_CSS_SASS.md
docs/skeletons/003-WEB_FRONTEND.md
```
Bootstrap, Tailwind CSS ou une alternative sont des choix locaux. Leur présence dans Games/KSP ne les élève pas en règle Tauri ni en règle Web universelle.
État de préparation : **couvert**.
### Conclusion de préparation
Les cinq conditions de sortie formulées en `0.0.5-alpha.9` possèdent désormais des owners PGR matérialisés et non redondants.
Cela change le diagnostic de préparation, pas la décision de skeleton :
```text
conditions Web requises couvertes
skeleton Tauri dans 0.1.1 toujours DEFER
réexamen autorisé 0.1.4
création automatique interdite
```
`0.1.4` devra réexaminer le corpus alors courant, les versions/outils réellement soutenus, le profil `710-TAURI.md` et la composition avec `003-WEB_FRONTEND.md`. Il pourra confirmer, modifier ou abandonner le candidat historique. La présente étude ne préjuge pas de cette décision.
Le candidat historique `frontend/ + Vite + TypeScript + Sass + Bootstrap + TS-RS` reste donc une observation à réexaminer, pas une baseline déjà approuvée. En particulier, `frontend/`, Vite, Sass et Bootstrap ne deviennent pas des obligations Tauri du seul fait que les owners permettant de les encadrer existent désormais.
## Réexamen décisionnel `0.1.4-alpha.2`
`0.1.4-alpha.1` a réaudité le corpus au lieu de prolonger le `DEFER` par inertie. Les baselines réellement fournies sont :
```text
Games 0.3.6 1 host Tauri
KSP 0.3.19 6 hosts Tauri
```
Les `7` hosts actuels convergent encore sur un host Cargo direct `lib + bin`, `build.rs`, `tauri.conf.json`, `capabilities/`, `src/tauri.rs`, une racine frontend dédiée, TypeScript et Vite, sans `src-tauri/`. Games n'exerce toutefois plus les deux hosts du corpus historique, et Bootstrap/Sass/TS-RS, plugins, fenêtres, ACL, ports, bundle/resources et WASM restent suffisamment variables pour ne pas former une baseline Tauri indivisible.
Les cinq conditions de sortie historiques sont désormais couvertes par les owners Web `530/540/550/560`, `005-WEB_FRONTEND_VALIDATION.md` et `003-WEB_FRONTEND.md`. Le motif Web qui bloquait la matérialisation en `0.0.5` est donc levé.
La réconciliation de `710-TAURI.md` en révision `7` précise en outre :
- la distinction entre commande enregistrée, permission et capability ;
- la nécessité de traiter la sélection des capability files comme une décision de sécurité explicite ;
- la composition cumulative des droits lorsqu'une fenêtre/webview appartient à plusieurs capabilities ;
- le statut de `src-tauri/` comme layout supporté, tandis que le host Cargo direct reste une convention PGR recommandée pour les nouvelles baselines contrôlées ;
- l'ownership Web séparé : TypeScript, Vite, Sass/CSS, framework CSS, package manager et génération de bindings ne sont plus choisis par le profil Tauri lui-même ;
- la validation proportionnée par owner plutôt qu'un `tauri build` systématique.
### Décision active
La décision active de `0.1.4-alpha.2` est :
```text
DEFER historique pour absence d'owners Web LIFT
candidat organisationnel ADOPT FOR MATERIALIZATION
skeleton à matérialiser docs/skeletons/004-TAURI.md
matérialisation dans alpha.2 NO
matérialisation visée alpha.3
```
Le `DEFER` de `0.0.5-alpha.9` reste conservé comme décision historique ; il n'est plus la décision active du candidat courant.
### Composition retenue pour `alpha.3`
La specification Tauri candidate devra composer, sans duplication normative :
```text
001-PROJECT_GOVERNANCE_FOUNDATION
+ 002-RUST_CARGO_WORKSPACE
+ 003-WEB_FRONTEND lorsque le projet possède le frontend contrôlé correspondant
+ profil Tauri 710
+ profils plateforme réellement ciblés
```
Le skeleton pourra proposer `frontend/`, TypeScript et Vite comme baseline recommandée pour une nouvelle application contrôlée compatible, mais devra laisser visibles les décisions destinataire et ne pas convertir ces recommandations en obligations Tauri. Sass, Bootstrap, TS-RS, plugins, fenêtres, ports, CSP, bundle targets, ressources et valeurs plateforme restent conditionnels au besoin réel.
La specification devra également rendre explicite la politique de sélection des capabilities et la revue de la surface de sécurité avant sa gate initiale.
### Artefacts toujours différés
Le réexamen ne démontre toujours pas le besoin de créer en `alpha.2` :
- un template technique Tauri copiable ;
- un contrat de validation Tauri séparé ;
- un catalogue de plugins ou permissions par défaut ;
- un framework CSS universel ;
- un owner iOS, serveur Rust ou deployment/operations par proximité.
Ces décisions restent à réévaluer après matérialisation de la specification, conformément au plan `0.1.4`.
## Réconciliation finale des artefacts `0.1.4-beta.1`
La matérialisation de `docs/skeletons/004-TAURI.md` en `alpha.3` permet de vérifier la frontière entre specification organisationnelle, owner Tauri, owners Web et validations existantes.
### Couverture obtenue
La composition active est :
```text
001-PROJECT_GOVERNANCE_FOUNDATION
+ 002-RUST_CARGO_WORKSPACE
+ 003-WEB_FRONTEND si applicable
+ 710-TAURI
+ 004-TAURI
+ profils plateforme réellement ciblés
```
`004-TAURI.md` ne recopie pas les règles de ces owners. Il possède les décisions d'instanciation et renvoie les contraintes détaillées à leurs documents respectifs.
### Template technique Tauri
Décision : **DO NOT CREATE**.
Aucun ensemble de fichiers Tauri (`Cargo.toml`, `build.rs`, `tauri.conf.json`, capability files, `src/tauri.rs`) ne peut être rendu générique sans choisir prématurément au moins une partie des éléments suivants : nom du host, hooks frontend, ports/URLs, capabilities, permissions, plugins, fenêtres, identifiers, resources, bundle targets ou plateformes.
Les templates Rust/Cargo et Web existants possèdent déjà les parties réellement réutilisables. Un futur template Tauri reste possible uniquement après démonstration d'un sous-ensemble répétitif non arbitraire dans plusieurs instanciations réelles.
### Contrat de validation Tauri séparé
Décision : **DO NOT CREATE**.
La preuve nécessaire est déjà composable :
- Rust/Cargo par les owners Rust et la matrice de validation ;
- frontend par `005-WEB_FRONTEND_VALIDATION.md` ;
- intégration Tauri, ACL, hooks et packaging par `710-TAURI.md` et la gate initiale de `004-TAURI.md` ;
- plateformes mobiles par leurs profils applicables.
Créer `docs/validation/006-TAURI_VALIDATION.md` aujourd'hui dupliquerait ces responsabilités sans lacune démontrée.
### Dry-run local
Décision : **NOT REQUIRED** pour `0.1.4-beta.1`.
Le skeleton est une specification et ne fournit pas de scaffold exécutable. Créer un faux projet uniquement pour obtenir un lancement Tauri introduirait précisément les valeurs arbitraires que la specification cherche à éviter. Les sept hosts Games/KSP déjà audités fournissent le corpus d'implémentation ; `beta.1` doit vérifier statiquement que la specification les abstrait sans copier leurs choix locaux.
### Décision active après `beta.1`
```text
DEFER historique Web LIFT
004-TAURI.md KEEP
template Tauri générique DO NOT CREATE
validation Tauri séparée DO NOT CREATE
dry-run factice NOT REQUIRED
artefact supplémentaire sans lacune réelle FORBIDDEN BY DEFAULT
```
La prochaine étape est la RC : freeze du scope Tauri, préparation du changelog candidate et revue d'horizon transversale avant tout prompt de release suivante.

View File

@@ -0,0 +1,163 @@
<!-- file: docs/studies/003-V0_1_0_HORIZON_REVIEW.md -->
<!-- version: 1 -->
# Revue d'horizon 0.1.0 — trajectoire d'adoption et owners techniques
## Objet
Cette étude matérialise la revue d'horizon obligatoire prévue par `0.1.0-beta.1`. Elle intervient après validation de la première baseline Rust/Cargo réutilisable et avant RC.
Elle ne cherche pas à remplir artificiellement la roadmap. Elle engage seulement les releases `0.1.x` dont le domaine, l'ordre et les prérequis sont suffisamment décidés à partir des owners PGR existants et des corpus Games/KSP déjà audités.
## État acquis à l'entrée
`0.1.0-alpha.5` a démontré deux propriétés nécessaires à une adoption réelle :
```text
NEW les templates Rust/Cargo peuvent instancier un workspace temporaire accepté par Cargo/rustfmt/Clippy
ADOPTION un workspace Rust existant peut conserver des décisions KEEP-LOCAL / DEFER sans copie destructive
```
Le contrat `230-ADOPTION.md` permet donc de migrer progressivement un dépôt réel sans attendre que PGR possède un owner pour chaque technologie rencontrée.
Les profils suivants existent déjà :
```text
510 Rust / Cargo
520 Java / Maven / Gradle
610 Android
710 Tauri 2
```
Le skeleton Tauri reste toutefois `DEFER` tant que les owners Web requis par `002-TAURI_SKELETON_DECISION.md` ne sont pas matérialisés.
## Pression des corpus
### Games
La baseline Games fournie exerce déjà plusieurs domaines distincts :
- Rust/Cargo ;
- frontend Web avec TypeScript, Vite et Sass/CSS ;
- Java/Gradle ;
- Android/JNI/SDL ;
- Tauri ;
- WASM dans certains chemins ;
- trajectoire serveur future, mais sans implémentation Actix Web autoritaire suffisante dans le corpus audité.
Games possède déjà une future release locale `0.3.7` destinée à l'alignement PGR. PGR doit donc préparer rapidement les owners réellement nécessaires sans absorber tout le dépôt Games dans une seule release PGR.
### KSP
KSP exerce principalement Rust/Cargo et plusieurs applications Tauri. Son adoption ne doit pas attendre Java, Android, WASM ou un profil serveur qui ne lui sont pas nécessaires.
L'ordre retenu reste Games avant KSP, afin que la première adoption large fournisse un retour d'expérience avant la migration du second corpus.
## Releases `0.1.x` engagées
### `0.1.1` — fondation frontend Web
Domaine : Web frontend contrôlé.
Scope attendu :
- owner(s) TypeScript applicables ;
- Vite et contrat dev/build outputs ;
- Sass/CSS et statut des artefacts générés ;
- package manager et lockfile classifiés sans imposer arbitrairement npm ;
- validation frontend indépendante du host Tauri ;
- templates/skeletons/audits uniquement lorsqu'un besoin réutilisable est démontré.
Games est le corpus principal. Cette release ne crée pas le skeleton Tauri, n'intègre pas WASM et ne normalise pas encore un serveur Rust.
### `0.1.2` — réévaluation Java / Gradle
Domaine : Java et build Gradle génériques.
Le profil `520-JAVA_MAVEN_GRADLE.md` existe déjà. La release doit le confronter à Games, séparer ce qui appartient à Java/Gradle de ce qui appartient à Android, puis créer uniquement les templates, validations ou audits génériques manquants.
### `0.1.3` — réévaluation Android
Domaine : Android.
Le profil `610-ANDROID.md` existe déjà. La release doit l'éprouver sur le corpus Games, notamment autour du projet Gradle Android, des wrappers Java/JNI, des ressources et du packaging, sans transférer dans PGR les choix propres à un jeu ou à SDL lorsqu'ils ne sont pas génériques.
### `0.1.4` — Tauri contrôlé
Domaine : Tauri.
Cette release réexamine formellement le `DEFER` actuel après `0.1.1`. Le skeleton Tauri contrôlé n'est matérialisé que si les conditions de sortie de `002-TAURI_SKELETON_DECISION.md` sont réellement satisfaites par les owners Web alors disponibles.
Si ces conditions ne sont pas satisfaites, la release conserve explicitement le `DEFER` et REPLAN la suite au lieu de fabriquer un skeleton incomplet.
### `0.1.5` — adoption de Games
Domaine : adoption réelle de `sasedev-games`.
Utiliser `230-ADOPTION.md` et `007-EXISTING_PROJECT_ADOPTION.md` pour établir la baseline autoritaire, mapper les owners PGR applicables et découper la migration. Les domaines non encore possédés par PGR peuvent rester `KEEP-LOCAL` ou `DEFER` ; l'adoption ne doit pas créer une obligation de normaliser WASM ou le serveur uniquement pour obtenir un statut global artificiel.
### `0.1.6` — adoption de KSP
Domaine : adoption réelle de `khadhroony-solana-project`.
La pression principale attendue est Rust/Cargo + Tauri. La migration réutilise le retour d'expérience de Games et ne doit pas attendre les profils Java/Android/WASM/serveur non applicables.
### `0.1.7` — audits Rust/Clippy statiques Python
Domaine : prévalidation Rust dans un environnement Python-only.
Cette release reste volontairement après les deux adoptions afin de dériver les contrôles de conventions réellement utiles observés dans PGR, Games et KSP.
Les scripts :
- sont read-only et non interactifs ;
- fonctionnent sans Cargo ni `rustc` ;
- réutilisent les options Rust/Clippy possédées par PGR au lieu d'inventer une politique parallèle ;
- documentent chaque contrôle comme `FULL`, `LIMITED` ou `UNSUPPORTED` ;
- ne présentent jamais un `PASS` Python comme équivalent à `cargo clippy PASS`.
## Candidats laissés sans numéro
### WASM
Le corpus Games exerce WASM, mais la valeur d'un owner PGR séparé doit être confirmée pendant `0.1.5`. Aucun numéro n'est réservé maintenant.
### Serveur Web Rust
Actix Web ou une alternative reste un candidat à partir d'un corpus d'implémentation réel. La présence d'une trajectoire HTTP/3/WebTransport dans un roadmap projet ne suffit pas à normaliser aujourd'hui un framework serveur.
### Projets documentaires et généricité hors logiciel
`saselang-bible` reste un bon corpus futur pour tester PGR sur un projet documentaire/spécification. Cet axe, ainsi que la généricité hors logiciel, reste orienté vers une trajectoire `0.2.x` / `0.3.x` à décider ultérieurement.
### Déploiement et exploitation
Une future famille majeure devra traiter de manière composable les responsabilités de déploiement et d'exploitation : reverse proxy Nginx/Apache, PostgreSQL/MySQL ou autres bases, Docker/Compose, services Linux, environnements/secrets, migrations, backup/restore, health, observabilité et skeletons/audits de déploiement.
Un horizon `0.4.x` ou `0.5.x` est plausible, mais aucun numéro précis n'est réservé tant que les séries intermédiaires n'ont pas déterminé le découpage réel.
## Décision sur Tauri
La décision `DEFER` de `002-TAURI_SKELETON_DECISION.md` reste vraie pendant `0.1.0`.
La roadmap engage `0.1.4` comme release de domaine Tauri, pas comme autorisation anticipée de créer le skeleton. Son premier devoir sera de vérifier que `0.1.1` a effectivement fourni les owners Web nécessaires.
## Prochaine cible
La prochaine release PGR après publication de `0.1.0` est :
```text
0.1.1 — fondation frontend Web
```
Le prompt `prompts/007-V0_1_1_START_PROMPT.md` est donc préparé pendant `beta.1`, mais ne doit être exécuté qu'après stable `v0.1.0` et vérification post-tag `PASS`.
## Critère de réouverture de la revue
Une nouvelle revue macro est requise si :
- `0.1.1` révèle que le domaine Web doit être scindé avant de pouvoir servir Tauri ;
- Games ne peut pas être adopté avec `KEEP-LOCAL` / `DEFER` sans owner WASM ou serveur supplémentaire ;
- `0.1.4` ne peut pas lever le `DEFER` Tauri ;
- l'ordre Games puis KSP cesse d'être rationnel à cause d'une dépendance technique nouvellement démontrée ;
- une release engagée perd son besoin réel ou doit être remplacée par une autre responsabilité.

View File

@@ -0,0 +1,139 @@
<!-- file: docs/studies/004-V0_1_4_HORIZON_REVIEW.md -->
<!-- version: 1 -->
# Revue d’horizon 0.1.4 — sémantique normative, autonomie et frontière Knowledge
## Objet
Cette étude clôt la revue d’horizon explicitement requise par le plan `0.1.4`. Elle décide si les adoptions Games/KSP peuvent suivre immédiatement la release Tauri ou si un contrat transversal doit être stabilisé auparavant.
Le déclencheur provient d’un usage réel de PGR pour initialiser SaseDev Knowledge. Trois ambiguïtés ont été observées sans remettre en cause le travail Tauri de `0.1.4` : force réelle de `SHOULD`, relation d’un projet avec PGR après adoption, et emplacement futur des howtos/recettes/snippets lorsque Knowledge devient suffisamment fonctionnel.
## Sources PGR examinées
Les owners actuels pertinents sont :
```text
RULES.md
rules/200-GOVERNANCE.md
rules/210-WORKFLOW.md
rules/220-SKELETONS.md
rules/230-ADOPTION.md
rules/400-VALIDATION.md
skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md
templates/003-NEW_SESSION_PROMPT.md
templates/007-EXISTING_PROJECT_ADOPTION.md
```
Ces documents contiennent déjà des éléments compatibles avec l’intention recherchée, notamment l’autonomie du projet et la copie locale des règles applicables. Le défaut est une insuffisance de précision et de propagation du contrat, pas l’absence totale du principe.
## 1. Force normative de `SHOULD`
La formulation actuelle décrit `SHOULD / SHOULD NOT` comme un comportement attendu par défaut avec dérogation possible si une autre solution est mieux adaptée et justifiée. Cette rédaction peut être interprétée comme une obligation conditionnelle.
La prochaine clarification doit établir sans ambiguïté :
```text
MUST / MUST NOT exigence normative ; écart = non-conformité sauf exception/override autorisé
SHOULD / SHOULD NOT forte recommandation ; préférence par défaut mais non obligatoire
MAY possibilité neutre ; aucune préférence implicite
```
Un écart à un `SHOULD` :
- MUST NOT devenir à lui seul une non-conformité ;
- MUST NOT faire échouer à lui seul une gate ;
- MUST NOT exiger automatiquement un `OVERRIDE` ;
- MAY être documenté lorsqu’il est significatif pour la maintenance, l’architecture ou la reprise future.
La distinction est suffisamment structurante pour être stabilisée avant toute nouvelle adoption réelle.
## 2. Autonomie après instanciation ou adoption
PGR doit être un référentiel d’initialisation, de comparaison et de réalignement volontaire, pas un upstream vivant implicitement suivi par chaque projet.
Le contrat cible est :
```text
snapshot PGR choisi
↓
instanciation / adoption / adaptation
↓
baseline locale du projet
↓
règles locales = autorité des sessions/releases suivantes
```
Après établissement de la baseline locale :
- le projet MUST fonctionner sans rechercher une version PGR plus récente ;
- le projet MUST NOT considérer PGR comme une dépendance documentaire implicite à mettre à jour à chaque session ;
- ses règles, architecture, plans, templates et validations locales deviennent l’autorité de son évolution ;
- la version PGR utilisée MAY être conservée comme provenance historique ;
- un réalignement futur avec PGR est une opération explicite, bornée et volontaire, utilisant un snapshot PGR choisi et une nouvelle comparaison des écarts.
Ce point doit être propagé dans les contrats de reprise et d’adoption, sinon l’autonomie déjà annoncée dans les règles reste trop facile à contourner involontairement.
## 3. Frontière PGR / SaseDev Knowledge
PGR et Knowledge doivent rester utilisables indépendamment.
La frontière cible est :
```text
PGR
contrats normatifs et de gouvernance
owners et règles applicables
skeleton specifications minimales
templates nécessaires à un contrat réutilisable
contrats de validation/audit directement liés à ces règles
SaseDev Knowledge
howtos détaillés
recettes et procédures pratiques
snippets
exemples d’intégration
dépannage et variantes d’implémentation
explications pédagogiques et comparatifs pratiques
```
PGR MUST rester auto-suffisant pour comprendre et appliquer une règle. Une règle PGR ne doit pas dépendre d’un howto Knowledge pour déterminer ce qu’elle exige.
La future disponibilité de Knowledge MAY justifier l’épuration de contenus pratiques devenus redondants dans PGR, mais aucune extraction ne doit être effectuée uniquement pour anticiper cette disponibilité. Le déplacement physique exige un corpus Knowledge suffisamment fonctionnel et explicitement fourni comme source autoritaire de destination.
## Décision d’horizon
Les trois sujets sont transversaux à toutes les adoptions futures. Les reporter après Games/KSP ferait courir le risque de propager une sémantique ambiguë ou une liaison implicite à PGR dans les projets précisément utilisés pour éprouver le modèle d’adoption.
Décision : **une release de gouvernance/autonomie doit précéder les adoptions Games/KSP**.
La trajectoire devient :
```text
0.1.4 Tauri et skeleton contrôlé
0.1.5 sémantique normative + autonomie + frontière PGR/Knowledge
0.1.6 adoption sasedev-games
0.1.7 adoption khadhroony-solana-project
0.1.8 audits Rust/Clippy read-only
```
Aucun numéro au-delà de `0.1.8` n’est réservé par cette étude.
## Scope attendu de 0.1.5
`0.1.5` devra au minimum :
1. clarifier la force de `MUST / SHOULD / MAY` et les conséquences de gate ;
2. rendre explicite l’autorité locale après instanciation/adoption dans `230-ADOPTION`, les skeletons et les patterns de reprise concernés ;
3. définir un mécanisme de réalignement PGR volontaire sans mise à jour automatique ;
4. formaliser la frontière PGR / SaseDev Knowledge et classifier les contenus qui doivent rester normatifs ou devenir candidats à un futur transfert ;
5. vérifier que PGR reste autonome sans dépendance à Knowledge ;
6. ne pas commencer les adoptions Games/KSP ni les audits Rust réservés aux releases suivantes.
Une archive SaseDev Knowledge MAY être utilisée comme corpus d’observation si elle est explicitement fournie, mais `0.1.5` ne doit pas dépendre de son existence pour corriger les contrats PGR.
## Hors scope de la présente RC
La présente étude ne modifie pas encore `RULES.md`, `230-ADOPTION.md`, `400-VALIDATION.md`, les skeletons de fondation ou les templates de reprise. Ces modifications appartiennent à `0.1.5` afin que `0.1.4-rc.1` reste une phase de freeze Tauri et de handoff.
Elle ne migre ni Games ni KSP et ne déplace aucun contenu vers SaseDev Knowledge.

View File

@@ -1,5 +1,5 @@
<!-- file: docs/templates/001-RUST_CARGO_TOOLING.md -->
<!-- version: 3 -->
<!-- version: 4 -->
# Templates d'outillage Rust/Cargo
@@ -33,6 +33,8 @@ Adapter le header `# file:` de chacun à son nouveau chemin relatif. Comme il s'
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.
Dans un projet existant, ces fichiers sont des références de comparaison. `rustfmt.toml`, `clippy.toml` ou `.cargo/config.toml` déjà présents MUST être comparés avant remplacement ; une différence locale peut rester `KEEP-LOCAL`, devenir un `OVERRIDE` explicite ou rester `DEFER` conformément à [`../rules/230-ADOPTION.md`](../rules/230-ADOPTION.md). L’adoption n’exige pas une copie byte-for-byte des templates PGR.
## Validation dans un projet Rust
Après adaptation, les contrôles utiles dépendent du code et des manifests effectivement présents :

View File

@@ -1,5 +1,5 @@
<!-- file: docs/templates/002-CARGO_MANIFESTS.md -->
<!-- version: 3 -->
<!-- version: 4 -->
# Modèles de manifests Cargo workspace et crate membre
@@ -9,6 +9,8 @@ Le [manifest racine](../../templates/rust-cargo/Cargo.toml) est celui d'un works
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.
Pour un projet existant, ne pas remplacer le manifest racine ou les manifests membres uniquement parce qu’ils diffèrent des exemples PGR. Les héritages, noms, membres, lints, métadonnées et dépendances sont d’abord comparés selon [`../rules/230-ADOPTION.md`](../rules/230-ADOPTION.md), puis classifiés `ADOPT / KEEP-LOCAL / OVERRIDE / DEFER`. Le dry-run de [`../validation/004-RUST_CARGO_BASELINE_DRY_RUN.md`](../validation/004-RUST_CARGO_BASELINE_DRY_RUN.md) exerce séparément ce chemin non destructif.
## 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.

View File

@@ -0,0 +1,126 @@
<!-- file: docs/templates/006-OPERATOR_COMMAND_HANDOFF.md -->
<!-- version: 1 -->
# Pattern — handoff des commandes opérateur
## Usage
Ce pattern matérialise la sortie opérateur exigée par [`210-WORKFLOW.md`](../rules/210-WORKFLOW.md) après production d'un history et pendant une clôture stable. Son objectif est d'éviter que l'opérateur doive demander séparément quelles commandes exécuter entre le history reçu, son commit, le delta suivant et, pour une stable, le tag puis la vérification post-tag.
Le pattern est un guide de rendu : `210-WORKFLOW.md` reste l'owner normatif.
## Informations à résoudre avant le rendu
Le générateur doit déterminer depuis les preuves disponibles :
```text
project
X.Y.Z
tranche courante
statut du history
archive history réellement livrée
message de commit attendu
remote Git établi
branche Git établie
delta/fix suivant déjà livré ou non
stable obtenue ou non
tag canonique attendu
forge/archive post-tag applicable
preuve publish.* attendue ou non
```
Une valeur non établie ne doit pas être inventée. Si le remote ou la branche manque, le rendu peut d'abord fournir une commande de découverte telle que `git remote -v` ou `git branch --show-current`, puis demander d'utiliser la valeur réellement observée ; il ne doit pas transformer silencieusement un exemple `origin/master` en règle universelle.
## Fermeture d'une tranche non stable
Lorsque le history est livré sous forme de ZIP et que remote/branche sont établis, le bloc remis suit cette forme :
```bash
unzip -o <project>-<X.Y.Z>-<tranche>.history.zip -d .
git add -A
git diff --cached --check
git status --short
git commit -m "<message attendu>"
git push <remote> <branche>
```
Si le delta suivant ou le fix est déjà livré dans la même réponse, son application est affichée **après** le bloc de commit/push :
```bash
unzip -o <archive delta suivante>.delta.zip -d .
```
L'ordre visuel du rendu doit refléter l'ordre autorisé : history → commit/push → delta suivant.
## Tranche échouée suivie d'un fix
Un `FAIL`, `PARTIAL` ou `BLOCKED` est d'abord committé avec l'identité de la tranche observée, puis le fix est appliqué. Exemple générique :
```bash
unzip -o <project>-<X.Y.Z>-alpha.2.history.zip -d .
git add -A
git diff --cached --check
git status --short
git commit -m "X.Y.Z-alpha.2"
git push <remote> <branche>
unzip -o <project>-<X.Y.Z>-alpha.2.fix.1.delta.zip -d .
```
Le history `FAIL` n'est jamais remplacé par le futur `PASS` du fix.
## Première clôture qui établit réellement la stable
Quand `rel.N[/fix.M]` obtient le premier `PASS` stable, le commit porte l'identité produit :
```bash
unzip -o <project>-<X.Y.Z>-<rel.N[/fix.M]>.history.zip -d .
git add -A
git diff --cached --check
git status --short
git commit -m "X.Y.Z"
git push <remote> <branche>
```
Le tag vient ensuite. Si la politique locale utilise un tag annoté, le bloc type est :
```bash
git status --short
git rev-parse HEAD
git tag -a vX.Y.Z -m "vX.Y.Z"
git push <remote> vX.Y.Z
git rev-list -n 1 vX.Y.Z
git ls-remote --exit-code --tags <remote> refs/tags/vX.Y.Z
git ls-remote <remote> 'refs/tags/vX.Y.Z^{}'
```
Pour un tag annoté, `refs/tags/vX.Y.Z` peut identifier l'objet tag et différer du SHA du commit. La référence déréférencée `refs/tags/vX.Y.Z^{}` est celle qui doit être comparée au commit stable.
Si le projet utilise volontairement une autre forme de tag, le bloc est adapté à cette politique au lieu d'imposer `git tag -a`.
## Remise nécessaire pour `publish.*`
Après création/push du tag et génération de l'archive par la forge, le générateur indique explicitement ce qu'il attend. Pour le cas source-archive usuel :
```text
1. télécharger depuis la forge le ZIP correspondant exactement au tag vX.Y.Z ;
2. fournir ce ZIP au générateur ;
3. fournir les sorties Git du commit/tag local et distant exécutées ci-dessus ;
4. fournir toute preuve de publication supplémentaire exigée localement.
```
Le générateur vérifie alors l'archive publiée, calcule son empreinte dans son propre environnement lorsque possible et produit le rapport `publish.*` à partir des observations réelles. Le rapport reste extérieur au tag qu'il vérifie.
## Après `publish.* PASS`
Si une version suivante est déjà décidée et son prompt existe dans la stable, le générateur remet automatiquement la phrase de nouvelle session définie par [`003-NEW_SESSION_PROMPT.md`](003-NEW_SESSION_PROMPT.md), avec les noms réels du ZIP taggé, du rapport post-tag et du prompt versionné.
Si l'horizon reste ouvert, il remet à la place le handoff ou la consigne de revue d'horizon applicable sans inventer de prochaine version.
## Critère de qualité
Le handoff est correct lorsque l'opérateur peut passer du history reçu au commit, au delta suivant ou à la publication sans devoir deviner une commande, un message de commit, un ordre d'application ou un artefact à fournir, tout en conservant explicites les valeurs Git qui ne sont pas encore établies.

View File

@@ -0,0 +1,97 @@
<!-- file: docs/templates/007-EXISTING_PROJECT_ADOPTION.md -->
<!-- version: 1 -->
# Pattern — adoption PGR d’un projet existant
## Usage
Ce pattern aide à préparer une adoption PGR sur un dépôt existant conformément à [`../rules/230-ADOPTION.md`](../rules/230-ADOPTION.md). Il n’est pas un manifest obligatoire, un générateur de migration ni un remplacement du plan de release local.
Il peut être instancié comme étude, plan, tableau de décision ou section d’un document existant si le projet a besoin d’une trace durable. Un petit alignement dont les décisions sont évidentes MAY rester directement documenté dans le delta et le history correspondants.
## Baseline autoritaire
Consigner uniquement ce qui est réellement établi :
```text
repository / archive : <source>
commit / tag : <si connu>
version : <si applicable>
validation connue : <preuves déjà acquises et encore pertinentes>
```
Ne pas reconstruire une baseline à partir d’hypothèses ou d’une version plus récente de PGR.
## Inventaire utile
Identifier les éléments qui déterminent l’applicabilité :
- gouvernance et workflow déjà présents ;
- langages et build systems réellement utilisés ;
- plateformes et frameworks présents ;
- validations et scripts existants ;
- contraintes locales ou historiques à préserver ;
- profils PGR sans rapport avec le dépôt, explicitement hors scope si leur confusion est probable.
## Mapping d’adoption
La classification canonique est `ADOPT / KEEP-LOCAL / OVERRIDE / DEFER`. La forme exacte du mapping reste libre. Une table courte peut suffire :
```text
Owner / contrat État local Décision Action / justification
-------------------- ---------------- ------------ -----------------------
<RULE/PGR owner> <état observé> ADOPT <migration ciblée>
<contrat local> <état observé> KEEP-LOCAL <raison>
<RULE/PGR owner> <état observé> OVERRIDE <scope + raison>
<RULE/PGR owner> <état observé> DEFER <prérequis / déclencheur>
```
Les quatre décisions ont le sens normatif défini par `230-ADOPTION.md`. Ne pas créer une cinquième catégorie uniquement pour éviter de décider si un point est adopté, local, overridé ou différé.
## Découpage de migration
Pour chaque tranche réellement nécessaire, préciser :
```text
scope : <owners / fichiers / contrats concernés>
hors scope : <domaines laissés intacts>
risque principal : <ce qui pourrait être cassé>
preuve : <gate proportionnée>
```
Le découpage SHOULD favoriser des changements vérifiables indépendamment. Une migration ne doit pas embarquer une technologie future uniquement parce qu’un profil PGR existe.
## Historique et compatibilité
Noter les conventions qui commencent au point d’adoption et les snapshots historiques qui doivent rester inchangés.
Exemples :
```text
- ancienne nomenclature de tags conservée avant <point d’adoption> ;
- anciennes règles locales conservées dans les histories ;
- nouvelle convention appliquée uniquement aux prochaines tranches ;
- dette héritée documentée mais non réécrite rétroactivement.
```
## Validation de sortie
L’adoption du scope est prête lorsque :
- chaque owner candidat du scope est classifié ;
- les changements `ADOPT` sont réellement appliqués ;
- les `KEEP-LOCAL` et `OVERRIDE` sont compréhensibles et possédés localement ;
- les `DEFER` ont un motif et restent hors du résultat présenté comme terminé ;
- les validations nécessaires ont réussi ;
- le projet reste autonome par rapport au dépôt PGR.
## Limites
Ce pattern ne décide pas à la place du projet :
- quels profils sont applicables ;
- si Games, KSP ou un autre dépôt doit migrer maintenant ;
- si une règle locale doit devenir une règle PGR générale ;
- si une migration doit occuper une ou plusieurs releases.
Ces décisions appartiennent au contexte réel du projet et à son plan actif.

View File

@@ -0,0 +1,154 @@
<!-- file: docs/templates/008-WEB_TYPESCRIPT_PACKAGE.md -->
<!-- version: 2 -->
# Templates de package Web TypeScript
## Rôle
Cette spécification accompagne les deux fichiers copiables :
- [`package.json`](../../templates/web-typescript/package.json) ;
- [`tsconfig.json`](../../templates/web-typescript/tsconfig.json).
Ils constituent une baseline **minimale** pour une application frontend TypeScript privée. Ils ne constituent ni un projet complet, ni un skeleton Web, ni un choix de Vite, Sass, framework UI ou package manager.
Les owners normatifs restent [`530-TYPESCRIPT.md`](../rules/530-TYPESCRIPT.md) et [`540-JAVASCRIPT_PACKAGE_ECOSYSTEM.md`](../rules/540-JAVASCRIPT_PACKAGE_ECOSYSTEM.md).
## Pourquoi les templates restent minimaux
PGR ne possède pas encore, à ce niveau générique, les décisions suivantes :
```text
package manager concret
version du package manager
version TypeScript
target ECMAScript
module / moduleResolution
lib / types
framework frontend
Vite ou autre bundler
Sass ou CSS direct
layout source final
aliases
WASM
host Tauri ou autre
```
Les templates MUST donc rester parsables sans figer arbitrairement ces choix.
`package.json` et `tsconfig.json` n'acceptent pas un header commentaire PGR sans sortir de leur grammaire standard. Leur chemin et leur rôle sont donc possédés par le présent document plutôt que par des commentaires internes `file/version`.
## `package.json`
Le template représente un package privé et contient uniquement :
```text
name valeur d'exemple à remplacer
private true
scripts typecheck
```
Avant utilisation :
1. remplacer `project-web` par le nom réellement choisi ;
2. sélectionner explicitement le package manager ;
3. ajouter TypeScript comme dépendance de développement avec une version compatible réellement décidée par le projet ;
4. ajouter les dépendances fonctionnelles seulement lorsqu'elles sont réellement nécessaires ;
5. pour chaque dépendance consommée depuis TypeScript, vérifier si elle fournit déjà ses propres déclarations ;
6. lorsque les déclarations manquent, rechercher le package `@types/...` maintenu correspondant et l'ajouter normalement à `devDependencies` pour une application privée ;
7. ajouter `@types/node` uniquement si du code/config/outillage TypeScript utilise réellement l'environnement Node, et `@types/bootstrap` uniquement si les API JavaScript Bootstrap typées sont consommées ;
8. vérifier la compatibilité de version entre la dépendance runtime, le package de déclarations éventuel et TypeScript ;
9. laisser le package manager choisi produire son lockfile si la politique applicable le recommande ;
10. ajouter `dev`, `build`, `preview` ou autres scripts uniquement lorsque leurs owners existent.
Le template ne contient pas de champ `version` parce qu'une application privée n'a pas besoin d'inventer une version npm distincte. Un projet qui aligne volontairement ce manifest sur sa release globale peut l'ajouter selon sa gouvernance locale.
## `devDependencies` et déclarations de types
Le fichier copiable n'inclut aucune `devDependencies` concrète, car PGR ne peut pas connaître à l'avance les versions ni les packages réellement utilisés. Un projet instancié doit toutefois compléter le manifest. Un exemple de forme, à adapter sans recopier les versions littéralement, est :
```json
{
"devDependencies": {
"typescript": "<version décidée>",
"@types/node": "<si Node est réellement utilisé>",
"@types/bootstrap": "<si les API JavaScript Bootstrap sont réellement utilisées et nécessitent des types externes>"
}
}
```
L'ordre de décision est important :
```text
package utilisé
↓
fournit-il déjà ses propres types ?
├─ oui → utiliser les types embarqués ; ne pas ajouter un @types redondant
└─ non → rechercher @types/<package> ou une déclaration maintenue équivalente
↓
vérifier compatibilité et besoin réel
↓
ajouter au manifest dans la classe de dépendance appropriée
```
Pour une application privée, un package de déclarations utilisé uniquement par le type-check appartient normalement à `devDependencies`. Pour une bibliothèque publiée, si les `.d.ts` publics produits référencent cette déclaration, le package doit rester disponible aux consommateurs et peut donc devoir appartenir aux dépendances publiées plutôt qu'aux seules `devDependencies`.
Cette étape participe directement à la qualité TypeScript et à l'expérience IDE : les déclarations permettent au language service de mieux comprendre les signatures et objets importés, d'améliorer les diagnostics et de fournir navigation et complétion lorsque l'éditeur les expose.
## `tsconfig.json`
Le template active uniquement les contrôles considérés génériques pour une baseline stricte :
```text
strict
noEmit
noUnusedLocals
noUnusedParameters
noFallthroughCasesInSwitch
```
Avant utilisation, le projet doit décider explicitement les options qui dépendent de sa target et de son host : `target`, `module`, `moduleResolution`, `lib`, `types`, `jsx`, `include`, `exclude`, aliases et éventuels chemins générés.
Le template ne copie donc pas les valeurs Games `ES2022`, `ESNext`, `bundler`, `vite/client`, `node` ou les aliases WASM. Ces valeurs restent des preuves de corpus et pourront être reprises seulement par l'owner qui les justifie.
## Type-check indépendant
Après installation locale de TypeScript, le script générique est :
```text
typecheck -> tsc --noEmit
```
Le type-check SHOULD pouvoir être exécuté indépendamment du bundler. Un futur script `build` MAY l'appeler avant le build de production, mais cela ne supprime pas sa responsabilité propre.
Exemples d'appel selon le package manager sélectionné :
```text
npm run typecheck
pnpm typecheck
yarn typecheck
```
Ces lignes sont des exemples, pas une sélection de package manager par PGR.
## Lockfile
Pour une application privée/deployable issue de ce template, le lockfile du package manager sélectionné SHOULD normalement être versionné.
Si le projet conserve volontairement une autre politique, l'écart doit être traité comme décision locale ou `OVERRIDE` lors d'une adoption PGR, avec justification proportionnée.
PGR MUST NOT conserver plusieurs lockfiles concurrents uniquement pour rendre le template compatible avec plusieurs package managers.
## Validation minimale du template dans PGR
Le dépôt PGR vérifie seulement que les deux fichiers sont du JSON parsable et qu'ils conservent les champs génériques attendus.
La validation réelle d'un projet destinataire sélectionne ensuite :
- le package manager choisi ;
- la résolution/install de dépendances si nécessaire ;
- le mode gelé/immutable lorsque le lockfile est versionné ;
- le script `typecheck` ;
- les validations Vite/CSS/Sass/host applicables dans leurs owners respectifs.
Le futur `alpha.5` de `0.1.1` réconciliera la validation frontend complète sans transformer cette paire de templates en skeleton prématuré.

174
docs/templates/009-WEB_VITE.md vendored Normal file
View File

@@ -0,0 +1,174 @@
<!-- file: docs/templates/009-WEB_VITE.md -->
<!-- version: 1 -->
# Guide d'adaptation Vite
## Rôle
Ce document accompagne le profil [`550-VITE.md`](../rules/550-VITE.md) lorsqu'un projet sélectionne réellement Vite.
Il ne fournit volontairement pas de `vite.config.ts` copiable universel. Les corpus montrent une responsabilité réutilisable claire pour Vite, mais pas des valeurs universelles pour les chemins, ports, aliases, plugins ou hosts.
L'objectif est donc de normaliser **ce qui doit être décidé et validé**, sans figer arbitrairement **la valeur de chaque décision**.
## Manifest
Le manifest réel du projet doit utiliser le package manager choisi par le projet et ajouter Vite comme outil de développement avec une version explicitement décidée.
Les scripts usuels, lorsqu'ils correspondent au workflow réel, sont conceptuellement :
```json
{
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
}
}
```
Ce fragment n'est pas un template complet de `package.json` et ne sélectionne aucun package manager.
`dev` et `build` sont naturels lorsqu'un frontend Vite existe. `preview` MAY être omis si aucun smoke/prévisualisation locale ne l'utilise.
Le type-check TypeScript reste une preuve séparée :
```text
typecheck -> tsc --noEmit
build -> vite build
```
Une CI peut exécuter successivement ces deux scripts sans imposer une syntaxe npm particulière.
## Décider `root`
Si `index.html` et les sources se trouvent à la racine comprise par Vite, aucune valeur explicite n'est nécessaire uniquement pour respecter PGR.
Si le package contient une racine frontend dédiée, le projet doit configurer `root` vers cette racine. Le nom `frontend/` observé dans Games est une convention locale utile mais pas une obligation générique.
## Décider `base`
`base` doit suivre le mode réel de service/embarquement :
```text
site servi à la racine souvent /
site sous un sous-chemin chemin public correspondant
host embarqué valeur relative si réellement requise
```
PGR ne copie donc pas automatiquement `base: "./"` depuis Games dans tous les projets Vite.
## Cache
Le cache Vite est reproductible et ne doit pas devenir un source versionné.
Ordre de préférence PGR :
1. placer `cacheDir` hors de l'arborescence source lorsqu'un emplacement de build externe existe déjà et reste simple à utiliser ;
2. sinon accepter un cache interne dédié et l'ignorer explicitement ;
3. ne jamais versionner le cache uniquement pour accélérer une machine locale.
L'effacement du cache doit rester sans conséquence fonctionnelle autre qu'un recalcul.
## Output de production
`build.outDir` contient des artefacts générés.
Ordre de préférence PGR :
1. utiliser un répertoire de build externe au source tree si l'environnement du projet le permet proprement ;
2. sinon utiliser un répertoire interne dédié, tel que `dist/`, explicitement ignoré ;
3. ne versionner un output que si un autre contrat de distribution l'exige réellement et documente cet artefact comme livrable.
Si `build.emptyOutDir` est activé, `outDir` doit être dédié à Vite. Le build ne doit pas pouvoir vider un répertoire partagé avec du WASM, des artefacts Rust, Android ou d'autres owners.
## Assets
Trois catégories doivent rester distinguées :
```text
asset source importé/référencé source versionné
asset source dans publicDir source statique versionné
asset copié/transformé dans outDir output généré
```
`publicDir` MAY rester au défaut Vite, être déplacé ou être désactivé avec `false` selon le besoin du projet.
Une copie réalisée par plugin n'autorise pas à supprimer la source de son owner ni à versionner la copie de build comme second source.
## Dev server et exposition réseau
Pour un développement local simple, rester sur une écoute locale/loopback est préférable.
N'élargir `server.host` au LAN/toutes interfaces que lorsqu'un besoin réel l'impose, par exemple un test sur device ou un host externe. Dans ce cas, revoir aussi les contraintes de hosts autorisés, CORS, TLS, proxy et HMR selon l'intégration réelle.
PGR déconseille les raccourcis globaux :
```text
server.allowedHosts = true
server.cors = true
```
Ils ne doivent pas devenir des valeurs de template universelles.
## Ports déterministes
Un port fixe n'est pas une règle PGR universelle.
Si rien ne consomme une URL déterministe, laisser Vite gérer son port peut être suffisant.
Si un host ou un smoke attend un port connu, utiliser ensemble :
```text
server.port valeur locale choisie
server.strictPort true
```
Ainsi, un conflit de port échoue explicitement au lieu de déplacer silencieusement le dev server.
La même logique peut s'appliquer à `preview.port` + `preview.strictPort` lorsqu'un smoke de preview exige une URL stable.
## Preview
`vite preview` sert à vérifier localement le build produit. Il ne constitue pas un serveur de production PGR.
Un smoke MAY lancer `preview` après un build lorsque cette observation apporte une preuve nécessaire. Le deployment/serving réel reste hors du présent owner.
## Ce qui reste local
La configuration suivante n'est pas normalisée par ce guide sans preuve supplémentaire :
```text
ports exacts
host exact
base exact
aliases
plugins
noms de chunks/assets
minification
sourcemaps
proxy
TLS
HMR / WebSocket
filesystem allowlists
intégration WASM
intégration Tauri
```
Games fournit des exemples utiles pour plusieurs de ces points, mais PGR ne transforme pas ces valeurs en défauts génériques.
## Validation dans PGR et dans un projet destinataire
PGR ne livre pas encore de `vite.config.ts` exécutable générique dans cette tranche ; il n'installe donc pas Vite uniquement pour valider un fichier fictif.
Dans un projet réel qui adopte ce profil, la gate applicable doit sélectionner l'outil réel et peut comprendre :
```text
typecheck séparé
build Vite de production
inspection du outDir attendu
preview/smoke seulement si nécessaire
validation du host séparée
```
Les commandes concrètes passent par le package manager sélectionné par le projet. Un exemple npm dans une documentation tierce ne devient pas une obligation PGR.

111
docs/templates/010-WEB_CSS_SASS.md vendored Normal file
View File

@@ -0,0 +1,111 @@
<!-- file: docs/templates/010-WEB_CSS_SASS.md -->
<!-- version: 1 -->
# Guide d'adaptation CSS / Sass
## Objet
Ce guide accompagne le profil [`../rules/560-CSS_SASS.md`](../rules/560-CSS_SASS.md). Il aide un projet à décider sa chaîne de styles sans transformer Sass, Bootstrap, Vite ou un layout particulier en obligation universelle.
PGR ne fournit volontairement pas de `main.scss`, de thème Bootstrap ou de structure `styles/` copiable par défaut : ces fichiers ne deviennent utiles qu'après choix du framework, des entrypoints, du layout et du niveau de personnalisation réel.
## Décider d'abord si Sass apporte une valeur
CSS seul reste valide lorsque les besoins sont simples ou que les capacités CSS modernes suffisent.
Sass est particulièrement pertinent lorsque le projet a besoin de :
- variables et configuration de compilation ;
- mixins, fonctions ou composition de modules ;
- factorisation d'une chaîne de styles non triviale ;
- personnalisation d'un package qui expose officiellement des sources Sass/SCSS ;
- construction sélective d'un framework ou thème sans modifier les sources tierces.
La décision doit rester liée au besoin réel. Un smoke ou un petit frontend n'a pas à recevoir Sass uniquement pour ressembler à un autre projet.
## Choisir l'implémentation
Dans un projet Vite compatible, les sources `.scss` / `.sass` peuvent être prises en charge par Vite lorsque le préprocesseur correspondant est installé. Pour une nouvelle baseline contrôlée, `sass-embedded` est un bon choix de `devDependency` lorsqu'il est supporté ; `sass` reste une alternative légitime.
Le package manager, la version et la commande d'installation sont décidés par le projet. Le guide ne transforme donc pas un exemple `npm add -D ...` en commande normative.
Hors Vite, utiliser l'intégration officielle du bundler ou du compilateur Sass sélectionné.
## Organiser les sources
Le projet décide ses noms de répertoires et entrypoints. Une organisation possible peut séparer :
```text
variables / configuration
modules internes
adaptations de packages tiers
styles applicatifs
entrypoint principal
```
Cette organisation n'est qu'un pattern. PGR n'impose ni `frontend/sass/`, ni `_variables.scss`, ni `main.scss`.
Les fichiers sources intentionnels sont versionnés. Les CSS compilées, fichiers minifiés, sourcemaps et copies du build restent générés sauf artefact de distribution explicitement gouverné.
## Préférer les modules Sass modernes
Pour le nouveau code :
```text
@use
@forward
```
sont préférés lorsque les dépendances les supportent.
`@import` Sass peut rester nécessaire pour une dépendance historique ou une API tierce qui le documente encore. Cette compatibilité doit rester locale ; elle ne doit pas conduire à écrire de nouveau code PGR autour de `@import` lorsque le système de modules fonctionne.
Lorsqu'un module accepte une configuration, utiliser son API publique et ses variables configurables plutôt que copier/modifier ses sources dans le projet.
## Packages npm et entrypoints de styles
Pour une dépendance de styles :
1. vérifier l'entrypoint CSS/Sass public documenté par le package ;
2. vérifier s'il expose une configuration Sass supportée ;
3. utiliser cet entrypoint public avant d'envisager un chemin interne sous `node_modules` ;
4. conserver tout override dans un source possédé par le projet ;
5. ne jamais modifier directement le package installé.
Un package peut exposer CSS, Sass, JavaScript ou plusieurs de ces surfaces. Les dépendances `@types/*` ne concernent que les API JavaScript/TypeScript qui en ont réellement besoin ; importer uniquement le Sass/CSS d'un package ne suffit pas à justifier un package de déclarations.
## Exemple Bootstrap
Bootstrap illustre un package pouvant être utilisé de plusieurs façons : CSS précompilé, API JavaScript et sources Sass configurables.
Si le projet choisit Bootstrap avec Sass, il doit suivre l'API Sass de la version réellement sélectionnée, placer ses variables/overrides avant les étapes requises par cette API et conserver les adaptations dans ses propres sources.
PGR ne fixe ni Bootstrap, ni Bootswatch, ni un thème, ni un ordre d'import particulier comme baseline universelle. Un projet existant utilisant encore `@import` pour compatibilité MAY le conserver jusqu'à une migration sûre.
## Relation avec Vite
Lorsque Vite est sélectionné :
- l'import d'un entrypoint `.scss` depuis le graphe frontend peut suffire à déclencher la compilation ;
- `css.preprocessorOptions` MAY adapter le compilateur lorsque le projet en a réellement besoin ;
- une configuration globale injectée dans chaque fichier doit rester limitée aux symboles nécessaires ; injecter des styles complets partout peut dupliquer le CSS ;
- les CSS présentes dans `build.outDir` sont des outputs Vite générés, pas de nouveaux sources.
Le profil Vite reste propriétaire de `vite.config.ts`, du cache et de l'output ; le profil CSS/Sass reste propriétaire de la chaîne de styles elle-même.
## Validation
Pour un frontend où Sass est intégré au build Vite :
```text
typecheck preuve TypeScript séparée si applicable
build preuve Vite + compilation/transformation des styles
browser smoke seulement si une propriété observable le nécessite
host gate séparée
```
Ne pas ajouter une commande Sass autonome si elle ne prouve rien de plus que le build déjà exécuté.
Si le projet possède au contraire une compilation Sass autonome, un linter ou un package de styles publié séparément, ajouter la preuve officielle correspondante.
Le contrat complet est décrit dans [`../validation/005-WEB_FRONTEND_VALIDATION.md`](../validation/005-WEB_FRONTEND_VALIDATION.md).

View File

@@ -1,5 +1,5 @@
<!-- file: docs/validation/001-VALIDATION_MATRIX.md -->
<!-- version: 12 -->
<!-- version: 15 -->
# Matrice de validation PGR
@@ -14,8 +14,9 @@ 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-TEXT-HYGIENE-001` | `AUDIT` | `python3 -B scripts/audit_text_hygiene.py <paths...>` | Python 3 | fichier texte gouverné modifié | alpha/beta/RC/stable | faible | opérateur/CI |
| `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 chemins, rôles et responsabilités des documents touchés | fichiers documentaires | modification documentaire | alpha/beta/RC/stable | faible | opérateur/revue |
@@ -27,6 +28,8 @@ Les catégories et règles de sélection sont définies dans [`../rules/400-VALI
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-TEXT-HYGIENE-001` est un contrôle mécanique indépendant du sens documentaire. Sur les fichiers texte sélectionnés, il exige des fins de ligne LF, interdit le whitespace terminal et exige exactement une seule newline finale ; une ligne vide supplémentaire à EOF est donc rejetée avant commit. Il complète les contrôles Git au lieu de les remplacer.
`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.
@@ -43,6 +46,14 @@ Pour une nouvelle baseline contrôlée, les propriétés sans ordre métier peuv
[`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.
[`004-RUST_CARGO_BASELINE_DRY_RUN.md`](004-RUST_CARGO_BASELINE_DRY_RUN.md) décrit une preuve temporaire de réutilisabilité des skeletons/templates Rust/Cargo. Le mode « nouveau projet » utilise la toolchain officielle dans un répertoire temporaire ; le mode « projet existant » vérifie qu’un mapping d’adoption n’écrase pas les décisions locales classées `KEEP-LOCAL` ou `DEFER`. Cette preuve est sélectionnée lorsque les artefacts Rust/Cargo eux-mêmes changent ou lorsqu’une phase de release doit reconfirmer leur composabilité ; elle n’est pas une cérémonie de chaque delta documentaire.
## Validation frontend Web réutilisable, hors gate du dépôt PGR
[`005-WEB_FRONTEND_VALIDATION.md`](005-WEB_FRONTEND_VALIDATION.md) décrit la validation indépendante du host pour un frontend réel : restauration reproductible selon le package manager choisi, type-check TypeScript, styles, build de production et smoke navigateur seulement lorsqu'il apporte une preuve supplémentaire.
Cette validation appartient aux projets qui possèdent réellement un frontend ou aux dry-runs de skeletons correspondants. Le dépôt PGR n'installe pas TypeScript, Vite ou Sass uniquement pour simuler une gate qu'il ne possède pas. Les outils officiels restent propriétaires de leurs preuves ; un audit Python PGR ne les réimplémente pas.
## 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.

View File

@@ -0,0 +1,100 @@
<!-- file: docs/validation/004-RUST_CARGO_BASELINE_DRY_RUN.md -->
<!-- version: 1 -->
# Dry-run de baseline Rust/Cargo
## Rôle
Ce contrat vérifie que la fondation PGR, le skeleton Rust/Cargo et les cinq templates techniques peuvent être utilisés sans dépendre de KSP ou Games.
Il possède deux modes distincts :
```text
NEW nouveau projet : instanciation temporaire réelle des templates
ADOPTION projet existant : comparaison et mapping non destructifs
```
Le dry-run n’est ni un générateur de projet permanent ni une nouvelle architecture applicative. Les répertoires temporaires sont supprimés après la preuve.
## Owners exercés
Le chemin `NEW` compose :
```text
001-PROJECT_GOVERNANCE_FOUNDATION
002-RUST_CARGO_WORKSPACE
500-LANGUAGES
510-RUST_CARGO
001-RUST_CARGO_TOOLING
002-CARGO_MANIFESTS
```
Le chemin `ADOPTION` ajoute [`../rules/230-ADOPTION.md`](../rules/230-ADOPTION.md) et traite `001` / `002` comme checklists de comparaison plutôt que comme recettes de remplacement.
## Mode NEW — nouveau workspace
La preuve temporaire SHOULD :
1. copier les cinq artefacts de `templates/rust-cargo/` dans un répertoire temporaire ;
2. remplacer `project-name`, `project-core-lib`, le membre workspace et la version d’exemple par des valeurs propres au dry-run ;
3. créer uniquement le `src/lib.rs` minimal nécessaire à Cargo ;
4. vérifier qu’aucun placeholder PGR ne reste dans les fichiers adoptés ;
5. parser les manifests/configurations TOML avec un parseur fiable ;
6. lorsque Cargo est disponible, exécuter au minimum :
```bash
cargo metadata --format-version 1 --no-deps
cargo fmt --all -- --check
cargo check --workspace
cargo clippy --workspace --all-targets --all-features -- -D warnings
```
Le code source temporaire ne devient pas un template PGR. Son seul rôle est de permettre à la toolchain officielle de vérifier les manifests et l’outillage copiés.
## Mode ADOPTION — workspace existant
La preuve d’adoption MUST partir d’un état local qui ne correspond pas byte-for-byte aux templates PGR. Elle doit démontrer au minimum un mapping contenant plusieurs décisions, par exemple :
```text
510-RUST_CARGO ADOPT
rustfmt.max_width local KEEP-LOCAL
configuration d’artefacts PGR DEFER
audit de façade strict DEFER
```
Le dry-run MUST vérifier que les fichiers classés `KEEP-LOCAL` ou `DEFER` restent inchangés. Une adoption n’est pas prouvée en recopiant les templates puis en déclarant que le projet existant était compatible.
Lorsque la toolchain est disponible, le workspace existant synthétique ou réel SHOULD rester valide avant et après le mapping : `cargo metadata`, `cargo fmt -- --check`, `cargo check` et, lorsque pertinent, `cargo clippy` restent les preuves autoritaires des contrats Cargo/Rust.
## Prévalidation sans Cargo
Un environnement disposant de Python mais pas de Cargo MAY prévalider :
- syntaxe TOML avec `tomllib` ou un parseur équivalent ;
- résolution des placeholders attendus ;
- cohérence des liens entre skeletons, templates et owners ;
- caractère non destructif du mapping d’adoption ;
- absence de dépendance à KSP/Games dans les artefacts copiables.
Cette prévalidation ne constitue pas un `PASS` de la toolchain. Lorsqu’une tranche exige le mode `NEW` complet, l’absence de Cargo conduit à `BLOCKED` ou à une preuve explicitement incomplète, jamais à un faux succès.
## Critères de sortie
Le dry-run est réussi lorsque :
```text
NEW
- templates adaptés sans placeholder résiduel ;
- TOML valide ;
- toolchain Rust/Cargo sélectionnée réussie ;
- aucun artefact temporaire n’entre dans le dépôt PGR.
ADOPTION
- baseline locale explicitement distincte ;
- mapping ADOPT / KEEP-LOCAL / OVERRIDE / DEFER valide ;
- fichiers KEEP-LOCAL / DEFER préservés ;
- toolchain locale toujours valide lorsque cette preuve est applicable ;
- aucun historique n’est réécrit.
```
Le résultat de release reste possédé par le history de la tranche qui exécute cette preuve.

View File

@@ -0,0 +1,128 @@
<!-- file: docs/validation/005-WEB_FRONTEND_VALIDATION.md -->
<!-- version: 1 -->
# Validation frontend Web indépendante du host
## Objet
Ce document décrit une validation réutilisable pour un frontend Web composé à partir des owners TypeScript/package/Vite/CSS-Sass de PGR.
Il complète [`../rules/400-VALIDATION.md`](../rules/400-VALIDATION.md). Il n'ajoute aucune gate au dépôt PGR lui-même, qui ne contient pas de frontend exécutable. Il sert aux projets destinataires et aux dry-runs de skeletons lorsqu'un frontend réel est présent.
## Principe d'indépendance
Le frontend **SHOULD** être validable indépendamment du host autant que son graphe réel le permet.
Un résultat frontend `PASS` prouve uniquement les propriétés frontend sélectionnées. Il ne vaut pas `PASS` Tauri, Android, WASM, backend ou deployment.
Inversement, un échec du host ne doit pas être requalifié en échec TypeScript/Vite/Sass lorsque la gate frontend indépendante est déjà propre et que le défaut appartient clairement à l'intégration du host.
Une dépendance d'entrée réellement générée par un autre owner reste un prérequis explicite. PGR ne doit pas prétendre à une indépendance complète lorsque le build frontend consomme effectivement un artefact externe absent.
## Couches de preuve
Une gate frontend sélectionne uniquement les couches applicables :
```text
1. restauration reproductible des dépendances
2. type-check TypeScript
3. compilation/transformation des styles si distincte
4. build frontend de production
5. inspection ciblée des outputs si nécessaire
6. preview / smoke navigateur si une propriété runtime le justifie
7. validation du host séparée
```
Ces étapes décrivent des responsabilités, pas une liste obligatoire de commandes.
## Restauration des dépendances
Si le package possède un lockfile versionné, CI et les gates reproductibles **SHOULD** utiliser le mode frozen/immutable/clean-install équivalent du package manager sélectionné.
PGR MUST NOT imposer `npm ci` à un projet pnpm, Yarn ou autre. La commande appartient au package manager réel.
Une tranche purement documentaire ou une preuve qui n'a pas besoin de résoudre les dépendances MAY réutiliser une installation déjà autorisée si les règles locales de reproductibilité le permettent.
## Type-check
Lorsqu'un frontend sélectionne le profil TypeScript `530`, le script canonique `typecheck` **SHOULD** rester directement exécutable.
La preuve conceptuelle est :
```text
<package-manager> run typecheck
```
La syntaxe exacte dépend de l'outil sélectionné.
Si le script `build` exécute déjà exactement le même type-check, la matrice locale MAY éviter une exécution redondante lorsque cette composition est stable et visible. Pour une séparation de diagnostic plus claire, exécuter `typecheck` puis `build` reste préférable lorsque le coût est faible.
## Styles
Si Sass/CSS est transformé à l'intérieur du build frontend, le build réussi MAY constituer la preuve de compilation des styles.
Une compilation Sass autonome, un linter CSS/Sass ou une publication de package de styles reçoit une gate séparée uniquement si elle possède un contrat distinct.
PGR SHOULD NOT lancer deux compilations équivalentes uniquement pour augmenter le nombre de checks.
## Build de production
Lorsqu'un bundler tel que Vite est sélectionné, un changement qui touche ses entrées, sa configuration ou ses outputs **SHOULD** exécuter le build de production réel :
```text
<package-manager> run build
```
La réussite du build prouve la capacité du frontend à produire ses outputs avec le graphe courant. Elle ne prouve pas automatiquement le comportement dans un navigateur ni le fonctionnement du host.
Un contrôle ciblé MAY vérifier l'existence ou l'emplacement d'un output critique lorsque cette propriété n'est pas déjà garantie de façon suffisante par le build.
## Preview et smoke navigateur
Un smoke navigateur n'est requis que lorsqu'une propriété importante ne peut pas être prouvée utilement par type-check/build seuls, par exemple :
- chargement réel de l'entrypoint ;
- résolution d'assets ou de `base` ;
- comportement runtime critique ;
- connexion à un service local de test ;
- intégration navigateur spécifique.
Avec Vite, `preview` MAY servir à exposer localement le build pour ce smoke. `preview` n'est pas un serveur de production.
Un smoke **SHOULD** rester court, déterministe autant que possible et centré sur la propriété qui justifie son existence.
## Host séparé
Un host tel que Tauri peut déclencher le dev/build frontend via ses hooks, mais ce couplage ne transfère pas l'ownership de la validation frontend au host.
La matrice locale **SHOULD** conserver au minimum une voie permettant d'exécuter les preuves frontend pertinentes sans lancer l'ensemble du host, lorsque la topologie réelle du projet le permet.
Ensuite seulement, une gate d'intégration du host vérifie la composition : hooks, chemins, artefacts attendus, capacités natives, packaging ou comportement end-to-end selon le framework.
## Matrice minimale adaptable
Exemple de classification, à adapter au projet :
```text
restore reproductible | lockfile versionné | package manager | mode frozen/immutable/clean-install
type-check | TypeScript sélectionné | TypeScript | script typecheck
styles | compilation distincte du build | Sass/CSS toolchain | commande officielle ciblée
build | bundler sélectionné | Vite ou alternative | script build
browser smoke | comportement runtime à prouver | navigateur / harness | smoke court
host integration | host présent | Tauri ou autre host | gate du host
```
Le projet peut fusionner deux lignes uniquement lorsque la même commande prouve réellement les deux contrats et que cette composition reste explicite.
## Validation d'un skeleton Web
Une instanciation temporaire du skeleton Web MAY être utilisée pour vérifier :
- que les fichiers copiés/adaptés sont parsables ;
- que le package manager et les versions sélectionnés résolvent réellement ;
- que `typecheck` passe ;
- que le build sélectionné produit les outputs attendus ;
- que les styles choisis compilent ;
- qu'aucune validation du host n'est nécessaire pour ces preuves frontend.
Cette preuve de toolchain doit utiliser les outils officiels réels. Un audit Python statique ne remplace pas TypeScript, Vite ou Sass pour les propriétés qu'ils possèdent.

103
history/0.1.0/alpha.1.md Normal file
View File

@@ -0,0 +1,103 @@
<!-- file: history/0.1.0/alpha.1.md -->
<!-- version: 1 -->
# History 0.1.0-alpha.1 — audit de la stable et cadrage de la baseline réutilisable
## Statut
PASS
La gate opérateur de `0.1.0-alpha.1` exécutée le `2026-09-25` valide l'audit de reprise depuis `v0.0.5`, le plan de la première baseline PGR réutilisable et le maintien des futurs domaines `0.1.x` comme axes non numérotés. Aucun fix ni REPLAN de `alpha.1` n'est requis.
Cette preuve ferme uniquement le cadrage `alpha.1`. Elle ne matérialise encore ni la nouvelle convention `rel.N`, ni le handoff automatique des commandes Git, ni un profil technologique supplémentaire.
## Baseline et version
La tranche part de la stable taggée `v0.0.5`, dont l'archive autoritaire et le rapport post-tag `publish.001` ont été audités pendant la préparation du delta.
La version contrôlée après application du delta est :
```text
0.1.0-alpha.1
```
L'opérateur a confirmé la présence de `deltas/0.1.0/alpha.1.md` et l'absence du présent history pendant la gate. Les révisions attendues ont été retrouvées :
```text
README.md version 15
docs/000-README.md version 18
docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md présent et indexé
```
## Validation opérateur observée
L'opérateur a fourni les sorties du `2026-09-25` depuis `~/Projects/pgr`, à `22:08:29`–`22:08:30`.
La suite Python globale a exécuté `48` tests, tous réussis :
```text
Ran 48 tests in 0.720s
OK
```
Les audits documentaires sont propres :
```text
Markdown header audit: clean (173 file(s))
Markdown table audit: clean (8 table(s), 173 file(s))
Markdown link audit: clean (163 local link(s), 173 file(s))
```
Le contrôle structurel spécifique a affiché :
```text
0.1.0 alpha.1 structural audit: clean (62 prior pairs, stable workflow truth preserved, future 0.1.x unnumbered)
```
Il confirme notamment :
- les `62` couples delta/history des releases `0.0.1` à `0.0.5` ;
- la conservation de `rel.001` en `FAIL` et `rel.001.fix.1` en `PASS` dans l'historique `0.0.5` ;
- la présence des profils Rust/Cargo, Java/Maven/Gradle, Android et Tauri ainsi que des skeletons et de l'étude Tauri attendus ;
- les décisions de cadrage `rel.1`, commit stable final, releases `0.1.x` par domaine, Games avant KSP et maintien des axes Web/Vite/Android/WASM/Tauri/serveur Rust comme horizons non numérotés ;
- l'absence de réservation prématurée de `0.1.1` dans `ROADMAP.md`.
## Contrôles Git
`git diff --check` et `git diff --cached --check` n'ont produit aucun diagnostic.
Le statut indexé transmis avant ajout du présent history est exactement :
```text
M README.md
M VERSION
A deltas/0.1.0/alpha.1.md
M docs/000-README.md
A docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md
```
Le scope correspond donc au delta livré et aucun fichier normatif, profil, template, skeleton, script ou history antérieur n'a été modifié par `alpha.1`.
## Revue de cadrage
Les précisions ajoutées pendant la session ne remettent pas en cause le scope validé de `alpha.1` :
- les domaines Web, serveur Rust, Java/Android, WASM et Tauri restent destinés à des releases `0.1.x` séparées ;
- KSP reste principalement dépendant de la baseline Rust/Cargo déjà mûre et du futur déblocage Tauri ;
- un futur audit Python simulant uniquement un sous-ensemble statiquement vérifiable des conventions Clippy est conservé comme candidat non prioritaire après les adoptions Games puis KSP ; il ne remplacera pas `cargo clippy` ;
- les profils de déploiement/exploitation — reverse proxy, bases de données, conteneurs et responsabilités associées — restent un horizon plus lointain, sans numéro de release réservé.
Ces deux derniers horizons n'ont pas été introduits dans les fichiers de `alpha.1`. Ils peuvent être enregistrés dans le plan actif lors d'une tranche ultérieure sans transformer cette gate en échec.
## Transition
Appliquer le présent history puis committer et pousser `0.1.0-alpha.1`.
La tranche suivante est :
```text
0.1.0-alpha.2
```
Elle est strictement consacrée à la convention future `rel.N`, à l'abandon du padding `rel.001` pour les nouvelles releases et à la distinction entre commits de clôture échoués et commit final stable `X.Y.Z`. Les anciennes releases restent immuables.

View File

@@ -0,0 +1,92 @@
<!-- file: history/0.1.0/alpha.2.fix.1.md -->
<!-- version: 1 -->
# History 0.1.0-alpha.2.fix.1 — correction de la gate `rel.N`
## Statut
PASS
La gate opérateur de `0.1.0-alpha.2.fix.1` exécutée le `2026-09-26` valide la correction strictement opérationnelle de la gate `rel.N`. Le `FAIL` de `alpha.2` reste conservé comme vérité historique ; aucun owner normatif de la convention `rel.N` n'a dû être réécrit.
## Baseline opérateur
La tranche `0.1.0-alpha.2` a été clôturée avec son history `FAIL`, puis committée et poussée avant application du fix :
```text
commit 62f3d25
message 0.1.0-alpha.2
push origin/master PASS
```
Après application du delta de correction, les contrôles initiaux ont confirmé :
```text
VERSION 0.1.0-alpha.2.fix.1
history/0.1.0/alpha.2.md présent dans HEAD et le workspace
deltas/0.1.0/alpha.2.md présent
deltas/0.1.0/alpha.2.fix.1.md présent
history/0.1.0/alpha.2.fix.1.md absent pendant la gate
docs/rules/200-GOVERNANCE.md version 5
docs/rules/210-WORKFLOW.md version 6
docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md version 3
```
Le statut `FAIL` de `history/0.1.0/alpha.2.md` a également été retrouvé explicitement.
## Validation opérateur observée
La preuve Python corrigée a terminé proprement :
```text
0.1.0 alpha.2.fix.1 rel gate audit: clean (failed gate preserved, rel.N content reconfirmed, shell-sensitive assertions safe)
```
Elle reconfirme notamment :
- `rel.1` et `rel.1.fix.1` comme représentation future sans padding ;
- la règle du premier `history rel.N[/fix.M] PASS` qui établit réellement la stable ;
- la conservation de `publish.001` comme identité indépendante ;
- la présence intacte des quatre artefacts historiques `rel.001*` de `0.0.5` ;
- les horizons différés concernant le sous-ensemble statique Rust/Clippy et le futur domaine deployment/operations ;
- l'absence de réservation prématurée de `0.1.1` dans `ROADMAP.md`.
La suite Python globale a exécuté `48` tests, tous réussis :
```text
Ran 48 tests in 0.715s
OK
```
Les audits documentaires sont propres :
```text
Markdown header audit: clean (177 file(s))
Markdown table audit: clean (8 table(s), 177 file(s))
Markdown link audit: clean (163 local link(s), 177 file(s))
```
## Contrôles Git
Le statut indexé transmis avant ajout du présent history est exactement :
```text
M VERSION
A deltas/0.1.0/alpha.2.fix.1.md
M docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md
```
Le scope correspond au correctif annoncé. `docs/rules/200-GOVERNANCE.md`, `docs/rules/210-WORKFLOW.md` et le delta historique `alpha.2.md` sont restés inchangés.
## Décision
`0.1.0-alpha.2.fix.1` est `PASS`. Aucun nouveau fix ni REPLAN n'est requis.
La trajectoire normale reprend à :
```text
0.1.0-alpha.3
```
Cette tranche formalise la remise automatique des commandes opérateur après chaque history, l'ordre commit/push avant le delta suivant, la clôture stable avec tag et les preuves à fournir pour la vérification post-tag.

130
history/0.1.0/alpha.2.md Normal file
View File

@@ -0,0 +1,130 @@
<!-- file: history/0.1.0/alpha.2.md -->
<!-- version: 1 -->
# History 0.1.0-alpha.2 — clôture stable et identité `rel.N`
## Statut
FAIL
La gate opérateur de `0.1.0-alpha.2` exécutée le `2026-09-26` n'a pas atteint un PASS complet. Le contenu normatif de la tranche est présent et les suites Python ainsi que les audits Markdown ont réussi, mais plusieurs commandes `grep -F` prescrites par le delta ont été mal formées pour le shell en raison d'apostrophes littérales dans des motifs entourés de quotes simples. La preuve opérateur contient donc des erreurs de commande et la tranche doit rester `FAIL` jusqu'à correction de sa gate.
Le défaut observé appartient à la validation livrée par `alpha.2`; aucun défaut du contenu `rel.N` n'est établi par les contrôles exécutés.
## Baseline opérateur
La tranche précédente `0.1.0-alpha.1` a été committée et poussée avant application de `alpha.2` :
```text
commit c22cf39
message 0.1.0-alpha.1
push origin/master PASS
```
Après application de `alpha.2`, les contrôles initiaux ont confirmé :
```text
VERSION 0.1.0-alpha.2
history/0.1.0/alpha.1.md présent
deltas/0.1.0/alpha.2.md présent
history/0.1.0/alpha.2.md absent pendant la gate
docs/rules/200-GOVERNANCE.md version 5
docs/rules/210-WORKFLOW.md version 6
docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md version 2
```
## Défaut exact de la gate
Le delta contenait notamment :
```bash
grep -F 'représentation canonique n'utilise pas de zéro de padding' docs/rules/200-GOVERNANCE.md
```
L'apostrophe de `n'utilise` ferme la quote simple ouverte avant `représentation`. Le shell poursuit alors l'analyse des lignes suivantes avec un état de quoting incohérent. La transcription opérateur contient notamment :
```text
bash: publish.001 : commande introuvable
grep: pas: Aucun fichier ou dossier de ce nom
grep: zéro: Aucun fichier ou dossier de ce nom
grep: clôture: Aucun fichier ou dossier de ce nom
grep: rel.1: Aucun fichier ou dossier de ce nom
```
Un second motif comportait également une apostrophe littérale :
```bash
grep -F 'série dédiée au déploiement et à l'exploitation' docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md
```
Ces erreurs ne peuvent pas être classées comme simples diagnostics attendus : elles proviennent de commandes de validation obligatoires livrées par la tranche. Conformément à la chaîne PGR, une gate prescrite qui n'est pas exécutable proprement rend la tranche `FAIL` même si une preuve ultérieure couvre correctement le fond.
## Preuves de fond réussies
La suite Python globale a exécuté `48` tests et tous ont réussi :
```text
Ran 48 tests in 0.717s
OK
```
Les audits Markdown ont affiché :
```text
Markdown header audit: clean (175 file(s))
Markdown table audit: clean (8 table(s), 175 file(s))
Markdown link audit: clean (163 local link(s), 175 file(s))
```
Le contrôle structurel spécifique de la tranche a également réussi :
```text
0.1.0 alpha.2 rel identity audit: clean (rel.N unpadded, historical rel.001 preserved, stable commit identity explicit)
```
Cette preuve confirme notamment que :
- la convention future `rel.N` sans padding est matérialisée ;
- les artefacts historiques `rel.001*` sont conservés ;
- l'identité du commit stable est explicitement distinguée de la tranche de clôture ;
- `publish.001` reste indépendant ;
- les horizons Clippy statique et deployment/operations restent différés dans le plan.
Le scope Git observé avant ajout du présent history est exactement :
```text
M VERSION
A deltas/0.1.0/alpha.2.md
M docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md
M docs/rules/200-GOVERNANCE.md
M docs/rules/210-WORKFLOW.md
```
## Décision
Aucun REPLAN n'est requis et aucun owner normatif ne doit être réécrit pour corriger cet incident.
La correction reste strictement dans :
```text
0.1.0-alpha.2.fix.1
```
Le fix doit :
- conserver intégralement le delta historique `alpha.2.md` ;
- conserver les contenus actuels de `200-GOVERNANCE.md` et `210-WORKFLOW.md` ;
- remplacer les assertions shell fragiles par une preuve Python syntaxiquement sûre ;
- rejouer les `48` tests et les trois audits Markdown ;
- confirmer à nouveau le scope et la vérité historique avant progression vers `alpha.3`.
## Résultat
`0.1.0-alpha.2` est enregistré `FAIL` pour défaut de gate opérateur, sans défaut normatif établi sur la convention `rel.N`.
La seule transition autorisée est :
```text
0.1.0-alpha.2.fix.1
```

View File

@@ -0,0 +1,94 @@
<!-- file: history/0.1.0/alpha.3.fix.1.md -->
<!-- version: 1 -->
# History 0.1.0-alpha.3.fix.1 — correction de la gate du handoff opérateur
## Statut
PASS
La gate opérateur de `0.1.0-alpha.3.fix.1` exécutée le `2026-09-26` a réussi. Le `FAIL` historique de `alpha.3` est conservé, la syntaxe du contrôle Python a été corrigée sans modifier les owners du handoff, puis le contenu de `210-WORKFLOW.md` et de `006-OPERATOR_COMMAND_HANDOFF.md` a été reconfirmé.
## Baseline opérateur
La tranche `0.1.0-alpha.3` a été clôturée avec son history `FAIL`, puis committée et poussée avant application du fix :
```text
commit f374816
message 0.1.0-alpha.3
push origin/master PASS
```
Après application du correctif, les contrôles initiaux ont confirmé :
```text
VERSION 0.1.0-alpha.3.fix.1
history/0.1.0/alpha.3.md présent dans HEAD et le workspace
deltas/0.1.0/alpha.3.md présent
deltas/0.1.0/alpha.3.fix.1.md présent
docs/templates/006-OPERATOR_COMMAND_HANDOFF.md présent
history/0.1.0/alpha.3.fix.1.md absent pendant la gate
docs/rules/210-WORKFLOW.md version 7
docs/templates/006-OPERATOR_COMMAND_HANDOFF.md version 1
docs/000-README.md version 19
docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md version 5
```
Le statut `FAIL` de `history/0.1.0/alpha.3.md` a été retrouvé explicitement.
## Validation opérateur observée
Le contrôle Python corrigé a terminé proprement :
```text
0.1.0 alpha.3.fix.1 operator handoff gate: clean (alpha.3 FAIL preserved, workflow/template reconfirmed, Python literals safe)
```
Il reconfirme notamment :
- le contrat normatif de remise automatique dans `210-WORKFLOW.md` ;
- l'interdiction d'inventer remote, branche ou politique de tag ;
- la clôture stable au premier `rel.N[/fix.M]` réellement `PASS` ;
- la distinction entre objet tag et commit déréférencé ;
- la production de `publish.*` uniquement à partir de preuves post-publication réellement disponibles ;
- les blocs du pattern opérateur pour tranche ordinaire, échec + fix, stable, tag et reprise après `publish.* PASS`.
La suite Python globale a exécuté `48` tests, tous réussis :
```text
Ran 48 tests in 0.688s
OK
```
Les audits documentaires sont propres :
```text
Markdown header audit: clean (182 file(s))
Markdown table audit: clean (8 table(s), 182 file(s))
Markdown link audit: clean (167 local link(s), 182 file(s))
```
## Contrôles Git
Le statut indexé transmis avant ajout du présent history est exactement :
```text
M VERSION
A deltas/0.1.0/alpha.3.fix.1.md
M docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md
```
Le scope correspond au correctif annoncé. `docs/rules/210-WORKFLOW.md`, `docs/templates/006-OPERATOR_COMMAND_HANDOFF.md`, `docs/000-README.md` et le delta historique `alpha.3.md` sont restés inchangés.
## Décision
`0.1.0-alpha.3.fix.1` est `PASS`. Aucun nouveau fix ni REPLAN n'est requis.
La trajectoire normale reprend à :
```text
0.1.0-alpha.4
```
Cette tranche formalise l'adoption proportionnée de PGR par un projet existant, distincte de l'instanciation d'un nouveau projet et sans migration concrète de Games ou KSP dans `0.1.0`.

115
history/0.1.0/alpha.3.md Normal file
View File

@@ -0,0 +1,115 @@
<!-- file: history/0.1.0/alpha.3.md -->
<!-- version: 1 -->
# History 0.1.0-alpha.3 — handoff automatique des commandes opérateur
## Statut
FAIL
La gate opérateur de `0.1.0-alpha.3` exécutée le `2026-09-26` n'a pas atteint un PASS complet. Le contenu de workflow et le nouveau pattern de handoff ont été appliqués, les `48` tests ont réussi et les trois audits Markdown sont propres, mais le contrôle Python obligatoire livré par le delta contient une chaîne littérale invalide : l'apostrophe de `d'une` ferme prématurément une chaîne entourée de quotes simples.
Le défaut appartient donc à la gate de validation de `alpha.3`. Aucun défaut normatif de `210-WORKFLOW.md` ni de `006-OPERATOR_COMMAND_HANDOFF.md` n'est établi par les preuves opérateur disponibles.
## Baseline opérateur
La tranche précédente `0.1.0-alpha.2.fix.1` a été clôturée avec son history `PASS`, puis committée et poussée avant application de `alpha.3` :
```text
commit 3230356
message 0.1.0-alpha.2.fix.1
push origin/master PASS
```
Après application de `alpha.3`, les contrôles initiaux ont confirmé :
```text
VERSION 0.1.0-alpha.3
history/0.1.0/alpha.2.fix.1.md présent
deltas/0.1.0/alpha.3.md présent
docs/templates/006-OPERATOR_COMMAND_HANDOFF.md présent
history/0.1.0/alpha.3.md absent pendant la gate
docs/rules/210-WORKFLOW.md version 7
docs/000-README.md version 19
docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md version 4
```
## Défaut exact de la gate
Le delta contenait dans son bloc Python :
```python
for phrase in (
'## Fermeture d'une tranche non stable',
...
):
assert phrase in template, phrase
```
L'apostrophe de `d'une` termine la chaîne Python avant `une tranche non stable`. L'interpréteur a donc arrêté le contrôle spécifique avec :
```text
File "<stdin>", line 24
'## Fermeture d'une tranche non stable',
^
SyntaxError: unterminated string literal (detected at line 24)
```
La gate spécifique n'a donc pas pu produire son message final `clean`. Ce défaut est analogue à celui déjà rencontré sur `alpha.2`, mais il se situe cette fois dans une chaîne Python et non dans le quoting shell d'un `grep`.
## Preuves réussies malgré le défaut
La suite Python globale a exécuté `48` tests et tous ont réussi :
```text
Ran 48 tests in 0.698s
OK
```
Les audits Markdown ont affiché :
```text
Markdown header audit: clean (180 file(s))
Markdown table audit: clean (8 table(s), 180 file(s))
Markdown link audit: clean (167 local link(s), 180 file(s))
```
Le scope Git observé avant ajout du présent history est exactement :
```text
M VERSION
A deltas/0.1.0/alpha.3.md
M docs/000-README.md
M docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md
M docs/rules/210-WORKFLOW.md
A docs/templates/006-OPERATOR_COMMAND_HANDOFF.md
```
Ce scope correspond aux six fichiers annoncés par `alpha.3`.
## Décision
Aucun REPLAN n'est requis. Le correctif doit rester strictement limité à la gate de `alpha.3` :
```text
0.1.0-alpha.3.fix.1
```
Le fix doit :
- conserver intégralement le delta historique `alpha.3.md` ;
- conserver `docs/rules/210-WORKFLOW.md`, `docs/templates/006-OPERATOR_COMMAND_HANDOFF.md` et `docs/000-README.md` inchangés ;
- remplacer uniquement les littéraux Python fragiles de la validation par une forme syntaxiquement sûre ;
- reconfirmer le history `alpha.3` en `FAIL`, le contenu du workflow et du template, les `48` tests et les trois audits Markdown ;
- vérifier que le scope du fix reste borné à `VERSION`, au plan actif et au nouveau delta de correction.
## Résultat
`0.1.0-alpha.3` est enregistré `FAIL` pour défaut de syntaxe dans sa gate opérateur, sans défaut normatif établi sur le handoff automatique des commandes.
La seule transition autorisée est :
```text
0.1.0-alpha.3.fix.1
```

102
history/0.1.0/alpha.4.md Normal file
View File

@@ -0,0 +1,102 @@
<!-- file: history/0.1.0/alpha.4.md -->
<!-- version: 1 -->
# History 0.1.0-alpha.4 — adoption PGR d’un projet existant
## Statut
PASS
La gate opérateur de `0.1.0-alpha.4` exécutée le `2026-09-26` a réussi. Le contrat d’adoption d’un projet existant, son pattern documentaire, leur indexation et leur représentation architecturale ont été validés sans migration effective de Games ou KSP.
## Baseline opérateur
La tranche `0.1.0-alpha.3.fix.1` a été clôturée avec son history `PASS`, puis committée et poussée avant application de `alpha.4` :
```text
commit 351025b
message 0.1.0-alpha.3.fix.1
push origin/master PASS
```
Après application du delta `alpha.4`, les contrôles initiaux ont confirmé :
```text
VERSION 0.1.0-alpha.4
history/0.1.0/alpha.3.fix.1.md présent dans HEAD et le workspace
deltas/0.1.0/alpha.4.md présent
docs/rules/230-ADOPTION.md version 1
docs/templates/007-EXISTING_PROJECT_ADOPTION.md version 1
RULES.md version 12
docs/rules/000-README.md version 14
docs/000-README.md version 20
docs/architecture/002-GOVERNANCE_ARCHITECTURE.md version 4
docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md version 6
history/0.1.0/alpha.4.md absent pendant la gate
```
Le history précédent a été retrouvé avec statut `PASS`.
## Validation opérateur observée
Le contrôle structurel ciblé a terminé proprement :
```text
0.1.0 alpha.4 existing-project adoption audit: clean (baseline, owner mapping, decision classes, progressive migration and history preservation explicit)
```
Il confirme notamment :
- le mapping canonique `ADOPT / KEEP-LOCAL / OVERRIDE / DEFER` ;
- la baseline autoritaire comme point de départ d’une adoption ;
- la migration progressive et proportionnée ;
- la préservation explicite de l’historique ;
- l’usage d’un skeleton comme checklist de comparaison plutôt que comme copie aveugle ;
- l’indexation des nouveaux owners et patterns ;
- l’absence de réservation prématurée d’une future `0.1.1`.
La suite Python globale a exécuté `48` tests, tous réussis :
```text
Ran 48 tests in 0.723s
OK
```
Les audits documentaires sont propres :
```text
Markdown header audit: clean (186 file(s))
Markdown table audit: clean (8 table(s), 186 file(s))
Markdown link audit: clean (178 local link(s), 186 file(s))
```
## Contrôles Git
Le statut indexé transmis avant ajout du présent history est exactement :
```text
M RULES.md
M VERSION
A deltas/0.1.0/alpha.4.md
M docs/000-README.md
M docs/architecture/002-GOVERNANCE_ARCHITECTURE.md
M docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md
M docs/rules/000-README.md
A docs/rules/230-ADOPTION.md
A docs/templates/007-EXISTING_PROJECT_ADOPTION.md
```
Le scope correspond exactement au delta annoncé.
## Décision
`0.1.0-alpha.4` est `PASS`. Aucun fix ni REPLAN n’est requis.
La trajectoire normale reprend à :
```text
0.1.0-alpha.5
```
Cette tranche réconcilie la fondation de gouvernance, le skeleton Rust/Cargo, les templates techniques et la validation minimale, puis exerce deux dry-runs : instanciation d’un nouveau workspace Rust et adoption non destructive d’un workspace Rust existant synthétique.

148
history/0.1.0/alpha.5.md Normal file
View File

@@ -0,0 +1,148 @@
<!-- file: history/0.1.0/alpha.5.md -->
<!-- version: 1 -->
# History 0.1.0-alpha.5 — baseline Rust/Cargo réutilisable et dry-run
## Statut
PASS
La gate opérateur de `0.1.0-alpha.5` exécutée le `2026-09-26` a réussi. Les deux chemins définis par `004-RUST_CARGO_BASELINE_DRY_RUN.md` ont été exercés avec la toolchain Cargo réelle : instanciation d'un nouveau workspace à partir des templates PGR et adoption non destructive d'un workspace Rust existant synthétique.
## Baseline opérateur
La tranche `0.1.0-alpha.4` a été clôturée avec son history `PASS`, puis committée et poussée avant application de `alpha.5` :
```text
commit e4b5992
message 0.1.0-alpha.4
push origin/master PASS
```
Après application du delta `alpha.5`, les contrôles initiaux ont confirmé :
```text
VERSION 0.1.0-alpha.5
history/0.1.0/alpha.4.md présent dans HEAD et le workspace
deltas/0.1.0/alpha.5.md présent
docs/validation/004-RUST_CARGO_BASELINE_DRY_RUN.md présent
history/0.1.0/alpha.5.md absent pendant la gate
docs/000-README.md version 21
docs/skeletons/000-README.md version 5
docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md version 4
docs/skeletons/002-RUST_CARGO_WORKSPACE.md version 6
docs/templates/001-RUST_CARGO_TOOLING.md version 4
docs/templates/002-CARGO_MANIFESTS.md version 4
docs/validation/001-VALIDATION_MATRIX.md version 13
docs/validation/004-RUST_CARGO_BASELINE_DRY_RUN.md version 1
docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md version 7
```
Le history précédent a été retrouvé avec statut `PASS`.
## Validation structurelle
Le contrôle structurel et TOML a terminé proprement :
```text
0.1.0 alpha.5 structural/TOML audit: clean (NEW and ADOPTION paths explicit, templates parse, external corpora not required)
```
Il confirme notamment :
- le lien des skeletons `001` et `002` vers le contrat d'adoption `230-ADOPTION.md` ;
- l'existence des deux chemins `NEW` et `ADOPTION` ;
- la présence de `KEEP-LOCAL` et `DEFER` dans les guides applicables ;
- le parsing TOML des cinq templates Rust/Cargo ;
- l'absence de dépendance obligatoire à Games ou KSP pour cette preuve ;
- l'absence de réservation anticipée d'une future `0.1.1` avant la revue d'horizon.
## Dry-run `NEW`
La gate a matérialisé les templates dans un répertoire temporaire, résolu les placeholders, créé uniquement le source Rust minimal nécessaire au test, puis exécuté la toolchain officielle.
Résultat observé :
```text
cargo metadata --format-version 1 --no-deps PASS
cargo fmt --all -- --check PASS
cargo check --workspace PASS
cargo clippy --workspace --all-targets --all-features -- -D warnings PASS
0.1.0 alpha.5 NEW dry-run: clean (temporary templates accepted by Cargo/rustfmt/Clippy)
```
La crate temporaire `pgr-dryrun-core-lib` en version `9.9.9` a été reconnue par Cargo et les commandes `check` / `clippy` ont terminé sans diagnostic bloquant.
## Dry-run `ADOPTION`
La gate a créé un workspace Rust synthétique préexistant distinct des templates PGR, avec notamment `rustfmt.toml` conservant `max_width = 120`.
Le mapping exercé contenait :
```text
510-RUST_CARGO ADOPT
rustfmt.max_width=120 KEEP-LOCAL
PGR external artifact configuration DEFER
strict crate-root export audit DEFER
```
Les mêmes contrôles Cargo ont réussi et les hashes des fichiers protégés avant/après sont restés identiques.
Résultat observé :
```text
0.1.0 alpha.5 ADOPTION dry-run: clean (local KEEP-LOCAL/DEFER choices preserved, workspace remains valid)
```
La preuve établit donc qu'une adoption ne nécessite pas de recopier aveuglément les templates ni d'écraser les décisions locales légitimes.
## Tests et audits PGR
La suite Python globale a exécuté `48` tests, tous réussis :
```text
Ran 48 tests in 0.726s
OK
```
Les audits documentaires sont propres :
```text
Markdown header audit: clean (189 file(s))
Markdown table audit: clean (8 table(s), 189 file(s))
Markdown link audit: clean (189 local link(s), 189 file(s))
```
## Contrôles Git
Le statut indexé transmis avant ajout du présent history est exactement :
```text
M VERSION
A deltas/0.1.0/alpha.5.md
M docs/000-README.md
M docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md
M docs/skeletons/000-README.md
M docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md
M docs/skeletons/002-RUST_CARGO_WORKSPACE.md
M docs/templates/001-RUST_CARGO_TOOLING.md
M docs/templates/002-CARGO_MANIFESTS.md
M docs/validation/001-VALIDATION_MATRIX.md
A docs/validation/004-RUST_CARGO_BASELINE_DRY_RUN.md
```
Le scope correspond exactement au delta annoncé. Les templates techniques sous `templates/rust-cargo/` eux-mêmes sont restés inchangés.
## Décision
`0.1.0-alpha.5` est `PASS`. Aucun fix ni REPLAN n'est requis.
La trajectoire quitte les alphas et reprend à :
```text
0.1.0-beta.1
```
`beta.1` réconcilie la baseline durable, exécute la revue d'horizon obligatoire et engage uniquement les prochaines releases `0.1.x` dont le domaine, l'ordre et les prérequis sont suffisamment décidés avant RC.

110
history/0.1.0/beta.1.md Normal file
View File

@@ -0,0 +1,110 @@
<!-- file: history/0.1.0/beta.1.md -->
<!-- version: 1 -->
# History 0.1.0-beta.1 — réconciliation finale et revue d'horizon
## Statut
PASS
La gate opérateur de `0.1.0-beta.1` exécutée le `2026-09-26` a réussi. Elle valide la réconciliation de la baseline `0.1.0`, la revue d'horizon obligatoire, la roadmap engagée `0.1.1` à `0.1.7` et le prompt de reprise `007` vers la fondation frontend Web.
## Baseline opérateur
La tranche `0.1.0-alpha.5` a été clôturée avec son history `PASS`, puis committée et poussée avant application de `beta.1` :
```text
commit a65a183
message 0.1.0-alpha.5
push origin/master PASS
```
Après application du delta `beta.1`, les contrôles initiaux ont confirmé :
```text
VERSION 0.1.0-beta.1
history/0.1.0/alpha.5.md présent dans HEAD et le workspace
deltas/0.1.0/beta.1.md présent
docs/studies/003-V0_1_0_HORIZON_REVIEW.md présent
prompts/007-V0_1_1_START_PROMPT.md présent
history/0.1.0/beta.1.md absent pendant la gate
ROADMAP.md version 9
docs/000-README.md version 22
docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md version 8
docs/studies/000-README.md version 3
docs/studies/003-V0_1_0_HORIZON_REVIEW.md version 1
prompts/007-V0_1_1_START_PROMPT.md version 1
```
Le history `alpha.5` a été retrouvé avec statut `PASS`.
## Revue d'horizon
Le contrôle structurel a affiché :
```text
0.1.0 beta.1 horizon review audit: clean (0.1.1..0.1.7 engaged, Tauri conditional, deferred domains remain unnumbered)
```
La roadmap engage désormais, dans cet ordre :
```text
0.1.1 fondation frontend Web
0.1.2 Java / Gradle
0.1.3 Android
0.1.4 Tauri sous condition de readiness Web
0.1.5 adoption sasedev-games
0.1.6 adoption khadhroony-solana-project
0.1.7 audits Rust/Clippy statiques Python-only
```
La gate confirme simultanément qu'aucune `0.1.8` n'est réservée, que WASM et le serveur Web Rust/Actix ou alternative restent sans numéro et que le domaine `deployment & operations` demeure un horizon ultérieur sans réservation précise.
La décision `DEFER` du skeleton Tauri reste applicable pendant `0.1.0`. Le prompt `007` prépare `0.1.1` mais n'autorise ni migration Games/KSP, ni Tauri, ni WASM, ni serveur Rust dans cette release Web.
## Tests et audits PGR
La suite Python globale a exécuté `48` tests, tous réussis :
```text
Ran 48 tests in 0.762s
OK
```
Les audits documentaires sont propres :
```text
Markdown header audit: clean (193 file(s))
Markdown table audit: clean (8 table(s), 193 file(s))
Markdown link audit: clean (193 local link(s), 193 file(s))
```
## Contrôles Git
`git diff --check` et `git diff --cached --check` n'ont produit aucun diagnostic. Le statut indexé transmis avant ajout du présent history est exactement :
```text
M ROADMAP.md
M VERSION
A deltas/0.1.0/beta.1.md
M docs/000-README.md
M docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md
M docs/studies/000-README.md
A docs/studies/003-V0_1_0_HORIZON_REVIEW.md
A prompts/007-V0_1_1_START_PROMPT.md
```
Le scope correspond exactement au delta annoncé. Aucun profil technique, template Rust/Cargo, skeleton ou script d'audit n'a été modifié par `beta.1`.
## Décision
`0.1.0-beta.1` est `PASS`. Aucun fix ni REPLAN n'est requis.
La tranche suivante est :
```text
0.1.0-rc.1
```
La RC gèle le scope, produit l'entrée candidate du `CHANGELOG`, rejoue le release gate complet applicable, vérifie le handoff opérateur et le prompt `007`, puis prépare la première promotion stable utilisant la convention `rel.1`.

119
history/0.1.0/rc.1.md Normal file
View File

@@ -0,0 +1,119 @@
<!-- file: history/0.1.0/rc.1.md -->
<!-- version: 1 -->
# History 0.1.0-rc.1 — release candidate
## Statut
PASS
La gate opérateur de `0.1.0-rc.1` exécutée le `2026-09-26` a réussi. Elle confirme le scope gelé de la première baseline PGR réutilisable, l'intégrité des histories antérieurs, le `CHANGELOG` candidat, la trajectoire `0.1.x`, le prompt `007` et les deux dry-runs Rust/Cargo avec la toolchain réelle.
## Baseline opérateur
La tranche `0.1.0-beta.1` a été clôturée avec son history `PASS`, puis committée et poussée avant application de `rc.1` :
```text
commit 5393257
message 0.1.0-beta.1
push origin/master PASS
```
Après application du delta `rc.1`, les contrôles initiaux ont confirmé :
```text
VERSION 0.1.0-rc.1
history/0.1.0/beta.1.md présent dans HEAD et le workspace
deltas/0.1.0/rc.1.md présent
prompts/007-V0_1_1_START_PROMPT.md présent
history/0.1.0/rc.1.md absent pendant la gate
CHANGELOG.md version 10
docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md version 9
ROADMAP.md version 9
prompts/007-V0_1_1_START_PROMPT.md version 1
```
Le history `beta.1` a été retrouvé avec statut `PASS` et le `CHANGELOG` contient l'entrée `## 0.1.0 (candidate)`.
## Gate d'intégration
Le contrôle d'intégration a affiché :
```text
0.1.0 rc.1 integration audit: clean (8 prior histories, frozen reusable baseline, candidate changelog, horizon and prompt 007 verified)
```
Il a vérifié les huit histories antérieurs avec leurs statuts réels :
```text
alpha.1 PASS
alpha.2 FAIL
alpha.2.fix.1 PASS
alpha.3 FAIL
alpha.3.fix.1 PASS
alpha.4 PASS
alpha.5 PASS
beta.1 PASS
```
La gate reconfirme également le contrat `ADOPT / KEEP-LOCAL / OVERRIDE / DEFER`, la convention `rel.N` sans padding, le commit stable final `X.Y.Z`, le handoff `publish.*`, la roadmap `0.1.1` à `0.1.7`, l'absence de `0.1.8` et la préparation du prompt `007`.
## Dry-runs Rust/Cargo de release
La toolchain Cargo réelle a exercé les deux chemins de la baseline :
```text
NEW cargo metadata / fmt / check / clippy -D warnings PASS
ADOPTION cargo metadata / fmt / check / clippy -D warnings PASS
```
Résultat observé :
```text
0.1.0 rc.1 Rust/Cargo release dry-runs: clean (NEW and ADOPTION accepted by Cargo/rustfmt/Clippy)
```
Le chemin `ADOPTION` conserve le principe de non-écrasement des choix locaux protégés.
## Tests et audits PGR
La suite Python globale a exécuté `48` tests, tous réussis :
```text
Ran 48 tests in 0.702s
OK
```
Les audits documentaires sont propres :
```text
Markdown header audit: clean (195 file(s))
Markdown table audit: clean (8 table(s), 195 file(s))
Markdown link audit: clean (193 local link(s), 195 file(s))
```
## Contrôles Git
`git diff --check` et `git diff --cached --check` n'ont produit aucun diagnostic. Le statut indexé transmis avant ajout du présent history est exactement :
```text
M CHANGELOG.md
M VERSION
A deltas/0.1.0/rc.1.md
M docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md
```
Le scope correspond exactement au delta annoncé. Aucun owner, profil, template, skeleton ou script technique n'a été modifié pendant la RC.
## Décision
`0.1.0-rc.1` est `PASS`. Aucun fix ni REPLAN n'est requis.
La tranche suivante est la promotion stable pré-tag :
```text
0.1.0-rel.1
```
`rel.1` est la première utilisation réelle de la convention sans padding. Si sa gate obtient `PASS`, son history sera inclus dans le commit stable nommé `0.1.0`, avant création et publication du tag `v0.1.0`.

141
history/0.1.0/rel.1.md Normal file
View File

@@ -0,0 +1,141 @@
<!-- file: history/0.1.0/rel.1.md -->
<!-- version: 1 -->
# History 0.1.0-rel.1 — promotion stable pré-tag
## Statut
PASS
La gate opérateur de `0.1.0-rel.1` exécutée le `2026-09-26` a réussi. Elle confirme la promotion mécanique de la release candidate vers la stable `0.1.0`, la cohérence complète des histories antérieurs, la présentation stable du dépôt, les tests Python et les audits documentaires avant création du tag.
## Baseline opérateur
La tranche `0.1.0-rc.1` a été clôturée avec son history `PASS`, puis committée et poussée avant application de `rel.1` :
```text
commit d5e1fc4
message 0.1.0-rc.1
push origin/master PASS
```
Après application du delta `rel.1`, les contrôles initiaux ont confirmé :
```text
VERSION 0.1.0
history/0.1.0/rc.1.md présent dans HEAD et le workspace
deltas/0.1.0/rel.1.md présent
prompts/007-V0_1_1_START_PROMPT.md présent
history/0.1.0/rel.1.md absent pendant la gate
README.md version 16
ROADMAP.md version 10
CHANGELOG.md version 11
docs/000-README.md version 23
docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md version 10
```
Le history `rc.1` a été retrouvé avec statut `PASS`.
La présentation stable est établie :
```text
ROADMAP.md 0.1.0 marqué terminé
CHANGELOG.md entrée `## 0.1.0`
README.md première baseline réutilisable stable
docs index plan 006 classé historique
```
## Gate stable pré-tag
Le contrôle structurel a affiché :
```text
0.1.0 rel.1 stable gate audit: clean (9 prior histories, rel.1 pending, stable presentation and post-tag handoff coherent)
```
Il a vérifié les neuf histories antérieurs avec leurs statuts réels :
```text
alpha.1 PASS
alpha.2 FAIL
alpha.2.fix.1 PASS
alpha.3 FAIL
alpha.3.fix.1 PASS
alpha.4 PASS
alpha.5 PASS
beta.1 PASS
rc.1 PASS
```
Avant application du présent history, `rel.1.md` est la seule tranche `0.1.0` possédant un delta sans history.
La gate reconfirme également :
- `0.1.0` terminé dans la roadmap ;
- `0.1.1` à `0.1.7` engagés sans réservation de `0.1.8` ;
- le `CHANGELOG` stable sans suffixe `(candidate)` ;
- l'absence de la coquille `produit produit` ;
- le plan `006` classé historique ;
- le prompt `007` préparé pour démarrer `0.1.1` depuis le tag `v0.1.0` et le rapport `publish.001` ;
- la convention `rel.N` et le commit stable final `X.Y.Z`.
## Preuve Rust/Cargo
Les deux dry-runs Rust/Cargo de release ont obtenu `PASS` pendant `0.1.0-rc.1` avec la toolchain réelle :
```text
NEW cargo metadata / fmt / check / clippy -D warnings PASS
ADOPTION cargo metadata / fmt / check / clippy -D warnings PASS
```
Ils n'ont pas été rejoués pendant `rel.1`, car la promotion stable ne modifie aucun owner, template, skeleton, script ou artefact Rust/Cargo depuis la RC. Le présent history ne prétend donc pas à une nouvelle exécution de ces dry-runs.
## Tests et audits PGR
La suite Python globale a exécuté `48` tests, tous réussis :
```text
Ran 48 tests in 0.757s
OK
```
Les audits documentaires sont propres :
```text
Markdown header audit: clean (197 file(s))
Markdown table audit: clean (8 table(s), 197 file(s))
Markdown link audit: clean (193 local link(s), 197 file(s))
```
## Contrôles Git
`git diff --check` et `git diff --cached --check` n'ont produit aucun diagnostic.
Le statut indexé transmis avant ajout du présent history est exactement :
```text
M CHANGELOG.md
M README.md
M ROADMAP.md
M VERSION
A deltas/0.1.0/rel.1.md
M docs/000-README.md
M docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md
```
Le scope correspond exactement à la promotion stable annoncée. Aucun owner, profil, template, skeleton ou script technique n'a été modifié.
## Décision
`0.1.0-rel.1` est `PASS`. Aucun fix ni REPLAN n'est requis.
Conformément à la convention stable désormais normative, le présent history doit être inclus dans le commit final nommé exactement :
```text
0.1.0
```
Le commit stable sera ensuite poussé sur la branche établie, puis le tag annoté `v0.1.0` sera créé et publié.
Le rapport `pgr-0.1.0-publish.001-report.md` ne pourra être produit qu'après réception des preuves post-publication réelles : identité du commit stable, propreté du workspace, objet et cible déréférencée du tag local, références distantes du tag et archive ZIP téléchargée depuis le tag Gitea.

101
history/0.1.1/alpha.1.md Normal file
View File

@@ -0,0 +1,101 @@
<!-- file: history/0.1.1/alpha.1.md -->
<!-- version: 1 -->
# History 0.1.1-alpha.1 — audit de stable et cadrage frontend Web
## Statut
PASS
La gate opérateur de `0.1.1-alpha.1` exécutée le `2026-09-27` a réussi. La stable `v0.1.0`, le plan de fondation frontend Web et le scope de la première tranche sont cohérents ; aucun fix de cadrage n'est requis avant `alpha.2`.
## Baseline opérateur
Après application du delta `0.1.1-alpha.1`, les contrôles initiaux ont confirmé :
```text
VERSION 0.1.1-alpha.1
docs/plans/007-V0_1_1_WEB_FRONTEND_FOUNDATION_PLAN.md présent
deltas/0.1.1/alpha.1.md présent
history/0.1.1/alpha.1.md absent pendant la gate
README.md version 17
docs/000-README.md version 24
```
Les index `README.md` et `docs/000-README.md` référencent bien le plan actif `007`.
## Tests et audits PGR
La suite Python globale a exécuté `48` tests, tous réussis :
```text
Ran 48 tests in 0.671s
OK
```
Les audits documentaires sont propres :
```text
Markdown header audit: clean (200 file(s))
Markdown table audit: clean (8 table(s), 200 file(s))
Markdown link audit: clean (198 local link(s), 200 file(s))
```
## Validation structurelle
Le contrôle structurel spécifique a terminé proprement :
```text
0.1.1 alpha.1 structural audit: clean (72 prior pairs, Web scope bounded, Tauri DEFER preserved)
```
Il confirme notamment :
- les `72` couples delta/history antérieurs complets ;
- la conservation de `alpha.2 FAIL`, `alpha.2.fix.1 PASS`, `alpha.3 FAIL`, `alpha.3.fix.1 PASS` et `rel.1 PASS` pour `0.1.0` ;
- l'engagement de `0.1.1` à `0.1.7` sans réservation de `0.1.8` ;
- le maintien du skeleton Tauri en `DEFER` ;
- le maintien hors scope de WASM, du serveur Web Rust et de deployment/operations ;
- la présence dans le prompt `007` des responsabilités TypeScript, Vite, package manager/manifest/lockfile et de la contrainte de ne pas lever le `DEFER` Tauri ;
- la présence dans le plan des tranches `alpha.2` à `beta.1` et de leurs frontières.
## Contrôles Git
`git diff --check` et `git diff --cached --check` n'ont remonté aucun défaut.
Le statut indexé transmis avant ajout du présent history est exactement :
```text
M README.md
M VERSION
A deltas/0.1.1/alpha.1.md
M docs/000-README.md
A docs/plans/007-V0_1_1_WEB_FRONTEND_FOUNDATION_PLAN.md
```
Le scope correspond exactement au delta annoncé.
## Revue qualitative et précisions acquises
La revue opérateur confirme que `alpha.1` reste un cadrage et n'impose pas arbitrairement npm, Bootstrap, WASM ou un host particulier.
Trois préférences supplémentaires sont acquises pour leur formalisation à partir de `alpha.2` :
- Vite n'est pas obligatoire, mais constitue le build tool/dev server **fortement recommandé** pour les frontends contrôlés lorsque ses capacités correspondent au besoin ; une alternative reste possible avec justification ;
- TypeScript n'est pas obligatoire, mais constitue le langage **fortement recommandé** pour les frontends contrôlés afin d'ajouter une vérification statique avant génération/exécution du JavaScript et de faciliter les frontières typées avec d'autres écosystèmes, notamment Rust lorsque des outils tels que TS-RS sont applicables ;
- Sass n'est pas obligatoire, mais est **fortement recommandé** pour les chaînes de styles non triviales, particulièrement lorsqu'un package frontend expose des sources/entrypoints Sass ou SCSS et permet une personnalisation contrôlée via variables, maps, mixins ou modules sans modifier le package tiers.
Dans la force normative PGR, « fortement recommandé » se traduit par `SHOULD`, jamais par `MUST`. Bootstrap reste un exemple concret de bibliothèque exploitable via Sass, pas une dépendance Web universelle.
## Décision
`0.1.1-alpha.1` est `PASS`. Aucun fix ni REPLAN n'est requis.
La trajectoire reprend à :
```text
0.1.1-alpha.2
```
`alpha.2` doit fixer les frontières d'ownership Web et classifier les choix Games selon `ADOPT / KEEP-LOCAL / OVERRIDE / DEFER`, tout en conservant les détails de configuration TypeScript/package pour `alpha.3`, Vite/outputs pour `alpha.4` et CSS/Sass/validation pour `alpha.5`.

View File

@@ -0,0 +1,108 @@
<!-- file: history/0.1.1/alpha.2.fix.1.md -->
<!-- version: 1 -->
# History 0.1.1-alpha.2.fix.1 — correction de la gate d'ownership Web
## Statut
PASS
La gate opérateur de `0.1.1-alpha.2.fix.1` exécutée le `2026-09-27` est propre.
Le correctif reste strictement limité au défaut de syntaxe de la gate de `alpha.2`. Aucun profil Web, index normatif, document d'architecture ou profil Tauri n'a été réécrit par le fix.
## Baseline opérateur
La tranche `0.1.1-alpha.2` et son history `FAIL` ont été commités puis poussés avant application du fix :
```text
commit dc63b54
message 0.1.1-alpha.2
push origin/master PASS
```
Le history `FAIL` reste présent dans `HEAD` et le delta historique `alpha.2.md` est conservé.
## Contrôles d'identité
Les contrôles opérateur ont confirmé :
```text
VERSION 0.1.1-alpha.2.fix.1
history/0.1.1/alpha.2.md présent dans HEAD
deltas/0.1.1/alpha.2.md présent
deltas/0.1.1/alpha.2.fix.1.md présent
history/0.1.1/alpha.2.fix.1.md absent pendant la gate
history alpha.2 FAIL
RULES.md version 13
docs/000-README.md version 25
docs/architecture/003-RULE_PROFILE_MODEL.md version 6
docs/plans/007-V0_1_1_WEB_FRONTEND_FOUNDATION_PLAN.md version 3
docs/rules/000-README.md version 15
docs/rules/710-TAURI.md version 6
```
## Gate spécifique
La gate Python corrigée atteint son message final :
```text
0.1.1 alpha.2.fix.1 ownership gate: clean (alpha.2 FAIL preserved, 530/540/550/560 reconfirmed, Python literals safe)
```
Elle reconfirme notamment :
- le statut `FAIL` historique de `alpha.2` ;
- les owners indépendants `530 TypeScript`, `540 JavaScript package ecosystem`, `550 Vite` et `560 CSS / Sass` ;
- les recommandations `SHOULD` TypeScript, Vite et Sass ;
- la classification Games préparatoire ;
- le maintien de `0.1.8` hors roadmap ;
- le maintien du `DEFER` du skeleton Tauri.
## Tests Python
La suite complète a affiché :
```text
Ran 48 tests in 0.711s
OK
```
Soit `48/48` tests `PASS`.
## Audits Markdown
Les audits ont affiché :
```text
Markdown header audit: clean (208 file(s))
Markdown table audit: clean (9 table(s), 208 file(s))
Markdown link audit: clean (219 local link(s), 208 file(s))
```
## Hygiène Git et scope
`git diff --check` et `git diff --cached --check` n'ont produit aucune erreur.
Le scope indexé observé est exactement :
```text
M VERSION
A deltas/0.1.1/alpha.2.fix.1.md
M docs/plans/007-V0_1_1_WEB_FRONTEND_FOUNDATION_PLAN.md
```
Aucun contenu prévu pour `alpha.3` n'a été absorbé dans le fix.
## Décision
`0.1.1-alpha.2.fix.1` est validée `PASS`.
La trajectoire normale reprend avec :
```text
0.1.1-alpha.3
```
Cette tranche est consacrée à TypeScript et à l'écosystème de package : `tsconfig`, `package.json`, scripts, sélection explicite du package manager et politique de lockfile. Vite reste réservé à `alpha.4` et CSS/Sass à `alpha.5`.

134
history/0.1.1/alpha.2.md Normal file
View File

@@ -0,0 +1,134 @@
<!-- file: history/0.1.1/alpha.2.md -->
<!-- version: 1 -->
# History 0.1.1-alpha.2 — frontières d'ownership Web
## Statut
FAIL
La gate opérateur de `0.1.1-alpha.2` exécutée le `2026-09-27` n'a pas atteint un PASS complet.
Le contenu attendu de la tranche a été appliqué, la tranche précédente `alpha.1` est bien enregistrée `PASS`, les `48` tests Python ont réussi et les trois audits Markdown sont propres. Le contrôle spécifique d'ownership Web n'a toutefois pas pu s'exécuter : un littéral Python entouré de quotes simples contient l'apostrophe de `s'applique`, ce qui provoque un `SyntaxError`.
Aucun défaut normatif des profils Web livrés par `alpha.2` n'est établi par les preuves disponibles. Le défaut appartient à la gate de validation elle-même.
## Baseline opérateur
`0.1.1-alpha.1` a été clôturée avec son history `PASS`, puis committée et poussée avant application de `alpha.2` :
```text
commit 7b7565d
message 0.1.1-alpha.1
push origin/master PASS
```
Après application de `alpha.2`, les contrôles initiaux ont confirmé :
```text
VERSION 0.1.1-alpha.2
history/0.1.1/alpha.1.md présent dans HEAD
deltas/0.1.1/alpha.2.md présent
history/0.1.1/alpha.2.md absent pendant la gate
docs/rules/530-TYPESCRIPT.md présent
docs/rules/540-JAVASCRIPT_PACKAGE_ECOSYSTEM.md présent
docs/rules/550-VITE.md présent
docs/rules/560-CSS_SASS.md présent
RULES.md version 13
docs/000-README.md version 25
docs/architecture/003-RULE_PROFILE_MODEL.md version 6
docs/plans/007-V0_1_1_WEB_FRONTEND_FOUNDATION_PLAN.md version 2
docs/rules/000-README.md version 15
docs/rules/710-TAURI.md version 6
```
## Défaut exact de la gate
Le delta contenait dans son bloc Python :
```python
'Le profil s'applique uniquement lorsqu'un projet utilise réellement Vite.'
```
La chaîne étant entourée de quotes simples, l'apostrophe de `s'applique` termine le littéral prématurément. Python a donc arrêté le contrôle avec :
```text
File "<stdin>", line 20
'Le profil s'applique uniquement lorsqu'un projet utilise réellement Vite.',
^^^^^^^^^^^^^^^^^^^^^
SyntaxError: invalid syntax. Perhaps you forgot a comma?
```
Le message final attendu :
```text
0.1.1 alpha.2 ownership audit: clean (...)
```
n'a donc pas été produit.
## Preuves réussies malgré le défaut
La suite Python globale a exécuté `48` tests et tous ont réussi :
```text
Ran 48 tests in 0.738s
OK
```
Les audits Markdown ont affiché :
```text
Markdown header audit: clean (206 file(s))
Markdown table audit: clean (9 table(s), 206 file(s))
Markdown link audit: clean (219 local link(s), 206 file(s))
```
Le scope Git observé avant ajout du présent history est exactement :
```text
M RULES.md
M VERSION
A deltas/0.1.1/alpha.2.md
M docs/000-README.md
M docs/architecture/003-RULE_PROFILE_MODEL.md
M docs/plans/007-V0_1_1_WEB_FRONTEND_FOUNDATION_PLAN.md
M docs/rules/000-README.md
A docs/rules/530-TYPESCRIPT.md
A docs/rules/540-JAVASCRIPT_PACKAGE_ECOSYSTEM.md
A docs/rules/550-VITE.md
A docs/rules/560-CSS_SASS.md
M docs/rules/710-TAURI.md
```
Ce scope correspond aux fichiers annoncés par `alpha.2`.
## Décision
Aucun REPLAN n'est requis. La tranche reste conceptuellement bornée aux frontières d'ownership Web et aux préférences `SHOULD` déjà livrées.
La correction autorisée est :
```text
0.1.1-alpha.2.fix.1
```
Le fix doit :
- conserver intégralement `deltas/0.1.1/alpha.2.md` comme snapshot historique ;
- conserver `RULES.md`, `docs/000-README.md`, `docs/architecture/003-RULE_PROFILE_MODEL.md`, `docs/rules/000-README.md`, `docs/rules/710-TAURI.md` et les profils `530/540/550/560` inchangés ;
- remplacer uniquement les littéraux Python fragiles dans la nouvelle gate par une forme syntaxiquement sûre ;
- reconfirmer le `FAIL` historique de `alpha.2` et le contenu déjà livré ;
- exécuter à nouveau les `48` tests et les trois audits Markdown ;
- vérifier que le scope du fix reste limité à `VERSION`, au plan actif et au nouveau delta de correction.
## Résultat
`0.1.1-alpha.2` est enregistré `FAIL` pour défaut de syntaxe dans sa gate opérateur, sans défaut normatif établi sur les nouveaux owners Web.
La seule transition autorisée est :
```text
0.1.1-alpha.2.fix.1
```

Some files were not shown because too many files have changed in this diff Show More